Comments (4)
The way you would check the condition you're asking about is material->has_pbr_metallic_roughness && material->pbr_metallic_roughness.metallic_factor > 0
and material->has_pbr_metallic_roughness && material->pbr_metallic_roughness.roughness_factor > 0
, respectively.
has_pbr_metallic_roughness
specifically refers to the presence of pbrMetallicRoughness
node in glTF material file; cgltf mirrors the structure of glTF files pretty much one to one, so since glTF files don't have metallic and roughness separated, other than through factors, that's how cgltf represents this as well.
from cgltf.
Hi Arseny, I apologize in advanced that I'm responding in the early hours of the morning. Hopefully my response is still comprehensible.
Here's some clarification to what I was trying to ask originally: What I'm trying to do is figure out from cgltf if I should use the values from metallicFactor
/roughnessFactor
or from the texture. Based on my understanding, I think there are some ambiguous cases using the checks that have been suggested.
I beg your patience, this is a long example. Below I have 4 materials. Each material name has a suffix for metallic or roughness that indicates what/where the value for each respective field should come from:
_F
- means the value for metallic and/or roughness should come from the *Factor
variable(s).
_T
- means the value for metallic and/or roughness should come from the texture. *Factor
variables are ignored.
_Z
- means the value for metallic and/or roughness is zero but should also come from the *Factor
variable(s).
I created a scene in Blender with the 4 materials and exported:
"materials":[
// We know there is a metallicRoughness texture.
// cgltf will have 0 for metallicFactor and 1.0 for roughnessFactor.
// The intent of this material is to have metallic be 0 and
// use the roughness from the texture.
// From the cgltf perspective, it's ambiguous if roughness
// should come from the the factor or the texture.
// We know from looking at the GLTF file that there isn't roughnessFactor
// so this must mean that roughness must come from the texture.
{
"doubleSided":true,
"name":"metallic_Z_and_roughness_T",
"pbrMetallicRoughness":{
"baseColorFactor":[
0.800000011920929,
0.800000011920929,
0.800000011920929,
1
],
"metallicFactor":0,
"metallicRoughnessTexture":{
"index":0
}
}
},
// We know 100% that both metallic and roughness are factors.
// cgltf will have 0.25 for metallicFactor and 0.5 for roughnessFactor.
// The intent of this material is to use both metallic and roughness from the factors.
// The absence of a metallicRoughness texture means that this
// material will not have texture reads.
{
"doubleSided":true,
"name":"mettalic_F_and_roughness_F",
"pbrMetallicRoughness":{
"baseColorFactor":[
0.800000011920929,
0.800000011920929,
0.800000011920929,
1
],
"metallicFactor":0.25,
"roughnessFactor":0.5
}
},
// We know there is a metallicRoughness texture.
// cgltf will have 1.0 for both metallicFactor and roughnessFactor.
// The intent of this material is to use both metallic and roughness from the texture.
// From the cgltf perspective, it's ambiguous if metallica nd roughness
// should come from the factor or the texture.
// We know by looking at the GLTF file that isn't metallicFactor
// or roughnessFactor, so this must mean that both metallic and roughness
// must come from the texture.
{
"doubleSided":true,
"name":"metallic_T_and_roughness_T",
"pbrMetallicRoughness":{
"baseColorFactor":[
0.800000011920929,
0.800000011920929,
0.800000011920929,
1
],
"metallicRoughnessTexture":{
"index":1
}
}
},
// We know there is a metallicRoughness texture.
// cgltf will have 1.0 for metallicFactor and 0 for roughness.
// The intent of this material is to have metallic come from the texture
// and roughness be 0.
// From the cgltf perspective, it's ambiguous if metallic
// should come from the the factor or the texture.
// We know from looking at the GLTF file that there isn't metallicFactor
// so this must mean that metallic must come from the texture. {
"doubleSided":true,
"name":"metallic_T_and_roughness_Z",
"pbrMetallicRoughness":{
"baseColorFactor":[
0.800000011920929,
0.800000011920929,
0.800000011920929,
1
],
"metallicRoughnessTexture":{
"index":2
},
"roughnessFactor":0
}
}
],
From what I understand, a check like material->has_pbr_metallic_roughness && material->pbr_metallic_roughness.metallic_factor > 0
even with an additional check for material->pbr_metallic_roughness.metallic_roughness_texture.texture != NULL
can't indicate with certainty whether the value for metallic should come from the factor or thet exture. Also want to note that both metallic_factor = 0
and 'roughness_factor = 0are both legit use cases for a material. By looking at the GLTF JSON we can know with certainty that if
metallicFactorand/or
roughnessFactoris not present then the values for metallic/roughness must from the texture - assuming the JSON is well formed and
metallicRoughnessTexture` exists.
Based on what I've said above (fully admit my understanding might be flawed), it seems like if there existed something like:
cgltf_bool has_metallic_factor; // starts out as false and becomes true IFF metallicFactor is in JSON
cgltf_bool has_roughness_factor; // starts out as false and becomes true IFF roughnessFactor is in JSON
then could be certainty on which source the values metallic/roughness could come from.
from cgltf.
Let's ignore cgltf for now, as I said it tries to give a 1-1 semantic mirror of the glTF file.
The way glTF metallic roughness node works is that for every pixel, the metalness value is computed as metallicFactor * textureSample(metallicRoughnessTexture, uv).b
, and roughness value is computed as roughnessFactor * textureSample(metallicRoughnessTexture, uv).g
. When texture is absent, the texture sample is assumed to return (1, 1, 1, 1)
. When either factor is absent, it is assumed to be 1. See https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#metallic-roughness-material.
A factor is not ignored when a texture is present. A factor that is absent is indistinguishable from a factor that is specified and equal to 1.
As such, you can determine the definite absence of metalness (if the goal is to skip some computations) by checking if metalnessFactor is exactly 0 - even if texture is present, that will nullify whatever values the texture has.
If the factor is not 0 or absent (which means it's 1), and the texture is present, you can't definitively say whether any pixels of the mesh must be rendered as a metallic material - this requires analyzing the blue channel of the texture and seeing if all pixels are 0, which glTF file doesn't provide anywhere.
Hopefully that clarifies this? Getting back to cgltf, since absence of metallicFactor is equivalent to metallicFactor being specified as 1, cgltf doesn't store the presence of the factor in source document anywhere because from the spec perspective it doesn't matter if it exists.
from cgltf.
That's a helpful explanation. Thanks!
I had forgotten that the factors acts as multiplier in the cases I stated above. In thinking about it, the ambiguous case(s) will need to be addressed with workflow requirements.
from cgltf.
Related Issues (20)
- Add support for MSFT_texture_dds extension HOT 1
- Potential Undefined Behaviour in "cgltf_component_read_index"
- How to enable draco support? HOT 3
- fopen or strcpy this function or variable is unsafe. HOT 1
- Library will not compile if using GCC in Windows.
- Node parent sanity check prevents loading files created with UniGLTF-1.27 HOT 5
- different joints for same primitive
- Stack allocate cgltf_data structure? HOT 1
- Invalid gltf file with EXT_mesh_gpu_instancing HOT 2
- Double-precision transform hierarchy
- native app EXT_meshopt_compression support HOT 2
- GLTF primitive type not written correctly? HOT 1
- Support for KHR_animation_pointer HOT 3
- load glb crash HOT 3
- Support for EXT_texture_webp HOT 3
- Reading glTF binary files in GLB format HOT 2
- Incorrect parsing of numeric values from glb file HOT 2
- Based on the current node, how to find out the bufferView number? HOT 1
- Support for Draco mesh decompression HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cgltf.