还原水插件
This commit is contained in:
@@ -4,8 +4,6 @@
|
||||
#ifndef CREST_WATER_REFRACTION_H
|
||||
#define CREST_WATER_REFRACTION_H
|
||||
|
||||
#if !d_Crest_SimpleTransparency
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Depth.hlsl"
|
||||
@@ -20,144 +18,91 @@
|
||||
#define FoveatedRemapLinearToNonUniform(uv) uv
|
||||
#endif
|
||||
|
||||
#if (UNITY_VERSION < 60000000) || !defined(CREST_URP)
|
||||
float4 _CameraDepthTexture_TexelSize;
|
||||
#endif
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
float2 GetRefractionCoordinates(const half3 i_View, const half3 i_Normal, const float3 i_Position, const half i_IOR, const half i_Strength)
|
||||
{
|
||||
float3 position = i_Position;
|
||||
|
||||
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
|
||||
position -= _WorldSpaceCameraPos;
|
||||
#endif
|
||||
|
||||
const half3 ray = refract(-i_View, i_Normal, i_IOR) * i_Strength;
|
||||
float2 uv = ComputeNormalizedDeviceCoordinates(position + ray, UNITY_MATRIX_VP);
|
||||
|
||||
#if CREST_HDRP
|
||||
// Prevent artifacts at edge. Maybe because depth is an atlas for HDRP.
|
||||
uv = clamp(uv, _CameraDepthTexture_TexelSize.xy, 1.0 - _CameraDepthTexture_TexelSize.xy);
|
||||
#endif
|
||||
|
||||
return FoveatedRemapLinearToNonUniform(uv);
|
||||
}
|
||||
|
||||
// We take the unrefracted scene colour as input because having a Scene Colour node in the graph
|
||||
// appears to be necessary to ensure the scene colours are bound?
|
||||
void RefractedScene
|
||||
(
|
||||
const half i_RefractionStrength,
|
||||
const half i_AirIOR,
|
||||
const half i_WaterIOR,
|
||||
const half3 i_NormalWS,
|
||||
const float3 i_PositionWS,
|
||||
const float2 i_PositionNDC,
|
||||
const float4 i_ScreenPositionRaw,
|
||||
const float i_PixelZ,
|
||||
const half3 i_View,
|
||||
const half3 i_SceneColorUnrefracted,
|
||||
const float i_SceneZ,
|
||||
const float i_SceneZRaw,
|
||||
const float i_Scale,
|
||||
const float i_LodAlpha,
|
||||
const bool i_Underwater,
|
||||
const half i_TotalInternalReflectionIntensity,
|
||||
out half3 o_SceneColor,
|
||||
out float o_SceneDistance,
|
||||
out float3 o_ScenePositionWS,
|
||||
out float2 o_PositionSS,
|
||||
out bool o_Caustics
|
||||
)
|
||||
{
|
||||
float2 positionNDC = i_PositionNDC;
|
||||
float sceneDepthRaw = i_SceneZRaw;
|
||||
|
||||
o_Caustics = true;
|
||||
|
||||
half strength = i_RefractionStrength;
|
||||
|
||||
const half _AirToWaterRatio = i_AirIOR / i_WaterIOR;
|
||||
const half _WaterToAirRatio = i_WaterIOR / i_AirIOR;
|
||||
|
||||
// If no TIR, then use same IOR.
|
||||
const bool isA2WR = !i_Underwater || i_TotalInternalReflectionIntensity < 1.0;
|
||||
|
||||
const half eta = isA2WR ? _AirToWaterRatio : _WaterToAirRatio;
|
||||
|
||||
half3 normal = i_NormalWS;
|
||||
|
||||
// Exchanges accuracy for less artifacts.
|
||||
if (isA2WR)
|
||||
// View ray intersects geometry surface either above or below water surface.
|
||||
float2 refractOffset = i_RefractionStrength * i_NormalWS.xz;
|
||||
if (!i_Underwater)
|
||||
{
|
||||
half multiplier = 0.0;
|
||||
|
||||
if (i_Underwater)
|
||||
{
|
||||
multiplier = 1.0;
|
||||
// Max fade when water is 5m deep.
|
||||
multiplier = saturate(g_Crest_WaterDepthAtViewer * 0.2);
|
||||
// Max fade by displacement.
|
||||
multiplier *= saturate(g_Crest_MaximumVerticalDisplacement - 1.0);
|
||||
// Fade towards screen edge where off screen samples happen. + n is fade start.
|
||||
multiplier *= saturate((dot(i_PositionNDC - 0.5, -g_Crest_HorizonNormal) + 0.5) * 2.0);
|
||||
}
|
||||
|
||||
normal.y *= multiplier;
|
||||
// We're above the water, so behind interface is depth fog.
|
||||
refractOffset *= min(1.0, 0.5 * (i_SceneZ - i_PixelZ)) / i_SceneZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// When looking up through water, full strength ends up being quite intense so reduce it a bunch.
|
||||
refractOffset *= 0.3;
|
||||
}
|
||||
|
||||
// Since we lose detail at a distance, boosting refraction helps visually.
|
||||
strength *= lerp(i_Scale, i_Scale * 2.0, i_LodAlpha) * 0.25;
|
||||
// Blend at the edge of the screen to avoid artifacts.
|
||||
refractOffset *= 1.0 - EdgeBlendingFactor(positionNDC, i_PixelZ);
|
||||
|
||||
// Restrict to a reasonable maximum.
|
||||
strength = min(strength, i_RefractionStrength * 4.0);
|
||||
|
||||
float2 uv = GetRefractionCoordinates(i_View, normal, i_PositionWS, eta, strength);
|
||||
|
||||
o_PositionSS = min(uv * _ScreenSize.xy, _ScreenSize.xy - 1.0);
|
||||
|
||||
#if CREST_BIRP
|
||||
float deviceDepth = LoadSceneDepth(o_PositionSS);
|
||||
#else
|
||||
float deviceDepth = SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv);
|
||||
#endif
|
||||
const float2 positionNDCRefracted = FoveatedRemapLinearToNonUniform(positionNDC + refractOffset);
|
||||
float sceneDepthRawRefracted = SHADERGRAPH_SAMPLE_SCENE_DEPTH(positionNDCRefracted);
|
||||
|
||||
#if (CREST_PORTALS != 0)
|
||||
#if _ALPHATEST_ON
|
||||
Portal::EvaluateRefraction(uv, i_SceneZRaw, i_Underwater, deviceDepth, o_Caustics);
|
||||
// Portals
|
||||
Portal::EvaluateRefraction(positionNDCRefracted, i_SceneZRaw, i_Underwater, sceneDepthRawRefracted, o_Caustics);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float linearDepth = Utility::CrestLinearEyeDepth(deviceDepth);
|
||||
float depthDifference = linearDepth - i_PixelZ;
|
||||
|
||||
normal *= saturate(depthDifference);
|
||||
const float sceneZRefract = Utility::CrestLinearEyeDepth(sceneDepthRawRefracted);
|
||||
|
||||
uv = GetRefractionCoordinates(i_View, normal, i_PositionWS, eta, strength);
|
||||
// Depth fog & caustics - only if view ray starts from above water.
|
||||
// Compute depth fog alpha based on refracted position if it landed on an
|
||||
// underwater surface, or on unrefracted depth otherwise.
|
||||
if (sceneZRefract > i_PixelZ)
|
||||
{
|
||||
// Refracted.
|
||||
o_SceneDistance = sceneZRefract - i_PixelZ;
|
||||
o_SceneColor = SHADERGRAPH_SAMPLE_SCENE_COLOR(positionNDCRefracted);
|
||||
|
||||
o_PositionSS = min(uv * _ScreenSize.xy, _ScreenSize.xy - 1.0);
|
||||
positionNDC = positionNDCRefracted;
|
||||
sceneDepthRaw = sceneDepthRawRefracted;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unrefracted.
|
||||
// It seems that when MSAA is enabled this can sometimes be negative.
|
||||
o_SceneDistance = max(i_SceneZ - i_PixelZ, 0.0);
|
||||
o_SceneColor = i_SceneColorUnrefracted;
|
||||
|
||||
#if CREST_BIRP
|
||||
deviceDepth = LoadSceneDepth(o_PositionSS);
|
||||
#else
|
||||
deviceDepth = SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv);
|
||||
#endif
|
||||
// NOTE: Causes refraction artifact with caustics. Cannot remember exactly why this was added.
|
||||
// o_Caustics = false;
|
||||
positionNDC = FoveatedRemapLinearToNonUniform(positionNDC);
|
||||
}
|
||||
|
||||
linearDepth = Utility::CrestLinearEyeDepth(deviceDepth);
|
||||
// It seems that when MSAA is enabled this can sometimes be negative.
|
||||
depthDifference = max(linearDepth - i_PixelZ, 0.0);
|
||||
if (i_Underwater)
|
||||
{
|
||||
// Depth fog is handled by underwater shader.
|
||||
o_SceneDistance = i_PixelZ;
|
||||
}
|
||||
|
||||
#if CREST_BIRP
|
||||
// Sampling artifacts which manifest as a fine outline around refractions. Always
|
||||
// affects BIRP unless we use Load. Does not affect URP unless downsampling or MSAA
|
||||
// is used, but Load exposes us to RT scaling. Best to use Sample with HDRP too.
|
||||
o_SceneColor = LoadSceneColor(o_PositionSS).rgb;
|
||||
#else
|
||||
// Sampling artifacts if downsampling or MSAA used. Load does not help. And we get
|
||||
// outlines around all objects irrespective of refraction.
|
||||
o_SceneColor = SHADERGRAPH_SAMPLE_SCENE_COLOR(uv).rgb;
|
||||
#endif
|
||||
|
||||
o_SceneDistance = depthDifference;
|
||||
o_ScenePositionWS = ComputeWorldSpacePosition(uv, deviceDepth, UNITY_MATRIX_I_VP);
|
||||
o_ScenePositionWS = ComputeWorldSpacePosition(positionNDC, sceneDepthRaw, UNITY_MATRIX_I_VP);
|
||||
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
|
||||
o_ScenePositionWS += _WorldSpaceCameraPos;
|
||||
#endif
|
||||
@@ -166,4 +111,3 @@ void RefractedScene
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user