Skip to content

Extensions

David Komer edited this page May 26, 2018 · 14 revisions

Extensions must satisfy the GLTF_PARSE_Extension interface. See the interface itself for exact typing, what follows is the reason why and where comes into play.

Note that as of now, code for extensions must be built-in. Arbitrary extensions cannot be added on the fly (though this might change in the future)

Setting Pure3D Scene/Nodes

The following functions are all about extracting the info from the original GLTF file and injecting it into the Pure3D Scene/Nodes objects so that the core pipeline does not need to hunt through the original GLTF at all.

Similarly, since the data object cannot be passed over the wire, the relevant info must be on the pure3d scene, not data.original (i.e. even if parsing the original weren't a heavy cost, it isn't there to work with post-serialization).

loadAssets()

If the extension needs external files - json, textures, etc., this happens at the same part of the pipeline as the main Gltf file loading. There's almost never a need to write to anywhere other than the GltfDataAssets.extensions[name] object. This happens immediately after the core GltfDataAssets is loaded.

createData()

Appends the GltfData with extension-specific data, derived from the GltfDataAssets. There's almost never a need to write to anywhere other than the GltfData.extensions[name] object. This happens immediately after the core GltfData is created.

createScene()

Typically this is only used for items that are defined in the GltfScene itself. Similar to the scene itself, the data must be simple primitives. This happens when GltfBridge is requested to create a scene.

createNode()

Similar to GltfScene, but per-node, and it happens at original parsing time.

Dynamic Shader Generation

shaderConfig is an object that sits on each primitive and it is used to indicate whether a shader needs to be re-generated or not. The shape of this object is hardcoded to fit with the custom hash function, and it should not be changed by the calling code. Neither should it be removed, as doing so would make it impossible for the renderer to know what shader to use for rendering the primitive.

In other words, defining the data of the shaderConfig object, whether at init or runtime, is done by writing code for the functions in the extensions interface, listed below.

initialShaderConfig()

Appends the GltfShaderConfig option with custom shader config info. Only called once at init.

runtimeShaderConfig()

Appends the GltfShaderConfig option with custom shader config info. Called at init, and then whenever GltfBridge.updateShaderConfigs() or gltf_updatePrimitiveShaderConfig() is called

shaderSource()

Appends vertex and fragment shader sources, with the given shaderConfig. Usually two techniques are used:

  1. Generating ifdefs
  2. Replacing placeholders (like %LIGHTING_VARS%)

Both of these require that the original shader code be written with these in place (in other words the original glsl shader code must be written as so-called uber-shaders with the extension code opted-in via these techniques)

Marshalling (TODO)

The following are to allow the extensions to be marshalled

  1. marshallScene

TODO

  1. unmarshallScene

TODO