我一直在尝试使用 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 x 600)。对应的渲染是:
我向 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);
}
网站上的输出是:
我不明白这里发生了什么,网站上的几何形状是否有所不同?我的程序的最终目的是在 GPU 上运行光线行进器算法,但我不确定要渲染什么几何体。我的猜测只是一个覆盖整个屏幕的矩形(并根据相机进行变换),但我需要不同的东西吗?我希望能够单独控制每个像素的颜色,并使用光线行进而不是光栅器渲染几何图形。我的方法完全失效了吗?
注:图片中最左边是我裁剪不当的结果。
你的
fragCoord
和Shadertoy的fragCoord
其实不一样。
fragCoord
在 vec2(-1.0)
到 vec2(1.0)
的范围内,即标准化设备坐标 (NDC)fragCoord
在 vec2(0.0)
到 iResolution
的范围内,即窗口相对坐标(这就是你想要的)Shadertoy的
fragCoord
简单来说就是gl_FragCoord.xy
,就是当前fragment的窗口相对坐标。
此外,您看到这样 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);
}