Я полагаю, что это больше математический вопрос, чем что-либо.
Вот базовый шейдер:
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 < 0,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);
}
Что приводит к тому же:
По логике, я должен иметь возможность использовать 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 — это операция с плавающей запятой, а значения 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);
Если кто-то хочет увидеть результат ответа 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);
}
Ух ты! Большое спасибо! Это помогло мне лучше понять, что происходит!