-
Notifications
You must be signed in to change notification settings - Fork 855
Multiple Scattering Approximation for Hair #5604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…F, ShaderGraph, etc.)
… to post evaluate BSDF
This reverts commit 0ace987.
|
||
// Pragmas | ||
$splice(PassPragmas) | ||
#pragma enable_d3d11_debug_symbols |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
miss comment
sebastienlagarde
approved these changes
Sep 20, 2021
sebastienlagarde
pushed a commit
that referenced
this pull request
Sep 20, 2021
* Initial commit of the marschner infrastructure (LUT/LTC, Analytic BSDF, ShaderGraph, etc.) * Initial commit to add scattering mode dropdown * Add the framework for a preintegrated Marschner FGD * Re-hide the material type for hair * Correct some slight typos * Un-hide the hair material type * Initial commit strand count estimation from density volume * Initial work for Surface to BSDF data * Initial readdition of the hair reference * Adapt the reference to use the new BSDF data * Use the reference for the raster BSDF * Add the first lobe approximation * Initial commit TRT approximation * Add TT attenuation term * Further simplify the attenuation TT * Add roughened azimuthal scattering, remove IOR param, add TT distribution * Initial work for environment evaluation * Add the approximated scattering mode. Move the environment evaluation to post evaluate BSDF * Disable area lights for Marschner (temporary until LTC is fixed for anisotropy) * Use the newly fitted gaussian coefficient LUT for azimuthal transmission roughness * Readjust the gaussian fit for azimuthal roughness * Skip TT lobe for environment sample * Improve Parameterization: Longitudinal Roughness -> Smoothness * Improve Parameterization: Azimuthal Roughness -> Radial Smoothness * Optimize the math for spherical coordinate angles. * NaN suppression * Revert back from sine theta to the half angle for longitudinal scatter * Fix all the warnings * Re-enable area light and fall back to GGX like Kajiya * Add note regarding Marschner pre-integration * Update hair graphics test * Update some reference images for Vulkan/Metal due to some shadow cascade discrepancy * Remove the primary reflection smooth parameter. * Roughness clamping for longitudinal scattering * Rename Use Light Facing Normal to Geometry Mode (Cards, Strands) * Documentation - First Pass * Rename Geometry Mode -> Geometry Type * Tooltips - Also hide the Scattering Mode until the improved approximation is merged. * Un-hide the scattering mode. * Initial commit dual scattering preintegration and global scattering computation * Compute the average backscattering attenuation * Add the local scattering term. * Organize the dual scattering term computation * Refactor dual scattering to better integrate with the light loop, add directional support, add hair volume shadow bias * Progress on average scattering preintegration for the DS scatter bcsdf * Initial commit of completed DS implementation (average azimuthal scattering preintegration) * Initial commit of completed DS implementation (average azimuthal scattering preintegration) * Further simplify the dual scattering approximation and nan suppresion * Remove density tracing code from HDRP * Add the new new stack block inputs for sampling pre-processed global scattering * Configure GPU-side new bsdf inputs for multiple scattering * Fix reflection probe support and revert baked lighting modifications * Switch to spherical harmonic representation of strand count as input * Rename to strand count probe * Disable shadows again until reintroducing a biasing solution * Resolve some bad merge artifacts impacting the PR diff * More PR cleanup * Update test images due to the environment lighting fix * Add multiple scattering to the test and update images * Add documentation and update appearance of scattering mode (only for marschner strands) * Explicitly set the multiple scattering test graph to Marschner + Strands type to fix the test. * Fix preintegration NaN in BSDF * Fix various subtle issues (preintegration domain, scattering gaussian discrepancies). * Add spline shadow bias * Update test images * Update reference images for Vulkan and Metal + re-run * Change the default azimuthal from 0.3 -> 0.8 * Revert "Add spline shadow bias" This reverts commit 0ace987. * Add back the strand shadow bias property * Incorporate spline shadow bias to light loop for analytic light shadow maps. * Add second shadow tap for strand visibility term. * Remove the debug symbols * Mitigate SH ringing
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Purpose of this PR
This PR introduces an improved multiple scattering approximation to the HDRP Hair shading model.
Currently we rely on the Kajiya-Kay diffuse component to approximate this, which generally is good enough for high-absorbing (dark) hair, but far from what is necessary to properly depict low-absorbing (light) hair. This is due to the multiple scattering most prominent in low-absorbent hair which gives (for example) blonde hair its voluminous look.
Thus, this PR offers a new advanced scattering mode, and is based on the dual scattering approximation.
Usage
Users access this new scattering mode through the following steps:
The Advanced mode is based off of pre-integrated tables derived from the physically principled Marschner BSDF and currently is only confirmed to support strand geometry, which is why currently we only support the Advanced mode when the Marschner model is chosen.
Parameterization
Enabling the Advanced Scattering Mode will add only one new input block to the Shader Graph:
The only other terms that govern the multiple scattering are the Base Color (defining the absorption) and the Smoothness (defining the scattering) parameters.
Comparison between Approximate and Advanced scattering modes.

Performance
As expected, performance will come at roughly a ~15% extra cost as compared to the normal Marschner model with simplified Kajiya-Kay diffuse component. Below are some performance metrics captured on a standalone Windows build with a NVIDIA Quadro RTX 8000, at 3840x2160 resolution, no MSAA.
Scenario #1: Three screen-aligned quads (Kajiya, Marschner with and without dual scattering), each taking up a third of the viewport. Illuminated by one point, one directional, and two environment light evaluations (HDRI and realtime reflection probe).
Side note, there is an emissive red ball in the reflection probe causing the red result for the Marschner quads, which evaluate environment lighting different from Kajiya. Additionally, the test quad doesn't have any meaningful strand count probe as input to the model, so the visual result is not relevant in this case.
Light Loop Integration
Testing
Updated the hair graph test to cover the new multiple scattering case, as well as the fixed environment lighting evaluation.
I only added a general singular case as the other test permutations already have good coverage from the initial Kajiya and Marschner tests.
Comments to reviewers
The algorithm is dependent on the number of strands between the shading position and light. This information is typically computed in real-time via deep opacity maps, however for now we retrieve this information via an L1 spherical harmonic "strand probe" that allows us to quickly decode the strand count for analytic lights. This probe field is readily generated by the demo team's hair package.
This PR also fixes an issue with environment light evaluation. Previously we utilized the light probe lighting and treated it as a directional light; I forgot to transpose this concept to the actual environment evaluation (and not from the diffuse probes), and thus it has been corrected. Environment lighting should appear correct now. Note that we use the lowest mip of the environment instead of a spherical harmonic representation, but it might be possible in the future to do that latter with APV.
It's important to note that the dual scattering approach is currently biased to depict straight to wavy hair, due to the assumptions it makes about hairs being oriented similarly in the shading neighborhood and toward the light. Sebastien Lachambre wrote a great document going into further detail on hair types and parameterization. It is worth improving our multiple scattering approximation in the future to ensure we have good representation for all hair types. Below is a table describing the hair type classifications (this PR should be good to approximate 1-3, but might break down in quality for 3-7 in low-absorbent hair).