OpenGL shapes look darker when camera is below them

时间:2018-01-23 19:25:23

标签: opengl graphics glsl

I have a problem with rendering my quads in OpenGL. They look darker when translucency is applied, if the camera is below a certain point. How can I fix this? The objects are lots of quads with tiny amounts of Z difference. I have implemented rendering of translucent objects from this webpage: http://www.alecjacobson.com/weblog/?p=2750

Render code:

double alpha_factor = 0.75;
double alpha_frac = (r_alpha - alpha_factor * r_alpha) / (1.0 - alpha_factor * r_alpha);
double prev_alpha = r_alpha;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);

// quintuple pass to get the rendering of translucent objects, somewhat correct
// reverse render order for getting alpha going!
// 1st pass: only depth checks
glDisable(GL_CULL_FACE);
glDepthFunc(GL_LESS);
r_alpha = 0;
// send alpha for each pass
// reverse order
drawobjects(RENDER_REVERSE);

// 2nd pass: guaranteed back face display with normal alpha
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glDepthFunc(GL_ALWAYS);
r_alpha = alpha_factor * (prev_alpha + 0.025);
// reverse order
drawobjects(RENDER_REVERSE);

// 3rd pass: depth checked version of fraction of calculated alpha. (minus 1)
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glDepthFunc(GL_LEQUAL);
r_alpha = alpha_frac + 0.025;
// normal order
drawobjects(RENDER_NORMAL);

// 4th pass: same for back face
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glDepthFunc(GL_ALWAYS);
r_alpha = alpha_factor * (prev_alpha + 0.025);
// reverse order
drawobjects(RENDER_REVERSE);

// 5th pass: just put out the entire thing now
glDisable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
r_alpha = alpha_frac + 0.025;
// normal order
drawobjects(RENDER_NORMAL);

glDisable(GL_BLEND);

r_alpha = prev_alpha;

GLSL shaders:

Vertex shader:

#version 330 core

layout(location = 0) in vec3 vPos_ModelSpace;
layout(location = 1) in vec2 vertexUV;
layout(location = 2) in mat4 model_instance;

out vec2 UV;
out float alpha;

flat out uint alpha_mode;

// model + view + proj matrix
uniform mat4 proj;
uniform mat4 view;
uniform float v_alpha;
uniform uint v_alpha_mode;

void main() {
    gl_Position = proj * view * model_instance * vec4(vPos_ModelSpace, 1.0);

    // send to frag shader
    UV = vertexUV;
    alpha = v_alpha;
    alpha_mode = v_alpha_mode;
}

Fragment shader:

#version 330 core

// texture UV coordinate
in vec2 UV;
in float alpha;
flat in uint alpha_mode;

out vec4 color;

// Values that stay constant for the whole mesh.
uniform sampler2D texSampler;

void main() {
    int amode = int(alpha_mode);
    color.rgb = texture(texSampler, UV).rgb;
    color.a = alpha;

    if(amode == 1)
        color.rgb *= alpha;
}

Image when problem happens: How it looks

Image comparison for how it should look regardless of my position: How it should look

1 个答案:

答案 0 :(得分:1)

它在中心消失的原因是因为当你看到飞机的无限薄侧面时,它们会消失。至于亮度变化顶部与底部,它是由于你的传球如何处理表面法线。暗平面是远离相机的法线,但没有面向相机的平面使它们变亮。

看起来您在立方体中渲染了许多半透明平面来估计体积。以下是体积渲染的简单示例:https://www.shadertoy.com/view/lsG3D3

http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch39.html是一个很棒的资源。它解释了渲染音量的不同方法,展示了它有多棒。作为参考,最后一个示例使用球体作为代理几何体来对体积分形进行射线追踪。

快乐的编码!