浏览代码

further changes to water shader

/feature-infinite-sea
André McGrail 4 年前
当前提交
e28561b1
共有 4 个文件被更改,包括 113 次插入83 次删除
  1. 13
      Packages/com.verasl.water-system/Shaders/InfiniteWater.shader
  2. 83
      Packages/com.verasl.water-system/Shaders/WaterCommon.hlsl
  3. 37
      Packages/com.verasl.water-system/Shaders/WaterInput.hlsl
  4. 63
      Packages/com.verasl.water-system/Shaders/WaterTessellation.hlsl

13
Packages/com.verasl.water-system/Shaders/InfiniteWater.shader


output.uv.xy = input.texcoord;
float3 cameraPosition = GetCameraPositionWS();
cameraPosition.y = 0.0;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz + cameraPosition);
float3 cameraOffset = GetCameraPositionWS();
//input.positionOS.y *= abs(cameraOffset.y) + 1;
cameraOffset.y *= 0.0;
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz + cameraOffset);
output.positionCS = vertexInput.positionCS;
output.screenPosition = ComputeScreenPos(vertexInput.positionCS);
output.clipPos = vertexInput.positionCS;
output.screenPosition = ComputeScreenPos(vertexInput.positionCS);
output.viewDirectionWS.xyz = UNITY_MATRIX_IT_MV[2].xyz;
output.viewDirectionWS.w = length(viewPos / viewPos.z);

83
Packages/com.verasl.water-system/Shaders/WaterCommon.hlsl


#endif
#define DEPTH_MULTIPLIER 1 / _MaxDepth
///////////////////////////////////////////////////////////////////////////////
// Structs //
///////////////////////////////////////////////////////////////////////////////
struct Attributes // vert struct
{
float4 positionOS : POSITION; // vertex positions
float2 texcoord : TEXCOORD0; // local UVs
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings // fragment struct
{
float4 uv : TEXCOORD0; // Geometric UVs stored in xy, and world(pre-waves) in zw
float3 positionWS : TEXCOORD1; // world position of the vertices
half3 normalWS : NORMAL; // vert normals
float4 viewDirectionWS : TEXCOORD2; // view direction
float3 preWaveSP : TEXCOORD3; // screen position of the verticies before wave distortion
half2 fogFactorNoise : TEXCOORD4; // x: fogFactor, y: noise
float4 additionalData : TEXCOORD5; // x = distance to surface, y = distance to surface, z = normalized wave height, w = horizontal movement
half4 screenPosition : TEXCOORD6; // screen position after the waves
float4 clipPos : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
#define WaterFX(uv) SAMPLE_TEXTURE2D(_WaterFXMap, sampler_ScreenTextures_linear_clamp, uv)
///////////////////////////////////////////////////////////////////////////////
// Water debug functions //

float4 DetailUVs(float3 positionWS, half noise)
{
float4 output;
output.zw = positionWS.xz * 0.1h + WATER_TIME * 0.05h + (noise * 0.1);
output.xy = positionWS.xz * 0.4h - WATER_TIME * 0.1h + (noise * 0.2);
float4 output = positionWS.xzxz * half4(0.4, 0.4, 0.1, 0.1);
output.xy -= WATER_TIME * 0.1h + (noise * 0.2); // small detail
output.zw += WATER_TIME * 0.05h + (noise * 0.1); // medium detail
return output;
}

input.positionWS.y += waterFX.w * 2 - 1;
// After waves
input.clipPos = TransformWorldToHClip(input.positionWS);
input.screenPosition = ComputeScreenPos(input.clipPos);
input.positionCS = TransformWorldToHClip(input.positionWS);
input.screenPosition = ComputeScreenPos(input.positionCS);
input.fogFactorNoise.x = ComputeFogFactor(input.clipPos.z);
input.fogFactorNoise.x = ComputeFogFactor(input.positionCS.z);
input.preWaveSP = screenUV.xyz; // pre-displaced screenUVs
// Additional data

return input;
}
void InitializeInputData(Varyings input, out WaterInputData inputData)
void InitializeInputData(Varyings input, out WaterInputData inputData, float2 screenUV)
float3 depth = WaterDepth(input.positionWS, input.additionalData, screenUV);// TODO - hardcoded shore depth UVs
inputData.reflectionUV = 0;
inputData.reflectionUV = 0;
inputData.detailUV = input.uv;
// Sample water FX texture
inputData.waterFX = WaterFX(input.preWaveSP.xy);
inputData.depth = 1;
inputData.depth = 0;
// Detail waves
DetailNormals(input.normalWS, input.detailUV, input.waterFX, input.depth);
surfaceData.absorption = 0;
surfaceData.scattering = 0;
surfaceData.normalWS = 0;

half shadow = SoftShadows(screenUV, input.positionWS);
half3 GI = SampleSH(input.normalWS);
// SSS
half3 directLighting = dot(mainLight.direction, half3(0, 1, 0)) * mainLight.color;
//directLighting += saturate(pow(dot(input.viewDirectionWS.xyz, -mainLight.direction) * IN.additionalData.z, 3)) * 5 * mainLight.color;
//half3 sss = directLighting * shadow + GI;
BRDFData brdfData;
InitializeBRDFData(half3(0, 0, 0), 0, half3(1, 1, 1), 0.95, 1, brdfData);
half3 spec = DirectBDRF(brdfData, input.normalWS, mainLight.direction, input.viewDirectionWS);// * shadow * mainLight.color;

half4 WaterFragment(Varyings IN) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);
half3 screenUV = IN.screenPosition.xyz / IN.screenPosition.w; // screen UVs
half4 screenUV = 0.0;
screenUV.xy = IN.screenPosition.xy / IN.screenPosition.w; // screen UVs
screenUV.zw = IN.preWaveSP.xy; // screen UVs
InitializeInputData(IN, inputData);
InitializeInputData(IN, inputData, screenUV.xy);
WaterSurfaceData surfaceData;
InitializeSurfaceData(inputData, surfaceData);

//return color;
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
half4 waterFX = SAMPLE_TEXTURE2D(_WaterFXMap, sampler_ScreenTextures_linear_clamp, IN.preWaveSP.xy);
// Depth

half3 directLighting = dot(mainLight.direction, half3(0, 1, 0)) * mainLight.color;
directLighting += saturate(pow(dot(IN.viewDirectionWS.xyz, -mainLight.direction) * IN.additionalData.z, 3)) * 5 * mainLight.color;
half3 sss = directLighting * shadow + GI;
////////////////////////////////////////////////////////////////////////////////////////
// Foam
half3 foamMap = SAMPLE_TEXTURE2D(_FoamMap, sampler_FoamMap, IN.uv.zw).rgb; //r=thick, g=medium, b=light

comp = MixFog(comp, fogFactor);
// alpha
float alpha = 1 - saturate((distance(IN.positionWS, GetCameraPositionWS()) - 30) * 0.1);
float3 camPos = GetCameraPositionWS();
camPos.y = 0;
float alpha = 1 - saturate((distance(IN.positionWS, camPos) - 50) * 1);
#if defined(_DEBUG_FOAM)
return half4(foamMask.xxx, 1);

37
Packages/com.verasl.water-system/Shaders/WaterInput.hlsl


TEXTURE2D(_FoamMap); SAMPLER(sampler_FoamMap);
TEXTURE2D(_DitherPattern); SAMPLER(sampler_DitherPattern);
///////////////////////////////////////////////////////////////////////////////
// Structs //
///////////////////////////////////////////////////////////////////////////////
struct Attributes // vert struct
{
float4 positionOS : POSITION; // vertex positions
float2 texcoord : TEXCOORD0; // local UVs
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings // fragment struct
{
float4 uv : TEXCOORD0; // Geometric UVs stored in xy, and world(pre-waves) in zw
float3 positionWS : TEXCOORD1; // world position of the vertices
half3 normalWS : NORMAL; // vert normals
float4 viewDirectionWS : TEXCOORD2; // view direction
float3 preWaveSP : TEXCOORD3; // screen position of the verticies before wave distortion
half2 fogFactorNoise : TEXCOORD4; // x: fogFactor, y: noise
float4 additionalData : TEXCOORD5; // x = distance to surface, y = distance to surface, z = normalized wave height, w = horizontal movement
half4 screenPosition : TEXCOORD6; // screen position after the waves
float4 positionCS : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
struct WaterSurfaceData
{
half3 absorption;

half3 viewDirectionWS;
float2 reflectionUV;
float2 refractionUV;
float4 detailUV;
half4 waterFX;
};
struct WaterLighting
{
half3 driectLighting;
half3 ambientLighting;
half3 sss;
half3 shadow;
};
#endif // WATER_INPUT_INCLUDED

63
Packages/com.verasl.water-system/Shaders/WaterTessellation.hlsl


struct TessellationControlPoint
{
float4 vertex : INTERNALTESSPOS;
float4 texcoord : TEXCOORD0; // Geometric UVs stored in xy, and world(pre-waves) in zw
float3 posWS : TEXCOORD1; // world position of the vertices
float4 positionOS : INTERNALTESSPOS;
float4 texcoord : TEXCOORD0; // Geometric UVs stored in xy, and world(pre-waves) in zw
float3 positionWS : TEXCOORD1; // world position of the vertices
UNITY_VERTEX_INPUT_INSTANCE_ID
};

half _TessellationEdgeLength;
float TessellationEdgeFactor (float3 p0, float3 p1)
float TessellationEdgeFactor (float3 p0, float3 p1)
{
float edgeLength = distance(p0, p1);

return edgeLength * _ScreenParams.y / (_TessellationEdgeLength * viewDistance);
}
TessellationControlPoint TessellationVertex( WaterVertexInput v )
TessellationControlPoint TessellationVertex( Attributes input )
TessellationControlPoint o;
o.vertex = v.vertex;
o.posWS = TransformObjectToWorld(v.vertex.xyz);
o.texcoord.xy = v.texcoord;
o.texcoord.zw = o.posWS.xz;
//o.color = v.color;
return o;
TessellationControlPoint output;
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
output.positionOS = input.positionOS;
output.texcoord.xy = input.texcoord;
output.texcoord.zw = output.positionWS.xz;
return output;
float3 p0 = TransformObjectToWorld(Input[0].vertex.xyz);
float3 p1 = TransformObjectToWorld(Input[1].vertex.xyz);
float3 p2 = TransformObjectToWorld(Input[2].vertex.xyz);
HS_ConstantOutput o = (HS_ConstantOutput)0;
o.TessFactor[0] = TessellationEdgeFactor(p1, p2);
o.TessFactor[1] = TessellationEdgeFactor(p2, p0);
o.TessFactor[2] = TessellationEdgeFactor(p0, p1);
o.InsideTessFactor = (TessellationEdgeFactor(p1, p2) +
TessellationEdgeFactor(p2, p0) +
float3 p0 = TransformObjectToWorld(Input[0].positionOS.xyz);
float3 p1 = TransformObjectToWorld(Input[1].positionOS.xyz);
float3 p2 = TransformObjectToWorld(Input[2].positionOS.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) +
return o;
return output;
}
[domain("tri")]

// Domain: replaces vert for tessellation version
[domain("tri")]
WaterVertexOutput Domain( HS_ConstantOutput HSConstantData, const OutputPatch<TessellationControlPoint, 3> Input, float3 BarycentricCoords : SV_DomainLocation)
Varyings Domain( HS_ConstantOutput HSConstantData, const OutputPatch<TessellationControlPoint, 3> input, float3 BarycentricCoords : SV_DomainLocation)
WaterVertexOutput o = (WaterVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
float4 vertex = Input[0].vertex * fU + Input[1].vertex * fV + Input[2].vertex * fW;
o.uv = Input[0].texcoord * fU + Input[1].texcoord * fV + Input[2].texcoord * fW;
o.posWS = Input[0].posWS * fU + Input[1].posWS * fV + Input[2].posWS * fW;
float4 vertex = input[0].positionOS * fU + input[1].positionOS * fV + input[2].positionOS * fW;
output.uv = input[0].texcoord * fU + input[1].texcoord * fV + input[2].texcoord * fW;
output.positionWS = input[0].positionWS * fU + input[1].positionWS * fV + input[2].positionWS * fW;
o = WaveVertexOperations(o);
output = WaveVertexOperations(output);
return o;
return output;
}
#endif // WATER_TESSELLATION_INCLUDED
正在加载...
取消
保存