水法线不抵消

Water normals don't offset

我正在处理我的水着色器,但我 运行 遇到了一些问题。看起来我的法线没有得到与我的顶点相同的偏移量。您可以在我的水面上方看到一个白色平面,水的阴影投射在该平面上,除了另一个不是对象的白色平面,但很可能是我的水网格的法线没有移动,它挡住了部分阴影。拜托,我真的需要一些帮助,找不到任何人知道这是什么。

这是我的代码:

Shader "Custom/NoobShader_04" {
     Properties {
         _Color ("Color", Color) = (0,0.55,0.83,1)
         _Diffuse ("Diffuse Map", 2D) = "white" {}
         _Displacement ("Displacement Map", 2D) = "white" {}

         _Scale ("Wave Scale", float) = 0.7
         _Frequency ("Frequency", float) = 0.6
         _Speed ("Speed", float) = 0.5

     }
     SubShader {
         Pass{
         Tags { "LightMode" = "ForwardBase"}
         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag

         float4 _Color;
         sampler2D _Displacement;
         sampler2D _Diffuse;

         float _Scale;
         float _Frequency;
         float _Speed;

         float4 _LightColor0;

         struct VertexOutput
         {
             float4 pos : SV_POSITION;
             float3 nor : NORMAL;
             float4 col : COLOR;
             float4 tex : TEXCOORD0;
         };

         struct VertexInput
         {
             float4 vertex : POSITION;
             float3 normal : NORMAL;
             float4 texcoord : TEXCOORD0;
         };

         struct FragmentOutput
         {
             float4 color : COLOR;
         };

         VertexOutput vert (VertexInput i)
         {
             VertexOutput VOUT;

             float4 disp = tex2Dlod(_Displacement, float4(i.texcoord.x * _Frequency + (_Time.x * _Speed), i.texcoord.y * _Frequency + (_Time.x * _Speed),0.0,0.0));
             float4 newPos = i.vertex;
             float3 newNor = i.normal;
             newPos.y += _Scale * disp.y; 
             newNor.y += _Scale * disp.y;

             VOUT.nor = newNor;
             VOUT.pos = mul(UNITY_MATRIX_MVP,newPos);
             VOUT.tex = i.texcoord;

             float3 normalDirection = normalize( mul(float4(newNor,0.0),_World2Object).xyz);
             float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
             float atten = 1.0;

             float3 diffuseRefflection = atten * _LightColor0.xyz * _Color.rgb *  max( 0.0, dot(normalDirection, lightDirection));

             VOUT.col = float4(diffuseRefflection, 1.0);

             return VOUT;
         }

         FragmentOutput frag(VertexOutput v) 
         {
             FragmentOutput FOUT;
             float4 tex = tex2D(_Diffuse,float4(v.tex.x * _Frequency + (_Time.x * _Speed), v.tex.y * _Frequency + (_Time.x * _Speed),0.0,0.0));
             FOUT.color = tex * v.col + UNITY_LIGHTMODEL_AMBIENT.xyzw;
             return FOUT;
         }
         ENDCG
         }
     } 
     FallBack "Diffuse"
 }

You can see a white plane belof my water where the shadow of the water is cast upon, exept another white plane which is not a object but most likely the normals of my water mesh that didn't move block a part of the shadow.

我试过你的着色器,但我看不到任何平面,除了我添加到场景中以接收投射阴影的平面。无论如何,水的法线与平面没有任何关系。

It looks like my normals aren't getting the same offset as my vertexes

同样,我不确定你的意思。偏移对法线没有影响,因为它们表示方向,而不是位置。

如果你的意思是投影在平面上的阴影不考虑顶点偏移,那是因为自动生成的shadow caster pass,无法考虑顶点偏移量。所以你可能需要明确地实现它。

类似于:

Pass
    { 
        Name "ShadowCaster"
        Tags { "LightMode" = "ShadowCaster" }

        Fog {Mode Off}
        ZWrite On ZTest Less Cull Off
        Offset 1, 1

        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag
        #pragma fragmentoption ARB_precision_hint_fastest
        #pragma multi_compile_shadowcaster
        #include "UnityCG.cginc"


        v2f vert( appdata_full v )
        {
            v2f o;
            //TRANSFER_SHADOW_CASTER(o) this is how default shadow are casted
            o.pos = ...;// put here your calculation taking into account the vertex offset. Basically repeating the same calculation you wrote for forward pass in regards to vertex position

          return o;
        }

        float4 frag( v2f i ) : COLOR
        {
            fixed4 texcol = tex2D( _MainTex, i.uv );
            clip( texcol.a - _Cutoff );
            SHADOW_CASTER_FRAGMENT(i)
        }
        ENDCG
    }