Skip to content
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

Basic export of KHR_materials_sheen factors. #1344

Closed
wants to merge 2 commits into from

Conversation

donmccurdy
Copy link
Contributor

Sheen in Blender's Principled BSDF node doesn't exactly match KHR_materials_sheen: glTF defines a sheen color. Blender defines a sheen factor (0-1), and defines color in a "tint" that can be lerped between white and the base color. Blender does not offer sheen roughness, but sheen appears to inherit the roughness of the material itself.

This is a basic export implementation for KHR_materials_sheen, supporting only factors and not textures. If the approach seems reasonable I am happy to add tests, but I don't think I have bandwidth to extend this and also bake textures. The example below uses a "hot pink" base color, and full-strength white sheen. The effect appears stronger in BabylonJS than in Blender, but I don't know why and don't yet have other implementations to compare against.

Blender BabylonJS
Screen Shot 2021-03-02 at 7 50 27 PM Screen Shot 2021-03-02 at 7 50 05 PM

SheenTest.glb.zip

@donmccurdy donmccurdy added enhancement New feature or request exporter This involves or affects the export process Material labels Mar 3, 2021
@donmccurdy donmccurdy requested a review from emackey March 3, 2021 03:55
@donmccurdy
Copy link
Contributor Author

On second thought, here is one other viewer we can compare: http://gltf.ux3d.io/. It looks pretty similar to BabylonJS in this case.

Screen Shot 2021-03-02 at 7 59 57 PM

@donmccurdy
Copy link
Contributor Author

donmccurdy commented Mar 3, 2021

Background for curious readers: sheen is a material property providing a light scattering effect at the edges of an object. It is generally used when rendering textiles, like velvet.

See: https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_sheen/

@@ -317,6 +323,34 @@ def __gather_clearcoat_extension(blender_material, export_settings):

return Extension('KHR_materials_clearcoat', clearcoat_extension, False)

def __gather_sheen_extension(blender_material, export_settings):
sheen_enabled = False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable.

@scurest
Copy link
Contributor

scurest commented Mar 3, 2021

defines color in a "tint" that can be lerped between white and the base color

The color is actually lerped between white and tint_from_color(base_color) where tint_from_color is defined as here.

(Note that the result will not necessarily be in the range [0,1], so you have to clamp sheenColorFactor at the very last step.)

That takes it to here:

out

which is.... uh....... b-better?

@emackey emackey linked an issue Mar 3, 2021 that may be closed by this pull request
@scurest
Copy link
Contributor

scurest commented Mar 3, 2021

sheen appears to inherit the roughness of the material itself

The (regular) roughness has no effect on sheen in Blender AFAICT.

@scurest
Copy link
Contributor

scurest commented Mar 3, 2021

I can get better results in Babylon by decreasing the sheenRoughness.

ll

But it seems like the first step should be to find a way to setup Babylon and Blender so that they match without sheen. Otherwise there's no real way to evaluate if the exporter is correct or not.

@CLAassistant
Copy link

CLAassistant commented Feb 7, 2022

CLA assistant check
All committers have signed the CLA.

@donmccurdy
Copy link
Contributor Author

Thanks for these corrections @scurest, and sorry for the long delay. :)

The implementation of sheen in three.js has been completed, which makes it much easier (for me at least) to do a more thorough comparison here...

renderer sheen=0 sheen=1
blender blender_sheen_off blender_sheen_on
three.js three_sheen_off three_sheen_on

Additional steps:

  • https://gltf-viewer.donmccurdy.com/
    1. Under "Display", enable "Background"
    2. Under "Lighting", disable "addLights"
  • Blender
    1. Under "Color Management" → "View Transform", select "Standard"
    2. Under "Viewport Shading", disable "Scene World", then select "sunset.exr" (last option)

The screenshots above all used the current implementation of passing regular roughness (1) into sheen roughness. Decreasing the value to about 0.25 (as you suggest) we can get much closer to Blender:

three_sheen_on_lower_roughness

With that I think we're in the right ballpark, but the sheen color ([1,1,1]) is stronger in three.js (and similar in babylon.js). I don't like hard-coding sheen roughness here but am not sure where else to get that value.

Copy link
Collaborator

@julienduroure julienduroure left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @donmccurdy Did you see that you have some KO unit tests?
Also seems you pushed with 2 differents emails, and 1 didn't signed the CLA

@donmccurdy
Copy link
Contributor Author

Thanks @julienduroure - I've resolved those issues!

Also, the lower roughness gets us more in the right range of general color and strength, but also makes the sheen appear noticeably "less rough" than it appears in Blender. Something doesn't seem to match up there. For another experiment I tried increasing the "Sheen" value beyond one, which brings us in the right direction visually, but also seems like the wrong solution.

blender_sheen_4x

I'm not having much luck comparing Blender's implementation with the KHR_materials_sheen specification or three.js...

... but the fact that Blender is only scaling diffuse radiance sounds like a possible source of difference.

@emackey @elalish Do you know of anyone who might be able to look at Blender's implementation and suggest a mapping to KHR_materials_sheen here? I think the best I can come up with otherwise is to do a bunch of export trials, and then pick roughness and intensity values that seem to look approximately consistent.

@donmccurdy
Copy link
Contributor Author

Some interesting discussion here in Blender Forums: Principled Shader needs ‘Sheen Roughness’...

This is what i ended up with… If i set the sheen up high approx 4 on one principled shader and mix it with a velvet shader with low sheen and use a Fresnel node as the mix factor it gives the effect of a roughness control for the sheen so i can get a sharper more velvet like sheen.

@julienduroure
Copy link
Collaborator

Some thought about how we can manage "hard-coding" values needed for approximation when there is no 100% mapping between Blender and glTF. Example: sheen roughness

Some possible solutions:

  • add it to glTF settings node (used for AO), with 0.25 by default. Use will be able to change it if needed
  • add it to addon preferences. We don't currently have addon preferences panels, but it will change in a near future. cf Fix #1465 - add UI for glTF settings node creation #1574 for a basic example.
  • Keep it hard coded if the value seems OK

@donmccurdy
Copy link
Contributor Author

I'm hoping we can derive values of sheen and sheen roughness that are accurate, or close to it. If so, then I don't think it's necessary to expose additional settings. I am thinking of the "glTF Settings" node as a last resort, for concepts that exist in Blender (e.g. baking AO and thickness maps) but cannot otherwise be exported.

@scurest
Copy link
Contributor

scurest commented Mar 9, 2022

I played with this a bit without getting anywhere. After some simplifying assumptions I managed to line up Three and Blender somewhat and did get to a form with two constants, F and R, your intensity and roughness.

sheenColor = F * sheen * lerp(white, baseColorTint, sheenTint)
sheenRoughness = R

They were supposed to be chosen to make two curves line up but the values I worked out (F=0.5, R=0.5) didn't work all that great when I actually tried it lol. I made some swatches instead.

swatches

The lower left quadrant is most promising. I tried around F=0.3, R=0.4 but didn't come up with anything that good...

(Also I'm not sure if it would be better to scale by 1/max instead of clamping for colors outside white.....)

@julienduroure
Copy link
Collaborator

julienduroure commented Jun 9, 2022

Hello @proog128 ,
I saw you are also part of contributors for KHR_materials_sheen.
Any chance you help us to get a as accurate as possible conversion glTF-->Blender and Blender --> glTF ?
(as you did for specular)

Note: Implementation is not on this PR, but on #1646

@proog128
Copy link

I had a look at this thread and the code but, unfortunately, there is not much I can add. Blender's Principled sheen BRDF doesn't map well to the (more flexible) BRDF defined in KHR_materials_sheen.

  • Blender sheen BRDF lobe is (1 - LdotH)^5. KHR_materials_sheen is based on the microfacet framework. Side-effect of this is that sheen in Blender does not have a roughness parameter.
  • Blender sheen layer is simply added to the base layer. KHR_materials_sheen uses albedo scaling to decrease the contribution of the base layer such that the combination of layers is energy conserving.
  • The normalization by luminance in Blender allows sheen_color to be greater than 1. This is not energy conserving. (Same problem as in KHR_materials_specular).

Overall this makes the sheen models look and behave significantly different. Unlike the specular extension there is no easy conversion between the two sheen models.

@julienduroure
Copy link
Collaborator

Thanks for your feedback!

@julienduroure julienduroure mentioned this pull request Jun 14, 2022
@donmccurdy
Copy link
Contributor Author

Thank you @proog128!

I wonder if this is worth raising with the developers of the Principled BSDF node? I would assume the principled node is intended to be energy-conserving. 🤔

@julienduroure
Copy link
Collaborator

We can now close this PR, as sheen is now in master, after merging #1646

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request exporter This involves or affects the export process Material
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for KHR_materials_sheen
5 participants