片段着色器中的屏幕坐标

时间:2014-04-05 12:47:48

标签: unity3d shader fragment-shader vertex-shader cg

在如下所示的片段着色器中:

Shader "ColorReplacement" {

    Properties {
        _MainTex ("Greyscale (R) Alpha (A)", 2D) = "white" {}
    }
    SubShader {
        ZTest LEqual
        ZWrite On
        Pass {
            Name "ColorReplacement"
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma fragmentoption ARB_precision_hint_fastest
        #pragma target 3.0
                #include "UnityCG.cginc"


                struct v2f
                {
                    float4  pos : SV_POSITION;
                    float4  uv : TEXCOORD0;
                }; 

                v2f vert (appdata_tan v)
                {
                    v2f o;
                    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                    o.uv = v.texcoord.xy;
                    return o;
                }

                sampler2D _MainTex;

                float4 frag(v2f i) : COLOR
                {

                }
            ENDCG
        }
    }
    Fallback off
 }

有没有办法知道屏幕中i.uv的坐标?

我对着色器完全陌生。着色器应用于在屏幕中某处绘制的对象,传递给frag的第一个像素可能不对应于屏幕的第一个像素(视口),有没有办法知道这个位置屏幕坐标中的像素?


修改 是的,我想在屏幕上获取片段位置。 Unity接受用Cg和HLSL编写的顶点和片段程序。但我不知道如何将此着色器转换为HLSL。

Cg中gl_FragCoord的等价物是WPOS。我可以运行以下着色器:

Shader "Custom/WindowCoordinates/Base" {
SubShader {
    Pass {
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag
        #pragma target 3.0

        #include "UnityCG.cginc"

        float4 vert(appdata_base v) : POSITION {
            return mul (UNITY_MATRIX_MVP, v.vertex);
        }

        fixed4 frag(float4 sp:WPOS) : COLOR {
            return fixed4(sp.xy/_ScreenParams.xy,0.0,1.0);
        }
        ENDCG
    }
}
}

它以我想要的方式使用屏幕位置,但是我可以使用这样的菜鸟,甚至可以混合两个着色器以获得我想要的东西:在我的着色器中我试图访问{ {1}},其计算方法与上面着色器中v2f.pos的计算方式相同,但我得到错误:

sp

如果我将Program 'frag', variable/member "pos" has semantic "POSITION" which is not visible in this profile 更改为pos而不是WPOS,我会收到类似的错误:

SV_POSITION

这很奇怪,因为我使用了上述着色器中相同的Program 'vert', variable/member "pos" has semantic "WPOS" which is not visible in this profile at line 35

3 个答案:

答案 0 :(得分:0)

在GLSL片段阶段,有一个内置变量gl_FragCoord,它携带视口内的片段像素位置。如果视口覆盖整个屏幕,这就是您所需要的。如果视口仅覆盖屏幕的子窗口,则必须将xy偏移到视口并将其添加到gl_FragCoord.xy以获取屏幕位置。现在你的着色器代码不是用GLSL编写的,但显然是Cg(看起来像Unity扩展)。但是这应该有一些对应。

答案 1 :(得分:0)

以为我建议你阅读一些关于着色器的书籍或手册,这是一个简单的解决方案

      vec2 texelSize = 1.0 / vec2(textureSize(yourTexSampler, 0));
  vec2 screenCoords = gl_FragCoord.xy * texelSize;

我不记得在Cg中如何调用gl_FragCoord,因此在doc中搜索。对于textureSize() - 替换输入纹理的宽度/高度。

Here is我前段时间提出的同样问题。

另请查看this

答案 2 :(得分:0)

According to docs有一个辅助功能-ComputeScreenPos。