NeHe Lesson 11 – A Parametric Surface

A Waving Texture as Parametric Surface

A Parametric Surface with Texture

Introduction

This post is  little more interesting than some of the earlier posts as it took me a couple of  tries to get it right. Initially, I patterned the code after the original NeHe implementation. I knew that would suffer from poor performance, which it did. I then realized the solution was to build a single vertex buffer object (VBO) in JavaScript and pass that to the GPU.  The VBO was created by three.js using a parametric surface mesh.

Initial Go

The first try simply replicated the original NeHe C++ code directly by building a grid in JavaScript and then updating all of those vertices  in JS and passing that mesh to the GPU.  This was of course thrashing the memory and choking the memory pathway to the GPU.

Using the Vertex Buffer and a Parametric Surface

Instead the solution was create a parametric surface by allocating a THREE.ParametricMesh.  The constructor takes a small callback (in JS) which returns a 3-element vector, which three.js uses to create the surface.  Those vectors are not used as-is, but are used to fill out a  VBO which is then passed to the GPU.  However, the JavaScript Mesh object has member variable (a uniform) that points to the VBO via a shader interface.  One can then update the vertices via that member variable. This updates the vertices in the VBO, which is all done on the GPU so it is very efficient.

Shader Implementation?

I looked at a shader-side implementation but, at least in WebGL this doesn’t seem possible.  It may be possible to in GL-4 to access adjacent vertex coordinates, but not in WebGL.  But the solution as-is works well.

You can find the lesson at Geo-F/X here. As always, the sources are on github here. Feel free to contact me at rkwright@geofx.com or comment on this article directly.

NeHe Lesson 13 – Using Sprites for Text Labels in three.js

Test Sprites in three.js

Text Sprites Demo in three.js

 

Introduction

This post is a bit of a hybrid as it makes use of Canvas2D to render the text and labels, then composites them into the scene as three.js sprites.  The original NeHe lesson 13 was about bitmapped fonts and how to use them, but that’s so last century.  Canvas2D provides support for true vector fonts so why would one use bitmap fonts?

On the other hand, being able to place labels where you want in a 3D scene is a handy feature.  Moreover, the use of three.js sprites has another useful aspect as three.js sprites are implemented such that they are effectively in 2D space in the plane of the screen, so they are always facing the user, no matter how the scene is oriented.

There are four main parts to the demo:

  • Setting up the Canvas2D that is the basis for the sprite
  • Rendering the text and label on the canvas
  • Loading the contents of the canvas as a texture
  • Positioning the resulting sprite in the scene

Setting up the Canvas

This is standard HTLM5 – nothing tricky here.  Two tips:

  • Make the canvas big since only the label and the text will actually be rendered as the texture since the rest of the canvas is transparent as far as three.js is concerned
  • Ensure that the canvas size is a power of two, e.g. 2048×2048.  If you don’t three.js will change it for you and send a warning to the console

Rendering the Text Sprites

I won’t go into the details how HOW this is done.  Take a look at the lesson on the Geo-F/X website here for all the details (and of course the sources are on github).  The key is the call to makeTextSprite:

var txSprite1 = makeTextSprite( "Bottom-Right", -1, 1, 0.25, { fontsize: 72, fontface: 
      "Georgia", borderColor: {r:0, g:0, b:255, a:1.0}, borderThickness:4, 
      fillColor: {r:255, g:255, b:255, a:1.0}, radius:0, vAlign:"bottom", hAlign:"right" } );

Yeah, the function’s signature is unwieldy.  I have a to-do item to convert it to use some form of class/object but it works as-is.  Notice that you can set the vertical and horizontal alignment of the text with respect to the 3D point where the sprite will be rendered.  You can set the color of both the text and the label, round-corners or not, opacity, etc. etc.

And that’s pretty much it!  Fairly simple but rather handy.  At some point I will do the refactoring mentioned above and add it to the GFXScene class.

You can find the lesson at Geo-F/X here. As always, the sources are on github here. Feel free to contact me at rkwright@geofx.com or comment on this article directly.