您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
326 行
14 KiB
326 行
14 KiB
Shader "BoatAttack/Water"
|
|
{
|
|
Properties
|
|
{
|
|
_TessellationEdgeLength ("Tessellation Edge Length", Range(5, 100)) = 50
|
|
[NoScaleOffset]
|
|
_BumpMap("Detail Wave Normal", 2D) = "bump" {}
|
|
_BumpScale("Detail Wave Amount", Range(0, 1)) = 0.2//fine detail multiplier
|
|
[NoScaleOffset]
|
|
_FoamMap("Foam Texture", 2D) = "black" {}
|
|
[KeywordEnum(Cubemap, Probes, PlanarReflection)]
|
|
_Reflection ("ReflectionMode", float) = 0
|
|
[Header(Debug)]
|
|
[Toggle(_DEBUG)]
|
|
_Debug ("Debug Rendering", Float) = 0
|
|
[KeywordEnum(Final, Reflection, Color, Depth, WaterFX, Normals, Fresnel, Specular, Temporary)]
|
|
_DebugPass ("Debug Mode", Float) = 0
|
|
// Remove after testing
|
|
[Header(Performance)]
|
|
[Toggle(_PERF_REF)]
|
|
_Perf_Ref ("Perf Reflection", float) = 0
|
|
[Toggle(_PERF_COL)]
|
|
_Perf_Col ("Perf Color", float) = 0
|
|
[Toggle(_PERF_DEPTH)]
|
|
_Perf_Depth ("Perf Depth", float) = 0
|
|
[Toggle(_PERF_VERT)]
|
|
_Perf_Vert ("Perf Vert", float) = 0
|
|
[Toggle(_PERF_LIGHTING)]
|
|
_Perf_Light ("Perf Lighting", float) = 0
|
|
[Toggle(_PERF_FRESNEL)]
|
|
_Perf_Fres ("Perf Fresnel", float) = 0
|
|
[Toggle(_PERF_GERSTNER)]
|
|
_Perf_Gerstner ("Perf Gerstner Waves", float) = 0
|
|
[Toggle(_PERF_FOAM)]
|
|
_Perf_Foam ("Perf Foam", float) = 0
|
|
}
|
|
SubShader
|
|
{
|
|
Tags { "RenderType"="Transparent" "Queue"="Transparent-500" "RenderPipeline" = "LightweightPipeline" }
|
|
LOD 300
|
|
ZWrite Off
|
|
|
|
Pass
|
|
{
|
|
Name "WaterShading"
|
|
|
|
HLSLPROGRAM
|
|
|
|
/////////////////SHADER FEATURES//////////////////
|
|
#pragma shader_feature _ _TESSELLATION
|
|
#define _TESSELLATION 0
|
|
#pragma shader_feature _ _DEBUG
|
|
|
|
#pragma multi_compile _REFLECTION_CUBEMAP _REFLECTION_PROBES _REFLECTION_PLANARREFLECTION
|
|
#pragma multi_compile _ FOG_LINEAR FOG_EXP2
|
|
|
|
///////////////PERF SHADER FEATURES///////////////
|
|
#pragma multi_compile _ _PERF_REF
|
|
#pragma multi_compile _ _PERF_COL
|
|
#pragma multi_compile _ _PERF_DEPTH
|
|
#pragma multi_compile _ _PERF_VERT
|
|
#pragma multi_compile _ _PERF_LIGHTING
|
|
#pragma multi_compile _ _PERF_FRESNEL
|
|
#pragma multi_compile _ _PERF_GERSTNER
|
|
#pragma multi_compile _ _PERF_FOAM
|
|
|
|
////////////////////INCLUDES//////////////////////
|
|
#include "WaterCommon.hlsl"
|
|
|
|
//non-tess
|
|
#pragma vertex WaterVertex
|
|
#pragma fragment WaterFragment
|
|
|
|
////////////////////STRUCTS///////////////////////
|
|
//vert struct
|
|
// struct appdata
|
|
// {
|
|
// float4 vertex : POSITION;
|
|
// float2 uv : TEXCOORD0;//TODO - May not need later
|
|
// float4 uv2 : TEXCOORD1;//lightmap
|
|
// };
|
|
// //passing struct
|
|
// struct midStruct
|
|
// {
|
|
// float4 vertex : POS;
|
|
// float2 uv :TEXCOORD0;
|
|
// float4 uv2 : TEXCOORD1;//lightmap
|
|
// };
|
|
// //tess CP
|
|
// struct tessCP
|
|
// {
|
|
// float4 vertex : INTERNALTESSPOS;
|
|
// float2 uv : TEXCOORD0;
|
|
// float4 uv2 : TEXCOORD1;//lightmap
|
|
// };
|
|
// //frag struct
|
|
// struct v2f
|
|
// {
|
|
// float4 uvs : TEXCOORD0;//Geometric UVs stored in xy, and world(pre-waves) in zw
|
|
// float2 uv2 : TEXCOORD1;//lightmapUVs
|
|
// float4 worldPos : TEXCOORD4;//world position of the vertices
|
|
// float4 viewDir : TEXCOORD2;//screen position of the verticies after wave distortion
|
|
// float2 screenPosPreVert : TEXCOORD3;//screen position of the verticies before wave distortion
|
|
// half4 normal : NORMAL;//vert normals(not used right now)
|
|
// half4 diff : COLOR0; // diffuse lighting color
|
|
// half3 spec : TEXCOORD5;//for spec data
|
|
// //UNITY_FOG_COORDS(6)
|
|
// float4 vertex : SV_POSITION;
|
|
// };
|
|
|
|
// //Hull Constant struct
|
|
// struct HS_ConstantOutput
|
|
// {
|
|
// float TessFactor[3] : SV_TessFactor;
|
|
// float InsideTessFactor : SV_InsideTessFactor;
|
|
// };
|
|
|
|
//////////////////New variables final//////////////////
|
|
|
|
//Gerstner Wave variables
|
|
// uniform int _WaveCount;//how many waves, set via the water component
|
|
// uniform float4 _WaveData[10];//the data for the waves, x=amplitude, y=direction, z=wavelength, w=omniDir set via the water component
|
|
// uniform float4 _WaveData2[10];//more data, x=omnidirX, y=omnidirZ
|
|
|
|
// //Screen-based textures/samplers
|
|
// Texture2D _PlanarReflectionTexture;//screen-based planar reflection
|
|
// Texture2D _WaterDisplacementTexture;//screen-based displacement pass
|
|
// SamplerState sampler_PlanarReflectionTexture;//screen-based sampler, clamped for no repetition/edge issues
|
|
|
|
// //Tiling textures/samplers
|
|
// Texture2D _BumpMap;//Detailed normalmap for high frequence details
|
|
// sampler2D _FoamMap;//Foam map for crest whitecaps, etc..
|
|
// sampler2D _WaterDepthMap;//The captured depth map under the water
|
|
// sampler2D _CameraDepthTexture;//depth texture
|
|
// sampler2D _ColorRamp;
|
|
// SamplerState sampler_BumpMap;//Tiling sampler, has repeat wrap mode
|
|
|
|
// float _MaxDepth;
|
|
// float _MaxWaveHeight;
|
|
// half _BumpValue;
|
|
|
|
////////////////////////Tesselation shader///////////////////////////
|
|
// half _TessellationEdgeLength;
|
|
|
|
// float TessellationEdgeFactor (float3 p0, float3 p1)
|
|
// {
|
|
// float edgeLength = distance(p0, p1);
|
|
|
|
// float3 edgeCenter = (p0 + p1) * 0.5;
|
|
// float viewDistance = distance(edgeCenter, _WorldSpaceCameraPos);
|
|
|
|
// return edgeLength * _ScreenParams.y / (_TessellationEdgeLength * viewDistance);
|
|
// }
|
|
|
|
// tessCP vert( appdata Input )
|
|
// {
|
|
// tessCP Output;
|
|
// Output.vertex = Input.vertex;
|
|
// Output.uv = Input.uv;
|
|
// Output.uv2 = Input.uv2;
|
|
// return Output;
|
|
// }
|
|
|
|
// HS_ConstantOutput HSConstant( InputPatch<tessCP, 3> Input )
|
|
// {
|
|
// float3 p0 = mul(unity_ObjectToWorld, Input[0].vertex).xyz;
|
|
// float3 p1 = mul(unity_ObjectToWorld, Input[1].vertex).xyz;
|
|
// float3 p2 = mul(unity_ObjectToWorld, Input[2].vertex).xyz;
|
|
// HS_ConstantOutput Output = (HS_ConstantOutput)0;
|
|
// Output.TessFactor[0] = TessellationEdgeFactor(p1, p2);
|
|
// Output.TessFactor[1] = TessellationEdgeFactor(p2, p0);
|
|
// Output.TessFactor[2] = TessellationEdgeFactor(p0, p1);
|
|
// Output.InsideTessFactor = (TessellationEdgeFactor(p1, p2) +
|
|
// TessellationEdgeFactor(p2, p0) +
|
|
// TessellationEdgeFactor(p0, p1)) * (1 / 3.0);
|
|
// return Output;
|
|
// }
|
|
|
|
// [domain("tri")]
|
|
// [partitioning("fractional_odd")]
|
|
// [outputtopology("triangle_cw")]
|
|
// [patchconstantfunc("HSConstant")]
|
|
// [outputcontrolpoints(3)]
|
|
// tessCP hull( InputPatch<tessCP, 3> Input, uint uCPID : SV_OutputControlPointID )
|
|
// {
|
|
// tessCP Output = (tessCP)0;
|
|
// Output.vertex = Input[uCPID].vertex;
|
|
// Output.uv = Input[uCPID].uv;
|
|
// Output.uv2 = Input[uCPID].uv2;
|
|
// return Output;
|
|
// }
|
|
|
|
////////////////////////////VERT SHADER////////////////////////////
|
|
// [domain("tri")]
|
|
// v2f domain( HS_ConstantOutput HSConstantData,
|
|
// const OutputPatch<tessCP, 3> Input,
|
|
// float3 BarycentricCoords : SV_DomainLocation)
|
|
// {
|
|
// v2f Output = (v2f)0;//initialize OUT
|
|
// /////////////////////Tessellation////////////////////////
|
|
// //DS_Output Output = (DS_Output)0;
|
|
|
|
// float fU = BarycentricCoords.x;
|
|
// float fV = BarycentricCoords.y;
|
|
// float fW = BarycentricCoords.z;
|
|
|
|
// float4 vertex = Input[0].vertex * fU + Input[1].vertex * fV + Input[2].vertex * fW;
|
|
// float2 uv = Input[0].uv * fU + Input[1].uv * fV + Input[2].uv * fW;
|
|
// float4 uv2 = Input[0].uv2 * fU + Input[1].uv2 * fV + Input[2].uv2 * fW;
|
|
|
|
// ///////////////////////Pre-waves/////////////////////////
|
|
// Output.worldPos.xyz = TransformObjectToWorld(vertex.xyz);
|
|
// float4 screenPosRaw = TransformObjectToHClip(vertex.xyz);
|
|
// Output.screenPosPreVert = ComputeNormalizedDeviceCoordinates(screenPosRaw.xyz);//screen uvs pre-waves
|
|
// Output.uvs.xy = uv;//geometry UVs
|
|
// Output.uvs.zw = Output.worldPos.xz * 0.1;//worldspace UVs
|
|
// Output.uv2 = uv2.xy;// * unity_LightmapST.xy + unity_LightmapST.zw;;
|
|
// Output.normal = float4(0, 0, 1, 0);//intialize tangent normals
|
|
// half waterDepth = (tex2Dlod(_WaterDepthMap, float4(Output.uvs.xy, 0, 0)).r * _MaxDepth) *0.05;//get depth map
|
|
// ///////////////////////Gerstner Waves/////////////////////
|
|
// // #ifdef GERSTNER_WAVES
|
|
// // WaveStructOut waves[10];
|
|
// // for(int i = 0; i < _WaveCount; i++)
|
|
// // {
|
|
// // waves[i] = GerstnerWave(Output.worldPos.xyz, _WaveCount, _WaveData[i].x * (1-clamp(waterDepth, 0, 1)), _WaveData[i].y, _WaveData[i].z, _WaveData[i].w, half2(_WaveData2[i].x, _WaveData2[i].y));//calculate the wave
|
|
// // vertex.xyz += waves[i].pos;//add the position to the vertices
|
|
// // Output.normal.xyz += waves[i].normal;//add to the normal
|
|
// // Output.diff.w += length(abs(waves[i].pos.xz));
|
|
// // }
|
|
// // Output.normal.xyz = normalize(Output.normal.xyz);//normalize the normal :D
|
|
// // Output.normal.w = vertex.y;//encode wave height into w component of normal
|
|
// // #endif
|
|
// //////////////////////Post-waves//////////////////////////
|
|
// //vertex.y += _WaterDisplacementTexture.SampleLevel(sampler_PlanarReflectionTexture, float4(Output.screenPosPreVert, 0, 0), 0).r;//added displacement pass
|
|
// Output.vertex = TransformWorldToHClip(vertex);//calculate the vertices for rendering
|
|
// //Output.screenPos = ComputeScreenPos(Output.vertex);//create screenUVs that ignore wave disp
|
|
// Output.worldPos.xyz = mul(unity_ObjectToWorld, vertex).xyz;//recalculate the world pos
|
|
// Output.worldPos.w = 1;// length(ObjSpaceViewDir(vertex)); TODO
|
|
// float3 viewPos = TransformWorldToView(Output.worldPos.xyz);
|
|
// Output.viewDir.w = length(viewPos / viewPos.z);
|
|
// ////////////////////Lighting info/////////////////////////
|
|
// half3 lightDirectionWS;
|
|
// //LightInput mainLight;
|
|
// //INITIALIZE_MAIN_LIGHT(mainLight);
|
|
|
|
// //half realtimeMainLightAtten = GetMainLightDirectionAndRealtimeAttenuation(mainLight, Output.normal.xzy, Output.worldPos, lightDirectionWS);
|
|
// //half NdotL = saturate(dot(Output.normal.xzy, lightDirectionWS));
|
|
// Output.diff.x = 0.5;// mainLight.color * NdotL;
|
|
|
|
// half3 viewDir = SafeNormalize(_WorldSpaceCameraPos - Output.worldPos.xyz);
|
|
// Output.viewDir.xyz = viewDir;
|
|
// Output.spec = 0; //normalize(lightDirectionWS + viewDir);
|
|
// //float nh = max(0, dot(Output.normal.xzy, h));
|
|
// //Output.diff.y = pow(nh, 128.0) * 128;
|
|
|
|
// //UNITY_TRANSFER_FOG(Output, Output.vertex);//Do fog
|
|
// return Output;
|
|
// }
|
|
////////////////////////////FRAG SHADER///////////////////////////
|
|
|
|
// half4 frag (v2f IN) : SV_Target
|
|
// {
|
|
// half3 waveNormals = IN.normal.xyz; //0;
|
|
// half waveHeight = IN.normal.w;
|
|
// float2 reflectionUV = ComputeNormalizedDeviceCoordinates(IN.vertex.xyz);//screen UVs
|
|
// reflectionUV = float2(reflectionUV.x, 1-reflectionUV.y);
|
|
// ///////////////////////Gerstner Waves/////////////////////
|
|
// // #ifdef GERSTNER_WAVES
|
|
// // WaveStructOut waves[10];
|
|
// // for(int i = 0; i < _WaveCount; i++)
|
|
// // {
|
|
// // waves[i] = GerstnerWave(IN.worldPos, _WaveCount, _WaveData[i].x, _WaveData[i].y, _WaveData[i].z);//calculate the wave
|
|
// // waveNormals += waves[i].normal;//add to the normal
|
|
// // waveHeight += waves[i].pos.y;
|
|
// // }
|
|
// // waveNormals = normalize(waveNormals);
|
|
// // #endif
|
|
// ///////////////////////////Normals////////////////////////
|
|
// //Tangent normals
|
|
// half roughness = saturate(_BumpValue + (snoise(IN.worldPos.xz * 0.01) * 0.1));
|
|
// half3 bump1 = UnpackNormal(_BumpMap.Sample(sampler_BumpMap, ((IN.uvs.zw) + frac(_Time.y * 0.05)))) * roughness;//detail01
|
|
// half3 bump2 = UnpackNormal(_BumpMap.Sample(sampler_BumpMap, ((IN.uvs.zw * 3) + frac(_Time.yy * -0.05)))) * roughness;//detail02
|
|
// half3 dispNormal = HeightToNormal(_WaterDisplacementTexture, sampler_PlanarReflectionTexture, IN.screenPosPreVert.xy, 2) * 0.4;//convert displacement pass to normal
|
|
// half3 normal = bump1 + bump2 + dispNormal + waveNormals;//combine all the normals
|
|
// //World normals
|
|
// half3 worldNormal = normal.xzy;//we can cheat here since the water is always facing up, we can convert tangent to world with a swizzle
|
|
// ///////////////////////Fresnel////////////////////////////
|
|
// half3 worldViewDir = IN.viewDir.xyz;
|
|
// half fresnel = 0.02 + 0.97 * pow(1.0 - saturate(dot (normalize(worldViewDir), worldNormal)), 5);//fresnel
|
|
// /////////////////////Lighting////////////////////////////
|
|
// // half3 lighting = DecodeLightmap(tex2D(unity_Lightmap, IN.uv2));
|
|
// // half spec = pow(max(0, dot(normal.xzy, IN.spec)), 128) * 12;
|
|
// // half translucency = (-IN.diff.w * 0.5 + waveHeight) * IN.diff.x;
|
|
// // translucency *= fresnel;
|
|
///////////////////////Depth/Refraction////////////////////
|
|
// float d = tex2D(_CameraDepthTexture, (ComputeNormalizedDeviceCoordinates(IN.vertex.xyz))).r;
|
|
// float depth = LinearEyeDepth(d, _ZBufferParams) * IN.viewDir.w - IN.worldPos.w;
|
|
// half waterDepth = (tex2D(_WaterDepthMap, IN.uvs.xy).r * _MaxDepth);
|
|
// waterDepth += IN.worldPos.y;
|
|
// ////////////////////////////Edgeing///////////////////////
|
|
// half edging = 0;
|
|
// //////////////////////////Colouring///////////////////////
|
|
// half4 disp = _WaterDisplacementTexture.Sample(sampler_PlanarReflectionTexture, IN.screenPosPreVert.xy);//sample displacement pass
|
|
// half3 col = tex2D(_ColorRamp, float2(saturate(depth * 0.01), 0));
|
|
// //col += saturate(translucency) * half3(0, 0.75, 0.5);
|
|
// //col *= lighting * (1.2-fresnel);
|
|
// reflection *= length(1-col.rgb) * fresnel;
|
|
// float3 blend = col + reflection.xyz;
|
|
// //half foam = _FoamMap.Sample(sampler_BumpMap, IN.uvs.zw + frac(_Time.y * 0.05)).r;
|
|
// half foam = tex2D(_FoamMap, (IN.uvs.zw * 0.25) + frac(_Time.y * 0.01) + (snoise(IN.uvs.xy) * 0.1)).r;
|
|
// foam += max(waveHeight / _MaxWaveHeight + disp.y, pow(waterDepth / _MaxDepth, 4) + 0.15);
|
|
// foam = saturate(Remap(foam, half4(1.2, 2.2, 0, 1)));// * lighting;
|
|
// //foam = clamp(Remap(foam + waveHeight + (disp.y * 2), float4(0.75, 1, 0, 1)), 0, 2); //lerp(0, foam, saturate((i.worldPos.y * 2 - 1) + (disp * 2)));
|
|
// //UNITY_APPLY_FOG(IN.fogCoord, blend);
|
|
// ///////////////////////DEBUG OUTPUTS//////////////////////
|
|
// //return float4(frac(depth * 0.01), frac(IN.worldPos.w * 0.01), 0, 1);
|
|
// //return float4(reflection.rgb, 1);
|
|
// //return float4(col, 1);
|
|
// //return float4(waveHeight, 0, 0, 1);
|
|
// return float4(blend + foam, 1);
|
|
// }
|
|
ENDHLSL
|
|
}
|
|
}
|
|
//Fallback "LightweightPipeline/Standard (Physically Based)"
|
|
}
|