Files
AIC-Project/Client/Assets/Game/shader/SGame/Base/Water_Base.hlsl
T

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