#ifndef SGAME_WATER_BASE #define SGAME_WATER_BASE #include "./ExpHeightFog_Base.hlsl" #include "./Lighting_Base.hlsl" TEXTURE2D(_ReflectionTex); SAMPLER(sampler_ReflectionTex); TEXTURE2D(_NormalTexture); SAMPLER(sampler_NormalTexture); TEXTURECUBE(_ReflectionCubeMap); SAMPLER(sampler_ReflectionCubeMap); TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture); CBUFFER_START(UnityPerMaterial) half4 _DeepWaterColor; half4 _ShallowWaterColor; half _ShallowDeepBlend; half _ShallowDeepFade; float4 _ReflectionTex_ST; half _ReflectionIntensity; half _DepthTransparency; half _Specular; half _Gloss; half _LightWrapping; float4 _NormalTexture_ST; half _Refraction; float4 _MainWaveTilingOffset; float4 _SecondWaveTilingOffset; half _SpecularRefraction; half _SpecularOffset; half _ReflectionDistortion; half4 _SpecularColor; half _FogFactor; half _MaxTransparency; half _ReflectionCubeMapOffset; half _CubeMapReflectionIntensity; CBUFFER_END struct VertexInput { float4 vertex : POSITION; half3 normal : NORMAL; half4 tangent : TANGENT; float2 texcoord0 : TEXCOORD0; }; struct VertexOutput { float4 pos : SV_POSITION; float4 uv0 : TEXCOORD0; float2 uv1 : TEXCOORD1; float4 posWorld : TEXCOORD2; float4 screenPos : TEXCOORD3; float4 projPos : TEXCOORD4; #if defined(_SG_EXPFOG) half4 _fogCoord : TEXCOORD5; #endif #if defined(_PROJECTOR_ON) half4 projectorUV : TEXCOORD6; #endif }; inline float3 UnityObjectToViewPos( in float3 pos ) { return mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, float4(pos, 1.0))).xyz; } #define COMPUTE_EYEDEPTH(o, vert) o = -UnityObjectToViewPos( vert ).z VertexOutput vert (VertexInput v) { VertexOutput o = (VertexOutput)0; VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz); VertexNormalInputs normalInput = GetVertexNormalInputs(v.normal, v.tangent); float4 worldPos = half4(vertexInput.positionWS, 1); o.posWorld = worldPos; o.pos = vertexInput.positionCS; o.projPos = ComputeScreenPos (o.pos); COMPUTE_EYEDEPTH(o.projPos.z, v.vertex.xyz); o.screenPos = o.pos; o.uv0.xy = v.texcoord0 * _MainWaveTilingOffset.xy + _MainWaveTilingOffset.zw * _Time.r * 0.1; o.uv1.xy = v.texcoord0 * _SecondWaveTilingOffset.xy + _SecondWaveTilingOffset.zw * _Time.r * 0.1; #if defined(_SG_EXPFOG) CUSTOM_TRANSFER_FOG(o, v.vertex); #endif #if defined(_PROJECTOR_ON) o.projectorUV = GetProjectorUV(v.vertex, unity_ObjectToWorld); #endif return o; } half4 frag(VertexOutput i) : SV_TARGET { float3 worldNormal = half3(0, 1, 0); half3x3 tangentTransform = half3x3(half3(1, 0, 0), half3(0, 0, 1), worldNormal); /////// Vectors: half3 viewDirection = GetCameraPositionWS() - i.posWorld.xyz; half4 _texture1 = SAMPLE_TEXTURE2D(_NormalTexture, sampler_NormalTexture, i.uv0.xy); half4 _texture2 = SAMPLE_TEXTURE2D(_NormalTexture, sampler_NormalTexture, i.uv1.xy); half3 _subtractor1 = (_texture1.rgb-_texture2.rgb); half3 normalLocal = lerp(half3(0,0,1),_subtractor1,_Refraction); half3 specularNormalLocal = lerp(half3(0,_SpecularOffset,1), _subtractor1, _SpecularRefraction); half3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals half3 specularNormalDirection = normalize(mul( specularNormalLocal, tangentTransform )); // Perturbed normals Light mainLight = GetMainLight(); half3 lightDirection = normalize(mainLight.direction); half3 lightColor = mainLight.color.rgb; float sceneZ = 0; float partZ = max(0,i.projPos.z - _ProjectionParams.g); float diffZ = 0; float sampleDepth = SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, i.projPos.xy / i.projPos.z).r; sampleDepth = 1.0 / (_ZBufferParams.z * sampleDepth + _ZBufferParams.w); sceneZ = max(0, sampleDepth - _ProjectionParams.g); diffZ = sceneZ - partZ; half finalAlpha = clamp((diffZ / _DepthTransparency), 0, _MaxTransparency); half NDotL = dot( normalDirection, lightDirection ); half NL = saturate(NDotL); half3 attenColor = lightColor; half3 ambientColor = UNITY_LIGHTMODEL_AMBIENT.rgb; ///////// Gloss: half gloss = _Gloss; half specPow = gloss * 128; ////// Specular: #if defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH) half3 specularColor = (_Specular*_SpecularColor.rgb); half3 specularHalfDirection = normalize(lightDirection + viewDirection); half NH = max(0,dot(specularHalfDirection,specularNormalDirection)); float specAtten = SGamePow(NH, specPow); half3 directSpecular = specAtten*specularColor*attenColor*NL; half3 specular = directSpecular; #else half3 specular = half3(0,0,0); #endif /////// Diffuse: half3 directDiffuse = NL * attenColor * _LightWrapping; half3 indirectDiffuse = ambientColor; half3 totalDiffuse = (directDiffuse + indirectDiffuse); half shallowRatio = 1 - saturate((sceneZ - partZ)/_ShallowDeepBlend); //1��ʾDZˮ,0��ʶ��ˮ shallowRatio = SGamePow(shallowRatio, _ShallowDeepFade); half3 waterColor = lerp(_DeepWaterColor.rgb, _ShallowWaterColor.rgb, shallowRatio); half3 diffuseWater = totalDiffuse * waterColor; half3 planarReflect = 0; i.screenPos = float4( i.screenPos.xy / i.screenPos.w, 0, 0 ); i.screenPos.y *= _ProjectionParams.x; half2 _componentMask = _subtractor1.rg; half2 remap = ((i.screenPos.rg+()*0.5+0.5); planarReflect = SAMPLE_TEXTURE2D(_ReflectionTex, sampler_ReflectionTex, TRANSFORM_TEX(remap, _ReflectionTex)); half3 cubeMapRefl = 0; #if defined(_CUBEMAPTOGGLE_ON) half3 R = reflect(-viewDirection, normalDirection); half3 cubeSampleUV = RotationY(R, _ReflectionCubeMapOffset); half4 refectionMap_Var = SAMPLE_TEXTURECUBE_LOD(_ReflectionCubeMap, sampler_ReflectionCubeMap, cubeSampleUV, 1); //这里计算的是CubeMap refectionMap_Var *= _CubeMapReflectionIntensity; cubeMapRefl = refectionMap_Var.rgb; #endif half3 ReflectionRGB = planarReflect + cubeMapRefl; half3 diffuse = lerp(diffuseWater, ReflectionRGB, _ReflectionIntensity); /// Final Color: half3 finalColor = diffuse + specular; finalColor.rgb = ApplyDark(finalColor.rgb); #if defined(_PROJECTOR_ON) finalColor.rgb = GetProjectorColor(finalColor.rgb, i.projectorUV).rgb; #endif #if defined(_SG_EXPFOG) CUSTOM_APPLY_FOG(i, finalColor.rgb, distance(_WorldSpaceCameraPos, i.posWorld.xyz)); #endif finalAlpha *= clamp(length(_WorldSpaceCameraPos.xyz - i.posWorld.xyz) / 3, 0, 1); half4 finalRGBA = half4(finalColor, finalAlpha); return finalRGBA; } #endif