-
Notifications
You must be signed in to change notification settings - Fork 1.2k
EXT_materials_specular_edge_color #2488
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
base: main
Are you sure you want to change the base?
EXT_materials_specular_edge_color #2488
Conversation
|
||
Specular reflectance in glTF as defined by `KHR_materials_specular` behaves a bit different than in OpenPBR. This extension defines an interpretation of the specular parameters that is compatible with OpenPBR's specular reflectance for both dielectrics and metals. | ||
|
||
This extension adds no additional parameters. Its presence merely changes how the parameters of `KHR_materials_specular` are used. |
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.
PBR Material extensions are generally designed to be "as if always defined" with their default state not affecting the material appearance. To follow this convention, consider adding a boolean property (optional, false by default) that enables the new semantics.
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.
I've added a single boolean value to the extension to enable it.
@@ -0,0 +1,145 @@ | |||
# EXT\_materials\_specular\_openpbr |
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.
It would be safer to name the extension based on the actual interpretation difference rather than using a reference.
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.
I was expecting that issue to be raised but I'm not sure of a good name.
EXT_materials_specular_edge_color
?
EXT_materials_specular_f82
? - the F82 really only refers to the metallic model so probably isn't ideal.
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.
I've changed the name to EXT_materials_specular_edge_color
for now.
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.
I don't know the math to be able to review that part, but the wording and explanation seems fine to me.
Co-authored-by: Gary Hsu <[email protected]>
Co-authored-by: Gary Hsu <[email protected]>
#### EXT_materials_specular_edge_color | ||
 | ||
|
||
The specular color factor is allowed to be set to values greater than [1, 1, 1]. Thus, the reflection amount can go beyond what is determined by the index of refraction (IOR). To still ensure energy conservation, the product of specular color factor, specular color texture, and f0 reflectance from IOR is clamped to 1. Please refer to [Implementation](#Implementation) for an example on where to place the clamping operation. |
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.
This sentence doesn't seem to be valid anymore.
Also, I think the reflectance conversion as such doesn't work when the specular color also affects f90.
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.
Yeah, the needed logic here is a bit more complex. I've tried to clarify.
Basically, OpenPBR allows specular_weight > 1.0 but not specular_color. Assuming that we want the data to remain the same for this sub-extension, we need to apply specularColorFactors > 1 to the weighting while keeping the color itself as a multiply on the specular lobe. I've updated the implementation code as well. Does it make sense?
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.
Looks good to me
``` | ||
function fresnel_mix(specular_color, ior, weight, base, layer) { | ||
f0 = ((1-ior)/(1+ior))^2 | ||
f0 = min(f0, float3(1.0)) |
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.
min
not needed anymore
f0 = ((1-ior)/(1+ior))^2 | ||
f0 = min(f0, float3(1.0)) | ||
fr = f0 + (1 - f0)*(1 - abs(VdotH))^5 | ||
return (1 - weight * fr) * base + weight * fr * specular_color * layer |
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.
I think the base weight needs to consider the specular_color
for reasons of energy preservation. E.g. low specular_color will lead to low specular contribution that is not compensated by the base layer. Also specular color values > 1.0 need to be handled somehow. Haven't fully thought this through but maybe sth. like
specular_weight = weight * fr * min(specular_color, float3(1.0))
base_weight = 1 - max_value(specular_weight)
return base_weight * base + specular_weight * layer
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.
My understanding is that, in OpenPBR, specular_color
does not effect the base weight.
From the specs:
The specular_color parameter modulates the Fresnel factor of Fdielectric, but only for the initial reflection of light incident from above, while the light transmitted from above or below (or reflected from below) is assumed to be unaffected. This is technically unphysical if altered from the default white color (as real dielectrics have a Fresnel factor dependent only on the index of refraction), but can be useful in practice to artificially tint the specular highlight without disturbing other aspects of the light transport, i.e. the reflection due to scattering from the internal medium, or the reflection from below, or the transmission from above or below.
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.
I think I've got something that works in the Implementation section now.
I definitely wasn't handling the > 1.0 case correctly.
} | ||
``` | ||
All that remains is a simple lerp between the dielectric and metallic lobes based on the metallic value. | ||
|
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.
Maybe small code chunk that shows the lerp for clarity?
Here's an extremely rough draft of an OpenPBR-compatible specular extension.
Based on @lexaknyazev's advice, I've made this a sub extension of
KHR_materials_specular
as they share the same parameters though I'm not sure how to specify this requirement in the schema.Feedback would be very appreciated.