CapersProject/Assets/StylizedWater2/Shaders/Libraries/Displacement.hlsl
2024-08-06 16:37:03 +09:00

80 lines
2.3 KiB
HLSL

//Functionality to sample the water's displacement pre-pass buffer
uniform bool _WaterDisplacementPrePassAvailable;
#define VOID_THRESHOLD -1000 //Same value as in DisplacementPrePass class
uniform float3 _WaterDisplacementCoords;
//XY: Bounds min
//Z: Bounds size
uniform Texture2D _WaterDisplacementBuffer;
#ifndef UNITY_CORE_SAMPLERS_INCLUDED
SamplerState sampler_LinearClamp;
#endif
//Position, relative to rendering bounds (normalized 0-1)
float2 WorldToDisplacementUV(float3 positionWS)
{
return (positionWS.xz - _WaterDisplacementCoords.xy) / _WaterDisplacementCoords.z;
}
//May be used to validate if the sampled height is actually from a water surface
bool HasHitWaterSurface(float height)
{
return height > VOID_THRESHOLD;
}
float SampleDisplacementBuffer(float2 uv)
{
if(_WaterDisplacementPrePassAvailable == false) return 0;
return _WaterDisplacementBuffer.SampleLevel(sampler_LinearClamp, uv, 0).r;
}
//Main function
float SampleWaterHeight(float3 positionWS)
{
return SampleDisplacementBuffer(WorldToDisplacementUV(positionWS));
}
//Derive a world-space normal from the height data
float3 SampleWaterNormal(float3 positionWS, float strength)
{
if(_WaterDisplacementPrePassAvailable == false) return float3(0,1,0);
//Note: not using the buffer's texel size so that the sampled result remains consistent across different resolutions.
const float radius = 1.0 / _WaterDisplacementCoords.z;
float2 uv = WorldToDisplacementUV(positionWS);
const float xLeft = SampleDisplacementBuffer(float2(uv.x - radius, uv.y));
const float xRight = SampleDisplacementBuffer(float2(uv.x + radius, uv.y));
const float yUp = SampleDisplacementBuffer(float2(uv.x, uv.y + radius));
const float yDown = SampleDisplacementBuffer(float2(uv.x, uv.y - radius));
float xDelta = (xLeft - xRight) * strength;
float zDelta = (yUp - yDown) * strength;
float3 normal = float3(xDelta, 1.0, zDelta);
return normalize(normal.xyz);
}
//Shader Graph
void SampleWaterHeight_float(float3 positionWS, out float height)
{
#if defined(SHADERGRAPH_PREVIEW)
height = 0;
#else
height = SampleWaterHeight(positionWS);
#endif
}
//Shader Graph
void SampleWaterNormal_float(float3 positionWS, float strength, out float3 normal)
{
#if defined(SHADERGRAPH_PREVIEW)
normal = float3(0,1,0);
#else
normal = SampleWaterNormal(positionWS, strength);
#endif
}