【问题标题】:Sun shader not working太阳着色器不工作
【发布时间】:2014-03-09 18:37:23
【问题描述】:

我正在尝试让遮阳板工作,但无法正常工作。
我目前得到的是屏幕左下角的四分之一圆/省略号,它真的粘在我的屏幕上(如果我移动相机,它也会移动)。

我所做的只是渲染两个三角形以形成一个覆盖屏幕的四边形,屏幕宽度和高度统一。

顶点着色器

#version 430 core

void main(void) {
    const vec4 vertices[6] = vec4[](
        vec4(-1.0, -1.0, 1.0, 1.0),
        vec4(-1.0, 1.0, 1.0, 1.0),
        vec4(1.0, 1.0, 1.0, 1.0),

        vec4(1.0, 1.0, 1.0, 1.0),
        vec4(1.0, -1.0, 1.0, 1.0),
        vec4(-1.0, -1.0, 1.0, 1.0)
    );

    gl_Position = vertices[gl_VertexID];
}

片段着色器

#version 430 core

layout(location = 7) uniform int screen_width;
layout(location = 8) uniform int screen_height;

layout(location = 1) uniform mat4 view_matrix;
layout(location = 2) uniform mat4 proj_matrix;

out vec4 color;

uniform vec3 light_pos = vec3(-20.0, 7.5, -20.0);

void main(void) {
    //calculate light position in screen space and get x, y components
    vec2 screen_space_light_pos = (proj_matrix * view_matrix * vec4(light_pos, 1.0)).xy;

    //calculate fragment position in screen space
    vec2 screen_space_fragment_pos = vec2(gl_FragCoord.x / screen_width, gl_FragCoord.y / screen_height);

    //check if it is in the radius of the sun
    if (length(screen_space_light_pos - screen_space_fragment_pos) < 0.1) {
        color = vec4(1.0, 1.0, 0.0, 1.0);
    }
    else {
        discard;
    }
}

认为它做了什么:

  • 获取太阳 (light_pos) 在屏幕空间中的位置。
  • 获取片段在屏幕空间中的位置。
  • 如果它们之间的距离低于某个值,则用黄色绘制片段;
  • 否则丢弃。

【问题讨论】:

    标签: opengl graphics 3d shader fragment-shader


    【解决方案1】:

    screen_space_light_pos 尚未在剪辑空间中。你错过了透视划分:

    vec3 before_division = (proj_matrix * view_matrix * vec4(light_pos, 1.0)).xyw;
    vec2 screen_space_light_pos = before_division.xy / before_division.z;
    

    对于常见的proj_matrix 配置,screen_space_light_pos 将位于[-1,1]x[-1,1] 中。要匹配screen_space_fragment_pos 范围,您可能需要调整screen_space_light_pos

    screen_space_light_pos = screen_space_light_pos * 0.5 + 0.5;
    

    【讨论】:

    • 此外,您可以通过在着色器之外计算剪辑空间太阳中心来优化这个简单的着色器
    • 奇怪;随着您的实现screen_space_light_posxy 组件上提供isnan()。但是before_division 以 vec3 形式给出了 xyz 组件上的所有正确值。
    • 其实是因为before_division.z == 0,但我还是要弄清楚为什么会这样。
    • 您的代码现在可以运行了,非常感谢。原来我忘记提供proj_matrixview_matrix 制服,但不知道为什么 GLSL/OpenGL 没有错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多