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.
138 lines
5.6 KiB
138 lines
5.6 KiB
Shader "Hidden/HDRP/WaterCaustics"
|
|
{
|
|
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
|
|
|
|
// General includes
|
|
#define HIGH_RESOLUTION_WATER
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.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"
|
|
|
|
// Water includes
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterUtilities.hlsl"
|
|
|
|
// This factor enlarges the size of the grid to compensate missing information on the sides
|
|
#define GRID_SCALE_FACTOR 1.1
|
|
ENDHLSL
|
|
|
|
SubShader
|
|
{
|
|
Tags{ "RenderPipeline" = "HDRenderPipeline" }
|
|
|
|
Pass
|
|
{
|
|
// This program doesn't require any culling or ztesting
|
|
Cull Off
|
|
ZTest Off
|
|
ZWrite Off
|
|
|
|
HLSLPROGRAM
|
|
|
|
struct Attributes
|
|
{
|
|
uint vertexID : SV_VertexID;
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
float3 originalPos : TEXCOORD0;
|
|
float3 refractedPos : TEXCOORD1;
|
|
};
|
|
|
|
// Resolution of the caustics geometry
|
|
int _CausticGeometryResolution;
|
|
int _CausticsNormalsMipOffset;
|
|
float _CausticsVirtualPlane;
|
|
|
|
bool IntersectPlane(float3 ray_originWS, float3 ray_dir, float3 pos, float3 normal, out float t)
|
|
{
|
|
float3 ray_originPS = ray_originWS;
|
|
float denom = dot(normal, ray_dir);
|
|
bool flag = false;
|
|
t = -1.0f;
|
|
if (abs(denom) > 1e-6)
|
|
{
|
|
float3 d = pos - ray_originPS;
|
|
t = dot(d, normal) / denom;
|
|
flag = (t >= 0);
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
Varyings EvaluateVaryings(float3 gridPositionWS)
|
|
{
|
|
float3 center = float3(0, 0, 0);
|
|
float3 baseNormal = float3(0, 1, 0);
|
|
float planeDistance = _CausticsVirtualPlane;
|
|
float3 incidentDir = float3(0, -1, 0);
|
|
|
|
// Evaluate the normal at the position
|
|
float3 surfaceGradient = EvaluateWaterSurfaceGradient_VS(gridPositionWS, _CausticsNormalsMipOffset, _CausticsBandIndex);
|
|
float3 normal = SurfaceGradientResolveNormal(baseNormal, surfaceGradient);
|
|
|
|
// Evaluate the refraction vector
|
|
float3 refractedDirection = refract(incidentDir, normal, WATER_INV_IOR);
|
|
|
|
// Intersect the straight ray with the ground plane
|
|
float t;
|
|
IntersectPlane(gridPositionWS, refractedDirection, center - float3(0, _CausticsVirtualPlane, 0), baseNormal, t);
|
|
|
|
// Intersect the refracted ray with the ground plane
|
|
float tRef;
|
|
IntersectPlane(gridPositionWS, incidentDir, center - float3(0, _CausticsVirtualPlane, 0), baseNormal, tRef);
|
|
|
|
// Fill the varyings
|
|
Varyings output;
|
|
output.originalPos = gridPositionWS + incidentDir * t;
|
|
output.refractedPos = gridPositionWS + refractedDirection * tRef;
|
|
float2 clipPos = output.refractedPos.xz / (_CausticsRegionSize * 0.5f);
|
|
#if UNITY_UV_STARTS_AT_TOP
|
|
clipPos.y = -clipPos.y;
|
|
#endif
|
|
output.positionCS = float4(clipPos, UNITY_NEAR_CLIP_VALUE, 1.0);
|
|
return output;
|
|
}
|
|
|
|
Varyings Vert(Attributes input)
|
|
{
|
|
// Compute the coordinates of the vertex
|
|
uint w = input.vertexID / (_CausticGeometryResolution + 1);
|
|
uint h = input.vertexID % (_CausticGeometryResolution + 1);
|
|
|
|
// Compute the world space position of the vertex
|
|
float2 vertexPos = float2(w / (float)_CausticGeometryResolution, h / (float)_CausticGeometryResolution);
|
|
float2 gridSize = _CausticsRegionSize * GRID_SCALE_FACTOR;
|
|
float3 center = float3(0, 0, 0);
|
|
float3 gridPositionWS = float3(vertexPos.x * gridSize.x, 0, vertexPos.y * gridSize.y) - float3(gridSize.x * 0.5, 0, gridSize.y * 0.5) + center - 0.5 / _BandResolution;
|
|
|
|
// Evaluate the caustics data
|
|
return EvaluateVaryings(gridPositionWS);
|
|
}
|
|
|
|
float2 Frag(Varyings input) : SV_Target
|
|
{
|
|
// https://medium.com/@evanwallace/rendering-realtime-caustics-in-webgl-2a99a29a0b2c
|
|
// Compute the original triangle area using the derivatives
|
|
float intialTriangleArea = length(ddx(input.originalPos)) * length(ddy(input.originalPos));
|
|
// Compute the refracted triangle area using the derivatives
|
|
float refractedTriangleArea = length(ddx(input.refractedPos)) * length(ddy(input.refractedPos));
|
|
// Compute the ratio between the two
|
|
return float2(clamp(intialTriangleArea / refractedTriangleArea, 0.0, 5.0), 1.0);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
Fallback Off
|
|
}
|