Water+

潘哲
2023-12-01
<pre class="plain" name="code">#ifndef WATERPLUS_CG_INCLUDED
#define WATERPLUS_CG_INCLUDED
	
	
	#include "UnityCG.cginc"
	#include "Lighting.cginc"
	#include "AutoLight.cginc"
	
	sampler2D _MainTex;
	float4 _MainTex_ST;
	half _EdgeFoamStrength;
	sampler2D _HeightGlossMap;
	sampler2D _DUDVFoamMap;
	sampler2D _WaterMap;

	//Required anyways for proper UVs
	float4 _WaterMap_ST;
	sampler2D _SecondaryRefractionTex;
	float4 _SecondaryRefractionTex_ST;
	half _refractionsWetness;
	half _Refractivity;
	sampler2D _FlowMap;
	half flowMapOffset0, flowMapOffset1, halfCycle;

	half _normalStrength;
	sampler2D _NormalMap;
	samplerCUBE _Cube;
	half _Reflectivity;
	half _WaterAttenuation;
	fixed3 _DeepWaterTint;
	fixed3 _ShallowWaterTint;
	half _Shininess;
	half _Gloss;
	
	half _Fresnel0;
	sampler2D _AnisoMap;
	half _CausticsStrength;
	half _CausticsScale;
	
	sampler2D _CausticsAnimationTexture;
	half3 causticsOffsetAndScale;
	half4 causticsAnimationColorChannel;

	half _Opaqueness;
	
	struct v2f {
    	float4  pos : SV_POSITION;
    	float2	uv_MainTex : TEXCOORD0;
    	half2	uv_WaterMap : TEXCOORD1;
    	fixed3	viewDir	: COLOR;
    	fixed3	lightDir : TEXCOORD2;
		fixed4 vertexColor : TEXCOORD3;
		float2 uv_SecondaryRefrTex : TEXCOORD5;
		fixed3 anisoDir : TEXCOORD6;
	};
	

	v2f vert (appdata_tan v)
	{
	    v2f o;
	    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
	    o.uv_MainTex = TRANSFORM_TEX (v.texcoord, _MainTex);
		o.uv_WaterMap = v.texcoord;// TRANSFORM_TEX(v.texcoord, _WaterMap);
	    o.viewDir = WorldSpaceViewDir(v.vertex);
	    o.lightDir = normalize(WorldSpaceLightDir( v.vertex ));
		o.uv_SecondaryRefrTex = TRANSFORM_TEX (v.texcoord, _SecondaryRefractionTex);
	    return o;
	}
	
	

	inline half CalculateCaustics(float2 uv, half waterAttenuationValue) 
	{

		half4 causticsFrame = tex2D(_CausticsAnimationTexture, frac(uv * _CausticsScale) * causticsOffsetAndScale.zz + causticsOffsetAndScale.xy );
		return (causticsAnimationColorChannel.x * causticsFrame.r
				+ causticsAnimationColorChannel.y * causticsFrame.g
				+ causticsAnimationColorChannel.z * causticsFrame.b) * _CausticsStrength * (1.0 - waterAttenuationValue);
	}
	
	
	inline half CalculateAttenuation(half sinAlpha, fixed3 normViewDir, half4 waterMapValue) 
	{				
		float heightValue = waterMapValue.r;
		return heightValue;
	}
	
	inline fixed3 CalculateNormalInTangentSpace(half2 uv_MainTex, out half2 _displacedUV, fixed3 normViewDir,half4 waterMapValue
												,half2 flowmapValue, half flowLerp, half flowSpeed)
	{
		float2 normalmapUV = uv_MainTex;		
		_displacedUV = normalmapUV;
		//#ifdef FLOWMAP_ANIMATION_ON	

		fixed3 normalT0 = UnpackNormal( tex2D(_NormalMap, normalmapUV + flowmapValue * flowMapOffset0 ) );
		fixed3 normalT1 = UnpackNormal( tex2D(_NormalMap, normalmapUV + flowmapValue * flowMapOffset1 ) );		
		fixed3 pNormal = lerp( normalT0, normalT1, flowLerp );

		//Account for speed
		pNormal.z /= max(flowSpeed, .1);	//Account for flow map average velocity
		pNormal = UnpackNormal( tex2D(_NormalMap, normalmapUV) );
		//#else
		//fixed3 pNormal = UnpackNormal( tex2D(_NormalMap, normalmapUV) );
		//#endif
			
		pNormal.z /= _normalStrength;
		pNormal = normalize(pNormal);	//Very very important to normalize!!!
		return pNormal;
		
	}
	
	
	inline fixed4 SampleTextureWithRespectToFlow(sampler2D _tex, float2 _uv, half2 flowmapValue, half flowLerp) 
	{
		fixed4 texT0 = tex2D(_tex, _uv + flowmapValue * flowMapOffset0 );
		fixed4 texT1 = tex2D(_tex, _uv + flowmapValue * flowMapOffset1 );
		return lerp( texT0, texT1, flowLerp );
	}
	

	inline fixed3 CalculateRefraction( float2 uv_Caustics,
										half refrStrength,
										float2 uv_SecondaryRefrTex,
										half waterAttenuationValue,
										fixed3 normViewDir,
										// half sinAlpha,
										float2 _dudvValue)
	{
		//Unpack and scale
		float2 dudvValue = _dudvValue * _Refractivity / 100000.0;
		fixed3 refractionColor;
				
		//Flat
		refractionColor = tex2D(_SecondaryRefractionTex, uv_SecondaryRefrTex + dudvValue * _SecondaryRefractionTex_ST.x).rgb * _refractionsWetness;
		//refractionColor += CalculateCaustics(uv_Caustics + dudvValue, waterAttenuationValue);
		return refractionColor;
	}

	inline fixed3 CombineEffectsWithLighting(
								fixed3 refraction, half refrStrength,
								fixed3 reflection,
								fixed3 pNormal,
								fixed3 normViewDir,
								fixed3 normLightDir,
								half2 uv_MainTex, half waterAttenuationValue
								,inout half foamAmount,
								fixed foamValue
								,fixed3 lightDir)
	{
		half nDotView = dot(pNormal, normViewDir);		//Masking
		half nDotLight = dot(pNormal, normLightDir);	//Shadows (diffuse)			
		fixed3 anisoDir = normalize( cross(pNormal, lightDir) );
		half lightDotT = dot(normLightDir, anisoDir);
		half viewDotT = dot(normViewDir, anisoDir);
		half spec = sqrt(1.0 - lightDotT * lightDotT) * sqrt(1.0 - viewDotT * viewDotT) - lightDotT * viewDotT;
		spec = pow(spec, _Shininess * 128.0);
		spec *= _Gloss;

		//Masking & self-shadowing
		spec *= max(.0, nDotView) * max(.0, nDotLight);
		//Prevent highlights from leaking to the wrong side of the light
		spec *= max(sign(dot(normViewDir, -normLightDir)), 0.0);    
		fixed specularComponent = spec;
		specularComponent *= _LightColor0.r / 2;
		half fresnel = _Fresnel0 + (1.0 - _Fresnel0) * pow( (1.0 - nDotView ), 5.0);
		fresnel = max(0.0, fresnel - .1);
		specularComponent *= fresnel;
	    specularComponent = specularComponent * specularComponent * 10.0;

		fixed3 finalColor;

	    finalColor = lerp(_ShallowWaterTint, _DeepWaterTint, waterAttenuationValue );
		    	
		//!!!!!!!!!!!!!!!!!!!!
		//!Magic! Don't touch!
		//!!!!!!!!!!!!!!!!!!!!
		    	
		refraction = lerp(refraction, _ShallowWaterTint, refrStrength * .5);
		    	
		finalColor = lerp(refraction, finalColor, saturate( max(waterAttenuationValue, refrStrength * .5) * .8 ) );

	    //Add reflection
	    finalColor = lerp(finalColor, reflection, clamp(fresnel, 0.0, _Reflectivity) );

	    //Foam isn't reflective, it goes on top of everything

	    foamAmount = saturate(foamAmount * foamValue);
		finalColor.rgb = lerp(finalColor, fixed3(foamValue, foamValue, foamValue), foamAmount);
		return (finalColor * _LightColor0.rgb + specularComponent) + UNITY_LIGHTMODEL_AMBIENT.rgb * .5;
		//return finalColor ;

	}

	fixed4 frag (v2f i) : COLOR
	{
		fixed4 outColor;
		fixed4 waterMapValue = tex2D (_WaterMap, i.uv_WaterMap);
		fixed3 normViewDir = normalize(i.viewDir);
	    half2 flowmapValue = tex2D (_FlowMap, i.uv_WaterMap).rg * 2.0 - 1.0;
	    half flowSpeed = length(flowmapValue);
	    	
	    half flowLerp = ( abs( halfCycle - flowMapOffset0 ) / halfCycle );

	    half2 displacedUV;
		fixed3 pNormal = CalculateNormalInTangentSpace(i.uv_MainTex, displacedUV, normViewDir,
													//sinAlpha,
													waterMapValue
													,flowmapValue, flowLerp, flowSpeed
													);
	    	
	    //pNormal = fixed3(-pNormal.x, pNormal.z, -pNormal.y);

		pNormal = UnpackNormal( tex2D(_NormalMap, i.uv_MainTex) );
		pNormal = fixed3(pNormal.x, pNormal.z, pNormal.y);

		half waterAttenuationValue = saturate( waterMapValue.r * _WaterAttenuation );
	    
	    //
	    //Sample dudv/foam texture

		fixed3 dudvFoamValue = SampleTextureWithRespectToFlow(_DUDVFoamMap, i.uv_MainTex, flowmapValue, flowLerp).rgb;				

	    float2 dudvValue = dudvFoamValue.rg;
		dudvValue = dudvValue * 2.0 - float2(1.0, 1.0);
		
		fixed3 refrColor = CalculateRefraction(
												i.uv_MainTex,
												waterMapValue.a,
												i.uv_SecondaryRefrTex,
												waterAttenuationValue,
												normViewDir,
												dudvValue);
	    //
	    //Reflectivity
		fixed3 refl = reflect( -normViewDir, pNormal);

		fixed3 reflectCol = texCUBE( _Cube , refl ).rgb;
		fixed foamValue = dudvFoamValue.b;
		half foamAmount = waterMapValue.g * _EdgeFoamStrength;
		//Have foam in the undefined areas
		foamAmount = max(foamAmount, flowSpeed * foamValue * .5);

		outColor.rgb = CombineEffectsWithLighting(
									refrColor, waterMapValue.a,
									reflectCol,
									pNormal,
									normViewDir,
									i.lightDir,
									i.uv_MainTex, waterAttenuationValue
									,foamAmount,
									foamValue
									,i.lightDir
									);
		//
		//Alpha
		outColor.a = waterMapValue.b;
			
		//outColor.rgb = pNormal;
		outColor.a *= _Opaqueness;
		
	    return outColor;
	}	
#endif

 

Shader "Water+/Desktop" {

Properties {
	_MainTex("Main texture", 2D) = "bump" {}
	_NormalMap("Normalmap", 2D) = "bump" {}
	_DUDVFoamMap ("DUDV(RG) Foam(B)", 2D) = "white" { }	//All the stuff affected by flowmaps goes in here
	_Cube ("Cubemap", CUBE) = "" {}
	_WaterMap ("Depth (R), Foam (G), Transparency(B) Refr strength(A)", 2D) = "white" {}
	_SecondaryRefractionTex("Refraction texture", 2D) = "bump" {}
	_FlowMap ("Flowmap (RG)", 2D) = "white" {}
	_AnisoMap ("AnisoDir(RGB), AnisoLookup(A)", 2D) = "bump" {}
	_CausticsAnimationTexture ("Caustics animation", 2D) = "white" {}
	_Reflectivity("Reflectivity", Range (.0, 1.0)) = .3
	_Refractivity("Refractivity", Range (1.0, 5.0)) = 1.0
	_WaterAttenuation("Water attenuation", Range (0.0, 2.0)) = 1.0
	_ShallowWaterTint("Shallow water wint", Color) = (.0, .26, .39, 1.0)
	_DeepWaterTint("Deep water tint", Color) = (.0, .26, .39, 1.0)
	_Shininess ("Shininess", Range (.05, 20.0)) = 1.0
	_Gloss("Gloss", Range(0.0, 20.0)) = 10.0
	_Fresnel0 ("fresnel0", Float) = 0.1
	_EdgeFoamStrength ("Edge foam strength", Range (.0, 3.0) ) = 1.0
	
	_CausticsStrength ("Caustics strength", Range (0.05, 0.3) ) = 0.1
	_CausticsScale ("Caustics scale", Range (10.0, 2000.0) ) = 500.0
	
	_normalStrength("Normal strength",  Range (.01, 5.0)) = .5
	_refractionsWetness("Refractions wetness", Range (.0, 1.0)) = .8

	_Opaqueness("Opaqueness", Range(.0, 1.0)) = .9
	
	flowMapOffset0 ("internal FlowMapOffset0", Float) = 0.0						//Provided by script
	flowMapOffset1 ("internal FlowMapOffset1", Float) = 0.5						//Provided by script
	halfCycle ("internal HalfCycle", Float) = 0.25								//Provided by script
	causticsOffsetAndScale("internal caustics animation offset and scale", Vector) = (.0, .0, .25, .0)
	causticsAnimationColorChannel("internal caustics animation color channel", Vector) = (1.0, .0, .0, .0)


	_GerstnerIntensity("Per vertex displacement", Float) = 1.0
	_GAmplitude ("Wave Amplitude", Vector) = (0.3 ,0.35, 0.25, 0.25)
	_GFrequency ("Wave Frequency", Vector) = (1.3, 1.35, 1.25, 1.25)
	_GSteepness ("Wave Steepness", Vector) = (1.0, 1.0, 1.0, 1.0)
	_GSpeed ("Wave Speed", Vector) = (1.2, 1.375, 1.1, 1.5)
	_GDirectionAB ("Wave Direction", Vector) = (0.3 ,0.85, 0.85, 0.25)
	_GDirectionCD ("Wave Direction", Vector) = (0.1 ,0.9, 0.5, 0.5)
}

	Category {
		Tags {"Queue"="Transparent-10" "IgnoreProjector"="True" "LightMode" = "ForwardBase"}
		Lighting on
	    
	
		 SubShader {
		 	Pass {
				ZWrite Off
			    Blend SrcAlpha OneMinusSrcAlpha
			    
				CGPROGRAM
				#pragma exclude_renderers xbox360 flash
				#pragma multi_compile FLOWMAP_ANIMATION_ON FLOWMAP_ANIMATION_OFF
				
				#pragma target 3.0
				#pragma glsl
				//#pragma glsl_no_auto_normalization	 //Important for mobile
				
				#pragma vertex vert
				#pragma fragment frag
				
				//#define LINEAR_COLOR_SPACE
				
				#define LIGHT_MODEL_ANISOTROPIC
				//#undef BAKED_ANISOTROPY_DIR
				
				#define LIGHTING_ON
				#define PERPIXEL_SPECULARITY_ON
				#define CAUSTICS_ON
				#define CAUSTICS_ALL
				#define FOAM_ON
				#define REFLECTIONS_ON
				#define WATERMAPS_ON
				#define CALCULATE_NORMALS_ON
				
				#define REFRACTIONS_ON
				#define USE_SECONDARY_REFRACTION
				
				#undef FLOWMAP_ADD_NOISE_ON
				
				#define FRESNEL_ON
				
				//#define ENABLE_SHADOWS
				
				#ifdef ENABLE_SHADOWS
					#pragma multi_compile_fwdbase
				#endif
				
				#include "WaterPlusInclude.cginc"
				ENDCG
		
			}
		
		 }
		 
	}
	
	Fallback "Water+/Desktop Lite"
 }



注意,以上有

half nDotView = dot(pNormal, normViewDir);		//Masking
		half nDotLight = dot(pNormal, normLightDir);	//Shadows (diffuse)			
		fixed3 anisoDir = normalize( cross(pNormal, lightDir) );
		half lightDotT = dot(normLightDir, anisoDir);
		half viewDotT = dot(normViewDir, anisoDir);
		half spec = sqrt(1.0 - lightDotT * lightDotT) * sqrt(1.0 - viewDotT * viewDotT) - lightDotT * viewDotT;

参考:ShaderX_PerPixelAniso

Strand Based Illumination
The basic idea behind the strand based illumination is the lighting of strands. These strands are modeled as having a circular cross-section. When lighting them, we use the standard Phong illumination model but with a slight modification. The normal used in the Phong model is a normal which is equal to the light vector projected into the normal plane of the strand at the point being lit, and normalized. We call this strand normal vector N’. The modified Phong equation is:
Io= ka Ia + (kd (L · N’) + ks (V · R’)n )Ii
The terms ka, kd, and ks are material properties for the ambient, diffuse and specular lighting respectively. Ia is the ambient light color, and Ii is the incident light color. L is the light direction vector, V is the view direction vector and n is the specular exponent. The reflection vector R’ can be found using
R’ = 2N’(N’·V) - V
As shown in [Banks94] and [Stalling97], using some trigonometric identities, and the knowledge that L, T, and N’ are coplanar, L·N’ and V·R’ can be expressed in terms of L, V, and T, the direction of the strand.
L·N’ = (1 - (L·T) 2)0.5
V·R’ = (1 - (L·T) 2) 0.5 (1 - (V·T) 2 ) ) 0.5 - (L·T) (V·T)

Luckily, these equations are a function of two dot products, L·T and V·T. This allows us to use these dot products to index into a pre-computed 2D texture map to compute the diffuse L·N’ and specular (V·R’) n terms. Using the fact that L, T, and V are unit length vectors, it is known that the terms L·T and V·T range between [–1,1]. To use these terms to index into a texture lookup table, first they must be scaled and biased into the range of [0,1].


 类似资料:

相关阅读

相关文章

相关问答