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.
167 lines
8.1 KiB
167 lines
8.1 KiB
#pragma kernel RayMarchKernel RAY_MARCH_KERNEL=RayMarchKernel
|
|
#pragma kernel RayMarchHalfKernel RAY_MARCH_KERNEL=RayMarchHalfKernel HALF_RESOLUTION
|
|
|
|
#pragma only_renderers d3d11 xboxseries ps5
|
|
|
|
// Include and define the shader pass
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
#define SHADERPASS SHADERPASS_RAYTRACING_GBUFFER
|
|
|
|
// HDRP generic includes
|
|
#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/ShaderLibrary/ShaderVariables.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/Material/NormalBuffer.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"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/StandardLit/StandardLit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitRayTracing.hlsl"
|
|
|
|
// Raytracing includes (should probably be in generic files)
|
|
#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/RaytracingSampling.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingCommon.hlsl"
|
|
|
|
// The dispatch tile resolution
|
|
#define RAY_MARCHING_TILE_SIZE 8
|
|
|
|
// Source depth texture for ray start position
|
|
TEXTURE2D_X(_InputDepthTexture);
|
|
// Input depth pyramid texture
|
|
TEXTURE2D_X(_DepthTexture);
|
|
// Stencil texture
|
|
TYPED_TEXTURE2D_X(uint2, _StencilTexture);
|
|
// Input direction buffer
|
|
RW_TEXTURE2D_X(float4, _RaytracingDirectionBuffer);
|
|
// Input texture that holds the offset for every level of the depth pyramid
|
|
StructuredBuffer<int2> _DepthPyramidMipLevelOffsets;
|
|
|
|
// Constant buffer that holds all scalar that we need
|
|
CBUFFER_START(UnityScreenSpaceRayMarching)
|
|
int _DeferredStencilBit;
|
|
int _RayMarchingSteps;
|
|
float _RayMarchingThicknessScale;
|
|
float _RayMarchingThicknessBias;
|
|
int _RayMarchingReflectsSky;
|
|
CBUFFER_END
|
|
|
|
// Must be included after the declaration of variables
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/RayMarching.hlsl"
|
|
|
|
// 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
|
|
RW_TEXTURE2D_X(float, _RaytracingDistanceBuffer);
|
|
|
|
[numthreads(RAY_MARCHING_TILE_SIZE, RAY_MARCHING_TILE_SIZE, 1)]
|
|
void RAY_MARCH_KERNEL(uint3 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID)
|
|
{
|
|
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
|
|
|
|
// Compute the pixel position to process
|
|
uint2 currentCoord = dispatchThreadId.xy;
|
|
#if HALF_RESOLUTION
|
|
currentCoord = ComputeSourceCoordinates(currentCoord, _RayTracingCheckerIndex);
|
|
#endif
|
|
|
|
// Read the depth value as early as possible
|
|
float depthValue = LOAD_TEXTURE2D_X(_InputDepthTexture, currentCoord).x;
|
|
|
|
// Read the direction
|
|
float4 direction = _RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentCoord)];
|
|
|
|
_RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentCoord)] = 0.0f;
|
|
_GBufferTexture0RW[COORD_TEXTURE2D_X(currentCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
_GBufferTexture1RW[COORD_TEXTURE2D_X(currentCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
_GBufferTexture2RW[COORD_TEXTURE2D_X(currentCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
_GBufferTexture3RW[COORD_TEXTURE2D_X(currentCoord)] = float4(0.0, 0.0, 0.0, 0.0);
|
|
|
|
// If this is a background pixel or the direction is invalid, skip it.
|
|
if (depthValue == UNITY_RAW_FAR_CLIP_VALUE || direction.w < 0.0)
|
|
return;
|
|
|
|
// Read the pixel normal
|
|
NormalData normalData;
|
|
DecodeFromNormalBuffer(currentCoord.xy, normalData);
|
|
|
|
// Compute the camera position
|
|
float3 camPosWS = GetCurrentViewPosition();
|
|
|
|
// Convert this to a world space position (camera relative)
|
|
PositionInputs posInput = GetPositionInput(currentCoord, _ScreenSize.zw, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
|
|
float3 positionWS = posInput.positionWS;
|
|
// Compute the view direction (world space)
|
|
float3 viewWS = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
|
|
|
|
// Apply normal bias with the magnitude dependent on the distance from the camera.
|
|
// Unfortunately, we only have access to the shading normal, which is less than ideal...
|
|
posInput.positionWS = camPosWS + (posInput.positionWS - camPosWS) * (1 - 0.001 * rcp(max(dot(normalData.normalWS, viewWS), FLT_EPS)));
|
|
depthValue = ComputeNormalizedDeviceCoordinatesWithZ(posInput.positionWS, UNITY_MATRIX_VP).z;
|
|
|
|
// Ray March along our ray
|
|
float3 rayPos;
|
|
bool hit = RayMarch(posInput.positionWS, direction.xyz, normalData.normalWS, posInput.positionSS, depthValue, false, rayPos);
|
|
|
|
// If we had a hit, store the NDC position of the intersection point
|
|
if (hit)
|
|
{
|
|
int2 resultCoords = rayPos.xy;
|
|
bool stencilCheckPassed = true;
|
|
if (_DeferredStencilBit != 0)
|
|
{
|
|
uint stencilValue = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, resultCoords));
|
|
stencilCheckPassed = ((stencilValue & _DeferredStencilBit) != 0);
|
|
}
|
|
if (stencilCheckPassed)
|
|
{
|
|
// Compute the depth of the result hit point
|
|
float resultDepth = LOAD_TEXTURE2D_X(_DepthTexture, resultCoords).x;
|
|
|
|
// Compute the world position of this pixel
|
|
PositionInputs resultPosInput = GetPositionInput(resultCoords, _ScreenSize.zw, resultDepth, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0);
|
|
|
|
// Ray Marching Distance
|
|
float distance = length(resultPosInput.positionWS - positionWS);
|
|
|
|
if (distance < _RaytracingRayMaxLength)
|
|
{
|
|
// Write the properties of this pixel
|
|
_RaytracingDistanceBuffer[COORD_TEXTURE2D_X(currentCoord)] = length(resultPosInput.positionWS - positionWS);
|
|
|
|
// Read the bsdf data and builtin data from the gbuffer at the target hitpoint
|
|
BSDFData bsdfData;
|
|
ZERO_INITIALIZE(BSDFData, bsdfData);
|
|
BuiltinData builtinData;
|
|
ZERO_INITIALIZE(BuiltinData, builtinData);
|
|
uint featureFlags = UINT_MAX;
|
|
DecodeFromGBuffer(resultCoords, featureFlags, bsdfData, builtinData);
|
|
builtinData.renderingLayers = RENDERING_LAYERS_MASK;
|
|
|
|
// Fit the data to the standard lit model
|
|
StandardBSDFData standardLitData;
|
|
ZERO_INITIALIZE(StandardBSDFData, standardLitData);
|
|
standardLitData.shadowMasks = 1;
|
|
standardLitData.renderingLayers = RENDERING_LAYERS_MASK;
|
|
FitToStandardLit(bsdfData, builtinData, resultCoords, standardLitData);
|
|
|
|
// Encode the standard lit into the gbuffer
|
|
float4 gbuffer0;
|
|
float4 gbuffer1;
|
|
float4 gbuffer2;
|
|
float4 gbuffer3;
|
|
EncodeIntoStandardGBuffer(standardLitData, gbuffer0, gbuffer1, gbuffer2, gbuffer3);
|
|
|
|
// Export the Gbuffer
|
|
_GBufferTexture0RW[COORD_TEXTURE2D_X(currentCoord)] = float4(LinearToSRGB(gbuffer0.xyz), gbuffer0.w);
|
|
_GBufferTexture1RW[COORD_TEXTURE2D_X(currentCoord)] = gbuffer1;
|
|
_GBufferTexture2RW[COORD_TEXTURE2D_X(currentCoord)] = gbuffer2;
|
|
_GBufferTexture3RW[COORD_TEXTURE2D_X(currentCoord)] = gbuffer3;
|
|
_RaytracingDirectionBuffer[COORD_TEXTURE2D_X(currentCoord)] = float4(direction.xyz, 0.0);
|
|
}
|
|
}
|
|
}
|
|
}
|