gkjohnson / three-gpu-pathtracer

Path tracing renderer and utilities for three.js built on top of three-mesh-bvh.
https://gkjohnson.github.io/three-gpu-pathtracer/example/bundle/index.html
MIT License
1.37k stars 133 forks source link

Sheen material property #167

Closed bhouston closed 2 years ago

bhouston commented 2 years ago

Is your feature request related to a problem? Please describe.

In adhering to the goal of reproducing the full glTF PBR Next model, one of the currently missing material properties is sheen. It is primarily used for cloth.

cushion

Describe the solution you'd like

Parameters and behavior should follow glTF KHR_materials_sheen extension:

https://github.com/KhronosGroup/glTF/tree/a9cd1cb657587b590b6f95c8654038a4e9d66596/extensions/2.0/Khronos/KHR_materials_sheen

The properties required to support are:

Type Description Required
sheenColorFactor array The sheen color in linear space No, default: [0.0, 0.0, 0.0]
sheenColorTexture textureInfo The sheen color (RGB).
The sheen color is in sRGB transfer function
No
sheenRoughnessFactor number The sheen roughness. No, default: 0.0
sheenRoughnessTexture textureInfo The sheen roughness (Alpha) texture. No
bhouston commented 2 years ago

I am pleased to be able to put a bounty of $500 USD on an accepted PR that implements the official glTF sheen extension in this path tracer.

richardassar commented 2 years ago

Taking a look at this, I recall the paper A Practical Microcylinder Appearance Model for Cloth Rendering which may or may not be useful here.

richardassar commented 2 years ago

Results from a quick first pass, I'll look into sourcing a cloth scene to better demonstrate this.

Highlights at grazing angles: Screenshot 2022-06-23 at 00-01-46 Material Orb Path Tracing

Custom sheen color: Screenshot 2022-06-23 at 00-26-40 Material Orb Path Tracing

Screenshot 2022-06-23 at 00-33-21 Material Orb Path Tracing

richardassar commented 2 years ago

I have found a good resource for the microcylinder cloth material bsdf but it seems that's outside the scope of this KHR extension since it involves thread orientations and other parameters e.g. gamma_s, gamma_v, eta_t, kd, A.

If that's something that people are interested in then I can create an issue for it.

richardassar commented 2 years ago

Also, incorporating this recent set of changes prompts a bsdfMix and bsdfBlend approach as it could be more modular and configurable.

I'm working on each of these recent feature requests (iridescence, sheen, clear coat) in separate branches but it might make sense to coalesce them into a single PR with the bsdf mix/blend approach. I'll update as to whether this is necessary or makes sense here.

richardassar commented 2 years ago

Showing the effect on the SheenCloth model from glTF-Sample-Models, there's also SheenChair which I'll test.

Without Sheen Screenshot 2022-06-23 at 06-31-24 Material Orb Path Tracing

Screenshot 2022-06-23 at 06-15-13 Material Orb Path Tracing

With Sheen Screenshot 2022-06-23 at 06-30-19 Material Orb Path Tracing

Screenshot 2022-06-23 at 06-17-17 Material Orb Path Tracing

Custom Sheen Color Screenshot 2022-06-23 at 06-37-38 Material Orb Path Tracing

Screenshot 2022-06-23 at 06-21-31 Material Orb Path Tracing

Low Light Setting Screenshot 2022-06-23 at 06-24-31 Material Orb Path Tracing

Just adding the sheen contributions to the bsdf pdf, color and direction for now, with the bsdfMix approach this should better sit on top of the underlying metalness/roughness bsdf and allow the sheen to contribute to specular and diffuse components separately. Materials some metalness and sheen look a bit more like plastic sheets than the velvet fabric look shown here.

The coefficients used in the computation of the sheen GGX terms, G and D, are the same coefficients as those used in the "Charlie" sheen that is referenced in the KHR spec. The functions they provide are only applicable to a BRDF so they are not directly applicable to a path tracer, this is also the case for the iridescence and clear coat extensions.

The model comes with a sheen color + sheen roughness texture, which I'll load and demonstrate next.

richardassar commented 2 years ago

A more plastic looking material, with a little higher metalness.

Screenshot 2022-06-23 at 07-13-50 Material Orb Path Tracing

Screenshot 2022-06-23 at 07-34-27 Material Orb Path Tracing

richardassar commented 2 years ago

Implemented the weighted bsdfMix approach so now the effect can be made more subtle and chained with other effects.

Screenshot 2022-06-23 at 11-31-50 Material Orb Path Tracing

richardassar commented 2 years ago

Here are some previews of models using sheen from glTF-Sample-Models.

I had to hook up a GLTFMaterialsSheenExtension to the GLTFLoader as THREE.js still doesn't support this extension, I added support for the sheenColorMap and sheenRoughnessMap giving us now the ability to load glTF files using the KHR_materials_sheen extension.

Hooking everything up gives us the following:

SheenChair.glb Screenshot 2022-06-23 at 15-02-48 Material Orb Path Tracing

See here for rasterized reference. Note that this only uses the sheenColorFactor and sheenRoughnessFactor, not the textures.

SheenCloth.glb Screenshot 2022-06-23 at 14-57-41 Material Orb Path Tracing_cropped

Reference.

This one masks the sheen on the black regions of the pattern. I had to tone down the sheen effect on this one using the brdfMix mentioned previously as it was a bit much, we can expose this as an extra parameter which defaults to 1.0.

richardassar commented 2 years ago

The README.md for the SheenChair model shows correspondence with what I have when turning FEATURE_SHEEN on and off.

FEATURE_SHEEN: 1 Screenshot 2022-06-23 at 17-19-13 Material Orb Path Tracing

FEATURE_SHEEN: 0 Screenshot 2022-06-23 at 17-19-23 Material Orb Path Tracing

richardassar commented 2 years ago

The README mentions KHR_materials_variants which would be nice to support also.

bhouston commented 2 years ago

The README mentions KHR_materials_variants which would be nice to support also.

This is actually supported at the Three.js data loading level, no need to support it within this renderer itself. :). At least I've seen Three.js projects that make use of that extension already in the wild.

Also, incorporating this recent set of changes prompts a bsdfMix and bsdfBlend approach as it could be more modular and configurable.

There is a very clear hierarchy on how to incorporate all these effects. It is actually a fixed system these days for these physical properties. While there isn't a chart on the glTF website that shows it, here is one from the "Autodesk Standard Surface" Which is near equivalent to the glTF material model:

diagram_closure_mix

https://autodesk.github.io/standard-surface/

The flexibility these days usually happens with arbitrary graphs which determine the properties that feed into the material system. I think the emerging standard is MaterialX and eventually it would be nice for both Three.js and this path tracer to support it -- but interestingly it doesn't actually change the base BRDF tree we are creating by implementing these glTF material extensions.

richardassar commented 2 years ago

The README mentions KHR_materials_variants which would be nice to support also.

This is actually supported at the Three.js data loading level, no need to support it within this renderer itself. :). At least I've seen Three.js projects that make use of that extension already in the wild.

From what I could see this isn't supported, at least not to our needs, the PR which added KHR_materials_sheen touches sheenTint and sheenRoughness. Instead I register a corrected GLTFMaterialsSheenExtension that populates sheenColor, sheenRoughness, sheenColorMap and sheenRoughnessMap, and pushes the parser.assignTexture results into pending that is passed on to the returned promise. Without this there isn't enough to fully satisfy this extension's requirements.

(Edit: I see in THREE.js/master they have exactly what I have, down to the character, so this is a versioning issue) (Edit edit: actually we're at latest, so I don't know why this didn't JustWork(tm), no need for my GLTFMaterialsSheenExtension, I'll look into it later)

Also, incorporating this recent set of changes prompts a bsdfMix and bsdfBlend approach as it could be more modular and configurable.

There is a very clear hierarchy on how to incorporate all these effects. It is actually a fixed system these days for these physical properties. While there isn't a chart on the glTF website that shows it, here is one from the "Autodesk Standard Surface" Which is near equivalent to the glTF material model:

diagram_closure_mix

Thanks, this is a very informative diagram. The one issue I have with the glTF specs is that they're suited only to BRDFs and involve NdotL terms, providing BSDF (both BRDF & BTDF terms) and PDF functions would be helpful but perhaps falls outside the scope of glTF.

https://autodesk.github.io/standard-surface/

The flexibility these days usually happens with arbitrary graphs which determine the properties that feed into the material system. I think the emerging standard is MaterialX and eventually it would be nice for both Three.js and this path tracer to support it -- but interestingly it doesn't actually change the base BRDF tree we are creating by implementing these glTF material extensions.

I was actually going to suggest exactly this, being a node/graph fan myself (see VisionMachine). With the introduction of bsdfMix now it would be possible to support render graphs by a code generation approach, each material could reference a graph by ID and then you switch and select e.g. graphBsdf0 and so on (of course OpTypePointer>OpTypeFunction would be nicer) - I'm quite tempted to experiment with laying initial foundations for this as part of the iridescence/sheen/clearcoat features, perhaps in a separate branch once these are done.

richardassar commented 2 years ago

In the following papers layered BRDFs are achieved by baking them into Fourier bases, providing efficiency and accuracy. It seems like something that would be easy to achieve with the node/graph based representation, and these could be baked on the GPU prior to the main scene or before rendering an animation.

A Comprehensive Framework for Rendering Layered Materials The paper is discussed in this project report, which shows some side-by-side comparisons.

Arbitrarily Layered Micro-Facet Surfaces

This is more relevant for the clear coat issue but I'm mentioning it in relation to graphs.

https://raytracing-docs.nvidia.com/mdl/introduction/index.html#mdl_introduction#distribution-function-modifiers-and-combiners also discusses layering and the weights, for example the fresnel_layer, are used as MIS heuristics in BRDF Blending in Path Tracing with Multiple Importance Sampling.

bhouston commented 2 years ago

I don't know if this helps but here is more information on the origins and goals of the glTF PBR Next model.

Starting in the mid 2010s the VFX indsutry started to develop a strong formalized Uber BRDF model. This really started with Disney's PBR model by Burley. Then it come to wider usage in the high end VFX industry with Andres Langland's alSurface model for Arnold.

Then every major 3D company decided to standardize their own version of these Uber shaders:

There are similar material models in Unreal Engine and Unity as well, but they are not as formalized as the above. Blender's "Principled BRDF" is basically the same as these with minor tweaks.

To try to help with the situation, the glTF PBR Next extensions are trying to find/distill the commonalities between these more proprietary systems. Adobe, Dassault, Autodesk, Unreal Engine and NVIDIA are involved in the glTF PBR Next standardization process.

This is the reason why I have specified all material improvements for this renderer as these glTF extensions. They are the distilled common best practices for transferable Uber shaders. Basically if we implement these, this renderer can be compatible with the ecosystem of Autodesk, Adobe, Dassault, and Unreal Engine and Unity.

I think that for the foreseeable future (5-10 years) these uber BRDFs are going to be the main material definition system. Of course there will be slow addition of new features to the common specification as things move forward, but it is generally tweaks and small additions, rather than major changes.

I found this on the glTF website -- a similar BRDF blending tree to the Autodesk Standard Surface one - although I think it may be incomplete:

pbrext

From here

I do not think because of the current stage of the industry that we have to expose the BRDF mixing nodes to the user any time soon. I think that we can hide them under an Uber Material interface as is now standard practice.

And if (when really) we add MaterialX support, it will just be for creating graphs that feed into the properties of the Uber Material, rather than remixing the BRDFs themselves in arbitrary fashions. I wrote up a draft of this a few years ago TK_MATERIAL_GRAPH...

richardassar commented 2 years ago

Changes in https://github.com/gkjohnson/three-gpu-pathtracer/pull/205, ready for review.