【问题标题】:Changing color of unity concentric circle shader更改统一同心圆着色器的颜色
【发布时间】:2021-05-04 22:01:48
【问题描述】:

尝试将此着色器的颜色从黑白更改为多种颜色,有什么方法可以做到这一点吗?我对团结很陌生,并尽我所能。如果可能的话,我希望能够制作至少 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
        }
    }
}

【问题讨论】:

    标签: c# unity3d shader


    【解决方案1】:

    我不擅长着色器,但我可以提供一些帮助。您可能想要添加一个 _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 函数更改为另一个产生不同结果的 trig 函数。

    编辑:这条线很酷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
            }
        }
    }
    

    我的结果

    只需在检查器中指定您想要的三种颜色。您可以编辑代码以更改有多少阈值或阈值是什么。

    【讨论】:

    • 所以我看到您使用 sin 和 cos 使两种颜色相反,如果可能的话,如何单独选择它们?完全不使用罪是否有可能完全摆脱黑人?如果你不知道那很好,只是想知道。
    • 是的,所以黑色的原因是由于 sin/cos 函数的工作方式。它们的范围从 [-1,1] 并直接从 float -> fixed4 将颜色值分配给这些浮点数。当函数为0时,你会变黑。我可以发布一个解决方案,让您确定颜色值
    • 如果你不介意我会很感激,我设法使用它,所以我可以选择 2 种单独的颜色,但我不是一个巨大的 c# 用户,所以我不真的知道我应该做的一切。如果您能告诉我如何制作它,以便我可以为圆圈选择 3 种不同颜色,我将不胜感激。
    • 哦,这不是 c#,是 glsl。
    • 那是有道理的。我也只是个白痴哈哈。我一直在 Visual Studio 中进行编辑,这就是我猜的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    相关资源
    最近更新 更多