unity同心圆着色器改变颜色

Changing color of unity concentric circle shader

尝试将此着色器的颜色从黑白更改为多种颜色,有什么方法可以做到这一点吗?我对团结还很陌生,并尽我所能。如果可能的话,我希望能够做至少 3 种不同的颜色,但我知道这对于这里制作的东西来说是否真的不可行。如果是这样,有人可能会指出我可以尝试使用类似的东西吗?

http://www.shaderslab.com/demo-01---concentric-circles.html

这是着色器本身的代码。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/ConcentricCircles" {
    Properties {
        _OrigineX ("PosX Origine", Range(0,1)) = 0.5
        _OrigineY ("PosY Origine", Range(0,1)) = 0.5
        _Speed ("Speed", Range(-100,100)) = 60.0
        _CircleNbr ("Circle quantity", Range(10,1000)) = 60.0
    }
 
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma target 3.0
 
            float _OrigineX;
            float _OrigineY;
            float _Speed;
            float _CircleNbr;
 
            struct vertexInput {
                float4 vertex : POSITION;
                float4 texcoord0 : TEXCOORD0;
            };
 
            struct fragmentInput{
                float4 position : SV_POSITION;
                float4 texcoord0 : TEXCOORD0;
            };
 
            fragmentInput vert(vertexInput i){
                fragmentInput o;
                o.position = UnityObjectToClipPos (i.vertex);
                o.texcoord0 = i.texcoord0;
                return o;
            }
 
            fixed4 frag(fragmentInput i) : SV_Target {
                fixed4 color;
                float distanceToCenter;
                float time = _Time.x * _Speed; 
                           
                float xdist = _OrigineX - i.texcoord0.x;
                float ydist = _OrigineY - i.texcoord0.y;
               
                distanceToCenter = (xdist * xdist + ydist * ydist) * _CircleNbr;
               
                color = sin(distanceToCenter + time);
                return color;
            }
            ENDCG
        }
    }
}

我不擅长着色器,但我可以提供一些帮助。您可能想要添加一个 _Color 属性。该值可以在代码或检查器中更改。有不同的方法可以通过求和或乘法来应用颜色。两种选择都会产生不同的结果。它只会替换白色部分,或在白色周围添加高光。黑色部分的原因是由于 sin 函数的工作原理。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Test" {
    Properties {
        _OrigineX ("PosX Origine", Range(0,1)) = 0.5
        _OrigineY ("PosY Origine", Range(0,1)) = 0.5
        _Speed ("Speed", Range(-100,100)) = 60.0
        _CircleNbr ("Circle quantity", Range(10,1000)) = 60.0
        _Color ("Main Color", Color) = (1,1,1,1)
    }
 
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma target 3.0
 
            float _OrigineX;
            float _OrigineY;
            float _Speed;
            float _CircleNbr;
            fixed4 _Color;
 
            struct vertexInput {
                float4 vertex : POSITION;
                float4 texcoord0 : TEXCOORD0;
            };
 
            struct fragmentInput{
                float4 position : SV_POSITION;
                float4 texcoord0 : TEXCOORD0;
            };
 
            fragmentInput vert(vertexInput i){
                fragmentInput o;
                o.position = UnityObjectToClipPos (i.vertex);
                o.texcoord0 = i.texcoord0;
                return o;
            }

            
 
            fixed4 frag(fragmentInput i) : SV_Target {
                fixed4 color;
                float distanceToCenter;
                float time = _Time.x * _Speed;
                           
                float xdist = _OrigineX - i.texcoord0.x;
                float ydist = _OrigineY - i.texcoord0.y;
               
                distanceToCenter = (xdist * xdist + ydist * ydist) * _CircleNbr;
               
                color = sin(distanceToCenter + time) + _Color;
                return color;
            }
            ENDCG
        }
    }
}

将行 color = sin(distanceToCenter + time) + _Color; 替换为 color = sin(distanceToCenter + time) * _Color; 以查看其他选项。左图是加法的,右图是乘法的。我将编辑器中的颜色设置为绿色。您也可以尝试将 sin 函数更改为另一个也会产生不同结果的三角函数。

编辑:这行很酷color = sin(distanceToCenter + time) + cos(distanceToCenter + time) * _Color;

编辑 2:根据要求,这是获得多种不同颜色的一种方法。当使用 sin 函数时,值介于 [-1, 1] 之间,因此有时这会等于 0,或 (0,0,0,1),这是黑色的。您可以使用 if 条件语句来捕获这些值的范围,然后直接设置颜色。这是我的处理方法。

Shader "Custom/Test" {
    Properties {
        _OrigineX ("PosX Origine", Range(0,1)) = 0.5
        _OrigineY ("PosY Origine", Range(0,1)) = 0.5
        _Speed ("Speed", Range(-100,100)) = 60.0
        _CircleNbr ("Circle quantity", Range(10,1000)) = 60.0
        _Color1 ("Color 1", Color) = (1,1,1,1)
        _Color2 ("Color 2", Color) = (1,1,1,1)
        _Color3 ("Color 3", Color) = (1,1,1,1)
    }
 
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma target 3.0
 
            float _OrigineX;
            float _OrigineY;
            float _Speed;
            float _CircleNbr;
            fixed4 _Color1;
            fixed4 _Color2;
            fixed4 _Color3;
 
            struct vertexInput {
                float4 vertex : POSITION;
                float4 texcoord0 : TEXCOORD0;
            };
 
            struct fragmentInput{
                float4 position : SV_POSITION;
                float4 texcoord0 : TEXCOORD0;
            };
 
            fragmentInput vert(vertexInput i){
                fragmentInput o;
                o.position = UnityObjectToClipPos (i.vertex);
                o.texcoord0 = i.texcoord0;
                return o;
            }

            
 
            fixed4 frag(fragmentInput i) : SV_Target {
                fixed4 color;
                float distanceToCenter;
                float time = _Time.x * _Speed;
                           
                float xdist = _OrigineX - i.texcoord0.x;
                float ydist = _OrigineY - i.texcoord0.y;
               
                distanceToCenter = (xdist * xdist + ydist * ydist) * _CircleNbr;

                float preColor = sin(distanceToCenter + time);

                if(preColor < -0.8)
                {
                    color = _Color1;
                }
                else if(preColor < 0.2)
                {
                    color = _Color2;
                }
                else
                {
                    color = _Color3;
                }
               
                return color;
            }
            ENDCG
        }
    }
}

还有我的结果

只需在检查器中分配您想要的三种颜色。您可以编辑代码以更改阈值的数量或阈值。