代码之家  ›  专栏  ›  技术社区  ›  yomag1234

着色器输出与Shadertoy不匹配(Raymarching)

  •  0
  • yomag1234  · 技术社区  · 1 年前

    我一直在尝试使用Rust、SDL2和OpenGL(GLSL)来显示图形。几何体渲染良好,但碎片着色器中的颜色有问题。我目前正在渲染两个三角形,它们一起形成一个覆盖整个屏幕的正方形。

    正在绘制的顶点:

    let vertices: Vec<f32> = vec![
    // positions      
     1.0, -1.0, 0.0,   // bottom right
    -1.0, -1.0, 0.0,  // bottom left
    -1.0,  1.0, 0.0,   // top
    
    -1.0,  1.0, 0.0,   // top
     1.0,  1.0, 0.0, // top right
     1.0, -1.0, 0.0,   // bottom right
    ];
    

    这是我的顶点着色器:

    #version 330 core
    
    layout (location = 0) in vec3 Position;
    out vec2 fragCoord;
    
    void main() {
        gl_Position = vec4(Position, 1.0);
        fragCoord = Position.xy;
    }
    

    还有我的碎片着色器:

    #version 330 core
    
    uniform vec2 u_resolution;
    in vec2 fragCoord;
    out vec4 fragColor;
    
    
    void main() {
        vec2 uv = fragCoord.xy/u_resolution.xy;
        vec3 col = vec3(uv,0.0);
        fragColor = vec4(col, 1.0);
    }
    

    u_resolution 变量只是屏幕的尺寸(800乘600)。相应的渲染为:

    my output

    我向Shadertoy.com提交了以下着色器,它应该与我的等效:

    void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
        vec2 uv = fragCoord/iResolution.xy;
        vec3 col = vec3(uv,0.0);
        fragColor = vec4(col,1.0);
    }
    

    网站上的输出是:

    site output

    我不明白这里发生了什么,网站上的几何图形有什么不同吗?我的程序的最终目的是在GPU上运行光线漫游算法,但我不确定要渲染什么几何体。我的猜测只是一个覆盖整个屏幕的矩形(并随着相机的变化),但我需要一些不同的东西吗?我希望能够单独控制每个像素的颜色,并使用光线行进而不是光栅化器渲染几何体。我的方法完全偏离了吗?

    编辑:我为照片最左边的奇怪线条道歉,它们是我裁剪不当的结果。

    1 回复  |  直到 1 年前
        1
  •  1
  •   vallentin Remi    1 年前

    你的 fragCoord 和Shadertoy’s fragCoord 实际上并不相同。

    • 你的 fragCoord 在的范围内 vec2(-1.0) vec2(1.0) ,即标准化设备坐标(NDC)
    • Shadertoy’s fragCoord 在的范围内 vec2(0.0) iResolution ,即窗口相对坐标(这是您想要的)

    Shadertoy’s fragCoord 只是 gl_FragCoord.xy ,是当前片段的窗口相对坐标。


    此外,你看到这样4种颜色的原因是 u_resolution 实际上是 vec2(0.0) .

    因为再一次,你 fragCoord 在NDC中。所以当 fragCoord 组件在下面 0.0 它将导致负无穷大。然后当 fragCoord 分量大于零,则会产生正无穷大。

    然后,这些无限值将被有效地钳制,并导致您所看到的颜色极端。

    可以通过转换在Shadertoy上镜像此行为 fragCoord 返回NDC,然后除以 vec2(0.0) .

    void mainImage(out vec4 fragColor, in vec2 fragCoord)
    {
        vec2 ndc = (fragCoord / iResolution.xy) * 2.0 - 1.0;
    
        vec2 wrongResolution = vec2(0.0);
        vec2 uv = ndc / wrongResolution;
    
        fragColor = vec4(vec3(uv, 0.0), 1.0);
    }
    

    sahdertoy

    推荐文章