Anonymous
Реализуйте взвешенную, смешанную независимую прозрачность с OpenGL в C ++
Сообщение
Anonymous » 13 фев 2025, 22:13
Итак, я в настоящее время пытаюсь реализовать взвешенные, смешанные OIT и использовал пример с сайта LearnoPengl; Это исходный исходный код. < /p>
Оригинальный код дал рабочий пример, в котором твердые объекты правильно сочетаются с частично прозрачными однократными объектами. Это работает, как и ожидалось. Тем не менее, моя цель состоит в том, чтобы смешать непрозрачные текстуры с частично прозрачными текстурами, а также прозрачные текстуры смешивания с другими прозрачными текстурами. Проблема возникает, когда один прозрачный объект находится непосредственно перед другим прозрачным объектом. В этом случае полностью непрозрачные пиксели текстуры, ближайшие к камере, выглядят прозрачными, что неверно. Я не могу найти решение этой проблемы. < /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
}
)";
composite-shader [/b]
Код: Выделить всё
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]
1739473983
Anonymous
Итак, я в настоящее время пытаюсь реализовать взвешенные, смешанные OIT и использовал пример с сайта LearnoPengl; Это исходный исходный код. < /p> Оригинальный код дал рабочий пример, в котором твердые объекты правильно сочетаются с частично прозрачными однократными объектами. Это работает, как и ожидалось. Тем не менее, моя цель состоит в том, чтобы смешать непрозрачные текстуры с частично прозрачными текстурами, а также прозрачные текстуры смешивания с другими прозрачными текстурами. Проблема возникает, когда один прозрачный объект находится непосредственно перед другим прозрачным объектом. В этом случае полностью непрозрачные пиксели текстуры, ближайшие к камере, выглядят прозрачными, что неверно. Я не могу найти решение этой проблемы. < /P> Вот как я загружаю прозрачную текстуру: < /p> [code]// 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 } )"; [/code] composite-shader [/b] [code]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]