170 lines
6.4 KiB
HLSL
170 lines
6.4 KiB
HLSL
#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 |