Using the following two-pass shader I was able to get realtime water reflections in Indie/Free Edition of Unity 3D:
Shader "Custom/water_mirror" { Properties { _DiffuseTex ("Diffuse (RGB)", 2D) = "white" {} _NormalTex ("Normal (RGB)", 2D) = "bump" {} _SpecularTex ("Specular (R) Gloss (G)", 2D) = "gray" {} _WaterLevel ("Water Level", float) = 0 } SubShader { Pass { Name "ContentBase" Tags {"LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" #include "AutoLight.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 lightDirT : TEXCOORD1; float3 viewDirT : TEXCOORD2; LIGHTING_COORDS(3,4) }; v2f vert (appdata_tan v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.texcoord.xy; TANGENT_SPACE_ROTATION; o.lightDirT = mul(rotation, ObjSpaceLightDir(v.vertex)); o.viewDirT = mul(rotation, ObjSpaceViewDir(v.vertex)); TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } sampler2D _DiffuseTex; sampler2D _SpecularTex; sampler2D _NormalTex; float4 _LightColor0; float4 frag(v2f i) : COLOR { float3 normal = normalize(tex2D(_NormalTex, i.uv).xyz * 2 - 1); float NdotL = dot(normal, i.lightDirT); float3 halfAngle = normalize(i.lightDirT + i.viewDirT); float atten = LIGHT_ATTENUATION(i); float3 specularity = (pow(saturate(dot(normal, halfAngle)), tex2D(_SpecularTex, i.uv).g * 200) * tex2D(_SpecularTex, i.uv).r) * _LightColor0; float4 result; result.rgb = tex2D(_DiffuseTex, i.uv).rgb * NdotL * atten * _LightColor0 + specularity; result.a = 0; return result; } ENDCG } Pass { Name "ContentBase" Tags {"LightMode" = "ForwardBase"} Cull Front CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" #include "AutoLight.cginc" struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 lightDirT : TEXCOORD1; float3 viewDirT : TEXCOORD2; LIGHTING_COORDS(3,4) }; float _WaterLevel; v2f vert (appdata_tan v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.texcoord.xy; float4 p = mul(_Object2World, v.vertex); p = float4(p[0], min(_WaterLevel, 2*_WaterLevel-p[1]), p[2], p[3]); p = mul(_World2Object, p); o.pos = mul(UNITY_MATRIX_MVP, p); TANGENT_SPACE_ROTATION; o.lightDirT = mul(rotation, ObjSpaceLightDir(v.vertex)); o.viewDirT = mul(rotation, ObjSpaceViewDir(v.vertex)); TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } sampler2D _DiffuseTex; sampler2D _SpecularTex; sampler2D _NormalTex; float4 _LightColor0; float4 frag(v2f i) : COLOR { float3 normal = normalize(tex2D(_NormalTex, i.uv).xyz * 2 - 1); float NdotL = dot(normal, i.lightDirT); float3 halfAngle = normalize(i.lightDirT + i.viewDirT); float atten = LIGHT_ATTENUATION(i); float3 specularity = (pow(saturate(dot(normal, halfAngle)), tex2D(_SpecularTex, i.uv).g * 200) * tex2D(_SpecularTex, i.uv).r) * _LightColor0; float4 result; result.rgb = tex2D(_DiffuseTex, i.uv).rgb * NdotL * atten * _LightColor0 + specularity; result.a = 0; return result; } ENDCG } } }
The shader was based on some other shader demonstrating light computations in Unity3D. I added the second pass, made a mirror reflection of geometry against water and switched face culling to front. Hope somebody finds it useful 😉
Hi there,
I’m very interested in being able to use reflections in the Indie version of Unity, so I tried to use this script. Only I got an error:
Assets/Scripts/Reflection.cs(1,28): error CS8025: Parsing error
Note that I’m a total n00b when it comes to scripting, perhaps I made a mistake implementing this.
Would you be able to help me out?
Thanks in advance!
-f
Oh wait I’m sorry, I got it now, haha. As said, I’m a total noob with this kind of stuff. Thanks for the script!!!
Sorry, but it does not work? How can i use it? thank you, could you please post some step by step?
Sorry I don’t offer any support for my code and I’m very busy with other projects at the moment. Anyway – if you want reflections in your game, better buy Unity Pro. This solution is clumsy at best.
esse efeito pode ser aplicado na versão grátis da Unity? se sim pode dizer como realizar (e se possÃvel disponibilizar o código) não intendo muito de shaders e esse seria um bom para esstudar e usá-lo^^.
decha quieto .. achei hehehe
mas é possÃvel usálo sem ter a versão pro da Unity?
Very nice! I used it in my project and got a very nice effect in water although I don’t know why I cannot get the mirror effect. I put a cubemap of my scene but cannot see the other things reflected in water. Is there something that I’m missing? I use Unity free.
Thanks.
Regards.