Unity3d 统一着色器像素操作

Unity3d 统一着色器像素操作,unity3d,shader,fragment-shader,Unity3d,Shader,Fragment Shader,我正在研究unity中的着色器,并试图获得下图。但我似乎无法让我的代码产生我的目标输出。我的最终目标是根据数组的大小划分整个图像。知道如何更正我的代码吗 目标产出: 代码:着色器“自定义/通道” { 性质 { _MainTex(“纹理”,2D)=“白色”{} } 子阴影 { 标记{“队列”=“透明”} 混合SrcAlpha ONEMUSSRCALPHA Pass { CGPROGRAM #pragma vertex vert #

我正在研究unity中的着色器,并试图获得下图。但我似乎无法让我的代码产生我的目标输出。我的最终目标是根据数组的大小划分整个图像。知道如何更正我的代码吗

目标产出:

代码:着色器“自定义/通道” { 性质 { _MainTex(“纹理”,2D)=“白色”{} } 子阴影 { 标记{“队列”=“透明”} 混合SrcAlpha ONEMUSSRCALPHA

    Pass
    {
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"
        uniform float4 _Test [3];

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
            float4 color : COLOR;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
            float4 color : COLOR;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
            o.uv = v.uv;
            return o;
        }

        sampler2D _MainTex;

        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 col;

            _Test[0] = fixed4(0,0,1,1);
            _Test[1] = fixed4(1,0,0,1);
            _Test[2] = fixed4(0,1,0,1);

            //Test1:
            int index = ceil(i.uv.x/1*_Test.Length)-1;
            col = _Test[index];

            return col;
        }
        ENDCG
    }
}
Pass
{
CGP程序
#pragma顶点顶点
#布拉格碎片碎片
#包括“UnityCG.cginc”
均匀漂浮4_试验[3];
结构appdata
{
浮动4顶点:位置;
float2uv:TEXCOORD0;
};
结构v2f
{
float2uv:TEXCOORD0;
浮动4顶点:SV_位置;
};
v2f垂直(appdata v)
{
v2fo;
o、 顶点=mul(单位矩阵,v顶点);
o、 uv=v.uv;
返回o;
}
取样器2D_MainTex;
固定4框架(v2f i):SV_目标
{
固定4柱;
_测试[0]=固定4(0,0,1,1);
_测试[1]=固定4(1,0,0,1);
_测试[2]=固定4(0,1,0,1);
//Test1:这个代码块生成output1图像。
int指数=圆形(i.uv.x*_测试长度);
col=_检验[指数];
//测试2:这个代码块输出纯绿色。
//如果(i.uv.x<1/3){
//col=_检验[0];
//}
//否则如果(i.uv.x<2/3){
//col=_检验[1];
//}
//否则如果(i.uv.x<3/3){
//col=_检验[2];
//}
返回列;
}
ENDCG
}
}
}

实际产量:


如果我理解正确,它会给我黑色像素,因为最大I.uv.x是1。因此,指数为3(基于计算i.uv.x/_Test.Length)。但是我的数组中没有索引3。

换成地板。因为要舍入,所以大于2.5的值将舍入为3。您可能知道,一个由3个元素组成的数组没有索引3,因此黑条。

改为地板。因为要舍入,所以大于2.5的值将舍入为3。您可能知道,一个由3个元素组成的数组没有索引3,因此出现了黑条。

我已经找到了它。以下是更新后的代码,供任何可能觉得有用的人使用。我将公式从int index=round(I.uv.x_测试长度)更改为:toint index=ceil(i.uv.x/1_检验长度)-1


着色器“自定义/通道”
{
性质
{
_MainTex(“纹理”,2D)=“白色”{}
}
子阴影
{
标记{“队列”=“透明”}
混合SrcAlpha ONEMUSSRCALPHA

    Pass
    {
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"
        uniform float4 _Test [3];

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
            float4 color : COLOR;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
            float4 color : COLOR;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
            o.uv = v.uv;
            return o;
        }

        sampler2D _MainTex;

        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 col;

            _Test[0] = fixed4(0,0,1,1);
            _Test[1] = fixed4(1,0,0,1);
            _Test[2] = fixed4(0,1,0,1);

            //Test1:
            int index = ceil(i.uv.x/1*_Test.Length)-1;
            col = _Test[index];

            return col;
        }
        ENDCG
    }
}
}

我已经弄明白了。这是为任何可能觉得有用的人更新的代码。我将公式从int index=round(I.uv.x_Test.Length);更改为int index=ceil(I.uv.x/1_Test.Length)-1;


着色器“自定义/通道”
{
性质
{
_MainTex(“纹理”,2D)=“白色”{}
}
子阴影
{
标记{“队列”=“透明”}
混合SrcAlpha ONEMUSSRCALPHA

    Pass
    {
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"
        uniform float4 _Test [3];

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
            float4 color : COLOR;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
            float4 color : COLOR;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
            o.uv = v.uv;
            return o;
        }

        sampler2D _MainTex;

        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 col;

            _Test[0] = fixed4(0,0,1,1);
            _Test[1] = fixed4(1,0,0,1);
            _Test[2] = fixed4(0,1,0,1);

            //Test1:
            int index = ceil(i.uv.x/1*_Test.Length)-1;
            col = _Test[index];

            return col;
        }
        ENDCG
    }
}
}

好的。我已经设法用if/else代码块将结果分成3种颜色。我只是将数字(1/3,2/3,3/3)更改为浮动(1.0/3.0,2.0/3.0,3.0/3.0)。但我仍然不知道如何使用数组。好的。我已经设法用if/else代码块将结果分成3种颜色。我只是更改了数字(1/3,2/3,3/3)浮动(1.0/3.0、2.0/3.0、3.0/3.0)。但我仍然不知道如何使用数组。是的。我知道这与公式有关。但我很惊讶它没有给我索引越界错误。好吧,着色器不会像普通代码那样抛出错误,因为GPU。floor解决了问题吗?当我使用floor时,它给了我错误的结果。这是我使用floor时的屏幕截图使用ceil。是的。我知道这与公式有关。但我很惊讶它没有给我索引越界错误。好吧,着色器不会像普通代码那样抛出错误,因为GPU。floor解决问题了吗?当我使用floor时,它给我错误的结果。这是使用ceil时的屏幕截图。ceil-1与floor.cei相同l与floor不同,因为0.1会给你一个0的floor,也会给ceil一个。另外,我把它除以一,因为max是一,然后用-1操作结果,以索引0开始。哎呀..没有注意到-1。我再次尝试floor,删除了-1,得到了相同的结果。我只是把参数搞砸了,应该已经超过了1.额外的-1意味着更多的着色器操作,这反过来意味着较慢的帧速率。您希望保持着色器代码尽可能干净和精确,以避免性能问题。ceil-1与floor相同。ceil与floor不同,因为0.1将为您提供0的floor,并为ceil提供1。此外,我还将其除以1,因为max是1,然后是just使用-1操纵结果,以索引0开始。Oops..没有注意到-1。我再次尝试地板并删除了-1,得到了相同的结果。我只是在参数上搞砸了,应该超过1。额外的-1意味着更多的着色器操作,这反过来意味着更慢的帧速率。你想保持着色器代码干净和prec吗尽可能避免性能问题。