2026-06-09 룸 프로토타입 디자인 (진행중)
This commit is contained in:
163
Assets/Stylized Water 3/Shaders/Libraries/Reflections.hlsl
Normal file
163
Assets/Stylized Water 3/Shaders/Libraries/Reflections.hlsl
Normal file
@@ -0,0 +1,163 @@
|
||||
// Stylized Water 3 by Staggart Creations (http://staggart.xyz)
|
||||
// COPYRIGHT PROTECTED UNDER THE UNITY ASSET STORE EULA (https://unity.com/legal/as-terms)
|
||||
// • Copying or referencing source code for the production of new asset store, or public, content is strictly prohibited!
|
||||
// • Uploading this file to a public repository will subject it to an automated DMCA takedown request.
|
||||
|
||||
#ifndef WATER_REFLECTIONS_INCLUDED
|
||||
#define WATER_REFLECTIONS_INCLUDED
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
|
||||
|
||||
#define AIR_RI 1.000293
|
||||
|
||||
//Schlick's BRDF fresnel
|
||||
float ReflectionFresnel(float3 worldNormal, float3 viewDir, float exponent)
|
||||
{
|
||||
float cosTheta = saturate(dot(worldNormal, viewDir));
|
||||
return pow(max(0.0, AIR_RI - cosTheta), exponent);
|
||||
}
|
||||
|
||||
float AttenuateSSR(float2 uv)
|
||||
{
|
||||
float offset = min(1.0 - max(uv.x, uv.y), min(uv.x, uv.y));
|
||||
|
||||
float result = offset / (0.1);
|
||||
result = saturate(result);
|
||||
|
||||
return pow(result, 0.5);
|
||||
}
|
||||
|
||||
|
||||
float4 _WaterSSRParams;
|
||||
//X: Enabled bool
|
||||
//Y: Accept skybox hits
|
||||
|
||||
#define ALLOW_SSR _WaterSSRParams.x > 0.5
|
||||
#define SSR_REFLECT_SKY _WaterSSRParams.y > 0.5
|
||||
|
||||
float4 _WaterSSRSettings;
|
||||
//X: Steps
|
||||
//Y: Step size
|
||||
//Z: Max distance
|
||||
//W: Thickness
|
||||
|
||||
#define SSR_SAMPLES _WaterSSRSettings.x
|
||||
#define SSR_STEPSIZE _WaterSSRSettings.y
|
||||
#define SSR_MAX_DISTANCE _WaterSSRSettings.z
|
||||
#define SSR_THICKNESS _WaterSSRSettings.w
|
||||
|
||||
void RaymarchSSR(float3 positionVS, float3 direction, uint samples, half stepSize, half thickness, out half2 sampleUV, out half valid, out half outOfBounds)
|
||||
{
|
||||
sampleUV = 0;
|
||||
valid = 0;
|
||||
outOfBounds = 0;
|
||||
|
||||
direction *= stepSize;
|
||||
const half rcpStepCount = rcp(samples);
|
||||
|
||||
UNITY_LOOP
|
||||
for(uint i = 0; i < samples; i++)
|
||||
{
|
||||
positionVS += direction;
|
||||
direction *= 1+stepSize;
|
||||
|
||||
//View-space to screen-space UV
|
||||
sampleUV = ComputeNormalizedDeviceCoordinates(positionVS, GetViewToHClipMatrix());
|
||||
|
||||
if (any(sampleUV < 0) || any(sampleUV > 1))
|
||||
{
|
||||
outOfBounds = 1;
|
||||
valid = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
outOfBounds = AttenuateSSR(sampleUV);
|
||||
|
||||
//Sample Mip0, gradient sampling cannot work with loops
|
||||
float deviceDepth = SAMPLE_TEXTURE2D_X_LOD(_CameraDepthTexture, sampler_CameraDepthTexture, sampleUV, 0).r;
|
||||
|
||||
//Depth is near-infinity. May want to reflect the skybox, if no reflection probes are present
|
||||
if(SSR_REFLECT_SKY && deviceDepth <= 0.00001)
|
||||
{
|
||||
valid = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
//Calculate view-space position from UV and depth
|
||||
//Not using the ComputeViewSpacePosition function, since this negates the Z-component
|
||||
float3 samplePos = ComputeWorldSpacePosition(sampleUV, deviceDepth, UNITY_MATRIX_I_P);
|
||||
|
||||
//Depth mismatch check. Geometry behind the water is invalid. If the difference in depth is large enough, consider it a miss.
|
||||
if (abs(samplePos.z - positionVS.z) > length(direction) * thickness) continue;
|
||||
|
||||
if(samplePos.z > positionVS.z)
|
||||
{
|
||||
valid = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEXTURE2D_X(_PlanarReflection);
|
||||
SAMPLER(sampler_PlanarReflection);
|
||||
|
||||
float3 SampleReflectionProbes(float3 reflectionVector, float3 positionWS, float smoothness, float2 screenPos)
|
||||
{
|
||||
float3 probes = float3(0,0,0);
|
||||
|
||||
probes = GlossyEnvironmentReflection(reflectionVector, positionWS, smoothness, 1.0, screenPos.xy).rgb;
|
||||
|
||||
return probes;
|
||||
}
|
||||
|
||||
float3 SampleReflections(float3 reflectionVector, float smoothness, float4 screenPos, float3 positionWS, float3 normalWS, float3 viewDir, float2 pixelOffset, bool planarReflectionsEnabled, bool ssrEnabled, out float3 renderedReflections)
|
||||
{
|
||||
screenPos.xy += pixelOffset.xy * lerp(1.0, 0.1, unity_OrthoParams.w);
|
||||
screenPos /= screenPos.w;
|
||||
|
||||
const float3 probes = SampleReflectionProbes(reflectionVector, positionWS, smoothness, screenPos.xy);
|
||||
|
||||
float3 reflections = probes;
|
||||
|
||||
//Output separately, for underwater rendering
|
||||
renderedReflections = 0;
|
||||
|
||||
#if !_DISABLE_DEPTH_TEX
|
||||
if(ssrEnabled && ALLOW_SSR)
|
||||
{
|
||||
const float3 positionVS = TransformWorldToView(positionWS);
|
||||
const float3 direction = TransformWorldToViewDir(reflectionVector);
|
||||
|
||||
float2 ssrUV = 0;
|
||||
half ssrRayMask, ssrEdgeMask = 0;
|
||||
|
||||
RaymarchSSR(positionVS, direction, SSR_SAMPLES, SSR_STEPSIZE, SSR_THICKNESS, ssrUV, ssrRayMask, ssrEdgeMask);
|
||||
|
||||
half ssrMask = ssrRayMask * ssrEdgeMask;
|
||||
const float3 reflectionSS = SampleSceneColor(ssrUV);
|
||||
|
||||
reflections = lerp(reflections, reflectionSS, ssrMask);
|
||||
|
||||
renderedReflections += reflectionSS * ssrMask;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !_RIVER //Planar reflections are pointless on curved surfaces, skip
|
||||
if(planarReflectionsEnabled)
|
||||
{
|
||||
float4 planarReflections = SAMPLE_TEXTURE2D_X_LOD(_PlanarReflection, sampler_PlanarReflection, screenPos.xy, 0);
|
||||
//Terrain add-pass can output negative alpha values. Clamp as a safeguard against this
|
||||
planarReflections.a = saturate(planarReflections.a);
|
||||
|
||||
reflections = lerp(reflections, planarReflections.rgb, planarReflections.a);
|
||||
|
||||
renderedReflections = lerp(renderedReflections, planarReflections.rgb, planarReflections.a);
|
||||
}
|
||||
#endif
|
||||
|
||||
return reflections;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user