unity3d 片段着色器中的屏幕坐标

46scxncf  于 2023-01-02  发布在  其他
关注(0)|答案(3)|浏览(141)

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

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的第一个像素可能与屏幕(视口)的第一个像素不对应,有没有办法知道这个像素在屏幕坐标中的位置?

EDIT是的,我想获得屏幕上的碎片位置。Unity接受用Cg和HLSL编写的顶点和碎片程序。但是我不知道如何将这个着色器转换为HLSL。

Gl_FragCoord在Cg中的等价物是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
    }
}
}

这使用屏幕位置的方式,我想要的,但我是这样一个新手,我甚至不能混合两个着色器,以获得我想要的:在我的着色器中,我尝试访问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

这很奇怪,因为我使用的是与上面相同的target 3.0着色器。

jhdbpxl9

jhdbpxl91#

在GLSL片段阶段,有一个内置变量gl_FragCoord,它携带了片段像素在视口中的位置。如果视口覆盖了整个屏幕,这就是你所需要的。如果视口只覆盖了屏幕的一个子窗口,你必须将xy偏移量传递给视口,并将其添加到gl_FragCoord.xy以获得屏幕位置。现在你的着色器代码不是用GLSL编写的,但显然Cg(与统一扩展,因为它似乎)。但它应该有一些对应这一点可用。

tkclm6bt

tkclm6bt2#

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

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

我不记得在Cg中如何调用gl_FragCoord,所以在docs中搜索textureSize()- -用输入纹理的宽度/高度替换。
这个问题和我不久前问的差不多。
还可以看一下this

taor4pac

taor4pac3#

According to docs有一个辅助函数- ComputeScreenPos。

相关问题