Three.js and Twgl.js

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?

No, you won’t be able to. TWGL.js uses different attribute names than Three.JS, and a different structure altogether.

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!

1 Like

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?

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

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

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?

@3DGraphics There are several methods to write text with Three.js. Here’s a small list in the docs of some WebGL options, but you can also use the CSS3DRenderer 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.

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.

bonds

segments

@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. :slight_smile:

Reminded me about this: https://threejs.org/examples/?q=loader#webgl_loader_pdb

@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.

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.

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.

Hi 3DGraphics.

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

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