You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

243 lines
7.2 KiB

Shader "Hidden/HDRP/WaterDecal"
{
Properties {}
HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
//#pragma enable_d3d11_debug_symbols
#pragma vertex Vert
#pragma fragment Frag
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Water/ShaderVariablesWater.cs.hlsl"
StructuredBuffer<WaterDecalData> _WaterDecalData;
Texture2D<float4> _WaterDecalAtlas;
float2 TransformUV(float2 transformedPositionAWS)
{
return (transformedPositionAWS - _DecalRegionOffset) * _DecalRegionScale;
}
struct Attributes
{
uint vertexID : VERTEXID_SEMANTIC;
uint instanceID : INSTANCEID_SEMANTIC;
};
struct Varyings
{
float4 positionCS : SV_Position;
float2 uv : TEXCOORD0;
float2 data : ADDITIONAL_DATA;
float4 scaleOffset : UV_SCALE_OFFSET;
};
Varyings GetDecalVaryings(Attributes input, float4 uvScaleOffset, float2 additionalData = 0)
{
Varyings varyings;
// Grab the current deformer
WaterDecalData decal = _WaterDecalData[input.instanceID];
// Compute the object space position of the quad
float2 uv = GetQuadTexCoord(input.vertexID).yx;
float2 positionOS = (uv - 0.5) * decal.regionSize;
// Evaluate the world space vertex position
float cosRot = decal.forwardXZ.x;
float sinRot = decal.forwardXZ.y;
float x = positionOS.x * cosRot - sinRot * positionOS.y;
float y = positionOS.x * sinRot + cosRot * positionOS.y;
float2 positionWS = decal.positionXZ + float2(x, y);
// Remap the position into the normalized area space
float2 vertexPositionCS = TransformUV(positionWS) * 2.0f;
varyings.positionCS = float4(vertexPositionCS.x, -vertexPositionCS.y, 0.5, 1.0);
varyings.uv = uv;
varyings.scaleOffset = uvScaleOffset;
varyings.data = additionalData;
if (uvScaleOffset.x < 0)
varyings.positionCS.w = FLT_NAN;
return varyings;
}
float2 RemapUV(float2 uv, float4 scaleOffset)
{
// Remap UV in atlas - clamp to avoid edge bleeding
float halfPixel = _DecalAtlasScale * 0.5f;
return clamp(uv * scaleOffset.xy, halfPixel, scaleOffset.xy - halfPixel) + scaleOffset.zw;
}
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
Name "DeformationDecal"
Cull Off
ZTest Off
ZWrite Off
Blend One One
HLSLPROGRAM
Varyings Vert(Attributes input)
{
WaterDecalData decal = _WaterDecalData[input.instanceID];
return GetDecalVaryings(input, decal.deformScaleOffset, decal.amplitude);
}
float4 Frag(Varyings input) : SV_Target
{
float2 uv = RemapUV(input.uv, input.scaleOffset);
return SAMPLE_TEXTURE2D_LOD(_WaterDecalAtlas, s_linear_clamp_sampler, uv, 0) * input.data.x;
}
ENDHLSL
}
Pass
{
Name "FoamDecal"
Cull Off
ZTest Off
ZWrite Off
Blend One One
HLSLPROGRAM
Varyings Vert(Attributes input)
{
WaterDecalData decal = _WaterDecalData[input.instanceID];
return GetDecalVaryings(input, decal.foamScaleOffset, float2(decal.surfaceFoamDimmer, decal.deepFoamDimmer));
}
float2 Frag(Varyings input) : SV_Target
{
float2 uv = RemapUV(input.uv, input.scaleOffset);
return SAMPLE_TEXTURE2D_LOD(_WaterDecalAtlas, s_linear_clamp_sampler, uv, 0).yz * input.data * _DeltaTime;
}
ENDHLSL
}
Pass
{
Name "MaskDecal"
Cull Off
ZTest Off
ZWrite Off
Blend One One, One One
BlendOp Min
HLSLPROGRAM
Varyings Vert(Attributes input)
{
WaterDecalData decal = _WaterDecalData[input.instanceID];
return GetDecalVaryings(input, decal.maskScaleOffset);
}
float4 Frag(Varyings input) : SV_Target
{
float2 uv = RemapUV(input.uv, input.scaleOffset);
return SAMPLE_TEXTURE2D_LOD(_WaterDecalAtlas, s_linear_clamp_sampler, uv, 0);
}
ENDHLSL
}
Pass
{
Name "LargeCurrentDecal"
Cull Off
ZTest Off
ZWrite Off
Blend One One
HLSLPROGRAM
Varyings Vert(Attributes input)
{
WaterDecalData decal = _WaterDecalData[input.instanceID];
return GetDecalVaryings(input, decal.largeCurrentScaleOffset);
}
float3 Frag(Varyings input) : SV_Target
{
float2 uv = RemapUV(input.uv, input.scaleOffset);
return SAMPLE_TEXTURE2D_LOD(_WaterDecalAtlas, s_linear_clamp_sampler, uv, 0).xyz;
}
ENDHLSL
}
Pass
{
Name "RipplesCurrentDecal"
Cull Off
ZTest Off
ZWrite Off
Blend One One
HLSLPROGRAM
Varyings Vert(Attributes input)
{
WaterDecalData decal = _WaterDecalData[input.instanceID];
return GetDecalVaryings(input, decal.ripplesCurrentScaleOffset);
}
float3 Frag(Varyings input) : SV_Target
{
float2 uv = RemapUV(input.uv, input.scaleOffset);
return SAMPLE_TEXTURE2D_LOD(_WaterDecalAtlas, s_linear_clamp_sampler, uv, 0).xyz;
}
ENDHLSL
}
Pass
{
Name "FoamAttenuation"
Cull Off
ZTest Off
ZWrite Off
Blend Zero SrcAlpha
HLSLPROGRAM
struct AttenuationAttributes
{
uint vertexID : SV_VertexID;
};
struct AttenuationVaryings
{
float4 positionCS : SV_POSITION;
};
AttenuationVaryings Vert(AttenuationAttributes input)
{
AttenuationVaryings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
return output;
}
float4 Frag(AttenuationVaryings input) : SV_Target
{
// Attenuation formula must be in sync with UpdateWaterDecals in C#
return float4(0.0, 0.0, 0.0, exp(-_DeltaTime * _FoamPersistenceMultiplier * 0.5));
}
ENDHLSL
}
}
Fallback Off
}