ProjectDDD/Assets/External/StylizedWater2/Shaders/DynamicEffects/DynamicEffects.hlsl
2025-07-08 19:46:31 +09:00

135 lines
3.9 KiB
HLSL

#if !defined(SHADERGRAPH_PREVIEW)
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#endif
#include "../Libraries/URP.hlsl"
#include "../Libraries/Common.hlsl"
#include "Common.hlsl"
TEXTURE2D(_WaterDynamicEffectsBuffer);
float4 _WaterDynamicEffectsBuffer_TexelSize;
TEXTURE2D(_WaterDynamicEffectsNormals);
float4 _WaterDynamicEffectsCoords;
//XY: Bounds min position
//Z: Bounds scale
//W: Bool, rendering pass active
float4 _WaterDynamicEffectsParams;
//X: Enable normals
//Y: Enable displacement
//Z: Render range
//W: End fade percentage (1/value)
#define NORMALS_AVAILABLE _WaterDynamicEffectsParams.x > 0
#define GLOBAL_DISPLACEMENT_STRENGTH _WaterDynamicEffectsParams.y
#define DE_DISPLACEMENT_CHANNEL 0
#define DE_FOAM_CHANNEL 1
#define DE_NORMALS_CHANNEL 2
#define DE_ALPHA_CHANNEL 3
float BoundsEdgeMask(float2 position)
{
const float blendDistance = (_WaterDynamicEffectsParams.z * 0.5) * _WaterDynamicEffectsParams.w;
const float extents = (_WaterDynamicEffectsCoords.z * 0.5);
position = position - extents;
const float2 boundsMin = _WaterDynamicEffectsCoords.xy - extents;
const float2 boundsMax = _WaterDynamicEffectsCoords.xy + extents;
float2 weightDir = min(position - boundsMin, boundsMax - position) / blendDistance;
return saturate(min(weightDir.x, weightDir.y));
}
//Shader Graph
void BoundsEdgeMask_float(float3 positionWS, out float mask)
{
#if !defined(SHADERGRAPH_PREVIEW)
mask = BoundsEdgeMask(positionWS.xz);
#else
mask = 1.0;
#endif
}
float2 DynamicEffectsSampleCoords(float3 positionWS)
{
return (positionWS.xz - _WaterDynamicEffectsCoords.xy) / (_WaterDynamicEffectsCoords.z);
}
//Account for the SampleDynamicEffectsData being called in a vertex or tessellation shader
#if defined(SHADER_STAGE_VERTEX) || defined(SHADER_STAGE_DOMAIN) || defined(SHADER_STAGE_HULL)
#define SAMPLE_FUNC(texName, sampler, uv) SAMPLE_TEXTURE2D_LOD(texName, sampler, uv, 0)
#else
#define SAMPLE_FUNC(texName, sampler, uv) SAMPLE_TEXTURE2D(texName, sampler, uv)
#endif
float4 SampleDynamicEffectsData(float3 positionWS)
{
float4 data = 0;
if(_WaterDynamicEffectsCoords.w > 0)
{
data = SAMPLE_FUNC(_WaterDynamicEffectsBuffer, sampler_LinearClamp, DynamicEffectsSampleCoords(positionWS));
if(_WaterDynamicEffectsHighPrecision == false)
{
data[DE_DISPLACEMENT_CHANNEL] = UnpackChannel(data[DE_DISPLACEMENT_CHANNEL]);
//data[DE_FOAM_CHANNEL] = UnpackChannel(data[DE_FOAM_CHANNEL]);
//data[DE_NORMALS_CHANNEL] = UnpackChannel(data[DE_NORMALS_CHANNEL]);
}
data[DE_DISPLACEMENT_CHANNEL] *= GLOBAL_DISPLACEMENT_STRENGTH;
const half mask = BoundsEdgeMask(positionWS.xz);
data *= mask;
data[DE_ALPHA_CHANNEL] = mask;
}
return data;
}
//Shorthand for only sampling displacement
float SampleDynamicEffectsDisplacement(float3 positionWS)
{
return SampleDynamicEffectsData(positionWS).r;
}
//Shader Graph
void SampleDynamicEffectsData_float(float3 positionWS, out float4 data)
{
#if !defined(SHADERGRAPH_PREVIEW)
data = SampleDynamicEffectsData(positionWS);
#else
data = 0;
#endif
}
float4 SampleDynamicEffectsNormals(float3 positionWS)
{
float4 normals = float4(0, 1, 0.0, 0.0);
if(_WaterDynamicEffectsCoords.w > 0 && NORMALS_AVAILABLE)
{
normals = SAMPLE_TEXTURE2D(_WaterDynamicEffectsNormals, sampler_LinearClamp, DynamicEffectsSampleCoords(positionWS));
normals.xz = normals.xy * 2.0 - 1.0;
normals.y = max(1.0e-16, sqrt(1.0 - saturate(dot(normals.xz, normals.xz))));
const half mask = BoundsEdgeMask(positionWS.xz);
normals = lerp(float4(0, 1, 0, 1), normals, mask);
}
return normals;
}
#include "../Libraries/Foam.hlsl"
TEXTURE2D(_FoamTexDynamic);
float SampleDynamicFoam(float2 uv, float tiling, float subTiling, float2 time, float speed, float subSpeed)
{
return SampleFoamTexture(TEXTURE2D_ARGS(_FoamTexDynamic, sampler_FoamTex), uv, tiling, subTiling, time, speed, subSpeed, 0.0, 0.0, 0.0, false);
}