光线投射穿过物体

时间:2019-02-19 12:42:49

标签: unity3d shader

我有一台投光器,上面贴有材料,还有一个脚本,可在水下投射出苛刻的效果。在脚本“检查器”中,我有一个软件生成的多个焦散纹理,并且在每个纹理中进行迭代,以更改投影仪的材质。

如何使着色器表现得更像光并且在阴影上不可见?

我没有着色器方面的经验,并且着色器并非来自我。

Screenshot1 Screenshot2

Shader "Projector/Caustics" {
    Properties {
        _Color ("Color", Color) = (1,1,1,0)
        [NoScaleOffset]_MainTex ("Texture", 2D) = "black" { }
        _Size ("Grid Size", Float) = 10
        _Height ("Water Height", Float) = 2.0
        _DepthBlend ("Depth Blend", Float) = 10.0
        _EdgeBlend ("Edge Blend", Range (0, 100)) = 0.5
        _Multiply ("Multiply", Range (1, 2)) = 1.0
        _LOD ("LOD Bias", Range (1, 1000)) = 100
     }

     Subshader {
        Tags { "RenderType"="Transparent" "Queue"="Transparent+100" }
        Pass {
            ZWrite Off
            Offset -1, -1
            //Blend OneMinusDstColor One //- Soft Additive
            //Blend One One //- Linear Dodge
            Blend DstColor One

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            #include "UnityCG.cginc"

            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 wPos : TEXCOORD1; // added for height comparisons.
                UNITY_FOG_COORDS(2)
            };

            uniform sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Color;
            float4x4 unity_Projector;
            float _Size;
            float _Height;
            float _DepthBlend;
            float _EdgeBlend;
            float _Multiply;
            float _LOD;
            float dist;

            v2f vert (appdata_tan v) {
                v2f o;
                o.pos = UnityObjectToClipPos (v.vertex);
                o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                o.uv = TRANSFORM_TEX (mul (unity_Projector, v.vertex).xy, _MainTex);
                UNITY_TRANSFER_FOG(o,o.pos);
                return o;
            }

            fixed4 frag (v2f i) : COLOR {
                dist = distance(_WorldSpaceCameraPos, i.wPos);
                fixed4 c = tex2Dlod (_MainTex, float4(fmod (i.uv, 1 / _Size)*_Size,0,dist/_LOD)); // project tiled texture, set lod.

                if (i.wPos.y<_Height) 
                    c = c-(i.wPos.y-_Height)/-_DepthBlend*2;
                else
                    c = lerp(c,0,(i.wPos.y-_Height)/_EdgeBlend);

                c = saturate(c);

                UNITY_APPLY_FOG_COLOR(i.fogCoord, c, fixed4(0,0,0,0));              
                return c * _Color *_Multiply ; // apply final color
            }
            ENDCG
        }
    }
}

1 个答案:

答案 0 :(得分:0)

不幸的是,投影机不能有阴影,这正是您所需要的。 Unity也不支持透明对象的阴影。

有三种方法可以达到这种效果:

  • 使用延迟贴花,只有延迟模式才支持。
  • 使用屏幕空间效果。
  • 创建一个自定义的地形着色器,该着色器根据世界空间Y的位置将焦散显示为地形渲染的一部分。您还需要对将要接收焦散的所有其他对象进行类似的着色器修改。

post中有一些有关延期贴花的示例。遗憾的是,尽管没有着色器编程知识,但修复起来并非如此简单。不过,有一些Unity内置的水解决方案内置了此功能-例如,LUX使用的屏幕空间焦散非常酷。