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.
191 lines
9.1 KiB
191 lines
9.1 KiB
// We need only need one bounce given that we want to see the objects and then direct lighting is not done using raytracing
|
|
#pragma max_recursion_depth 1
|
|
|
|
// Given that the algorithm requires BSDF evaluation, we need to define this macro
|
|
#define HAS_LIGHTLOOP
|
|
|
|
// 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
|
|
|
|
// Include and define the shader pass
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
#define SHADERPASS SHADERPASS_RAYTRACING_INDIRECT
|
|
|
|
// HDRP include
|
|
#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/Packing.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.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.core/ShaderLibrary/Sampling/Sampling.hlsl"
|
|
|
|
// Lighting 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/ShaderVariablesRaytracingLightLoop.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
|
|
// Raytracing includes
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Deferred/RaytracingIntersectonGBuffer.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/RayTracingCommon.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Common/RayTracingHelpers.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Common/AtmosphericScatteringRayTracing.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/RayCountManager.cs.hlsl"
|
|
|
|
// The target acceleration structure that we will evaluate the reflexion in
|
|
TEXTURE2D_X(_DepthTexture);
|
|
|
|
// Texture that holds the raytracing data
|
|
TEXTURE2D_X(_RaytracingDirectionBuffer);
|
|
RW_TEXTURE2D_X(float, _RaytracingDistanceBuffer);
|
|
|
|
// Output textures
|
|
RW_TEXTURE2D_X(float4, _GBufferTexture0RW);
|
|
RW_TEXTURE2D_X(float4, _GBufferTexture1RW);
|
|
RW_TEXTURE2D_X(float4, _GBufferTexture2RW);
|
|
RW_TEXTURE2D_X(float4, _GBufferTexture3RW); // Bake lighting and/or emissive
|
|
|
|
int _RaytracingHalfResolution;
|
|
uint _RayTracingLayerMask;
|
|
int _RayCountType;
|
|
uint _RayBinViewOffset;
|
|
uint _RayBinTileViewOffset;
|
|
|
|
[shader("miss")]
|
|
void MissShaderGBuffer(inout RayIntersectionGBuffer rayIntersection : SV_RayPayload)
|
|
{
|
|
rayIntersection.t = RAY_TRACING_DISTANCE_FLAG_SKY;
|
|
}
|
|
|
|
void TraceGBuffer(uint2 currentPixelCoord)
|
|
{
|
|
// Read the depth value
|
|
float depthValue = LOAD_TEXTURE2D_X(_DepthTexture, currentPixelCoord).x;
|
|
|
|
// Read the direction
|
|
float4 direction = LOAD_TEXTURE2D_X(_RaytracingDirectionBuffer, currentPixelCoord);
|
|
|
|
// If this is the background, or UnL is null or this pixel has been flagged as invalid, no
|
|
if (depthValue == UNITY_RAW_FAR_CLIP_VALUE || direction.w <= 0.0)
|
|
{
|
|
if (direction.w < 0.0)
|
|
{
|
|
_RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentPixelCoord)] = _RaytracingRayMaxLength;
|
|
_GBufferTexture0RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
_GBufferTexture1RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
_GBufferTexture2RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
_GBufferTexture3RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Compute the position input structure
|
|
PositionInputs posInput = GetPositionInput(currentPixelCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
|
|
|
|
// Decode the world space normal
|
|
NormalData normalData;
|
|
DecodeFromNormalBuffer(currentPixelCoord, normalData);
|
|
|
|
// Keep track of the new ray in the counters
|
|
if (_RayCountEnabled > 0)
|
|
{
|
|
uint3 counterIdx = uint3(currentPixelCoord, INDEX_TEXTURE2D_ARRAY_X(_RayCountType));
|
|
_RayCountTexture[counterIdx] = _RayCountTexture[counterIdx] + 1;
|
|
}
|
|
|
|
// Evaluate the ray bias
|
|
float rayBias = EvaluateRayTracingBias(posInput.positionWS);
|
|
|
|
// Create the ray descriptor for this pixel
|
|
RayDesc rayDescriptor;
|
|
rayDescriptor.Origin = posInput.positionWS + normalData.normalWS * rayBias;
|
|
rayDescriptor.Direction = direction.xyz;
|
|
rayDescriptor.TMin = 0.0;
|
|
rayDescriptor.TMax = _RaytracingRayMaxLength;
|
|
|
|
// Adjust world-space position to match the RAS setup with XR single-pass and camera relative
|
|
ApplyCameraRelativeXR(rayDescriptor.Origin);
|
|
|
|
// Create and init the RayIntersection structure for this
|
|
RayIntersectionGBuffer rayIntersection;
|
|
rayIntersection.t = -1.0;
|
|
rayIntersection.gbuffer0 = float4(0.0, 0.0, 0.0, 0.0);
|
|
rayIntersection.gbuffer1 = float4(0.0, 0.0, 0.0, 0.0);
|
|
rayIntersection.gbuffer2 = float4(0.0, 0.0, 0.0, 0.0);
|
|
rayIntersection.gbuffer3 = float4(0.0, 0.0, 0.0, 0.0);
|
|
|
|
// Evaluate the ray visibility term and PDF
|
|
TraceRay(_RaytracingAccelerationStructure, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, _RayTracingLayerMask, 0, 1, 0, rayDescriptor, rayIntersection);
|
|
|
|
// Output the gbuffer
|
|
_GBufferTexture0RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(LinearToSRGB(rayIntersection.gbuffer0.xyz), rayIntersection.gbuffer0.w);
|
|
_GBufferTexture1RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer1);
|
|
_GBufferTexture2RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer2);
|
|
_GBufferTexture3RW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(rayIntersection.gbuffer3);
|
|
_RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentPixelCoord)] = rayIntersection.t;
|
|
}
|
|
|
|
[shader("raygeneration")]
|
|
void RayGenGBuffer()
|
|
{
|
|
// Grab the dimensions of the current raytrace shader
|
|
uint3 LaunchIndex = DispatchRaysIndex();
|
|
uint3 LaunchDim = DispatchRaysDimensions();
|
|
|
|
UNITY_XR_ASSIGN_VIEW_INDEX(LaunchIndex.z);
|
|
|
|
// Pixel coordinate of the current pixel
|
|
uint2 currentPixelCoord = uint2(LaunchIndex.x, LaunchIndex.y);
|
|
|
|
// For the half res coordinates, we need to adjust the positions
|
|
if (_RaytracingHalfResolution)
|
|
currentPixelCoord = ComputeSourceCoordinates(currentPixelCoord, _RayTracingCheckerIndex);
|
|
|
|
// Trace and output the gbuffer
|
|
TraceGBuffer(currentPixelCoord);
|
|
}
|
|
|
|
StructuredBuffer<uint> _RayBinResult;
|
|
StructuredBuffer<uint> _RayBinSizeResult;
|
|
uint _RayBinTileCountX;
|
|
uint _BufferSizeX;
|
|
#define RAY_BINNING_TILE_SIZE 16
|
|
|
|
[shader("raygeneration")]
|
|
void RayGenGBufferBinned()
|
|
{
|
|
// Grab the dimensions of the current raytrace shader
|
|
uint3 LaunchIndex = DispatchRaysIndex();
|
|
|
|
UNITY_XR_ASSIGN_VIEW_INDEX(LaunchIndex.z);
|
|
|
|
// Pixel coordinate of the current pixel
|
|
uint2 currentBinIndex = uint2(LaunchIndex.x % _BufferSizeX, LaunchIndex.x / _BufferSizeX);
|
|
|
|
// Compute the various local/tile coordinates
|
|
uint2 localTileCoordinate = uint2(currentBinIndex.x % RAY_BINNING_TILE_SIZE, currentBinIndex.y % RAY_BINNING_TILE_SIZE);
|
|
uint localTileIndex = localTileCoordinate.y * RAY_BINNING_TILE_SIZE + localTileCoordinate.x;
|
|
uint2 tileCoordinate = uint2(currentBinIndex.x / RAY_BINNING_TILE_SIZE, currentBinIndex.y / RAY_BINNING_TILE_SIZE);
|
|
uint tileIndex = tileCoordinate.y * _RayBinTileCountX + tileCoordinate.x;
|
|
|
|
// Read and unpack the coordiante to screen space coordinates
|
|
uint globalBinIndex = tileIndex * RAY_BINNING_TILE_SIZE * RAY_BINNING_TILE_SIZE + localTileIndex;
|
|
uint packedPixelCoordinate = _RayBinResult[globalBinIndex + _RayBinViewOffset * LaunchIndex.z];
|
|
uint2 currentPixelCoord = uint2((packedPixelCoordinate & 0xffff0000) >> 16, packedPixelCoordinate & 0xffff);
|
|
|
|
// If the local index of this pixel is beyond the valid count, no need to compute it
|
|
if (localTileIndex > _RayBinSizeResult[tileIndex + _RayBinTileViewOffset * LaunchIndex.z])
|
|
return;
|
|
|
|
// For the half res coordinates, we need to adjust the positions
|
|
if (_RaytracingHalfResolution)
|
|
currentPixelCoord = ComputeSourceCoordinates(currentPixelCoord * 0.5, _RayTracingCheckerIndex);
|
|
|
|
// Trace and output the gbuffer
|
|
TraceGBuffer(currentPixelCoord);
|
|
}
|