如何向Unity自定义着色器添加发射?

时间:2018-02-12 10:21:55

标签: unity3d shader

我在Unity中使用以下着色器。 像声纳这样的环正在从游戏物体碰撞的地方蔓延开来。 参考底层图像。 Image of sonar effect. 我想添加发射,即使在黑暗中也可以看到这个环,但我是着色器的新手。我遇到了麻烦,因为我不知道在哪里改变。

使其变暗的设置如下。

  1. 将环境闪电的强度倍数设置为0.
  2. 删除天空盒。
  3. 将相机背景设置为黑色。
  4. 我使用的着色器如下。

    Shader "MadeByProfessorOakie/SimpleSonarShader" {
        Properties{
            _Color("Color", Color) = (1,1,1,1)
            _MainTex("Albedo (RGB)", 2D) = "white" {}
            _Glossiness("Smoothness", Range(0,1)) = 0.5
            _Metallic("Metallic", Range(0,1)) = 0.0
            _RingColor("Ring Color", Color) = (1,1,1,1)
            _RingColorIntensity("Ring Color Intensity", float) = 2
            _RingSpeed("Ring Speed", float) = 1
            _RingWidth("Ring Width", float) = 0.1
            _RingIntensityScale("Ring Range", float) = 1
            _RingTex("Ring Texture", 2D) = "white" {}
        }
    
        SubShader{
            Tags{ "RenderType" = "Opaque" }
            LOD 200
    
            CGPROGRAM
            // Physically based Standard lighting model, and enable shadows on all light types
            #pragma surface surf Standard fullforwardshadows
    
            // Use shader model 3.0 target, to get nicer looking lighting
            #pragma target 3.0
    
            sampler2D _MainTex;
            sampler2D _RingTex;
    
    
            struct Input {
                float2 uv_MainTex;
                float3 worldPos;
                float3 uv_Illum;
            };
    
            // The size of these arrays is the number of rings that can be rendered at once.
            // If you want to change this, you must also change QueueSize in SimpleSonarShader_Parent.cs
            half4 _hitPts[20];
            half _StartTime;
            half _Intensity[20];
    
            half _Glossiness;
            half _Metallic;
            fixed4 _Color;
            fixed4 _RingColor;
            // 追加
            fixed4 _EmissionLM;
            half _RingColorIntensity;
            half _RingSpeed;
            half _RingWidth;
            half _RingIntensityScale;
    
    
            void surf(Input IN, inout SurfaceOutputStandard o) {
                fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
                o.Albedo = c.rgb;
    
                half DiffFromRingCol = abs(o.Albedo.r - _RingColor.r) + abs(o.Albedo.b - _RingColor.b) + abs(o.Albedo.g - _RingColor.g);
    
    
                // Check every point in the array
                // The goal is to set RGB to highest possible values based on current sonar rings
                for (int i = 0; i < 20; i++) {
    
                    half d = distance(_hitPts[i], IN.worldPos);
                    half intensity = _Intensity[i] * _RingIntensityScale;
                    half val = (1 - (d / intensity));
    
                    if (d < (_Time.y - _hitPts[i].w) * _RingSpeed && d >(_Time.y - _hitPts[i].w) * _RingSpeed - _RingWidth && val > 0) {
                        half posInRing = (d - ((_Time.y - _hitPts[i].w) * _RingSpeed - _RingWidth)) / _RingWidth;
    
                        // Calculate predicted RGB values sampling the texture radially
                        float angle = acos(dot(normalize(IN.worldPos - _hitPts[i]), float3(1,0,0)));
                        val *= tex2D(_RingTex, half2(1 - posInRing, angle));
                        half3 tmp = _RingColor * val + c * (1 - val);
    
                        // Determine if predicted values will be closer to the Ring color
                        half tempDiffFromRingCol = abs(tmp.r - _RingColor.r) + abs(tmp.b - _RingColor.b) + abs(tmp.g - _RingColor.g);
                        if (tempDiffFromRingCol < DiffFromRingCol)
                        {
                            // Update values using our predicted ones.
                            DiffFromRingCol = tempDiffFromRingCol;
                            o.Albedo.r = tmp.r;
                            o.Albedo.g = tmp.g;
                            o.Albedo.b = tmp.b;
                            o.Albedo.rgb *= _RingColorIntensity;
                        }
                    }
                }
    
                o.Metallic = _Metallic;
                o.Smoothness = _Glossiness;
            }
    
            ENDCG
        }
        FallBack "Diffuse"
    }
    

2 个答案:

答案 0 :(得分:0)

创建自定义着色器时,始终可以查看内置着色器。 只需挑选那些你想要的行为,看看他们做了什么。

以下是BlinnPhong表面的示例:

//Properties
_EmissionLM ("Emission (Lightmapper)", Float) = 0
[Toggle] _DynamicEmissionLM ("Dynamic Emission (Lightmapper)", Int) = 0

//Output
o.Emission = c.rgb * tex2D(_Illum, IN.uv_Illum).a;

希望它可以帮到你

答案 1 :(得分:0)

问题解决了。我重写了如下代码。非常感谢那些想到的人。 我改写如下。

 // Determine if predicted values will be closer to the Ring color
            half tempDiffFromRingCol = abs(tmp.r - _RingColor.r) + abs(tmp.b - _RingColor.b) + abs(tmp.g - _RingColor.g);
            if (tempDiffFromRingCol < DiffFromRingCol)
            {
                // Update values using our predicted ones.
                //DiffFromRingCol = tempDiffFromRingCol;
                /*
                o.Albedo.r = tmp.r;
                o.Albedo.g = tmp.g;
                o.Albedo.b = tmp.b;
                o.Albedo.rgb *= _RingColorIntensity;
                */
                // I Changed here
                o.Emission = tmp;

            }