Оригинальный код дал рабочий пример, в котором твердые объекты правильно сочетаются с частично прозрачными однократными объектами. Это работает, как и ожидалось. Тем не менее, моя цель состоит в том, чтобы смешать непрозрачные текстуры с частично прозрачными текстурами, а также прозрачные текстуры смешивания с другими прозрачными текстурами. Проблема возникает, когда один прозрачный объект находится непосредственно перед другим прозрачным объектом. В этом случае полностью непрозрачные пиксели текстуры, ближайшие к камере, выглядят прозрачными, что неверно. Я не могу найти решение этой проблемы. < /P>
Вот как я загружаю прозрачную текстуру: < /p>
Код: Выделить всё
// Load texture
unsigned int transparentTexture;
glGenTextures(1, &transparentTexture);
glBindTexture(GL_TEXTURE_2D, transparentTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, nrChannels;
unsigned char* data = stbi_load(FileSystem::getPath("resources/textures/CharacterSprite.png").c_str(), &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
//glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout < /p>
const char *transparentVs =
R"(
#version 420 core
// shader inputs
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 uvCoords;
// model * view * projection matrix
uniform mat4 mvp;
out vec2 textureCoords;
void main()
{
gl_Position = mvp * vec4(position, 1.0f);
textureCoords = uvCoords;
}
)";
const char *transparentFs =
R"(
#version 420 core
// shader outputs
layout (location = 0) out vec4 accum;
layout (location = 1) out float reveal;
// In variables
in vec2 textureCoords;
// material color
uniform vec4 colorIn;
uniform bool useTexture;
uniform sampler2D textureSampler;
void main()
{
vec4 color = colorIn;
if (useTexture)
{
color = texture(textureSampler, textureCoords);
}
// 1. Premultiply Alpha:
color.rgb *= color.a; // color.r = color.r * color.a; color.g = color.g * color.a; color.b = color.b * color.a;
// 2. Calculate Weight
float weight = color.a; // or color.a * some_factor if you want to adjust the weighting
//float weight =
// max(min(1.0, max(max(color.r, color.g), color.b) * color.a)), color.a) *
// clamp(0.03 / (1e-5 + pow(z / 200, 4.0)), 1e-2, 3e3);
// 3. Output to Accumulation Buffer:
accum = vec4(color.rgb * weight, weight);
// 4. Output to Revealage Buffer:
reveal = color.a; // or 1.0 - color.a if you flip the blend equation in composite shader
}
)";
Код: Выделить всё
const char *compositeVs =
R"(
#version 420 core
// shader inputs
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0f);
}
)";
const char *compositeFs =
R"(
#version 420 core
// shader outputs
layout (location = 0) out vec4 fragColor;
// color accumulation buffer
layout (binding = 0) uniform sampler2D accum;
layout (binding = 1) uniform sampler2D reveal;
layout (binding = 2) uniform sampler2D opaqueTexture; // Opaque texture
// epsilon number
const float EPSILON = 0.00001f;
// calculate floating point numbers equality accurately
bool isApproximatelyEqual(float a, float b)
{
return abs(a - b)
Подробнее здесь: [url]https://stackoverflow.com/questions/79437495/implement-weighted-blended-order-independent-transparency-with-opengl-in-c[/url]