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

Updates to KHR_technique_webgl extension spec #1296

Merged
merged 18 commits into from Jul 21, 2018

Conversation

ggetz
Copy link
Contributor

@ggetz ggetz commented Mar 28, 2018

Fixes #1217

Makes the suggestion listed in the above issue, with the most significant changes being:

  • Inline technique.parameters in technique.attributes and technique.uniforms to reduce indirection, and allow the objects for each to be more specific to attributes and uniforms use
  • Don't allow default value for attributes, only uniforms.
  • Include list of WebGL 1.0 extensions in program.glExtensions
  • Remove render states.
  • KHR_techniques_webgl instead of KHR_technique_webgl
  • Update README
    • Mentioning targeting WebGL 1.0
    • Address material extension specifically

TODO:

  • Add contributors to "Contributors" section
  • Change "Status" to "Complete" once ready

@lilleyse let me know if you have any initial feedback.

@ggetz ggetz mentioned this pull request Mar 28, 2018
5 tasks
@pjcozzi
Copy link
Member

pjcozzi commented Mar 28, 2018

@ggetz congrats on your first glTF extension work!

@donmccurdy @lexaknyazev would love your feedback here.

@lilleyse
Copy link
Contributor

@ggetz I started to review this afternoon and should have some feedback posted tomorrow.

Copy link
Contributor

@donmccurdy donmccurdy left a comment

Choose a reason for hiding this comment

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

Thanks for getting this underway!

Could I talk you into writing a simple stub example? That would help me get a clearer picture of this.

About render states — Tilt Brush will need additive blending. Sketchfab is currently falling back to alpha blending for models that use additive transparency as well. Including blend states in KHR_techniques_webgl might be the quickest path to supporting that. But in the long run, I would prefer to see a GLSL-agnostic way to specify widely-supported blend operations, e.g. a KHR_blending extension... Preferences? Including blend states here would not rule out a separate extension later, but I realize time/energy are limited resources. 🙂

/cc @stevesan


#### Attributes

The `attributes` dictionary property specifies the vertex attributes of the data that will be passed to the shader. Each attribute's name is a string that corresponds to the attribute name in the GLSL source code. Each attribute's value is an [attribute](#reference-technique.attributes) object, where the type (GL types such as a floating point number, vector, texture, etc.) and semantic of the attribute is defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: perhaps say "Each attribute's key" or "Each attribute's index" rather than "name", to disambiguate from the ".name" properties used for human-readable labels throughout glTF.

@@ -310,7 +236,8 @@ Shader source files are stored in the asset's `shaders` dictionary property, whi
]
}
```
### Properties Reference

## Properties Reference
Copy link
Contributor

Choose a reason for hiding this comment

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

In this section, .programs, .shaders, and .techniques are now arrays with indices rather than an "ID in the global glTF namespace".


#### Values

The `values` property defines the list of values, each of which is passed to the technique uniform of the same name, and when specified, overrides the corresponding uniform `value`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Since neither .values here nor uniform.value below are required, perhaps we need to say that at least one of the two must be present?

@ggetz
Copy link
Contributor Author

ggetz commented Mar 30, 2018

@donmccurdy

Could I talk you into writing a simple stub example? That would help me get a clearer picture of this.

When you say simple stub, I assume you mean the entire (but simple) glTF?

l. Including blend states in KHR_techniques_webgl might be the quickest path to supporting that. But in the long run, I would prefer to see a GLSL-agnostic way to specify widely-supported blend operations, e.g. a KHR_blending extension...

I agree the more agnostic approach is best in the long run. If tilt brush needs it now, and it doesn't rule out the longer-term approach, I'm fine with addressing it in this extension.

@donmccurdy
Copy link
Contributor

When you say simple stub, I assume you mean the entire (but simple) glTF?

Yes, not necessarily including buffers or even meant to be rendered, but an example that shows all of the top-level properties cross-referencing one another.

Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

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

Looks good overall!

@@ -1,4 +1,4 @@
# KHR_technique_webgl
# KHR_techniques_webgl
Copy link
Contributor

Choose a reason for hiding this comment

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

Rename all files to KHR_techniques_webgl as well

@@ -1,4 +1,4 @@
# KHR_technique_webgl
# KHR_techniques_webgl

## Contributors
Copy link
Contributor

Choose a reason for hiding this comment

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

Add yourself and @lexaknyazev to the contributors section. Create a TODO item in the PR description to add others as we go.

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps add a copyright notice (and appendix) like the Draco extension.

General question: should the copyright notice be added to pbrSpecularGlossiness as well?

@@ -1,4 +1,4 @@
# KHR_technique_webgl
# KHR_techniques_webgl

## Contributors

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what should go under the Status heading initially, but add a TODO item to change this to "Complete" once ready.

* [`functions`](#reference-technique.states.functions)

* [`attributes`](#reference-technique.attributes)
* [`uniforms`](#reference-technique.uniforms)

## Known Implementations
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see this heading in the other extensions so it can be removed.

* [`functions`](#reference-technique.states.functions)

* [`attributes`](#reference-technique.attributes)
* [`uniforms`](#reference-technique.uniforms)

## Known Implementations
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps add the webgl spec to the References section.


### Extending Materials

If a `material` contains an `extensions` property and the `extensions` property defines its `KHR_techniques_webgl` property, then the specified shading technique can be used, as specified in the asset's `techniques`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider tweaking the wording to read more like https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness#extending-materials

, as specified in the asset's techniques.

This could be removed since it is described in the next section.


#### Attributes

The `attributes` dictionary property specifies the vertex attributes of the data that will be passed to the shader. Each attribute's name is a string that corresponds to the attribute name in the GLSL source code. Each attribute's value is an [attribute](#reference-technique.attributes) object, where the type (GL types such as a floating point number, vector, texture, etc.) and semantic of the attribute is defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to the other comment, remove texture.


If no `node` property is supplied for a semantic, the semantic is implied in a context-specific manner: either to the node which is being rendered, or in the case of camera-specific semantics, to the current camera. In the following fragment, which defines a parameter named `projectionMatrix` that is derived from the implementation's projection matrix, the semantic would be applied to the camera.
In the above example, the uniform `u_light0Transform` defines the `MODELVIEW` semantic, which corresponds to the world space position of the node referenced in the property `node`, in this case the node `1`, which refers to the id of a node that contains a light source.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should world space be eye space?

If no `node` property is supplied for a semantic, the semantic is implied in a context-specific manner: either to the node which is being rendered, or in the case of camera-specific semantics, to the current camera. In the following fragment, which defines a parameter named `projectionMatrix` that is derived from the implementation's projection matrix, the semantic would be applied to the camera.
In the above example, the uniform `u_light0Transform` defines the `MODELVIEW` semantic, which corresponds to the world space position of the node referenced in the property `node`, in this case the node `1`, which refers to the id of a node that contains a light source.

If no `node` property is supplied for a semantic, the semantic is implied in a context-specific manner: either to the node which is being rendered, or in the case of camera-specific semantics, to the current camera. In the following fragment, which defines a uniform named `u_projectionMatrix` that is derived from the implementation's projection matrix, the semantic would be applied to the camera.
Copy link
Contributor

Choose a reason for hiding this comment

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

Change semantic to uniform:

If no node property is supplied for a uniform

#### Programs

GLSL shader programs are stored in the asset's `programs` property. This property contains one or more objects, one for each program.

Each shader program includes an `attributes` property, which specifies the vertex attributes that will be passed to the shader, and the properties `fragmentShader` and `vertexShader`, which reference the files for the fragment and vertex shader GLSL source code, respectively.
Each shader program includes an `attributes` property, which specifies the vertex attributes that will be passed to the shader, and the properties `fragmentShader` and `vertexShader`, which reference the files for the fragment and vertex shader GLSL source code, respectively, as defined the id of the item in the `shaders` dictionary property.
Copy link
Contributor

Choose a reason for hiding this comment

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

as defined the id of the item in the shaders dictionary property.

This terminology should be tweaked since it is an index in an array instead of an id of a dictionary.

@donmccurdy donmccurdy mentioned this pull request Mar 31, 2018
4 tasks
@donmccurdy
Copy link
Contributor

Let's see if we can do blending in parallel, but keep it separate from this extension. I've started a thread for EXT_blend in #1302.

@ggetz
Copy link
Contributor Author

ggetz commented Apr 10, 2018

Thanks @donmccurdy and @lilleyse ! I've updated based on your comments, let me know if you have anymore feedback.

@donmccurdy
Copy link
Contributor

I think #1279 still applies here, do we want to fix that up in this PR?

@ggetz
Copy link
Contributor Author

ggetz commented Apr 12, 2018

@donmccurdy The one difference between arrayValues and this implementation is that we no longer accept strings as values, and instead use textureInfo to reference textures, see #1296 (comment)

@lilleyse
Copy link
Contributor

In https://github.com/KhronosGroup/glTF/tree/master/extensions rename KHR_technique_webgl to KHR_techniques_webgl.

@lilleyse
Copy link
Contributor

Rename material.KHR_technique_webgl.schema.json to material.KHR_techniques_webgl.schema.json

Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

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

Looks really good @ggetz. Mostly minor points from me.

@@ -0,0 +1,273 @@

Copy link
Contributor

Choose a reason for hiding this comment

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

While this is an abridged example, KHR_techniques_webgl should be added to extensionsUsed and extensionsRequired.


This extension specification is targeting WebGL 1.0, and can be supported in any WebGL 1.0-based engine if the device supports the necessary WebGL extensions.

* **Abridged example glTF**: [sample_techniques.gltf](examples/sample_techniques.json)
Copy link
Contributor

Choose a reason for hiding this comment

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

The link should be examples/sample_techniques.gltf


#### Values

The `values` dictionary property defines the uniform values of a [`technique.uniform`](#Uniforms) of the same key, and when specified, overrides the corresponding uniform `value`. The value supplied must conform to the `type` and `count` properties, if present, of the corresponding `Uniform` object, and must be present if no `value` is supplied in the referenced `Uniform` object.
Copy link
Contributor

Choose a reason for hiding this comment

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

The link needs to be lowercase #uniforms to go to the section header. (A github thing?)


#### Attributes

The `attributes` dictionary property specifies the vertex attributes of the data that will be passed to the shader. Each attribute's key is a string that corresponds to the attribute name in the GLSL source code. Each attribute's value is an [attribute](#reference-technique.attributes) object, where the type (GL types such as a floating point number, vector, etc.) and semantic of the attribute is defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

The #reference-technique.attributes link isn't going to the section correctly.


#### Uniforms

The `uniforms` dictionary property specifies the uniform variables that will be passed to the shader. Each uniform's key is a string that corresponds to the uniform name in the GLSL source code. Each uniform's value is a string that references a [uniform](#reference-technique.uniforms) object, where the type (GL types such as a floating point number, vector, etc.) and potentially the semantic and default value of the uniform is defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment for #reference-technique.uniforms


* **JSON schema**: [material.KHR_technique_webgl.schema.json](schema/material.KHR_technique_webgl.schema.json)

### khr_techniques_webgl.material.extension.technique :white_check_mark:
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it fine to drop the khr_techniques_webgl.material.extension. prefix for these? It looks like KHR_materials_pbrSpecularGlossiness doesn't have the prefix.

"additionalProperties" : {
"$ref" : "uniform.value.schema.json"
},
"default" : {},
Copy link
Contributor

Choose a reason for hiding this comment

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

I forget if this came up before, but is to safe to just remove "default" : {} throughout?

"type" : "object",
"description" : "A dictionary object of `Attribute` objects.",
"properties" : {
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Throughout, for empty property objects just condense to a single line: "properties" : {},

]
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Add newline.

"$ref" : "textureInfo.schema.json"
}
]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Add newline.

@ggetz
Copy link
Contributor Author

ggetz commented Apr 23, 2018

Thanks @lilleyse !

Addressed your comments, should we address these TODO items now then? Who all should be added to contributors?

  • Add contributors to "Contributors" section
  • Change "Status" to "Complete" once ready

"type" : "object",
"description" : "A dictionary object of `Uniform` objects.",
"properties" : {
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Change to "properties" : {}

"type" : "object",
"description" : "Dictionary object of uniform values.",
"properties" : {
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Change to "properties" : {}


* **JSON schema**: [glTF.KHR_techniques_webgl.schema.json](schema/glTF.KHR_techniques_webgl.schema.json)

### khr_techniques_webgl.gltf.extension.programs :white_check_mark:
Copy link
Contributor

Choose a reason for hiding this comment

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

I forgot to mention, also remove the khr_techniques_webgl.gltf.extension. prefixes in this section. Related to #1296 (comment)


Technique uniforms may also optionally define a *semantic*, an enumerated value describing how the runtime is to interpret the data to be passed to the shader.

In the above example, the uniform `u_light0Transform` defines the `MODEL` semantic, which corresponds to the world space position of the node referenced in the property `node`, in this case the node `1`, which refers to the id of a node that contains a light source.
Copy link
Contributor

Choose a reason for hiding this comment

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

@lilleyse
Copy link
Contributor

Addressed your comments, should we address these TODO items now then? Who all should be added to contributors?

I wonder if at least some of the glTF 1.0 contributors should be added here since it borrows from the 1.0 spec. Maybe @pjcozzi?

Change "Status" to "Complete" once ready

This one could be addressed now.

@lilleyse
Copy link
Contributor

Is anyone else interested in reviewing this? @lexaknyazev, @pjcozzi, @stevesan?

@lexaknyazev
Copy link
Member

Will do by tomorrow's call.

@pjcozzi
Copy link
Member

pjcozzi commented Apr 24, 2018

I won't be able to review, but looks like this is getting enough attention.

For carry over credits from the 1.0 spec, probably include:

  • Remi Arnaud
  • Patrick Cozzi
  • Tony Parisi
  • Fabrice Robinet

"type" : "object",
"description" : "A shader program, including its vertex and fragment shader, and names of vertex shader attributes.",
"description" : "A shader program, including its vertex and fragment shaders, and names of vertex shader attributes.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove and names of vertex shader attributes

@ggetz
Copy link
Contributor Author

ggetz commented Jun 18, 2018

@lilleyse Updated.

@@ -6,12 +6,12 @@
* [KHR_materials_pbrSpecularGlossiness](2.0/Khronos/KHR_materials_pbrSpecularGlossiness/README.md)
* [KHR_materials_unlit](2.0/Khronos/KHR_materials_unlit/README.md)
* [KHR_draco_mesh_compression](2.0/Khronos/KHR_draco_mesh_compression/README.md)
* [KHR_techniques_webgl](2.0/Khronos/KHR_techniques_webgl/README.md)
Copy link
Member

Choose a reason for hiding this comment

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

Can we mark this as draft here and in the main extension spec and then merge this?

@ggetz
Copy link
Contributor Author

ggetz commented Jul 11, 2018

@pjcozzi Marked as draft.

Ready to merge?

@donmccurdy
Copy link
Contributor

... modifying the supplied GLSL shader code at runtime if necessary

this one's a surprise to me — is that possible in the general case?

In either case I'm OK with merging this as an updated draft.

@lexaknyazev
Copy link
Member

@donmccurdy How else could an engine pass alphaCutoff value? For WebGL 1.0 shaders, it's probably not that hard given that gl_FragColor is a fixed name.

@donmccurdy
Copy link
Contributor

donmccurdy commented Jul 11, 2018

How would an engine know whether the supplied GLSL shader code needs to be patched at all? If the GLSL contains a line like this:

if ( myDiffuseColor.a < 0.5 ) discard;

The engine can't detect that without parsing the GLSL, which I don't think is a realistic expectation. It seems more reasonable to require that the GLSL include the alphaCutoff value. If alphaCutoff in the GLSL doesn't match the material then we can claim that's invalid, even though we can't really validate it programmatically. Then clients can safely ignore alphaCutoff without modifying the GLSL.

One implication, in any case — animating material.alphaCutoff, proposed by EXT_property_animation, seems tricky.

@lexaknyazev
Copy link
Member

If the GLSL contains a line like this...

That line seems to enforce 0.5 as a hard-coded cutoff value. I don't think an engine should care about such case.

I was thinking about adding something like

if ( gl_FragColor.a < cutOffUniformOrConstant ) discard;

to the very end of fragment shader's main.

@donmccurdy
Copy link
Contributor

donmccurdy commented Jul 11, 2018

That line seems to enforce 0.5 as a hard-coded cutoff value. I don't think an engine should care about such case.

I don't follow this — if the asset contains material.alphaCutoff: 0.5, then the GLSL should contain a 0.5 somewhere, either as a hard-coded value or a constant, unless there is a particular reason to need a uniform. And in any case, it seems like a decision that should be made by the exporter.

Even detecting the end of the fragment shader's main is not trivial — you need to count brackets and deal with multi-line comments. If our general philosophy is to put most responsibility on the exporter, why shouldn't we require the exporter to include the alphaCutoff in the GLSL if it's also writing it to the material entry? This gives the flexibility to use a uniform, a constant, or a hard-coded value as necessary.

One alternative might be to define a technique uniform semantic, ALPHACUTOFF, which is required to be present in this case.

@lexaknyazev
Copy link
Member

My understanding is that there could be one shader used by different materials that define different alphaCutoff values.

Requiring a pre-defined uniform name would definitely simplify engines.

@pjcozzi
Copy link
Member

pjcozzi commented Jul 18, 2018

@ggetz what is the latest here? Is this close to being merged as a draft?

@ggetz
Copy link
Contributor Author

ggetz commented Jul 18, 2018

@pjcozzi We may want to discuss the implications of the material properties interacting with the shaders more, however, I think the consensus is this is good to merge as a draft.

@ggetz
Copy link
Contributor Author

ggetz commented Jul 18, 2018

Removed the requirement to have the engine patch the shader at runtime. Instead, require shaders to respect these values, and specified the ALPHACUTOFF uniform semantic for passing the value of material.alphaCutoff' to the shader. Also added an implementation note for how to ensure the value of material.doubleSided` is respected.

> }
> ```

The value of a material `alphaCutoff` property should be passed to the technique shaders using a uniform with the semantic `ALPHACUTOFF`. A uniform with this semantic will ignore a supplied default value and the corresponding material uniform value.
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps say the uniform must be consistent with alphaCutoff? Then the client can treat it as a normal uniform, and I think it is more intuitive.

> {
> normal = -normal;
> }
> ```
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this affects tangent-space calculations, too. See: https://github.com/mrdoob/three.js/blob/2f207a5d7167884d002a697b6cb15306cf621924/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl#L34

But technically this applies to engines that don't support KHR_techniques_webgl, so maybe it would be better to specify it in the core spec and reference that here.

@donmccurdy
Copy link
Contributor

Added a couple more comments but I don't think they'd prevent this from being merged as a draft.

@pjcozzi
Copy link
Member

pjcozzi commented Jul 19, 2018

@ggetz please let me know when you want this merged.

@ggetz
Copy link
Contributor Author

ggetz commented Jul 19, 2018

Modified the Shader Requirement implementation note to instead include a TODO to reference once included in the main spec.

@pjcozzi I think this is good to merge.

@pjcozzi
Copy link
Member

pjcozzi commented Jul 21, 2018

Thanks @ggetz!

@pjcozzi pjcozzi merged commit 2ac2fc2 into KhronosGroup:master Jul 21, 2018
@ggetz ggetz deleted the techniques branch July 23, 2018 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants