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

// 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);
}