I’m rendering large amounts of sprites that have the same y orientation.
In other words, the lower z values are all 0, and the higher y values are all 100 (or some other constant value).
For example, imagine a city map aligned to the x/z plane. A large number of sprites are overlaid on top of this map. So my geometry is in essence planar (I only have lat/lon, in other words).
Is it possible to have memory, and only encode two of the coordinates (x and z) of each point in the VBO, and supply a constant y coordinate value in addition to that?
This would reduce my memory requirements by 33%, obviously.
Yep. I do that kind of thing with particle systems - only in that case I only send one number to the shader (the “particle vertex ID”) and compute the full 3D position of the particle from that.
It certainly works - and you’ll save memory. You may also save time - providing you have at least around 1000 vertices per draw call - otherwise the per-mesh setup time erases any saving you’d get.
When you call gl.vertexAttribPointer, tell it that you’ll only pass two numbers - and they’ll show up inside the vertex shader as the .x and .y component of the position variable. Then you can pass the Y coordinate in a “uniform” variable and use shader code to assemble the three numbers into a 3D coordinate as needed…so you’ll end up with something like:
attribute vec2 POSITION ;
uniform float myYcoord ;
vec4 myPosition = vec4 ( POSITION.x, myYcoord, POSITION.y, 1.0 ) ;
Ah, I expected it to work like this, but was not sure if this was a pattern common enough to yield good performance.
Thanks for confirming, I’ll definitely try this approach. Our vertex could is easily over 1000, and the memory savings will be quite welcome.
Thanks for the quick response.
Steve, thanks for your help - it works as expected.
My next step is to render a large number of triangles (triangle strips actually), that are all perpendicular to the x/z plane.
For example, given a line (x1,y1)-(x2,y2) on a two-dimensional map, I want to render a 3d rectangle with height “h” that has the following corner points:
- (x1,y1,0) - low start point
- (x2,y2,0) - low end point
- (x1,y1,h) - high start point
- (x2,y2,h) - high end point
So in essence, I still have 2d geometry, but with “low y” and “high y” values. If I understand correctly, I cannot apply such tricks here. The reason is that the vertex shader deals with a single vertex at a time.
Is this indeed the case (until geometry shaders are part of WebGL), or is there some clever trick that can be used here?
Here’s an image that illustrates what I want to render:
Can I make WebGL do this, given only one set of planar (2d) coordinates representing the curve, together with the two (lower and higher) offsets for the 3rd axis?
Well, if you’re rendering a triangle strip, you’re only sending ~one vertex per triangle - so it’s pretty lean already.
But you’re right, each vertex is totally independent and the vertex shaders can’t communicate.
There might be some devious way of doing it - but honestly, I don’t think you’re going to reclaim much (if any) performance or memory.