KhronosGroup / glTF

glTF – Runtime 3D Asset Delivery
Other
7.17k stars 1.14k forks source link

glTF 2.0: New/modified KHR_materials_common extension #947

Closed McNopper closed 7 years ago

McNopper commented 7 years ago

Using the pbrMetallicRoughness and pbrSpecularGlossiness material "syntax", I have adapted the common materials. Again here by example:

{
  "materials": [
    {
      "commonConstant": {
        "ambientFactor": [
          0.2,
          0.2,
          0.2
        ]
      }
    },
    {
      "commonLambert": {
        "ambientFactor": [
          0.2,
          0.2,
          0.2
        ],
        "diffuseFactor": [
          1,
          1,
          1,
          1
        ],
        "diffuseTexture": 0
      }
    },
    {
      "commonPhong": {
        "ambientFactor": [
          0.2,
          0.2,
          0.2
        ],
        "diffuseFactor": [
          1,
          1,
          1,
          1
        ],
        "diffuseTexture": 0,
        "specularFactor": [
          1,
          1,
          1,
          1
        ],
        "specularTexture": 1,
        "shininessFactor": 0.5,
        "shininessTexture": 2
      }
    },
    {
      "commonBlinn": {
        "ambientFactor": [
          0.2,
          0.2,
          0.2
        ],
        "diffuseFactor": [
          1,
          1,
          1,
          1
        ],
        "diffuseTexture": 0,
        "specularFactor": [
          1,
          1,
          1,
          1
        ],
        "specularTexture": 1,
        "shininessFactor": 0.5,
        "shininessTexture": 2
      }
    }
  ]
}

Like the current PBR materials, they extend the "base" materials. So e.g. emissive would be inherited.

stevenvergenz commented 7 years ago

@McNopper Is this update work happening in public anywhere? I'm looking to implement these types in the UnityGLTF project, as they seem easier to work with on mobile than pbrMetallicRoughness.

McNopper commented 7 years ago

It is happening in this thread. As soon as glTF 2.0 is final, the working group will get back to extensions and issues.I am currently implementing the materials, lights in an experimental way, that we do have a base to discuss about.Regarding the lightmap, I suggest u define an extension and provide an example and/or schema. This could also be used as a start to discuss about. Von meinem Samsung Galaxy Smartphone gesendet. -------- Ursprüngliche Nachricht --------Von: Steven Vergenz notifications@github.com Datum: 25.05.17 20:45 (GMT+01:00) An: KhronosGroup/glTF glTF@noreply.github.com Cc: Norbert Nopper norbert@nopper.tv, Mention mention@noreply.github.com Betreff: Re: [KhronosGroup/glTF] glTF 2.0: New/modified KHR_materials_common   extension (#947) @McNopper Is this update work happening in public anywhere? I'm looking to implement these types in the UnityGLTF project, as they seem easier to work with on mobile than pbrMetallicRoughness.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/KhronosGroup/glTF","title":"KhronosGroup/glTF","subtitle":"GitHub repository","main_image_url":"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in GitHub","url":"https://github.com/KhronosGroup/glTF"}},"updates":{"snippets":[{"icon":"PERSON","message":"@stevenvergenz in #947: @McNopper Is this update work happening in public anywhere? I'm looking to implement these types in the UnityGLTF project, as they seem easier to work with on mobile than pbrMetallicRoughness."}],"action":{"name":"View Issue","url":"https://github.com/KhronosGroup/glTF/issues/947#issuecomment-304090852"}}}

stevenvergenz commented 7 years ago

I've added a tentative lightmap implementation to the commonConstant material in UnityGLTF, since we use pre-computed lighting more routinely than PBR. What it looks like:

{
    "alphaMode" : "MASK",
    "doubleSided" : true,
    "emissiveFactor" : [
        0.0,
        1.0,
        0.0
    ],
    "emissiveTexture" : {
        "index" : 1
    },
    "name" : "Material",
    "commonConstant" : {
        "lightmapTexture": {
           "index": 0,
           "texCoord": 1
        }
    }
}
McNopper commented 7 years ago

Does the lightmapTexture make sense in commonConstant, as its inflcuence is on the diffuse part? In my opinion it should be restricted to commonLambert, commonBlinn and commonPhong.

stevenvergenz commented 7 years ago

In the case of the constant material, a lightmap is simply a multiply texture, but is still incredibly useful to my use cases. It gives you the ability to 1) have multiple variations of emissive textures without having to bake lighting onto them, 2) specify a separate UV channel, so you can vary the lightmap texel resolution w.r.t. the emissive texture.

McNopper commented 7 years ago

Ah, I see. Do you know, if other engines do have the same approach? Or it could be "easily" implemented?

stevenvergenz commented 7 years ago

I'm sure light maps as multiply textures are easy to implement on Unity and Three.js, as those are the platforms I use. Not sure about any others.

donmccurdy commented 7 years ago

lightmaps are implemented in threejs, multiplied against indirect diffuse: https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl

McNopper commented 7 years ago

Steven, seems my original assumption is correct. The lightmap is just applied to the diffuse part. As this is probably the "normal" approach, we should go for this solution,

Can we make for your approach another extension? Can you please post an image, to better understand your approach?

stevenvergenz commented 7 years ago

I don't want to derail this issue, which is meant for the materials definition. I'll write up a new issue with my proposal, we can discuss it there.

UX3D-nopper commented 7 years ago

Same with the current status of the common materials:

{
    "accessors" : [
        {
            "bufferView" : 0, 
            "componentType" : 5121, 
            "count" : 36, 
            "max" : [
                23
            ], 
            "min" : [
                0
            ], 
            "type" : "SCALAR"
        }, 
        {
            "bufferView" : 1, 
            "componentType" : 5126, 
            "count" : 24, 
            "max" : [
                1.0, 
                1.0, 
                1.0
            ], 
            "min" : [
                -1.0, 
                -1.0, 
                -1.0
            ], 
            "type" : "VEC3"
        }, 
        {
            "bufferView" : 2, 
            "componentType" : 5126, 
            "count" : 24, 
            "max" : [
                1.0, 
                1.0, 
                1.0
            ], 
            "min" : [
                -1.0, 
                -1.0, 
                -1.0
            ], 
            "type" : "VEC3"
        }, 
        {
            "bufferView" : 3, 
            "componentType" : 5126, 
            "count" : 24, 
            "max" : [
                1.0, 
                0.0, 
                0.0, 
                1.0
            ], 
            "min" : [
                0.0, 
                0.0, 
                -1.0, 
                1.0
            ], 
            "type" : "VEC4"
        }, 
        {
            "bufferView" : 4, 
            "componentType" : 5126, 
            "count" : 24, 
            "max" : [
                1.0, 
                2.0
            ], 
            "min" : [
                -1.0, 
                0.0
            ], 
            "type" : "VEC2"
        }, 
        {
            "bufferView" : 5, 
            "componentType" : 5121, 
            "count" : 6, 
            "max" : [
                3
            ], 
            "min" : [
                0
            ], 
            "type" : "SCALAR"
        }, 
        {
            "bufferView" : 6, 
            "componentType" : 5126, 
            "count" : 4, 
            "max" : [
                1.0, 
                0.0, 
                1.0
            ], 
            "min" : [
                -1.0, 
                0.0, 
                -1.0
            ], 
            "type" : "VEC3"
        }, 
        {
            "bufferView" : 7, 
            "componentType" : 5126, 
            "count" : 4, 
            "max" : [
                0.0, 
                1.0, 
                -0.0
            ], 
            "min" : [
                0.0, 
                1.0, 
                -0.0
            ], 
            "type" : "VEC3"
        }, 
        {
            "bufferView" : 8, 
            "componentType" : 5123, 
            "count" : 2880, 
            "max" : [
                503
            ], 
            "min" : [
                0
            ], 
            "type" : "SCALAR"
        }, 
        {
            "bufferView" : 9, 
            "componentType" : 5126, 
            "count" : 504, 
            "max" : [
                1.000000238418579, 
                1.0, 
                1.0000003576278687
            ], 
            "min" : [
                -0.9999998211860657, 
                -1.0, 
                -0.9999991655349731
            ], 
            "type" : "VEC3"
        }, 
        {
            "bufferView" : 10, 
            "componentType" : 5126, 
            "count" : 504, 
            "max" : [
                1.0, 
                1.0, 
                1.0
            ], 
            "min" : [
                -1.0, 
                -1.0, 
                -1.0
            ], 
            "type" : "VEC3"
        }, 
        {
            "bufferView" : 11, 
            "componentType" : 5126, 
            "count" : 504, 
            "max" : [
                0.9520357251167297, 
                0.9904618263244629, 
                0.3444094955921173, 
                1.0
            ], 
            "min" : [
                -0.9512326121330261, 
                -0.9901572465896606, 
                -0.34139394760131836, 
                1.0
            ], 
            "type" : "VEC4"
        }, 
        {
            "bufferView" : 12, 
            "componentType" : 5126, 
            "count" : 504, 
            "max" : [
                1.2534546852111816, 
                0.97004634141922
            ], 
            "min" : [
                0.0013766288757324219, 
                0.029953598976135254
            ], 
            "type" : "VEC2"
        }
    ], 
    "asset" : {
        "generator" : "Khronos Blender glTF 2.0 exporter", 
        "version" : "2.0"
    }, 
    "bufferViews" : [
        {
            "buffer" : 0, 
            "byteLength" : 36, 
            "byteOffset" : 0, 
            "target" : 34963
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 288, 
            "byteOffset" : 36, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 288, 
            "byteOffset" : 324, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 384, 
            "byteOffset" : 612, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 192, 
            "byteOffset" : 996, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 6, 
            "byteOffset" : 1188, 
            "target" : 34963
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 48, 
            "byteOffset" : 1194, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 48, 
            "byteOffset" : 1242, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 5760, 
            "byteOffset" : 1290, 
            "target" : 34963
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 6048, 
            "byteOffset" : 7050, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 6048, 
            "byteOffset" : 13098, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 8064, 
            "byteOffset" : 19146, 
            "target" : 34962
        }, 
        {
            "buffer" : 0, 
            "byteLength" : 4032, 
            "byteOffset" : 27210, 
            "target" : 34962
        }
    ], 
    "buffers" : [
        {
            "byteLength" : 31242, 
            "uri" : "04_common_materials.bin"
        }
    ], 
    "cameras" : [
        {
            "name" : "Camera", 
            "perspective" : {
                "aspectRatio" : 1.703595982340029, 
                "yfov" : 0.5033799409866333, 
                "zfar" : 100.0, 
                "znear" : 0.10000000149011612
            }, 
            "type" : "perspective"
        }
    ], 
    "extensions" : {
        "KHR_lights" : {
            "lights" : [
                {
                    "color" : [
                        1.0, 
                        1.0, 
                        1.0
                    ], 
                    "name" : "Directional", 
                    "type" : "directional"
                }, 
                {
                    "color" : [
                        0.0, 
                        0.0, 
                        0.0
                    ], 
                    "name" : "Ambient_Scene", 
                    "type" : "ambient"
                }
            ]
        }
    }, 
    "extensionsRequired" : [
        "KHR_materials_common", 
        "KHR_lights"
    ], 
    "extensionsUsed" : [
        "KHR_materials_common", 
        "KHR_lights"
    ], 
    "images" : [
        {
            "uri" : "04_crate.png"
        }
    ], 
    "materials" : [
        {
            "emissiveFactor" : [
                0.0, 
                0.0, 
                0.0
            ], 
            "extensions" : {
                "KHR_materials_common" : {
                    "ambientFactor" : [
                        1.0, 
                        1.0, 
                        1.0
                    ], 
                    "diffuseFactor" : [
                        1.0, 
                        1.0, 
                        1.0, 
                        1.0
                    ], 
                    "diffuseTexture" : {
                        "index" : 0
                    }, 
                    "shininessFactor" : 12.298039215686275, 
                    "specularFactor" : [
                        0.0, 
                        0.0, 
                        0.0
                    ], 
                    "type" : "commonPhong"
                }
            }, 
            "name" : "Crate"
        }, 
        {
            "emissiveFactor" : [
                0.0, 
                0.0, 
                0.0
            ], 
            "extensions" : {
                "KHR_materials_common" : {
                    "ambientFactor" : [
                        1.0, 
                        1.0, 
                        1.0
                    ], 
                    "diffuseFactor" : [
                        0.800000011920929, 
                        0.800000011920929, 
                        0.800000011920929, 
                        1.0
                    ], 
                    "shininessFactor" : 12.298039215686275, 
                    "specularFactor" : [
                        0.5, 
                        0.5, 
                        0.5
                    ], 
                    "type" : "commonPhong"
                }
            }, 
            "name" : "Plane"
        }, 
        {
            "emissiveFactor" : [
                0.0, 
                0.0, 
                0.0
            ], 
            "extensions" : {
                "KHR_materials_common" : {
                    "ambientFactor" : [
                        1.0, 
                        1.0, 
                        1.0
                    ], 
                    "diffuseFactor" : [
                        0.6400000190734865, 
                        0.0, 
                        0.0, 
                        1.0
                    ], 
                    "shininessFactor" : 12.298039215686275, 
                    "specularFactor" : [
                        0.5, 
                        0.5, 
                        0.5
                    ], 
                    "type" : "commonPhong"
                }
            }, 
            "name" : "Sphere"
        }
    ], 
    "meshes" : [
        {
            "name" : "Cube", 
            "primitives" : [
                {
                    "attributes" : {
                        "NORMAL" : 2, 
                        "POSITION" : 1, 
                        "TANGENT" : 3, 
                        "TEXCOORD_0" : 4
                    }, 
                    "indices" : 0, 
                    "material" : 0
                }
            ]
        }, 
        {
            "name" : "Plane", 
            "primitives" : [
                {
                    "attributes" : {
                        "NORMAL" : 7, 
                        "POSITION" : 6
                    }, 
                    "indices" : 5, 
                    "material" : 1
                }
            ]
        }, 
        {
            "name" : "Sphere", 
            "primitives" : [
                {
                    "attributes" : {
                        "NORMAL" : 10, 
                        "POSITION" : 9, 
                        "TANGENT" : 11, 
                        "TEXCOORD_0" : 12
                    }, 
                    "indices" : 8, 
                    "material" : 2
                }
            ]
        }
    ], 
    "nodes" : [
        {
            "camera" : 0, 
            "name" : "Correction_Camera", 
            "rotation" : [
                -0.7071067690849304, 
                -0.0, 
                0.0, 
                0.7071067690849304
            ]
        }, 
        {
            "children" : [
                0
            ], 
            "name" : "Camera", 
            "rotation" : [
                0.5730898976325989, 
                0.0, 
                -0.0, 
                0.8194926381111145
            ], 
            "translation" : [
                0.0, 
                12.0, 
                30.0
            ]
        }, 
        {
            "mesh" : 0, 
            "name" : "Cube", 
            "translation" : [
                0.0, 
                1.0, 
                -0.0
            ]
        }, 
        {
            "extensions" : {
                "KHR_lights" : {
                    "light" : 0
                }
            }, 
            "name" : "Correction_Directional", 
            "rotation" : [
                -0.7071067690849304, 
                -0.0, 
                0.0, 
                0.7071067690849304
            ]
        }, 
        {
            "children" : [
                3
            ], 
            "name" : "Directional", 
            "rotation" : [
                0.3535533845424652, 
                -0.3535533845424652, 
                0.1464466005563736, 
                0.8535534143447876
            ], 
            "scale" : [
                0.9999999403953552, 
                1.0, 
                0.9999999403953552
            ], 
            "translation" : [
                -8.0, 
                4.0, 
                8.0
            ]
        }, 
        {
            "mesh" : 1, 
            "name" : "Plane", 
            "scale" : [
                10.0, 
                10.0, 
                10.0
            ]
        }, 
        {
            "mesh" : 2, 
            "name" : "Sphere", 
            "translation" : [
                4.0, 
                1.0, 
                -0.0
            ]
        }
    ], 
    "samplers" : [
        {}
    ], 
    "scene" : 0, 
    "scenes" : [
        {
            "extensions" : {
                "KHR_lights" : {
                    "light" : 1
                }
            }, 
            "name" : "Scene", 
            "nodes" : [
                6, 
                2, 
                5, 
                4, 
                1
            ]
        }
    ], 
    "textures" : [
        {
            "sampler" : 0, 
            "source" : 0
        }
    ]
}
donmccurdy commented 7 years ago

This looks reasonable to me — @UX3D-nopper are you able to share a complete model (with the .bin and textures) in this format, or is this structure not reflected in the Blender exporter yet? I'd like to mock up an implementation in three.js.

UX3D-nopper commented 7 years ago

You can use this scene: https://github.com/KhronosGroup/glTF-Blender-Exporter/blob/master/scenes/04_common_materials.blend Also, set in the experimental section the common material to 'Phong'.

Basically, every scene based on Blender Render materials can be exported like that.

mlimper commented 7 years ago

Hey, great to see this!

Just my 0.02$, after thinking again about this material model:

Comparing to the PBR one, the materials_common model should be as simple as possible - which is also what @stevenvergenz names as a motivation to implement it (in this case for mobile):

I'm looking to implement these types [...], as they seem easier to work with on mobile than pbrMetallicRoughness.

Apart from that, I think one reason why it might be nice to have it is that many "traditional" pipelines and viewers (such as X3D viewers) built on a common model that became popular through standardization in the old OpenGL fixed function pipeline, offering ambient, diffuse, and specular material properites. I think the standard OpenGL implementation would use Blinn (with halfway vector, as opposed to Phong with reflected view vector), but I'd need to check again. My main point here is: Instead of offering to choose between Blinn and Phong, it could ease adaption to just limit this model to one of them (-> probably rather use Blinn?). In our CAD review apps, we clearly just use one of them (blinn), and there is no need to have two slightly different models for specularity. Also, I would guess that, if people want more sophisticated materials, they will use the PBR model anyway.

Again, just my opinion, you know I'm not a material expert - wondering if anyone had similar thoughts on this?

McNopper commented 7 years ago

I personally think, we should call the common material just Phong or Blinn and "kick" out Lambert and Constant, as they can be described by using zero factors in Phong and/or Blinn. I also agree, that we should take either the Blinn or Phong formula, as this would simplify the whole material.

If someone wants to use sophisticated materials, one is using PBR nowadays anyway.

Also, regarding PBR, we also did not fully specify(?), which terms should be used in the BRDF formula, see http://simonstechblog.blogspot.de/2011/12/microfacet-brdf.html

pjcozzi commented 7 years ago

I personally think, we should call the common material just Phong or Blinn and "kick" out Lambert and Constant, as they can be described by using zero factors in Phong and/or Blinn.

+1 from me. I think the original extension basically just copied COLLADA, which was not as simple as possible.

pjcozzi commented 7 years ago

My main point here is: Instead of offering to choose between Blinn and Phong, it could ease adaption to just limit this model to one of them (-> probably rather use Blinn?). In our CAD review apps, we clearly just use one of them (blinn), and there is no need to have two slightly different models for specularity. Also, I would guess that, if people want more sophisticated materials, they will use the PBR model anyway.

Let's get more input here. It would be great to simplify this, but will it create challenges for exporters or runtimes?

@lexaknyazev @bghgary @javagl?

javagl commented 7 years ago

Due to a limited understanding of the technical implications (also for the application cases, or even details like shader performance), I don't have a strong opinion here, but iff I understood this correctly, then

Then, one could only support Blinn, because it is a good trade-off between simplicity and power (in terms of capability to emulate the others). It would be nice if the differences could be covered with default values. I'll have to re-read some details, but ... wouldn't it be possible to boil this down to something like this (roughly equivalent to what @McNopper posted initially) :

materials : [

  // This is a "constant" material, because all other values are 0.0
  {
    ambient: [1,0,0,0].
  },

  // This is a "lambert" material, because all other values are 0.0
  {
    abmient: [1,0,0,0].
    diffuse: [1,0,0,0].
  },

  // This is a "blinn" material, because all other values are 0.0
  {
    abmient: [1,0,0,0].
    diffuse: [1,0,0,0].
    specular: [1,0,0,0].
    shininess: 10 // Multiply this by 4 to approximate "phong"
  },
]

Or more specifically: Is it worth to differentiate between

  "commonConstant": {
  "commonLambert": {
  "commonPhong": {
  "commonBlinn": {

when the shader implementation will basically be the same in all cases?

donmccurdy commented 7 years ago

An implementation note from three.js: we do not have an ambient property in our Phong shader. It was removed (https://github.com/mrdoob/three.js/issues/6501) and is now inferred from diffuse, because (1) having both caused confusion for some users, and (2) it more closely resembles physical materials.

Instead of offering to choose between Blinn and Phong, it could ease adaption to just limit this model to one of them (-> probably rather use Blinn?).

Can Phong approximate Blinn? I'm not sure I understand the difference, THREE.MeshPhongMaterial implements a "Blinn-Phong" model. Other than that confusion, +1 on the idea of having a single model, assuming it is OK for exporters.

McNopper commented 7 years ago

I think we should just support Blinn-Phong, as if an engine does support non-PBR, in most (all?) cases it is this shading model. So, let's define and finalize commonBlinnPhong. If at a later point of time someone really needs Phong, we can still add it as another extension - like we did for pbrSpecularGlossiness.

steveghee commented 7 years ago

From what I can pick up form this thread (and related), you seem to be converging on a model which effectively does the following

diffuseTerm = ? // extension ; texture is optional. specularTerm = ? // extension shineTerm = ? // extension emissiveTerm = ? // part of core Materials spec

Textures are optional, and if provided, will modulate the base Factor value?

color = emissiveTerm + ambientFactor aL + diffuseTerm max(N L, 0) + specularTerm max(H * N, 0)^shineTerm

where N (normal) can be geometric or can be provided by tangent-space normalTexture (part of core material spec).

Is that a fair assessment?
I like this model as it is simple (to generate and implement) and covers most cases.

I ask because we're building a pipeline and viewer based around glTF2.0 and we've got a ton of 'old' (pre-PBR) model data which we'd like to get converted, and it would be nice to have a clear definition to build against.

UX3D-nopper commented 7 years ago

Basically. it is what you have written, but the ambientTerm/ambientFactor is equal to the diffuseTerm: color = emissiveTerm + diffuseTerm aL + diffuseTerm max(N L, 0) + specularTerm max(H * N, 0)^shineTerm

Please also have a look at the Khrons Blender glTF 2.0 exporter: https://github.com/KhronosGroup/glTF-Blender-Exporter During export, you can enable experimental Blinn-Phong export.

steveghee commented 7 years ago

Thanks for confirming.

Interesting decision to drop ambient and replace with fixed diffuse term. Will be interesting to see how that looks.

And just to double check, textures will multiply, not add/replace? Texture modulation is pretty typical for diffuse (red plastic, green plastic etc.) but its not clear from the spec if these will be modulated, or if the texture replaces the factor term. Perhaps it is modulate for diffuse, replace for all others? Hopefully the final spec can make this clear e.g. write the full equation out pseudo-fashion as I did above.

UX3D-nopper commented 7 years ago

The reason to drop the ambient is because of a long discussion with three.js.

The following code snippet is the current formula, on how to calculate the terms:

vec3 diffuseColor = colorToLinear(texture(u_diffuseTexture, texcoord_0.st).rgb) * u_bufferMaterial_Common.diffuseFactor.rgb * color_0.rgb;
alpha = texture(u_diffuseTexture, texcoord_0.st).a * u_bufferMaterial_Common.diffuseFactor.a * color_0.a;
vec3 specularColor = colorToLinear(texture(u_specularTexture, texcoord_0.st).rgb) * u_bufferMaterial_Common.specularFactor.rgb;
float shininess = texture(u_shininessTexture, texcoord_0.st).g * u_bufferMaterial_Common.shininessFactor;

As I said, this is not all final yet and discussable.

steveghee commented 7 years ago

cool, thanks for than snippet. Probably safe to assume that we could infer vec3 emissiveColor using the same maths...

not 100% sure about dropping the ambient term, as I always felt it was useful to have unlit items fade to some darkish (greyish) background, instead of black, which is what you'd get if you just use the diffuse term. I guess that its very subjective, so it will be interesting to see what it looks like.

UX3D-nopper commented 7 years ago

Yes, for emissive it is the same:

vec3 emissive = colorToLinear(texture(u_emissiveTexture, texcoord_0.st).rgb) * u_bufferMaterial.emissiveFactor;
float occlusion = texture(u_occlusionTexture, texcoord_0.st).r;

There will be still an ambient light in the scene. But the light needs to be adapted, as it directly uses the diffuse term.

steveghee commented 7 years ago

Thanks.
I had not noticed occlusion in the core spec. Am guessing this is baked ambient occlusion, and affects everything outside of the emissiveTerm

color = emissiveTerm + occlusionTerm * (ambient + diffuse + specular)

I note there's a pattern here; occlusionTexture.r and shininessTexture.g suggests these textures can be combined into a single map?

lexaknyazev commented 7 years ago

I note there's a pattern here; occlusionTexture.r and shininessTexture.g suggests these textures can be combined into a single map?

Yep. Exporters could do this if they want. Loaders should be able to load texture data in either case.

UX3D-nopper commented 7 years ago

The .g is a typo in my shader (should be .r). Thank you for finding the bug :-) But it makes sense, to pack channels. I will write down a first spec the coming days, then we have something to discuss about.

stevepg commented 7 years ago

should shininessMap (scalar) be cooked into the alpha channel of the specularTexture?

specular = specularTexture.rgb shininess = specularTexture.a

UX3D-nopper commented 7 years ago

Yes, good idea. We just need to check, if this is common in most engines and if they can handle this mapping.

donmccurdy commented 7 years ago

I'm OK with the RGBA packing described, especially if there's precedent in other engines. The occ/rough/metal ordering had the nice characteristic of already being common in UE4.

But, I should note that the three.js blinn-phong material does not have the ability to take a shininess texture. We can support specularFactor, specularTexture, and shininess, but not shininessTexture currently. Here are docs for THREE.PhongMaterial, and some previous discussion of this issue. tl;dr it sounds like three.js would consider adding support eventually, but can't guarantee that.

UX3D-nopper commented 7 years ago

Let's discuss this on Wednesday with the glTF group. We cannot define something, which some engines do not support :-)

steveghee commented 7 years ago

I would argue that most engines could be extended to support this sort of thing assuming they want to claim support for glTF2.0. Either an extension to an existing shader, or simply a new shader.

here's one usecase that (for us) drives the value of this feature; i'm taking large CAD models (many 1000s of parts) and compressing them down into optimal drawable items, sometimes by coalescing a number of individual parts, each comprising of many surfaces, each using different material specs. The result is a single mesh with baked diffuse, normal, specular textures, sampled from the original surface materials. I can't just sample the specular rgb without similarly sampling the shininess associated with it, as different surface materials have a different response, and now these have been combined into a single material, I cannot really average out the single shininess factor to cover all components. Thus having a shininess map can really help in representing these composite objects.

UX3D-nopper commented 7 years ago

That's a good point. Also, common materials - in this case Blinn Phong - is an extension. So we could request, that these engines need to support shininess textures. Regarding channel packing and order, from my side, this would be okay. I will cross check with other tools.

lexaknyazev commented 7 years ago

Considering that CAD-related apps may be the main users of BlinnPhong model, I agree that shininess textures should be supported.

pjcozzi commented 7 years ago

@McNopper do you think KHR_materials_blinnPhong is a better name than KHR_materials_cmnBlinnPhong?

UX3D-nopper commented 7 years ago

Currently we have pbrMetallicRoughness and pbrSpecularGlossiness.

For common materials, we currently have only cmnBlinnPhong. If people later want to have just Phong, it would be called cmnPhong.

So, actually I would like to keep the name schema like this: pbr for any current and future PBR material. cmn for any common ("old school") material.

pjcozzi commented 7 years ago

Ah, I see. OK.

Misterblue commented 7 years ago

Has there been any progress on writing down the schema for the current common extension proposal? I have taken to reading the source code for the various loaders to find the names of attributes and JSON format, but is there a strawman definition for "material common extension 2.0" around somewhere to work from?

UX3D-nopper commented 7 years ago

This is the current status: https://github.com/UX3D-nopper/glTF/tree/master_lights_blinnphong/extensions/Khronos/KHR_materials_cmnBlinnPhong

We will continue on this and other extensions after SIGGRAPH.

steveghee commented 7 years ago

is specularShininessTexture the combined specular (rgb) + shininess (a)?

UX3D-nopper commented 7 years ago

Yes it is, Please note, the specification is not yet complete.

steveghee commented 7 years ago

thanks. I suspect there's a bunch of folks who can help contribute and help chase the spec through, as we're trying to implement something behind it. We've gone forwards with some 'assumptions' based on some earlier postings and discussion on this thread, which in general look like they are in line with what you've got in the spec, namely the model is a blinnphong equivalent and the math is roughly

diffuseTerm = diffuseFactor diffuseTexture // extension ; texture is optional. specularTerm = speculatFactor specularTexture.rgb // extension shineTerm = shininessFactor shininessTexture (==specularTexture.a) // extension emissiveTerm = emissiveFactor emissiveTexture // part of core Materials spec occlusionTerm = occlusionFactor * occlusionTexture // extension

Textures are optional, and if provided, will modulate the base Factor value

color = emissiveTerm + occlusionTerm ( diffuseTerm max(N L, 0) + specularTerm max(H * N, 0)^shineTerm)

I think this is in line with what you've got in your draft, right?

lexaknyazev commented 7 years ago

occlusionTerm = occlusionFactor * occlusionTexture // extension

Occlusion is a part of core materials spec

steveghee commented 7 years ago

thanks for pointing it out. copy/paste error on my behalf.

UX3D-nopper commented 7 years ago

Please fork my current status at GitHub, add your names and add the content you need to be specified. I am quite sure, nothing will happen on this before or during SIGGRAPH. But as soon as we are in "normal" mode, I am quite sure we can ratify this.

andreasplesch commented 7 years ago

Here is a nomenclature comment concerning 'Blinn', 'Phong', 'BlinnPhong' which is probably the result of my ignorance but which I could not resolve after going through the Blinn, 1977 paper: http://dl.acm.org/citation.cfm?id=563893 https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_materials_common#blinn cites a formula which in the paper is actually being attributed to Phong, 1975. So this is confusing. My working hypothesis is that the formula is a streamlined reformulation of the original Phong, 1975, formulation and is what elsewhere is referred to as 'BlinnPhong' ? So this would mean that 'Blinn' (in the draft) and 'BlinnPhong' (here) refers to the same method ? https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_materials_common#phong is then perhaps the original Phong, 1975 formulation ? But then why have two essentially identical techniques ? (Perhaps for historical reasons). Finally, the Blinn, 1977 paper actually is about and promotes the Torrance-Sparrow, 1967 model. So 'Blinn' in discussions may actually refer to 'Blinn-Torrance-Sparrow'? Since 'Blinn-Torrance-Sparrow' was mentioned here, should it become a distinct Material Common extension ? It looks like this extension will be exclusively about a single shading method, eg. 'BlinnPhong'. I thought providing the formula and shininess implementation note in the current draft were very helpful to minimize confusion.

McNopper commented 7 years ago

I did not do so much deep research, but it will be the Blinn-Phong lighting model, as it is the default shading model for - fixed - OpenGL and DirectX: https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model People are "visually" used to it.

For the future, if someone really needs Phong: https://en.wikipedia.org/wiki/Phong_reflection_model we can create the cmnPhong extension.

But from my undersatnding, in the old spec, Blinn should be called BlinnPhong. So the Blinn in the old spec will be BlinnPhong in the current/future one.

Also, it seems that you already invested much time in it. So my suggestion: Fork my repo, add your name and your specification elements you want to have in. Make a pull request to the offical repository and finally we can end this discussion :-)

andreasplesch commented 7 years ago

Thanks for the links which confirm what I had started to put together. Well, it looks like if you have to start to work with shaders and want to understand what some code is trying to do, you end up with reading the source texts anyways. Not sure if there is a need to end discussions but I can see if I can add anything to the existing language. Incremental improvement may be an appropriate strategy.