I've been trying to create billboarding effects for a game I'm making in dart using lwjgl.
I've been reading that you should have each billboard vertex is at the worlds center position and then just displace them by the cameras vectors. I do not quite understand how to do this.
Here's my rendering class:
class Quad {
Shader shader;
int posLocation;
Texture texture;
WebGL.UniformLocation objectTransformLocation, viewTransformLocation, textureTransformLocation,
colorLocation, fogColorLocation, cameraTransformLocation;
Quad(this.shader) {
posLocation = gl.getAttribLocation(shader.program, "a_pos");
objectTransformLocation = gl.getUniformLocation(shader.program, "u_objectTransform");
textureTransformLocation = gl.getUniformLocation(shader.program, "u_textureTransform");
viewTransformLocation = gl.getUniformLocation(shader.program, "u_viewTransform");
cameraTransformLocation = gl.getUniformLocation(shader.program, "u_cameraTransform");
colorLocation = gl.getUniformLocation(shader.program, "u_color");
fogColorLocation = gl.getUniformLocation(shader.program, "u_fogColor");
gl.useProgram(shader.program);
Float32List vertexArray = new Float32List(4 * 3);
vertexArray.setAll(0 * 3, [.5, .5, 0.0]);
vertexArray.setAll(1 * 3, [.5, -.5, 0.0]);
vertexArray.setAll(2 * 3, [-.5, -.5, 0.0]);
vertexArray.setAll(3 * 3, [-.5, .5, 0.0]);
Int16List elementArray = new Int16List(6);
elementArray.setAll(0, [0, 1, 2, 0, 2, 3]);
gl.enableVertexAttribArray(posLocation);
WebGL.Buffer vertexBuffer = gl.createBuffer();
gl.bindBuffer(WebGL.ARRAY_BUFFER, vertexBuffer);
gl.bufferDataTyped(WebGL.ARRAY_BUFFER, vertexArray, WebGL.STATIC_DRAW);
gl.vertexAttribPointer(posLocation, 3, WebGL.FLOAT, false, 0, 0);
WebGL.Buffer elementBuffer = gl.createBuffer();
gl.bindBuffer(WebGL.ELEMENT_ARRAY_BUFFER, elementBuffer);
gl.bufferDataTyped(WebGL.ELEMENT_ARRAY_BUFFER, elementArray, WebGL.STATIC_DRAW);
gl.bindBuffer(WebGL.ELEMENT_ARRAY_BUFFER, elementBuffer);
}
void setCamera(Matrix4 camera, Matrix4 viewMatrix) {
gl.uniformMatrix4fv(viewTransformLocation, false, viewMatrix.storage);
gl.uniformMatrix4fv(cameraTransformLocation, false, camera.storage);
}
void setTexture(Texture texture) {
this.texture = texture;
gl.bindTexture(WebGL.TEXTURE_2D, texture.texture);
}
void setFogColor(Vector4 fogColor) {
gl.uniform4fv(fogColorLocation, fogColor.storage);
}
Vector4 defaultColor = new Vector4(1.0, 1.0, 1.0, 1.0);
Matrix4 objectMatrix = new Matrix4.identity();
Matrix4 textureMatrix = new Matrix4.identity();
void render(Vector3 pos, num w, num h, num uo, num vo, {Vector4 color, Vector3 rotation, num tw, num th}) {
if (!texture.loaded) return;
if (color == null) color = defaultColor;
if (rotation == null) rotation = new Vector3(0.0, 0.0, 0.0);
if (tw == null) tw = w;
if (th == null) th = h;
objectMatrix.setIdentity();
objectMatrix.translate(pos.x, pos.y, pos.z);
objectMatrix.rotateX(rotation.x);
objectMatrix.rotateY(rotation.y);
objectMatrix.rotateZ(rotation.z);
objectMatrix.scale(w * 1.0, h * 1.0, 0.0);
gl.uniformMatrix4fv(objectTransformLocation, false, objectMatrix.storage);
textureMatrix.setIdentity();
textureMatrix.scale(1.0 / texture.width, -(1.0 / texture.height), 0.0);
textureMatrix.translate((uo + tw / 2.0), (vo + th / 2.0), 0.0);
textureMatrix.scale((tw - 0.5), (th - 0.5), 0.0);
gl.uniformMatrix4fv(textureTransformLocation, false, textureMatrix.storage);
gl.uniform4fv(colorLocation, color.storage);
gl.drawElements(WebGL.TRIANGLES, 6, WebGL.UNSIGNED_SHORT, 0);
}
}
And here's the tree I want to render as a billboard:
class Tree extends Object {
Tree(var pos): super(pos);
void render() {
quad.render(getRenderPos(), 48, 48, 0, 208);
}
Vector3 getRenderPos() {
return new Vector3(pos.x, pos.y + 24, pos.z);
}
}