80 lines
2.3 KiB (Stored with Git LFS)
HLSL
80 lines
2.3 KiB (Stored with Git LFS)
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
|
|
} |