【问题标题】:Apply transformation in a fragment shader在片段着色器中应用变换
【发布时间】:2021-12-25 09:47:11
【问题描述】:

我知道我可以在顶点着色器中执行转换(旋转、缩放)。但是我想知道我是否可以在 fragment 着色器中做类似的事情。

shadertoy.com - transformation_in_fragment_shade

我尝试通过将uv 相乘来在片段着色器中应用转换,但被结果弄糊涂了。

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;
    uv = fract(uv * 2.);
    vec4 img = texture(iChannel0, uv);
    
    // Output to screen
    fragColor = img;
}

我预计图片会被缩放2x而不是缩小,我也对这里fract的含义感到困惑,为什么应用这个功能可以将图像分成4块。

所以问题是,我可以在片段着色器中应用旋转或缩放吗?我应该使用不同的方法进行旋转,在此处缩放吗?

【问题讨论】:

    标签: glsl shader webgl fragment-shader


    【解决方案1】:

    纹理坐标在 [0.0, 1.0] 范围内。 (0, 0) 是左下角, (1, 1) 是右上角。 texture 在特定坐标处查找纹理并从该坐标返回颜色。 如果将纹理坐标乘以 2,则坐标将在 [0.0, 2.0] 范围内。从 1.0 到 2.0 的坐标不在纹理上,并被钳制到 1.0。
    fract 函数会跳过整数部分。例如,1.5 变为 0.5。所以uv = fract(uv * 2.) 将坐标从区间 [0.0, 1.0] 映射到 2 个区间 [0.0, 1.0], [0.0, 1.0]。
    如果要放大 (2x) 到中心,则需要在视图中的坐标 (0.25, 0.25) 和 (0.75, 0.75) 之间投影纹理:

    uv = uv / 2.0 + 0.25; // maps [0.0, 1.0] to [0.25, 0.75]
    

    您可以对 3x3 矩阵执行相同操作:

    mat3 zoom = mat3(
        vec3(0.5, 0.0, 0.0),
        vec3(0.0, 0.5, 0.0),
        vec3(0.25, 0.25, 1.0));
    
    uv = (zoom * vec3(uv, 1.0)).xy;
    

    【讨论】:

    • 谢谢!它解决了我的问题。这是否意味着我不能简单地应用矩阵(例如:mat * uv)来完成这项工作?
    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 2018-05-02
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    相关资源
    最近更新 更多