feat(rendering): add volumetric performance coverage
This commit is contained in:
@@ -9,6 +9,9 @@ Shader "Builtin Volumetric"
|
||||
_AmbientStrength ("Ambient Strength", Float) = 0.005
|
||||
_LightDirection ("Light Direction", Vector) = (0.5, 0.8, 0.3, 0.0)
|
||||
_LightSamples ("Light Samples", Float) = 8.0
|
||||
_EnableEntryHdda ("Enable Entry HDDA", Float) = 1.0
|
||||
_EnableEmptySpaceSkipping ("Enable Empty Space Skipping", Float) = 1.0
|
||||
_EnableEarlyTermination ("Enable Early Termination", Float) = 1.0
|
||||
}
|
||||
HLSLINCLUDE
|
||||
#define PNANOVDB_HLSL
|
||||
@@ -41,6 +44,9 @@ Shader "Builtin Volumetric"
|
||||
float4 gAmbientStrength;
|
||||
float4 gLightDirection;
|
||||
float4 gLightSamples;
|
||||
float4 gEnableEntryHdda;
|
||||
float4 gEnableEmptySpaceSkipping;
|
||||
float4 gEnableEarlyTermination;
|
||||
};
|
||||
|
||||
StructuredBuffer<uint> VolumeData;
|
||||
@@ -192,6 +198,9 @@ Shader "Builtin Volumetric"
|
||||
const int maxSteps = max((int)gMaxSteps.x, 1);
|
||||
const float ambientStrength = max(gAmbientStrength.x, 0.0f);
|
||||
const float lightSamples = max(gLightSamples.x, 0.0f);
|
||||
const bool enableEntryHdda = gEnableEntryHdda.x >= 0.5f;
|
||||
const bool enableEmptySpaceSkipping = gEnableEmptySpaceSkipping.x >= 0.5f;
|
||||
const bool enableEarlyTermination = gEnableEarlyTermination.x >= 0.5f;
|
||||
|
||||
const float3 cameraLocalPosition =
|
||||
mul(gInverseModelMatrix, float4(gCameraWorldPosition.xyz, 1.0f)).xyz;
|
||||
@@ -206,7 +215,8 @@ Shader "Builtin Volumetric"
|
||||
const bool cameraInside = IsPointInsideAabb(cameraLocalPosition, boxMin, boxMax);
|
||||
const float surfaceT = cameraInside ? tExit : max(tEnter, 0.0f);
|
||||
const float3 expectedSurfacePosition = cameraLocalPosition + rayDirection * surfaceT;
|
||||
if (distance(expectedSurfacePosition, input.localPosition) > stepSize * 1.5f + 0.01f) {
|
||||
const float surfaceTolerance = max(stepSize * 1.5f, 1.0f);
|
||||
if (distance(expectedSurfacePosition, input.localPosition) > surfaceTolerance + 0.01f) {
|
||||
discard;
|
||||
}
|
||||
|
||||
@@ -216,14 +226,14 @@ Shader "Builtin Volumetric"
|
||||
|
||||
NanoVolume volume;
|
||||
InitNanoVolume(volume);
|
||||
if (!GetHddaHit(volume.accessor, t, cameraLocalPosition, rayDirection, marchEnd, hitValue)) {
|
||||
if (enableEntryHdda &&
|
||||
!GetHddaHit(volume.accessor, t, cameraLocalPosition, rayDirection, marchEnd, hitValue)) {
|
||||
discard;
|
||||
}
|
||||
|
||||
float skipDistance = 0.0f;
|
||||
float3 integratedLight = 0.0f.xxx;
|
||||
float transmittance = 1.0f;
|
||||
float accumulatedDensity = 0.0f;
|
||||
|
||||
float3 resolvedLightDirectionWS = gLightDirection.xyz;
|
||||
float3 resolvedLightRadiance = 1.0f.xxx;
|
||||
@@ -251,21 +261,23 @@ Shader "Builtin Volumetric"
|
||||
}
|
||||
|
||||
float3 localPosition = cameraLocalPosition + rayDirection * t;
|
||||
const uint dim = GetDimCoord(volume.accessor, localPosition);
|
||||
if (dim > 1u) {
|
||||
const uint dim = enableEmptySpaceSkipping
|
||||
? GetDimCoord(volume.accessor, localPosition)
|
||||
: 1u;
|
||||
if (enableEmptySpaceSkipping && dim > 1u) {
|
||||
skipDistance = 15.0f;
|
||||
t += skipDistance;
|
||||
continue;
|
||||
}
|
||||
|
||||
float density = GetValueCoord(volume.accessor, localPosition) * densityScale;
|
||||
if (density < 0.01f) {
|
||||
float density = max(GetValueCoord(volume.accessor, localPosition) * densityScale, 0.0f);
|
||||
if (enableEmptySpaceSkipping && density < 0.01f) {
|
||||
skipDistance = 5.0f;
|
||||
t += skipDistance;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skipDistance > 0.0f) {
|
||||
if (enableEmptySpaceSkipping && skipDistance > 0.0f) {
|
||||
t -= skipDistance * 0.8f;
|
||||
localPosition = cameraLocalPosition + rayDirection * t;
|
||||
skipDistance = 0.0f;
|
||||
@@ -273,7 +285,6 @@ Shader "Builtin Volumetric"
|
||||
|
||||
const float sigmaS = density;
|
||||
const float sigmaE = max(0.000001f, sigmaS);
|
||||
accumulatedDensity += sigmaS;
|
||||
|
||||
const float shadow =
|
||||
ComputeVolumetricShadow(
|
||||
@@ -283,15 +294,12 @@ Shader "Builtin Volumetric"
|
||||
lightSamples,
|
||||
volume.accessor);
|
||||
const float3 S = sigmaS * shadow.xxx * resolvedLightRadiance;
|
||||
const float3 integratedSegment = (S - S * exp(-sigmaE * stepSize)) / sigmaE;
|
||||
const float segmentTransmittance = exp(-sigmaE * stepSize);
|
||||
const float3 integratedSegment = (S - S * segmentTransmittance) / sigmaE;
|
||||
integratedLight += transmittance * integratedSegment;
|
||||
transmittance *= exp(-sigmaE * stepSize);
|
||||
transmittance *= segmentTransmittance;
|
||||
|
||||
if (accumulatedDensity > 1.0f) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (transmittance < 0.05f) {
|
||||
if (enableEarlyTermination && transmittance < 0.05f) {
|
||||
transmittance = 0.0f;
|
||||
break;
|
||||
}
|
||||
@@ -300,11 +308,12 @@ Shader "Builtin Volumetric"
|
||||
}
|
||||
|
||||
const float3 ambientLight = ambientStrength.xxx;
|
||||
float3 finalColor = (integratedLight + ambientLight) * accumulatedDensity;
|
||||
const float opacity = saturate(1.0f - transmittance);
|
||||
float3 finalColor = integratedLight + ambientLight * opacity;
|
||||
finalColor *= gVolumeTint.rgb;
|
||||
finalColor = pow(max(finalColor, 0.0f.xxx), 1.0f / 2.2f);
|
||||
|
||||
const float alpha = saturate(accumulatedDensity) * saturate(gVolumeTint.a);
|
||||
const float alpha = opacity * saturate(gVolumeTint.a);
|
||||
if (alpha <= 0.001f) {
|
||||
discard;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user