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.
148 lines
7.0 KiB
148 lines
7.0 KiB
// We need only need one bounce given that we want to see the if there is anything that occludes the area light
|
|
#pragma max_recursion_depth 1
|
|
|
|
// Given that this pass does not use the shadow algorithm multi-compile, we need to define SHADOW_LOW to quite the shadow algorithm error
|
|
#define SHADOW_LOW
|
|
|
|
// Required for contact shadows
|
|
#define USE_FPTL_LIGHTLIST
|
|
|
|
// We are using DX12 here
|
|
#define SHADER_TARGET 50
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
#define SHADERPASS SHADERPASS_RAYTRACING
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesFunctions.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/ContactShadows.hlsl"
|
|
|
|
// Raytracing includes
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingIntersection.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RaytracingSampling.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Common/RayTracingHelpers.hlsl"
|
|
|
|
// The target acceleration structure that we will evaluate the reflexion in
|
|
TEXTURE2D_X(_DepthTexture);
|
|
|
|
[shader("miss")]
|
|
void MissShaderShadows(inout RayIntersectionVisibility rayIntersection : SV_RayPayload)
|
|
{
|
|
rayIntersection.color = float3(1.0, 1.0, 1.0);
|
|
}
|
|
|
|
bool RayTraceContactShadow(PositionInputs posInput, float3 direction)
|
|
{
|
|
if (_ContactShadowLength > 0.0f)
|
|
{
|
|
//Here LightDirection is not the light direction but the light position
|
|
float rayLength = _ContactShadowLength;
|
|
|
|
// Evaluate the ray bias
|
|
float rayBias = EvaluateRayTracingBias(posInput.positionWS);
|
|
|
|
// Create the ray descriptor for this pixel
|
|
RayDesc rayDescriptor;
|
|
rayDescriptor.Origin = posInput.positionWS + rayBias * direction;
|
|
rayDescriptor.Direction = direction;
|
|
rayDescriptor.TMin = 0.0;
|
|
rayDescriptor.TMax = rayLength - rayBias;
|
|
|
|
// Adjust world-space position to match the RAS setup with XR single-pass and camera relative
|
|
ApplyCameraRelativeXR(rayDescriptor.Origin);
|
|
|
|
// Create and init the RayIntersectionVisibility structure for this
|
|
RayIntersectionVisibility rayIntersection;
|
|
rayIntersection.color = float3(0.0, 0.0, 0.0);
|
|
rayIntersection.pixelCoord = posInput.positionSS;
|
|
|
|
// Evaluate the ray visibility term and PDF
|
|
TraceRay(_RaytracingAccelerationStructure, RAY_FLAG_CULL_FRONT_FACING_TRIANGLES | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, RAYTRACINGRENDERERFLAG_CAST_SHADOW, 0, 1, 0, rayDescriptor, rayIntersection);
|
|
|
|
// Not sure true translates to 1 in every compiler
|
|
return (rayIntersection.color.x == 0.0) ? 1 : 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
[shader("raygeneration")]
|
|
void RayGenContactShadows()
|
|
{
|
|
// Grab the dimensions of the current raytrace shader
|
|
uint3 LaunchIndex = DispatchRaysIndex();
|
|
uint3 LaunchDim = DispatchRaysDimensions();
|
|
|
|
UNITY_XR_ASSIGN_VIEW_INDEX(LaunchIndex.z);
|
|
|
|
// Get the current pixel coordinate
|
|
uint2 pixelCoord = uint2(LaunchIndex.x, LaunchIndex.y);
|
|
|
|
// Fetch the current depth value
|
|
float depth = LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord).x;
|
|
|
|
// Reconstruction world space position
|
|
uint2 tileIndex = pixelCoord / GetTileSize();
|
|
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), tileIndex);
|
|
|
|
// discard the shadow if we're on the sky or outside of the contact shadow range
|
|
if (depth == UNITY_RAW_FAR_CLIP_VALUE || posInput.linearDepth - _ContactShadowFadeEnd > 1)
|
|
return;
|
|
|
|
float fade = 0.0;
|
|
// store the 24 bit contact shadow mask mask (1: pixel is in contact shadow, 0: pixel is not shadowed)
|
|
uint contactShadowMask = 0;
|
|
UnpackContactShadowData(_ContactShadowTextureUAV[COORD_TEXTURE2D_X(pixelCoord)], fade, contactShadowMask);
|
|
|
|
for (int i = 0; i < _DirectionalLightCount; ++i)
|
|
{
|
|
DirectionalLightData light = _DirectionalLightDatas[i];
|
|
|
|
if (light.contactShadowMask != 0 && light.isRayTracedContactShadow == 1.0)
|
|
{
|
|
// We store the inverse of the contact shadow:
|
|
bool occluded = RayTraceContactShadow(posInput, -light.forward);
|
|
|
|
// light.contactShadowMask contains one bit at the position of the contact shadow index that will
|
|
// be tested in the lightloop, so it insert 1 at the index of the contact shadow if there is a contact shadow
|
|
// we take full bits at one multiplied by contact shadow and filter the bit at the contact shadow index.
|
|
contactShadowMask |= (light.contactShadowMask * occluded);
|
|
}
|
|
}
|
|
uint lightCount, lightStart;
|
|
|
|
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
|
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, lightStart, lightCount);
|
|
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
|
lightCount = _PunctualLightCount;
|
|
lightStart = 0;
|
|
#endif
|
|
|
|
uint v_lightListOffset = 0;
|
|
uint v_lightIdx = lightStart;
|
|
while (v_lightListOffset < lightCount)
|
|
{
|
|
v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
|
|
LightData s_lightData = FetchLight(v_lightIdx);
|
|
v_lightListOffset++;
|
|
if (s_lightData.contactShadowMask != 0 && s_lightData.isRayTracedContactShadow == 1.0)
|
|
{
|
|
// Compute light ray direction:
|
|
float3 direction = normalize(s_lightData.positionRWS.xyz - posInput.positionWS);
|
|
|
|
bool occluded = RayTraceContactShadow(posInput, direction);
|
|
|
|
// light.contactShadowMask contains one bit at the position of the contact shadow index that will
|
|
// be tested in the lightloop, so it insert 1 at the index of the contact shadow if there is a contact shadow
|
|
// we take full bits at one multiplied by contact shadow and filter the bit at the contact shadow index.
|
|
contactShadowMask |= (s_lightData.contactShadowMask * occluded);
|
|
}
|
|
}
|
|
|
|
_ContactShadowTextureUAV[COORD_TEXTURE2D_X(pixelCoord)] = PackContactShadowData(fade, contactShadowMask);
|
|
}
|