# Three.js and Twgl.js

**URL:** <https://discourse.threejs.org/t/three-js-and-twgl-js/9582>\
**Category:** Questions\
**Tags:** shaders\
**Created:** [September 10, 2019, 5:43pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582 "2019-09-10T17:43:13Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![3DGraphics](https://avatars.discourse-cdn.com/v4/letter/3/97f17d/32.png) [@3DGraphics](https://discourse.threejs.org/u/3DGraphics)\
**Post date:** [September 10, 2019, 5:43pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/1 "2019-09-10T17:43:13Z")

</div>

I have an application that requires me to write a vertex and fragment shader for Twgl.js (for text rendering). I’m not interested in creating a shader material. I want to know if I create shaders for Twgl.js will still be able to use Three.js native materials and geometries?

---

<div class="post-metadata">

**Author:** ![marquizzo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/marquizzo/32/25192_2.png) [@marquizzo](https://discourse.threejs.org/u/marquizzo)\
**Post date:** [September 10, 2019, 6:47pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/2 "2019-09-10T18:47:35Z")

</div>

> [@3DGraphics](#):
>
> if I create shaders for Twgl.js will still be able to use Three.js native materials and geometries?

No, you won’t be able to. [TWGL.js uses different attribute names than Three.JS](https://twgljs.org/), and a different structure altogether.

```javascript
const positionLoc = gl.getAttribLocation(program, "a_position");
const normalLoc = gl.getAttribLocation(program, "a_normal");
const texcoordLoc = gl.getAttribLocation(program, "a_texcoord");

```

There are too many differences in naming conventions, and you’d have to do a lot of manual work to “hook up” the Three.js objects to update TWGL.js objects. You should just stick with one library, they weren’t made to be used in unison.

But if you want to write your own shader code, you can still do so with Three.js!

---

<div class="post-metadata">

**Author:** ![3DGraphics](https://avatars.discourse-cdn.com/v4/letter/3/97f17d/32.png) [@3DGraphics](https://discourse.threejs.org/u/3DGraphics)\
**Post date:** [September 11, 2019, 2:56pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/3 "2019-09-11T14:56:32Z")

</div>

I really appreciate your quick and insightful response. I need to display text (numeric identifiers, hundred of thousands of them) and using TextGeometry is quite resource expensive. I was hoping to find a means to have the two libraries coexist, with Three.js managing the graphical objects and Twgl.js handling text. Does WebGL or WebGL2 support vertex subroutines? If so, can Three.js be modified to use them so that Twgl.js functions can be written?

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 11, 2019, 3:10pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/4 "2019-09-11T15:10:26Z")

</div>

@3DGraphics  
There are many ways to achieve what you want.  
Can you provide an explanatory pic with more detailed description of the desired result?

---

<div class="post-metadata">

**Author:** ![EliasHasle](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/eliashasle/32/3010_2.png) [@EliasHasle](https://discourse.threejs.org/u/EliasHasle)\
**Post date:** [September 11, 2019, 3:13pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/5 "2019-09-11T15:13:41Z")

</div>

> [@3DGraphics](#):
>
> I’m not interested in creating a shader material.

> [@marquizzo](#):
>
> No, you won’t be able to. TWGL.js uses different attribute names than Three.JS

With `THREE.RawShaderMaterial` and a custom `THREE.BufferGeometry`, no one decides your attribute names.

> [@3DGraphics](#):
>
> I need to display text (numeric identifiers, hundred of thousands of them) and using TextGeometry is quite resource expensive.

What alternatives are you exploring? Hundreds of thousands of text markers sounds visually bloated and computationally expensive regardless of how they are made. Any chance of displaying the markers only on hover/click, perhaps just using carefully configured and positioned HTML elements?

---

<div class="post-metadata">

**Author:** ![marquizzo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/marquizzo/32/25192_2.png) [@marquizzo](https://discourse.threejs.org/u/marquizzo)\
**Post date:** [September 11, 2019, 6:14pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/6 "2019-09-11T18:14:26Z")

</div>

@3DGraphics There are several methods to write text with Three.js. [Here’s a small list](https://threejs.org/docs/index.html#manual/en/introduction/Creating-text) in the docs of some WebGL options, but you can also use the [CSS3DRenderer](https://threejs.org/examples/?q=css#css3d_periodictable) approach. Not sure which one would work best with your project.

@EliasHasle He asked if he’d still be able to use “Three.js native materials and geometries” and the answer to that question is no; he’d have to write custom ones.

---

<div class="post-metadata">

**Author:** ![EliasHasle](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/eliashasle/32/3010_2.png) [@EliasHasle](https://discourse.threejs.org/u/EliasHasle)\
**Post date:** [September 11, 2019, 6:16pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/7 "2019-09-11T18:16:35Z")

</div>

That depends on what you mean with “native”. One possible interpretation would be that he writes the shader for Twgl.js, and uses it in Three.js. I outlined how that would be possible.

---

<div class="post-metadata">

**Author:** ![3DGraphics](https://avatars.discourse-cdn.com/v4/letter/3/97f17d/32.png) [@3DGraphics](https://discourse.threejs.org/u/3DGraphics)\
**Post date:** [September 11, 2019, 8:04pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/8 "2019-09-11T20:04:04Z")

</div>

![bonds](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/6/60f6ec551697de0f56a48a7f6e161fa5ba9b8386.jpeg)

![segments](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/b/b7c6c72dca569a0edfc9cd5dc0b6d3e19445c098.png)

@prisoner849, The above are examples of what I’m trying to do.

@marquizzo, I will review the list that you have provided.

@EliasHasle, you are correct about it being visually bloated but that is the worse case. The user has the ability to graphically cut away sections and isolate particular regions of interest. We’ve had discussions about using hovering but that was voted down.

I really appreciate you guys help. 🙂

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 11, 2019, 8:07pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/9 "2019-09-11T20:07:28Z")

</div>

Reminded me about this: [https://threejs.org/examples/?q=loader#webgl\_loader\_pdb](https://threejs.org/examples/?q=loader#webgl_loader_pdb)

---

<div class="post-metadata">

**Author:** ![3DGraphics](https://avatars.discourse-cdn.com/v4/letter/3/97f17d/32.png) [@3DGraphics](https://discourse.threejs.org/u/3DGraphics)\
**Post date:** [September 13, 2019, 2:47pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/10 "2019-09-13T14:47:54Z")

</div>

@prisoner849, I appreciate the help. I am studying the example. I would like to know if it is possible to switch shaders (vertex/fragment) between ones written by me and the ones provided by three.js? If this is possible, what mechanism does three.js provide to support shader switching.

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 13, 2019, 2:53pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/11 "2019-09-13T14:53:12Z")

</div>

It’s hard to say what’s possible or not possible without at least an example of shaders you have (jsfiddle, codepen, link to github). I’m not familiar with twgl.js, but maybe there are users on the forum who work(ed) with it, so they can provide better help.  
So far it’s very unclear what to what you want to convert.

---

<div class="post-metadata">

**Author:** ![3DGraphics](https://avatars.discourse-cdn.com/v4/letter/3/97f17d/32.png) [@3DGraphics](https://discourse.threejs.org/u/3DGraphics)\
**Post date:** [September 13, 2019, 2:59pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/12 "2019-09-13T14:59:13Z")

</div>

I appreciate the prompt response. I wasn’t thinking about using twgl but rather pure webgl. As stated earlier, I am studying the example you provided and so far it appears to provide a good starting point. I’m just seeing what options I may have. I have to present a solution strategy.

---

<div class="post-metadata">

**Author:** ![horsetopus](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/horsetopus/32/67_2.png) [@horsetopus](https://discourse.threejs.org/u/horsetopus)\
**Post date:** [September 13, 2019, 3:19pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/13 "2019-09-13T15:19:12Z")

</div>

Hi 3DGraphics.

> [@3DGraphics](#):
>
> I need to display text (numeric identifiers, hundred of thousands of them) and using TextGeometry is quite resource expensive.

Given what you are trying to do, they are ways of optimizing all this.

1/ If the letters are always facing the camera, you don’t need 3D models. Sprites would be more than enough.  
The thing is they have to be transparent and can raise issues with depth if you mix them with opaque meshes, but you can put all the objects in your scene as transparent (even when they don’t need to be) or render the numbers always on top of the rest 'playing with renderorder, or doing multiple renders using, for example, layers as a mean of selection).

2/ It seems a lot of the letters a repeated, be it for sprites or for 3D volumes, you can reuse the materials and the geometry objects. Don’t initiate a new one every time you need a letter.  
And if you need a sentence (ABCD) don’t make it one object but 4 objects side by side. That’s what makes this point valide ( you gonna have 40 As part of words in you scene, but only 2 ABCD as a whole for example).

3/ Level Of Details. If you want 3D model letters that look cool up close to the camera, I can understand. But if you you really are gonna hundreds of thousands, some of them ought to be in the back.  
They don’t need, when far away, to be fully detailed 3D models.  
That’s what LOD is for. Have a crisp 3D letter up close to the camera if you want, but make a sprite for when it is far from the camera.  
[https://threejs.org/docs/#api/en/objects/LOD](https://threejs.org/docs/#api/en/objects/LOD)

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [September 13, 2019, 3:35pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/14 "2019-09-13T15:35:42Z")

</div>

> [@horsetopus](#):
>
> and can raise issues with depth

Not always, actually. It’s enough to use `.alphaTest` with value of `0.5` (for example), without setting `.transparent` to `true` on a material.

---

<div class="post-metadata">

**Author:** ![3DGraphics](https://avatars.discourse-cdn.com/v4/letter/3/97f17d/32.png) [@3DGraphics](https://discourse.threejs.org/u/3DGraphics)\
**Post date:** [September 16, 2019, 9:20pm UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/15 "2019-09-16T21:20:36Z")

</div>

I do appreciate the examples provided and I’m examining them but the issue regarding vertex switching still has been unanswered. @prisoner849 you asked for an example. I have provided an example which is very generic(see below).

I want to implement vertex shading by creating multiple program objects. How can this be done with three.js? I’m not attempting to create a material.

var SOLID\_VSHADER\_SOURCE =  
‘attribute vec4 a\_Position;\n’ +  
‘attribute vec4 a\_Normal;\n’ +  
‘uniform mat4 u\_MvpMatrix;\n’ +  
‘uniform mat4 u\_NormalMatrix;\n’ +  
‘varying vec4 v\_Color;\n’ +  
‘void main() {\n’ +  
’ vec3 lightDirection = vec3(0.0, 0.0, 1.0);\n’ + // Light direction(World coordinate)  
’ vec4 color = vec4(0.0, 1.0, 1.0, 1.0);\n’ + // Face color  
’ gl\_Position = u\_MvpMatrix \* a\_Position;\n’ +  
’ vec3 normal = normalize(vec3(u\_NormalMatrix \* a\_Normal));\n’ +  
’ float nDotL = max(dot(normal, lightDirection), 0.0);\n’ +  
’ v\_Color = vec4(color.rgb \* nDotL, color.a);\n’ +  
‘}\n’;

// Fragment shader for single color drawing  
var SOLID\_FSHADER\_SOURCE =  
‘#ifdef GL\_ES\n’ +  
‘precision mediump float;\n’ +  
‘#endif\n’ +  
‘varying vec4 v\_Color;\n’ +  
‘void main() {\n’ +  
’ gl\_FragColor = v\_Color;\n’ +  
‘}\n’;

// Vertex shader for texture drawing  
var TEXTURE\_VSHADER\_SOURCE =  
‘attribute vec4 a\_Position;\n’ +  
‘attribute vec4 a\_Normal;\n’ +  
‘attribute vec2 a\_TexCoord;\n’ +  
‘uniform mat4 u\_MvpMatrix;\n’ +  
‘uniform mat4 u\_NormalMatrix;\n’ +  
‘varying float v\_NdotL;\n’ +  
‘varying vec2 v\_TexCoord;\n’ +  
‘void main() {\n’ +  
’ vec3 lightDirection = vec3(0.0, 0.0, 1.0);\n’ + // Light direction(World coordinate)  
’ gl\_Position = u\_MvpMatrix \* a\_Position;\n’ +  
’ vec3 normal = normalize(vec3(u\_NormalMatrix \* a\_Normal));\n’ +  
’ v\_NdotL = max(dot(normal, lightDirection), 0.0);\n’ +  
’ v\_TexCoord = a\_TexCoord;\n’ +  
‘}\n’;

// Fragment shader for texture drawing  
var TEXTURE\_FSHADER\_SOURCE =  
‘#ifdef GL\_ES\n’ +  
‘precision mediump float;\n’ +  
‘#endif\n’ +  
‘uniform sampler2D u\_Sampler;\n’ +  
‘varying vec2 v\_TexCoord;\n’ +  
‘varying float v\_NdotL;\n’ +  
‘void main() {\n’ +  
’ vec4 color = texture2D(u\_Sampler, v\_TexCoord);\n’ +  
’ gl\_FragColor = vec4(color.rgb \* v\_NdotL, color.a);\n’ +  
‘}\n’;

function main() {  
// Retrieve element  
var canvas = document.getElementById(‘webgl’);

// Get the rendering context for WebGL  
var gl = getWebGLContext(canvas);  
if (!gl) {  
console.log(‘Failed to get the rendering context for WebGL’);  
return;  
}

// Initialize shaders  
var solidProgram = createProgram(gl, SOLID\_VSHADER\_SOURCE, SOLID\_FSHADER\_SOURCE);  
var texProgram = createProgram(gl, TEXTURE\_VSHADER\_SOURCE, TEXTURE\_FSHADER\_SOURCE);  
if (!solidProgram || !texProgram) {  
console.log(‘Failed to intialize shaders.’);  
return;  
}

---

<div class="post-metadata">

**Author:** ![Cotterzz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/cotterzz/32/9011_2.png) [@Cotterzz](https://discourse.threejs.org/u/Cotterzz)\
**Post date:** [September 17, 2019, 12:55am UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/16 "2019-09-17T00:55:56Z")

</div>

twgl.js is for working more closely with webgl, whereas three.js is a whole layer of abstraction.  
If you want to work with three and write shaders yourself, use shadermaterial or rawshadermaterial.  
I’m doing that myself - using a class called shaderlayer, that includes a screen size quad that allows me to write a custom shader for a background (or foreground) to go behind or in front of my three.js content.  
Three.js does modify the custom shaders you provide before compiling them, iirc.  
Ther’e a good example of how to get started with three.js and custom shaders here:

> **[The Book of Shaders](https://thebookofshaders.com/04/)**
>
> Gentle step-by-step guide through the abstract and complex universe of Fragment Shaders.

---

<div class="post-metadata">

**Author:** ![Cotterzz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/cotterzz/32/9011_2.png) [@Cotterzz](https://discourse.threejs.org/u/Cotterzz)\
**Post date:** [September 17, 2019, 9:45am UTC](https://discourse.threejs.org/t/three-js-and-twgl-js/9582/17 "2019-09-17T09:45:28Z")

</div>

Sorry, I just noticed you specified that you want to create many objects, and not use a material.  
I recommend you consider using a single quad with a custom shader to display anything higher than 5000 objects, and that includes text, it really is the fastest solution, though tricky, to implement. Tracking hundreds of thousand of objects in any flavour of Javascript is going to be troublesome, with the possible exception of webassembly.  
There’s some amazing examples of massive text rendering using a shader here:  
[https://wdobbie.com/post/gpu-text-rendering-with-vector-textures/](https://wdobbie.com/post/gpu-text-rendering-with-vector-textures/)  
Though I had trouble understanding that one myself.  
You want to think in terms of writing per pixel, identifying which letter that pixel is in, and rendering that part of the letter, and having a shader cover the entire area with letters, so the number of letters shouldn’t slow things down. That’s the theory anyway. For rendering vectors at all sizes with a shader you need to use a technique called signed distance fields, which essentially tells you if a point is within a shape or outside it.
