Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions package/Shaders/Common/PBR.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,114 @@ namespace PBR
}
}

/**
* @brief Calculates and accumulates PBR direct lighting contributions for a single light source
*
* This function handles the core PBR lighting calculation that is identical across all call sites.
* It processes diffuse, specular, transmission, and coat lighting components for a given light
* and accumulates the results into the provided output variables.
*
* @note This function is designed to be called multiple times per pixel (once per light source)
* and accumulates results rather than returning them. All output parameters are modified in-place.
*
* @param[in] lightColor The RGB color of the light source (should be in linear space)
* @param[in] lightMultiplier Combined multiplier for light intensity (includes shadows, attenuation, etc.)
* @param[in] parallaxShadow Parallax occlusion mapping shadow factor (1.0 = no shadow)
* @param[in] N Surface normal vector in world space
* @param[in] N_coat Coat layer normal vector in world space (used for two-layer materials)
* @param[in] V_refracted View direction after refraction through coat layer
* @param[in] V Original view direction in world space
* @param[in] L_refracted Light direction after refraction through coat layer
* @param[in] L Original light direction in world space
* @param[in] surfaceProperties PBR material properties (roughness, metallic, F0, etc.)
* @param[in] tbnMatrix Transpose of the tangent-bitangent-normal matrix
* @param[in] texCoord Texture coordinates (used for feature texture sampling)
* @param[in,out] diffuseAccumulator Accumulated diffuse lighting contribution (modified in-place)
* @param[in,out] coatDiffuseAccumulator Accumulated coat layer diffuse lighting (modified in-place)
* @param[in,out] transmissionAccumulator Accumulated transmission/translucency contribution (modified in-place)
* @param[in,out] specularAccumulator Accumulated specular lighting contribution (modified in-place, automatically gated by interior status)
*
* @return PBR::LightProperties The calculated light properties, useful for additional effects like wetness
*
* @par Example Usage:
* @code
* // For directional light
* PBR::LightProperties lightProperties = PBR::ProcessPBRDirectLight(
* dirLightColor,
* dirLightColorMultiplier * dirDetailShadow,
* parallaxShadow,
* N, // Surface normal
* N_coat, // Coat normal
* V_refracted, // Refracted view direction
* V, // View direction
* L_refracted, // Refracted light direction
* L, // Light direction
* pbrSurfaceProperties,
* tbnMatrix,
* texCoord,
* lightsDiffuseColor,
* coatLightsDiffuseColor,
* transmissionColor,
* specularColorPBR);
*
* // Additional effects using the returned light properties
* if (waterRoughnessSpecular < 1.0) {
* specularColorPBR += PBR::GetWetnessDirectLightSpecularInput(
* wetnessNormal, V, L,
* lightProperties.CoatLightColor, waterRoughnessSpecular) * wetnessGlossinessSpecular;
* }
* @endcode
*
* @par Features Supported:
* - Standard PBR lighting (diffuse + specular)
* - Two-layer materials (coat layer)
* - Transmission/translucency effects
* - Interior/exterior lighting adjustments (specular automatically disabled in interiors)
* - Feature texture sampling
*
* @par Performance Notes:
* - Function is marked as @c inline for optimal performance
* - Designed to be called in tight loops for multiple light sources
* - Accumulates results to minimize memory bandwidth
*
* @see PBR::GetDirectLightInput
* @see PBR::InitLightProperties
* @see PBR::SurfaceProperties
*/
inline LightProperties ProcessPBRDirectLight(
float3 lightColor,
float lightMultiplier,
float parallaxShadow,
float3 N,
float3 N_coat,
float3 V_refracted,
float3 V,
float3 L_refracted,
float3 L,
SurfaceProperties surfaceProperties,
float3x3 tbnMatrix,
float2 texCoord,
inout float3 diffuseAccumulator,
inout float3 coatDiffuseAccumulator,
inout float3 transmissionAccumulator,
inout float3 specularAccumulator)
{
LightProperties lightProperties = InitLightProperties(lightColor, lightMultiplier, parallaxShadow);
float3 dirDiffuseColor, coatDirDiffuseColor, dirTransmissionColor, dirSpecularColor;

GetDirectLightInput(
dirDiffuseColor, coatDirDiffuseColor, dirTransmissionColor, dirSpecularColor,
N, N_coat, V_refracted, V,
L_refracted, L, lightProperties, surfaceProperties, tbnMatrix, texCoord);

diffuseAccumulator += dirDiffuseColor;
coatDiffuseAccumulator += coatDirDiffuseColor;
transmissionAccumulator += dirTransmissionColor;
specularAccumulator += dirSpecularColor * !SharedData::InInterior;

return lightProperties;
}

float3 GetWetnessDirectLightSpecularInput(float3 N, float3 V, float3 L, float3 lightColor, float roughness)
{
const float wetnessStrength = 1;
Expand Down
Loading