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.
 
 
 
 
 

82 lines
3.3 KiB

#ifndef RAY_TRACING_SHADOW_UTILITIES_H_
#define RAY_TRACING_SHADOW_UTILITIES_H_
// Constant buffer that holds all scalar that we need
CBUFFER_START(RayTracingShadowUtilitiesConstantBuffer)
uint _RaytracingTargetLight;
float _RaytracingLightRadius;
float _RaytracingLightAngle;
float _RaytracingLightSizeX;
float _RaytracingLightSizeY;
int _RaytracingShadowSlot;
float4 _RaytracingChannelMask;
float4 _RaytracingChannelMask0;
float4 _RaytracingChannelMask1;
CBUFFER_END
// The various cases for shadow rays (spot and point)
#define POINT_VALID_DIR_PDF 1.0
#define POINT_WHITE_PDF -1.0
#define POINT_BLACK_PDF -2.0
#define POINT_BACK_FACE_PDF -3.0
float DistSqrToLight(LightData lightData, float3 positionWS)
{
// If the point is inside the spherical range, it will be visible
float3 dir = (lightData.positionRWS - positionWS);
return dot(dir, dir);
}
bool PositionInSpotRange(LightData lightData, float spotAngle, float3 positionWS, float dist2)
{
// Is the light inside the range of the light?
bool pointInsideRange = dist2 < (lightData.range * lightData.range);
// If the direction is going out of the cone, we invalidate this ray (to avoid casting useless rays)
// We need to use the direction towards the cone origin for culling, not the sampled point on the light
float3 relativePosition = positionWS - lightData.positionRWS;
float3 cullingDirection = normalize(relativePosition);
bool pointInsideCone = dot(cullingDirection, lightData.forward) > cos(0.5f * spotAngle);
return pointInsideRange && pointInsideCone;
}
bool PositionInPyramidRange(LightData lightData, float spotAngleX, float spotAngleY, float3 positionWS, float dist2)
{
// Is the light inside the range of the light?
bool pointInsideRange = dist2 < (lightData.range * lightData.range);
// If the direction is going out of the cone, we invalidate this ray (to avoid casting useless rays)
float3 relativePosition = positionWS - lightData.positionRWS;
float3 lightX = normalize(lightData.right);
float3 lightY = normalize(lightData.up);
float3 cullingDirectionX = normalize(relativePosition - dot(relativePosition, lightY) * lightY);
float3 cullingDirectionY = normalize(relativePosition - dot(relativePosition, lightX) * lightX);
bool pointInsidePyramid = dot(cullingDirectionX, lightData.forward) > cos(0.5f * spotAngleX) &&
dot(cullingDirectionY, lightData.forward) > cos(0.5f * spotAngleY);
return pointInsideRange && pointInsidePyramid;
}
bool PositionInBoxRange(LightData lightData, float sizeX, float sizeY, float3 positionWS, float dist2)
{
// Is the light inside the range of the light?
bool pointInsideRange = dist2 < (lightData.range * lightData.range);
// If the position is outside of the box light shaft, we invalidate this ray (to avoid casting useless rays)
float3 relativePosition = positionWS - lightData.positionRWS;
bool pointInsideBox = abs(dot(relativePosition, normalize(lightData.right))) < 0.5f * sizeX &&
abs(dot(relativePosition, normalize(lightData.up))) < 0.5f * sizeY;
return pointInsideRange && pointInsideBox;
}
bool PositionInPointRange(LightData lightData, float dist2)
{
return dist2 < (lightData.range * lightData.range);
}
#endif // RAY_TRACING_SHADOW_UTILITIES_H_