<p>After spending a hard time to understand the way <a href="https://computergraphics.stackexchange.com/a/3624/361">how the binary buffers work in the gltf files</a> I finally managed to generate a truely <em>minimal</em> gltf file. It's a single yellow triangle (<a href="http://5chdn.github.io/gltf-tiles-loader-poc/" rel="nofollow noreferrer">demo</a>). </p>

<p><a href="https://i.sstatic.net/kMZO0.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/kMZO0.png" alt="minimal triangle"></a></p>

<p>I tried to remove everything which is not needed from the gltf. This is what is required it seems (<a href="https://github.com/5chdn/gltf-tiles-loader-poc/blob/8f25b30fed2324820e0a4a8958715fa2a424305d/data/Min/glTF-Embedded/Min.gltf" rel="nofollow noreferrer">github</a>):</p>

<pre><code>{
    "accessors": {
        "accessor0": {
            "bufferView": "bufferView0",
            "byteOffset": 0,
            "componentType": 5123,
            "count": 3,
            "type": "SCALAR"
        },
        "accessor1": {
            "bufferView": "bufferView1",
            "byteOffset": 0,
            "byteStride": 12,
            "componentType": 5126,
            "count": 3,
            "max": [
                0.5,
                0.5,
                0.5
            ],
            "min": [
                0.0,
                0.0,
                0.0
            ],
            "type": "VEC3"
        }
    },
    "asset": {
        "generator": "5chdn",
        "profile": {
            "api": "WebGL",
            "version": "1.0.3"
        },
        "version": "1.0",
        "extras": {
            "description": "minimal gltf, single triangle",
            "base64encoder": "https://jsfiddle.net/opkxy0xb/",
            "stackexchange": "https://computergraphics.stackexchange.com/q/1934/361"
        }
    },
    "bufferViews": {
        "bufferView0": {
            "buffer": "Min",
            "byteLength": 6,
            "byteOffset": 0,
            "target": 34963
        },
        "bufferView1": {
            "buffer": "Min",
            "byteLength": 36,
            "byteOffset": 6,
            "target": 34962
        }
    },
    "buffers": {
        "Min": {
            "bytelength": 42,
            "type": "arraybuffer",
            "uri": "data:application/octet-stream;base64,AAABAAIArK34PnZxmz29UhY9T6+UPXuD7z64QAI9UWuaPW/wBT3ysPA+"
        }
    },
    "materials": {
        "effect0": {
            "values": {
                "emission": [
                    0.8,
                    0.8,
                    0.0,
                    1.0
                ]
            },
            "technique": "technique0"
        }
    },
    "meshes": {
        "mesh0": {
            "name": "Triangle",
            "primitives": [
                {
                    "attributes": {
                        "POSITION": "accessor1"
                    },
                    "indices": "accessor0",
                    "material": "effect0",
                    "mode": 4
                }
            ]
        }
    },
    "nodes": {
        "node0": {
            "matrix": [
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                1
            ],
            "meshes": [
                "mesh0"
            ],
            "name": "TriangleMesh"
        }
    },
    "programs": {
        "program0": {
            "attributes": [
                "a_position"
            ],
            "fragmentShader": "fragmentShader0",
            "vertexShader": "vertexShader0"
        }
    },
    "scenes": {
        "scene0": {
            "nodes": [
                "node0"
            ]
        }
    },
    "shaders": {
        "vertexShader0": {
            "type": 35633,
            "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsNCmF0dHJpYnV0ZSB2ZWMzIGFfcG9zaXRpb247DQp2b2lkIG1haW4odm9pZCkNCnsNCmdsX1Bvc2l0aW9uID0gdV9wcm9qZWN0aW9uTWF0cml4ICogdV9tb2RlbFZpZXdNYXRyaXggKiB2ZWM0KGFfcG9zaXRpb24sMS4wKTsNCn0="
        },
        "fragmentShader0": {
            "type": 35632,
            "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdW5pZm9ybSB2ZWM0IHVfZW1pc3Npb247DQp2b2lkIG1haW4odm9pZCkNCnsNCmdsX0ZyYWdDb2xvciA9IHVfZW1pc3Npb247DQp9"
        }
    },
    "techniques": {
        "technique0": {
            "attributes": {
                "a_position": "position"
            },
            "parameters": {
                "modelViewMatrix": {
                    "semantic": "MODELVIEW",
                    "type": 35676
                },
                "projectionMatrix": {
                    "semantic": "PROJECTION",
                    "type": 35676
                },
                "emission": {
                    "type": 35666
                },
                "position": {
                    "semantic": "POSITION",
                    "type": 35665
                }
            },
            "program": "program0",
            "states": {
                "enable": [
                    2884,
                    2929
                ]
            },
            "uniforms": {
                "u_modelViewMatrix": "modelViewMatrix",
                "u_projectionMatrix": "projectionMatrix",
                "u_emission": "emission"
            }
        }
    }
}
</code></pre>

<p>A good starting point was the <a href="https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a" rel="nofollow noreferrer">Appendix A of the gltf Specification</a> which defines a default material and shaders. All I had to do was adding the scene description and the buffers.</p>

CC BY-SA 3.0
2016-06-15T20:50:54.617Z
2016-11-28T09:01:59.490Z
2017-04-13T13:00:43.660Z
q9f
<p>While creating a set of glTF models for a tutorial, I also intended to create <strong>THE</strong> minimal glTF file. </p>

<hr>

<p><strong>Update:</strong> The following referred to glTF 1.0/1.1. See below for an update of this example to glTF 2.0.</p>

<hr>

<p>As already mentioned in the <a href="https://computergraphics.stackexchange.com/a/3628/1649">answer by 5chdn</a>, one issue may be the <em>material</em>. According to the <a href="https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a" rel="nofollow noreferrer">Appendix A: Default Material</a> of the specification, an asset that does not contain a material should be rendered with a <em>default</em> material that simply shows the object in a uniform, 50% gray color. </p>

<p>Some viewers might not support this, and even if they do, there have been some minor subtleties in the spec regarding this point: In glTF 1.0, it was still necessary to define an "empty" material, because the <code>mesh.primitive.material</code> property was not yet optional. But this should be fixed in glTF 1.1. </p>

<p>So the following should indeed be <strong>THE</strong> minimal possible glTF asset (version 1.1) :</p>

<pre><code>{
  "scenes" : {
    "scene0" : {
      "nodes" : [ "node0" ]
    }
  },
  "nodes" : {
    "node0" : {
      "meshes" : [ "mesh0" ]
    }
  },

  "meshes" : {
    "mesh0" : {
      "primitives" : [ {
        "attributes" : {
          "POSITION" : "positionsAccessor"
        }
      } ]
    }
  },

  "buffers" : {
    "buffer0" : {
      "uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA",
      "byteLength" : 36
    }
  },
  "bufferViews" : {
    "positionsBufferView" : {
      "buffer" : "buffer0",
      "byteOffset" : 0,
      "byteLength" : 36,
      "target" : 34962
    }
  },
  "accessors" : {
    "positionsAccessor" : {
      "bufferView" : "positionsBufferView",
      "byteOffset" : 0,
      "componentType" : 5126,
      "count" : 3,
      "type" : "VEC3",
      "max" : [ 1.0, 1.0, 0.0 ],
      "min" : [ 0.0, 0.0, 0.0 ]
    }
  },

  "asset" : {
    "version" : "1.1"
  }
}
</code></pre>

<p>It also shows a single triangle:</p>

<p><a href="https://i.sstatic.net/ElVqk.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ElVqk.png" alt="TriangleWithoutIndices"></a></p>

<p>The version without embedded buffers is available at <a href="https://github.com/javagl/gltfTutorialModels" rel="nofollow noreferrer">https://github.com/javagl/gltfTutorialModels</a> , as well as a triangle with indices, at <a href="https://github.com/javagl/gltfTutorialModels/tree/master/Triangle" rel="nofollow noreferrer">https://github.com/javagl/gltfTutorialModels/tree/master/Triangle</a> </p>

<hr>

<p><strong>Update for glTF 2.0:</strong></p>

<hr>

<p>The concepts and top-level elements of glTF 2.0 are basically the same as for glTF 1.0. But there still have been some changes in the format. Most importantly (for this small example), the top-level dictionaries are now <em>arrays</em>. The following is the same "Triangle" model as above, updated accordingly:</p>

<pre><code>{
   "scenes":[
      {
         "nodes":[ 0 ]
      }
   ],
   "nodes":[
      {
         "mesh":0
      }
   ],
   "meshes":[
      {
         "primitives":[
            {
               "attributes":{
                  "POSITION":1
               },
               "indices":0
            }
         ]
      }
   ],
   "buffers":[
      {
         "uri":"data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=",
         "byteLength":44
      }
   ],
   "bufferViews":[
      {
         "buffer":0,
         "byteOffset":0,
         "byteLength":6,
         "target":34963
      },
      {
         "buffer":0,
         "byteOffset":8,
         "byteLength":36,
         "target":34962
      }
   ],
   "accessors":[
      {
         "bufferView":0,
         "byteOffset":0,
         "componentType":5123,
         "count":3,
         "type":"SCALAR",
         "max":[
            2
         ],
         "min":[
            0
         ]
      },
      {
         "bufferView":1,
         "byteOffset":0,
         "componentType":5126,
         "count":3,
         "type":"VEC3",
         "max":[
            1.0,
            1.0,
            0.0
         ],
         "min":[
            0.0,
            0.0,
            0.0
         ]
      }
   ],
   "asset":{
      "version":"2.0"
   }
}
</code></pre>

<p>This and other glTF sample models can be found in the <a href="https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0" rel="nofollow noreferrer">glTF sample models repository</a>.</p>

CC BY-SA 3.0
2016-11-27T14:16:49.077Z
2017-11-29T22:03:23.673Z
2017-11-29T22:03:23.673Z
Marco13
<p>You can put the data into a data uri to store the data inline in base64 format.</p>

<pre><code>"buffers": {
    "a-buffer-id": {
        "byteLength": 1024,
        "type": "arraybuffer",
        "uri"="data:application/octet-stream;base64,..."
    }
},
</code></pre>

<p>It's still a bit bloated compared to storing the data in a binary file though.</p>

CC BY-SA 3.0
2016-04-19T14:59:49.760Z
2016-04-19T14:59:49.760Z
ratchet freak
<p>I am currently looking into <a href="https://github.com/KhronosGroup/glTF/blob/master/specification/README.md" rel="nofollow">glTF</a> to use as a transfer format for my WebGL project. I already have the geometries I wish to render on my WebGL client available as preprocessed vertex and index buffers (and color buffers, but let's ignore them for now).</p>

<p>For example:</p>

<pre><code>[       // vertex buffer
  0,0,0,
  0,1,0,
  1,0,0,
  1,1,0,
]
</code></pre>

<p>And to draw simple <code>LINES</code>:</p>

<pre><code>[       // index buffer
  0,2,
  2,4,
  4,0,
  0,1,
  1,4,
]
</code></pre>

<p>I wonder how to create glTF files containing these buffers? Is this possible?</p>

<p>I want to avoid using COLLADA and <a href="https://github.com/KhronosGroup/glTF/wiki/converter" rel="nofollow">COLLADA2GLTF</a> as this would only add an additional step and might just bloat the resulting glTF files.</p>

<webgl><vertex-buffer-object><gltf><buffers>
Is it possible to create minimal glTF files with vertex and index buffers?
q9f
# Is it possible to create minimal glTF files with vertex and index buffers?

(Asked by: username_0 on 2016-01-21)

I am currently looking into [glTF](https://github.com/KhronosGroup/glTF/blob/master/specification/README.md) to use as a transfer format for my WebGL project. I already have the geometries I wish to render on my WebGL client available as preprocessed vertex and index buffers (and color buffers, but let's ignore them for now).

For example:

```
[       // vertex buffer
  0,0,0,
  0,1,0,
  1,0,0,
  1,1,0,
]

```

And to draw simple `LINES`:

```
[       // index buffer
  0,2,
  2,4,
  4,0,
  0,1,
  1,4,
]

```

I wonder how to create glTF files containing these buffers? Is this possible?

I want to avoid using COLLADA and [COLLADA2GLTF](https://github.com/KhronosGroup/glTF/wiki/converter) as this would only add an additional step and might just bloat the resulting glTF files.

**Tags:** webgl, vertex-buffer-object, gltf, buffers


---

## 3 answers

### Answer by username_0 on 2016-06-15. Score: 3 | Accepted answer

After spending a hard time to understand the way [how the binary buffers work in the gltf files](https://computergraphics.stackexchange.com/a/3624/361) I finally managed to generate a truely *minimal* gltf file. It's a single yellow triangle ([demo](http://5chdn.github.io/gltf-tiles-loader-poc/)).

[![minimal triangle](https://i.sstatic.net/kMZO0.png)](https://i.sstatic.net/kMZO0.png)

I tried to remove everything which is not needed from the gltf. This is what is required it seems ([github](https://github.com/5chdn/gltf-tiles-loader-poc/blob/8f25b30fed2324820e0a4a8958715fa2a424305d/data/Min/glTF-Embedded/Min.gltf)):

```
{
    "accessors": {
        "accessor0": {
            "bufferView": "bufferView0",
            "byteOffset": 0,
            "componentType": 5123,
            "count": 3,
            "type": "SCALAR"
        },
        "accessor1": {
            "bufferView": "bufferView1",
            "byteOffset": 0,
            "byteStride": 12,
            "componentType": 5126,
            "count": 3,
            "max": [
                0.5,
                0.5,
                0.5
            ],
            "min": [
                0.0,
                0.0,
                0.0
            ],
            "type": "VEC3"
        }
    },
    "asset": {
        "generator": "5chdn",
        "profile": {
            "api": "WebGL",
            "version": "1.0.3"
        },
        "version": "1.0",
        "extras": {
            "description": "minimal gltf, single triangle",
            "base64encoder": "https://jsfiddle.net/opkxy0xb/",
            "stackexchange": "https://computergraphics.stackexchange.com/q/1934/361"
        }
    },
    "bufferViews": {
        "bufferView0": {
            "buffer": "Min",
            "byteLength": 6,
            "byteOffset": 0,
            "target": 34963
        },
        "bufferView1": {
            "buffer": "Min",
            "byteLength": 36,
            "byteOffset": 6,
            "target": 34962
        }
    },
    "buffers": {
        "Min": {
            "bytelength": 42,
            "type": "arraybuffer",
            "uri": "data:application/octet-stream;base64,AAABAAIArK34PnZxmz29UhY9T6+UPXuD7z64QAI9UWuaPW/wBT3ysPA+"
        }
    },
    "materials": {
        "effect0": {
            "values": {
                "emission": [
                    0.8,
                    0.8,
                    0.0,
                    1.0
                ]
            },
            "technique": "technique0"
        }
    },
    "meshes": {
        "mesh0": {
            "name": "Triangle",
            "primitives": [
                {
                    "attributes": {
                        "POSITION": "accessor1"
                    },
                    "indices": "accessor0",
                    "material": "effect0",
                    "mode": 4
                }
            ]
        }
    },
    "nodes": {
        "node0": {
            "matrix": [
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                1
            ],
            "meshes": [
                "mesh0"
            ],
            "name": "TriangleMesh"
        }
    },
    "programs": {
        "program0": {
            "attributes": [
                "a_position"
            ],
            "fragmentShader": "fragmentShader0",
            "vertexShader": "vertexShader0"
        }
    },
    "scenes": {
        "scene0": {
            "nodes": [
                "node0"
            ]
        }
    },
    "shaders": {
        "vertexShader0": {
            "type": 35633,
            "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsNCmF0dHJpYnV0ZSB2ZWMzIGFfcG9zaXRpb247DQp2b2lkIG1haW4odm9pZCkNCnsNCmdsX1Bvc2l0aW9uID0gdV9wcm9qZWN0aW9uTWF0cml4ICogdV9tb2RlbFZpZXdNYXRyaXggKiB2ZWM0KGFfcG9zaXRpb24sMS4wKTsNCn0="
        },
        "fragmentShader0": {
            "type": 35632,
            "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdW5pZm9ybSB2ZWM0IHVfZW1pc3Npb247DQp2b2lkIG1haW4odm9pZCkNCnsNCmdsX0ZyYWdDb2xvciA9IHVfZW1pc3Npb247DQp9"
        }
    },
    "techniques": {
        "technique0": {
            "attributes": {
                "a_position": "position"
            },
            "parameters": {
                "modelViewMatrix": {
                    "semantic": "MODELVIEW",
                    "type": 35676
                },
                "projectionMatrix": {
                    "semantic": "PROJECTION",
                    "type": 35676
                },
                "emission": {
                    "type": 35666
                },
                "position": {
                    "semantic": "POSITION",
                    "type": 35665
                }
            },
            "program": "program0",
            "states": {
                "enable": [
                    2884,
                    2929
                ]
            },
            "uniforms": {
                "u_modelViewMatrix": "modelViewMatrix",
                "u_projectionMatrix": "projectionMatrix",
                "u_emission": "emission"
            }
        }
    }
}

```

A good starting point was the [Appendix A of the gltf Specification](https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a) which defines a default material and shaders. All I had to do was adding the scene description and the buffers.


---

### Answer by username_1 on 2016-11-27. Score: 6

While creating a set of glTF models for a tutorial, I also intended to create **THE** minimal glTF file.

---

**Update:** The following referred to glTF 1.0/1.1. See below for an update of this example to glTF 2.0.

---

As already mentioned in the [answer by 5chdn](https://computergraphics.stackexchange.com/a/3628/1649), one issue may be the *material*. According to the [Appendix A: Default Material](https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a) of the specification, an asset that does not contain a material should be rendered with a *default* material that simply shows the object in a uniform, 50% gray color.

Some viewers might not support this, and even if they do, there have been some minor subtleties in the spec regarding this point: In glTF 1.0, it was still necessary to define an "empty" material, because the `mesh.primitive.material` property was not yet optional. But this should be fixed in glTF 1.1.

So the following should indeed be **THE** minimal possible glTF asset (version 1.1) :

```
{
  "scenes" : {
    "scene0" : {
      "nodes" : [ "node0" ]
    }
  },
  "nodes" : {
    "node0" : {
      "meshes" : [ "mesh0" ]
    }
  },

  "meshes" : {
    "mesh0" : {
      "primitives" : [ {
        "attributes" : {
          "POSITION" : "positionsAccessor"
        }
      } ]
    }
  },

  "buffers" : {
    "buffer0" : {
      "uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA",
      "byteLength" : 36
    }
  },
  "bufferViews" : {
    "positionsBufferView" : {
      "buffer" : "buffer0",
      "byteOffset" : 0,
      "byteLength" : 36,
      "target" : 34962
    }
  },
  "accessors" : {
    "positionsAccessor" : {
      "bufferView" : "positionsBufferView",
      "byteOffset" : 0,
      "componentType" : 5126,
      "count" : 3,
      "type" : "VEC3",
      "max" : [ 1.0, 1.0, 0.0 ],
      "min" : [ 0.0, 0.0, 0.0 ]
    }
  },

  "asset" : {
    "version" : "1.1"
  }
}

```

It also shows a single triangle:

[![TriangleWithoutIndices](https://i.sstatic.net/ElVqk.png)](https://i.sstatic.net/ElVqk.png)

The version without embedded buffers is available at <https://github.com/javagl/gltfTutorialModels> , as well as a triangle with indices, at <https://github.com/javagl/gltfTutorialModels/tree/master/Triangle>

---

**Update for glTF 2.0:**

---

The concepts and top-level elements of glTF 2.0 are basically the same as for glTF 1.0. But there still have been some changes in the format. Most importantly (for this small example), the top-level dictionaries are now *arrays*. The following is the same "Triangle" model as above, updated accordingly:

```
{
   "scenes":[
      {
         "nodes":[ 0 ]
      }
   ],
   "nodes":[
      {
         "mesh":0
      }
   ],
   "meshes":[
      {
         "primitives":[
            {
               "attributes":{
                  "POSITION":1
               },
               "indices":0
            }
         ]
      }
   ],
   "buffers":[
      {
         "uri":"data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=",
         "byteLength":44
      }
   ],
   "bufferViews":[
      {
         "buffer":0,
         "byteOffset":0,
         "byteLength":6,
         "target":34963
      },
      {
         "buffer":0,
         "byteOffset":8,
         "byteLength":36,
         "target":34962
      }
   ],
   "accessors":[
      {
         "bufferView":0,
         "byteOffset":0,
         "componentType":5123,
         "count":3,
         "type":"SCALAR",
         "max":[
            2
         ],
         "min":[
            0
         ]
      },
      {
         "bufferView":1,
         "byteOffset":0,
         "componentType":5126,
         "count":3,
         "type":"VEC3",
         "max":[
            1.0,
            1.0,
            0.0
         ],
         "min":[
            0.0,
            0.0,
            0.0
         ]
      }
   ],
   "asset":{
      "version":"2.0"
   }
}

```

This and other glTF sample models can be found in the [glTF sample models repository](https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0).


---

### Answer by username_2 on 2016-04-19. Score: 4

You can put the data into a data uri to store the data inline in base64 format.

```
"buffers": {
    "a-buffer-id": {
        "byteLength": 1024,
        "type": "arraybuffer",
        "uri"="data:application/octet-stream;base64,..."
    }
},

```

It's still a bit bloated compared to storing the data in a binary file though.


---

