141 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
		
		
			
		
	
	
			141 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
|   | #ifndef TOONSKETCH_WATERMAIN_INCLUDED | |||
|  | #define TOONSKETCH_WATERMAIN_INCLUDED | |||
|  | 
 | |||
|  | #include "TS_WaterInput.cginc" | |||
|  | #include "../../Shared/Shaders/Noise/Noise.cginc" | |||
|  | 
 | |||
|  | float3 GetWaterFlow(float4 color) | |||
|  | { | |||
|  | #ifdef _USEVERTEXFLOW | |||
|  | 	return color.xyz; | |||
|  | #else | |||
|  | 	return float3(_FlowDirection, _FlowWaveFactor); | |||
|  | #endif | |||
|  | } | |||
|  | 
 | |||
|  | float CalculateWaveHeight(float2 pos, float3 flow) | |||
|  | { | |||
|  | 	float noise = snoise(pos * (5 * _WaveAmount) + (_Time.y * flow.xy * flow.z)); | |||
|  | 	float time = _Time.y * (5 * _WaveSpeed); | |||
|  | 	float wave = ((sin(noise + time) + sin(noise * 2.3 + time * 1.5) + sin(noise * 3.3 + time * 0.4)) / 3) * 0.5 + 0.5; | |||
|  | 	return saturate(wave * _WaveStrength); | |||
|  | } | |||
|  | 
 | |||
|  | void TS_ApplyVertexWaves(inout TS_VertexInput v) | |||
|  | { | |||
|  | 	float3 flow = GetWaterFlow(v.color); | |||
|  | #ifdef _WAVE_USEWORLD | |||
|  | 	float2 pos = mul(unity_ObjectToWorld, v.vertex).xz; | |||
|  | #else | |||
|  | 	float2 pos = v.uv0; | |||
|  | #endif | |||
|  | 	v.vertex.y += (CalculateWaveHeight(pos, flow) - CalculateWaveHeight(0, flow)); | |||
|  | } | |||
|  | 
 | |||
|  | half2 GetTextureUV(float2 uv, float3 flow, float speed, float distortion) | |||
|  | { | |||
|  | 	uv += _Time.y * flow.xy; | |||
|  | 	float noise = snoise(uv); | |||
|  | 	float time = _Time.y * (5 * speed); | |||
|  | 	float wave = ((sin(noise + time) + sin(noise * 2.3 + time * 1.5) + sin(noise * 3.3 + time * 0.4)) / 3) * 0.5 + 0.5; | |||
|  | 	return uv + (wave * distortion); | |||
|  | } | |||
|  | 
 | |||
|  | float4 BlendColors(float4 a, float4 b) | |||
|  | { | |||
|  | 	float3 color = (a.rgb * a.a) + (b.rgb * (1 - a.a)); | |||
|  | 	float alpha = a.a + b.a * (1 - a.a); | |||
|  | 	return float4(color, alpha); | |||
|  | } | |||
|  | 
 | |||
|  | half4 GetWaterColor(float2 uv, half4 color, float3 viewNormal, float3 posWorld, float4 screenPos) | |||
|  | { | |||
|  | 	float epsilon = 0.00001; | |||
|  | 	float depth; | |||
|  | 	float3 normals; | |||
|  | 
 | |||
|  | 	DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, screenPos.xyz / screenPos.w), depth, normals); | |||
|  | 
 | |||
|  | 	depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(screenPos)); | |||
|  | 	depth = LinearEyeDepth(depth) - screenPos.w; | |||
|  | 
 | |||
|  | 	float waterDepth = saturate(depth / max(_WaterDepthCutoff, epsilon)); | |||
|  | 	half4 waterColor = lerp(_WaterColorShallow, _WaterColorDeep, waterDepth); | |||
|  | 	 | |||
|  | 	float3 flow = GetWaterFlow(color); | |||
|  | 	 | |||
|  | 	float2 uv0, uv1; | |||
|  | 
 | |||
|  | 	#ifdef _SURFACE_USEWORLD | |||
|  | 		uv0 = posWorld.xz * _SurfaceTiling; | |||
|  | 		uv1 = posWorld.xz * _FoamTiling; | |||
|  | 	#else | |||
|  | 		uv0 = uv * _SurfaceTiling; | |||
|  | 		uv1 = uv * _FoamTiling; | |||
|  | 	#endif | |||
|  | 
 | |||
|  | 	half4 surfaceTex = tex2D(_MainTex, GetTextureUV(uv0, flow, _SurfaceSpeed, _SurfaceDistort)); | |||
|  | 	half4 foamTex = tex2D(_MainTex, GetTextureUV(uv1, flow, _FoamSpeed, _FoamDistort)); | |||
|  | 
 | |||
|  | 	float foamNoise = saturate(snoise(uv1 * (5 * _FoamAmount) + (_Time.y * _FoamSpeed)) * 0.5 + 0.5); | |||
|  | 	float foamDistance = lerp(_FoamMaxDepth, _FoamMinDepth, saturate(dot(normals, viewNormal))); | |||
|  | 
 | |||
|  | 	float foamDepth; | |||
|  | 	foamDepth = saturate(depth / max(foamDistance * _FoamHardEdge, epsilon)); | |||
|  | 	float hardFoam = smoothstep(foamDepth - epsilon, foamDepth + epsilon, foamNoise); | |||
|  | 
 | |||
|  | 	foamDepth = saturate(depth / max(foamDistance, epsilon)); | |||
|  | 	float softFoam = smoothstep(foamDepth - _FoamSoftness, foamDepth + _FoamSoftness, lerp(1, foamNoise, _FoamSoftNoise)); | |||
|  | 	foamDepth = saturate(depth / max(foamDistance * _FoamDistance, epsilon)); | |||
|  | 	softFoam = lerp(0, softFoam, smoothstep(_FoamFade, 0, foamDepth)); | |||
|  | 	 | |||
|  | 	half4 output = waterColor; | |||
|  | 	output.rgb -= _SurfaceStrength * surfaceTex; | |||
|  | 	output.rgb += softFoam * (_FoamStrength * _WaterColorFoam * foamTex); | |||
|  | 	output = BlendColors(_WaterColorFoam * hardFoam, saturate(output)); | |||
|  | 	return output; | |||
|  | } | |||
|  | 
 | |||
|  | inline FragmentCommonData TS_WaterSpecularSetup(half4 color) | |||
|  | { | |||
|  | 	half3 diffColor = color.rgb; | |||
|  | 	half3 specColor = half3(0, 0, 0); | |||
|  | 	half smoothness = 0; | |||
|  | 
 | |||
|  | 	half3 specularOut; | |||
|  | 	half oneMinusReflectivity; | |||
|  | 	diffColor = DiffuseAndSpecularFromMetallic(diffColor, 0, specularOut, oneMinusReflectivity); | |||
|  | 	specColor *= specularOut; | |||
|  | 
 | |||
|  | 	FragmentCommonData o; | |||
|  | 	UNITY_INITIALIZE_OUTPUT(FragmentCommonData, o); | |||
|  | 	o.diffColor = diffColor; | |||
|  | 	o.specColor = specColor; | |||
|  | 	o.oneMinusReflectivity = oneMinusReflectivity; | |||
|  | 	o.smoothness = smoothness; | |||
|  | 	return o; | |||
|  | } | |||
|  | 
 | |||
|  | inline FragmentCommonData TS_WaterFragmentSetup(inout float4 i_tex, float3 i_eyeVec, half3 i_viewDirForParallax, float4 tangentToWorld[3], float3 i_posWorld, | |||
|  | 	half4 i_color, float3 i_viewNormal, float4 i_screenPos) | |||
|  | { | |||
|  | 	i_tex = Parallax(i_tex, i_viewDirForParallax); | |||
|  | 
 | |||
|  | 	half4 color = GetWaterColor(i_tex.xy, i_color, i_viewNormal, i_posWorld, i_screenPos); | |||
|  | 
 | |||
|  | 	half alpha = color.a; | |||
|  | #if defined(_ALPHATEST_ON) | |||
|  | 	clip(alpha - _Cutoff); | |||
|  | #endif | |||
|  | 
 | |||
|  | 	FragmentCommonData o = TS_WaterSpecularSetup(color); | |||
|  | 
 | |||
|  | 	o.normalWorld = PerPixelWorldNormal(i_tex, tangentToWorld); | |||
|  | 	o.eyeVec = NormalizePerPixelNormal(i_eyeVec); | |||
|  | 	o.posWorld = i_posWorld; | |||
|  | 
 | |||
|  | 	o.diffColor = PreMultiplyAlpha(o.diffColor, alpha, o.oneMinusReflectivity, o.alpha); | |||
|  | 	return o; | |||
|  | } | |||
|  | 
 | |||
|  | #endif |