在屏幕上使用模数 Space GLSL 中的坐标未产生预期结果
Using Modulo on Screen Space Coordinates in GLSL Not Producing Expected Result
我想这更像是一道数学题。
这是一个基本的着色器:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if(uv.x < .5) col = vec3(0.0,0.0,0.0);
// Output to screen
fragColor = vec4(col,1.0);
}
首先,我们在 (0.0,0.1) 之间标准化 X 坐标,其中 0.0 是屏幕最左侧,1.0 是最右侧。通过将 x 坐标 < .5 的所有像素变为黑色,我只是将一半的屏幕遮盖成黑色。结果如下:
如果我用屏幕space坐标也能达到类似的效果,实际屏幕的宽度是800像素。所以我可以通过执行以下操作将 x < 400 的每个像素用黑色遮盖:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if(fragCoord.x < 400.) col = vec3(0.0,0.0,0.0);
// Output to screen
fragColor = vec4(col,1.0);
}
结果相同:
那么从逻辑上讲,我应该可以在屏幕 space 坐标上使用 Modulo 来创建条纹。通过获取 mod(fragCoord.x,10.0) 并检查结果为 0.0 的位置,我应该禁用其 x 值为 10 的任何像素行。
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if(mod(fragCoord.x, 10.0) == 0.0) col = vec3(0.0,0.0,0.0);
// Output to screen
fragColor = vec4(col,1.0);
}
然而,我所期望的并没有发生:
有人可以解释为什么我在 x%10 == 0 的地方看不到黑色像素行吗?
我假设 fragCoord
是由 gl_FragCoord
设置的。
mod
is a floating point operation and the values of gl_FragCoord
不是整数。请参阅 Khronos OpenGL 参考资料:
By default, gl_FragCoord assumes a lower-left origin for window coordinates and assumes pixel centers are located at half-pixel centers. For example, the (x, y) location (0.5, 0.5) is returned for the lower-left-most pixel in a window.
因此模运算的结果永远不会是0.0。将 fragCoord.x
转换为整数值并使用 %
运算符:
if(mod(fragCoord.x, 10.0) == 0.0) col = vec3(0.0,0.0,0.0);
if (int(fragCoord.x) % 10 == 0) col = vec3(0.0);
以防有人想看Rabbid76的回答结果
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if (int(fragCoord.x) % 10 == 0) col = vec3(0.0);
// Output to screen
fragColor = vec4(col,1.0);
}
我想这更像是一道数学题。
这是一个基本的着色器:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if(uv.x < .5) col = vec3(0.0,0.0,0.0);
// Output to screen
fragColor = vec4(col,1.0);
}
首先,我们在 (0.0,0.1) 之间标准化 X 坐标,其中 0.0 是屏幕最左侧,1.0 是最右侧。通过将 x 坐标 < .5 的所有像素变为黑色,我只是将一半的屏幕遮盖成黑色。结果如下:
如果我用屏幕space坐标也能达到类似的效果,实际屏幕的宽度是800像素。所以我可以通过执行以下操作将 x < 400 的每个像素用黑色遮盖:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if(fragCoord.x < 400.) col = vec3(0.0,0.0,0.0);
// Output to screen
fragColor = vec4(col,1.0);
}
结果相同:
那么从逻辑上讲,我应该可以在屏幕 space 坐标上使用 Modulo 来创建条纹。通过获取 mod(fragCoord.x,10.0) 并检查结果为 0.0 的位置,我应该禁用其 x 值为 10 的任何像素行。
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if(mod(fragCoord.x, 10.0) == 0.0) col = vec3(0.0,0.0,0.0);
// Output to screen
fragColor = vec4(col,1.0);
}
然而,我所期望的并没有发生:
有人可以解释为什么我在 x%10 == 0 的地方看不到黑色像素行吗?
我假设 fragCoord
是由 gl_FragCoord
设置的。
mod
is a floating point operation and the values of gl_FragCoord
不是整数。请参阅 Khronos OpenGL 参考资料:
By default, gl_FragCoord assumes a lower-left origin for window coordinates and assumes pixel centers are located at half-pixel centers. For example, the (x, y) location (0.5, 0.5) is returned for the lower-left-most pixel in a window.
因此模运算的结果永远不会是0.0。将 fragCoord.x
转换为整数值并使用 %
运算符:
if(mod(fragCoord.x, 10.0) == 0.0) col = vec3(0.0,0.0,0.0);
if (int(fragCoord.x) % 10 == 0) col = vec3(0.0);
以防有人想看Rabbid76的回答结果
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
if (int(fragCoord.x) % 10 == 0) col = vec3(0.0);
// Output to screen
fragColor = vec4(col,1.0);
}