3d – 在Dart WebGL的Billboarding

我一直试图使用lwjgl为我在dart中制作的游戏创建广告牌效果.

我一直在读你应该让每个广告牌顶点都位于世界中心位置,然后用相机矢量取代它们.我不太明白该怎么做.

这是我的渲染类:

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,0.0]);
    vertexArray.setAll(2 * 3,[-.5,0.0]);
    vertexArray.setAll(3 * 3,0.0]);

    Int16List elementArray = new Int16List(6);
    elementArray.setAll(0,[0,1,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);

    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,viewMatrix.storage);
    gl.uniformMatrix4fv(cameraTransformlocation,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);

  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,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,textureMatrix.storage);

    gl.uniform4fv(colorLocation,color.storage);
    gl.drawElements(WebGL.TRIANGLES,6,WebGL.UNSIGNED_SHORT,0);
  }
}

这是我想要呈现为广告牌的树:

class Tree extends Object {

  Tree(var pos): super(pos);

  void render() {

    quad.render(getRenderPos(),48,208);
  }

  Vector3 getRenderPos() {

    return new Vector3(pos.x,pos.y + 24,pos.z);
  }
}

解决方法

我知道你想知道如何在WebGL中实现一个摄像头,对吧?

您可能已经意识到,WebGL API不提供相机抽象,因此您必须手动构建自己的相机.

我认为最直接的方法是构建表示相机的变换矩阵(比例,旋转,平移),然后计算其逆矩阵,最后将其应用于场景的所有对象.

看看Gregg Tavares的精湛介绍:

WebGL 3D Cameras

相关文章

vue阻止冒泡事件 阻止点击事件的执行 <div @click=&a...
尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用...
后台我拿的数据是这样的格式: [ {id:1 , parentId: 0, name:...
JAVA下载文件防重复点击,防止多次下载请求,Cookie方式快速简...
Mip是什么意思以及作用有哪些