ShaderToy如何从Red创建Cyan?

时间:2017-12-12 10:07:30

标签: glsl

在此处运行:https://www.shadertoy.com/view/Mtsfzs

Buf A的来源:

vec4 getPixel(in vec2 xy)
{ return texture(iChannel0, xy);
}

vec4 getPixelBlurredB(in vec2 xy)
{  
return (getPixel(xy)+getPixel(xy + 1./iResolution.xy) )/2.;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 xy = fragCoord.xy/iResolution.xy; 
    vec4 c;

    c = getPixel( xy*.99 );      // Zoom in
    c -= getPixelBlurredB( xy*.99 )/4.; // Darken interior more than boundary
    c *= 1.3;                    // Brighten
    c -= 0.0001;                  // Darken - dark more

    if(fragCoord.x==.5 && fragCoord.y==.5 /*precarious*/)
        c=vec4(1.,0.,0.,0.);

    fragColor = clamp(c,-0.1,1.); //-ve causes cyan!s

}

图片来源:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    fragColor = texture(iChannel0, fragCoord.xy/iResolution.xy);
}

输出: enter image description here

模式种子是颜色R = 1,G = 0,B = 0并且由不添加到G或B的代码处理,因此我希望输出仅显示红色。但输出也显示青色,表明G和B通道在某种程度上变为非零。怎么样?

1 个答案:

答案 0 :(得分:1)

c -= 0.0001;
fragColor = clamp(c,-0.1,1.);

第一行从所有组件中减去一个小值,而不仅仅是红色。第二行将得到的颜色钳制在-0.1和1.0之间的范围内。假设采样为鲜红色,则会产生此输出:vec4(1.0, -0.0001, -0.0001, -0.0001)。由于无法显示负值,因此在将此颜色呈现给屏幕时,会将其限制在(0.0,1.0)范围内,从而产生纯红色。但负值仍然存在于缓冲区中。

c = getPixel( xy*.99 );
c -= getPixelBlurredB( xy*.99 )/4.;

现在,如果我们考虑当前像素为黑色的情况,但getPixelBlurredB()采样的像素具有略微负的颜色,则钳制后产生的c类似于:{{1禁止缩放。这会产生非常微弱的青色,太微弱而无法正常显示,但它就在那里。它最终会被放大到足以通过在每次迭代中逐步采样和相乘来变得可见。您可以通过将拐角值初始化为vec4(-0.1, 0.0001, 0.0001, 0.0001)来证明此放大效果。最终它会产生完全相同的模式,开始时只需要更长的时间。这也是你最初只看到红色的原因。

作为进一步证明,用vec4(0.0001, 0.0, 0.0, 0.0)替换减法仅产生预期的红色,c.r -= 0.0001显示红色和绿色而不是红色和青色,c.rg -= 0.0001最终显示为红色和蓝色。