#c #glsl #shader
#c #glsl #шейдер
Вопрос:
Я полагаю, что это скорее математический вопрос, чем что-либо еще.
Вот базовый шейдер:
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);
}
Сначала мы нормализуем наши координаты X между (0.0,0.1), где 0.0 — крайний левый угол экрана, а 1.0 — крайний правый. Превращая все пиксели с координатами x <.5 в черные, я просто маскирую половину экрана черным. Это приводит к следующему:
Если я использую координаты пространства экрана, я могу добиться аналогичного результата, ширина фактического экрана составляет 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);
}
Логически тогда я должен иметь возможность использовать координаты по модулю в пространстве экрана для создания полос. Взяв 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 == 0?
Ответ №1:
Я предполагаю fragCoord
, что задано gl_FragCoord
.
mod
это операция с плавающей запятой, и значения gl_FragCoord
не являются целыми. См. Ссылку на Khronos OpenGL:
По умолчанию gl_FragCoord принимает начало координат окна в нижнем левом углу и предполагает, что центры пикселей расположены в центрах полупикселей. Например, местоположение (x, y) (0,5, 0,5) возвращается для самого нижнего левого пикселя в окне.
Поэтому результат операции по модулю никогда не будет равен 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);
Комментарии:
1. Вау! Большое вам спасибо! Это помогло мне лучше понять, что происходит!
Ответ №2:
На случай, если кто-нибудь захочет увидеть результат ответа 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);
}