I am working on my water shader but I have run into some problems. It looks like my normals aren't getting the same offset as my vertexes. 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. PLEASE I really need some help with this can't find anyone who knows what this is.
This is my code:
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.
I tried your shader and I can't see any plane, except the one I add to a scene to receive the casted shadow. In any case, water's normals don't have anything to do with the plane.
It looks like my normals aren't getting the same offset as my vertexes
Again, not sure what you mean here. Offset has no effect on normals, because they express an orientation, not a position.
If you mean that the projected shadow on the plane, doesn't account for the vertex offset, it's because the auto generated shadow caster pass, can't take in consideration the vertex offset. So you probably need to explicitly implement it.
Something like:
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
}