WebGL多纹理立方体

时间:2016-04-30 01:53:41

标签: javascript opengl-es 3d webgl

我需要为每一面纹理一个具有不同纹理的立方体,除非单边做有优势。这是我的顶点着色器:..

precision mediump float;

attribute vec3 vertPosition;
attribute vec2 vertTexCoord;
attribute float aFace;
uniform mat4 mWorld;
uniform mat4 mView;
uniform mat4 mProj;

varying vec2 fragTexCoord;
varying float vFace;

void main()
{
  fragTexCoord = vertTexCoord;
  vFace = aFace;
  gl_Position = mProj * mView * mWorld * vec4(vertPosition, 1.0);
}

Fragment Shader:..

precision mediump float;

uniform sampler2D front;
uniform sampler2D back;
uniform sampler2D top;
uniform sampler2D bottom;
uniform sampler2D right;
uniform sampler2D left;

varying vec2 fragTexCoord;
varying float vFace;

void main()
{
  if(vFace < 0.1)
     gl_FragColor = texture2D(front, fragTexCoord);
  else if(vFace < 1.1)
     gl_FragColor = texture2D(back, fragTexCoord);
  else if(vFace < 2.1)
     gl_FragColor = texture2D(top, fragTexCoord);
  else if(vFace < 3.1)
     gl_FragColor = texture2D(bottom, fragTexCoord);
  else if(vFace < 4.1)
     gl_FragColor = texture2D(right, fragTexCoord);
  else
     gl_FragColor = texture2D(left, fragTexCoord);
}totorials

然后在我开始渲染之前运行。 (变量是全局定义的):..

cubeVertexBufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexBufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeVertices), gl.STATIC_DRAW);

cubeIndexBufferObject = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBufferObject);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeIndices), gl.STATIC_DRAW);

textureLookUpBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureLookUpBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(lookUpArray), gl.STATIC_DRAW);

cubeVertexTextureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);

positionAttributeLocation = gl.getAttribLocation(program, 'vertPosition');
gl.vertexAttribPointer(
    positionAttributeLocation,
    3,
    gl.FLOAT,
    gl.FALSE,
    5 * Float32Array.BYTES_PER_ELEMENT,
    0
);

texCoordAttributeLocation = gl.getAttribLocation(program, 'vertTexCoord');
gl.vertexAttribPointer(
    texCoordAttributeLocation,
    2,
    gl.FLOAT,
    gl.FALSE,
    5 * Float32Array.BYTES_PER_ELEMENT,
    3 * Float32Array.BYTES_PER_ELEMENT
);

textureLookUpAttribute = gl.getAttribLocation(program, "aFace");
gl.vertexAttribPointer(
    textureLookUpAttribute,
    1,
    gl.FLOAT,
    false,
    0,
    0
);

faces.front = gl.getUniformLocation(program,"front");
faces.back = gl.getUniformLocation(program,"back");
faces.top = gl.getUniformLocation(program,"top");
faces.bottom = gl.getUniformLocation(program,"bottom");
faces.right = gl.getUniformLocation(program,"right");
faces.left = gl.getUniformLocation(program,"left");
//
cubeMatWorldUniformLocation = gl.getUniformLocation(program, 'mWorld');
cubeMatViewUniformLocation = gl.getUniformLocation(program, 'mView');
cubeMatProjUniformLocation = gl.getUniformLocation(program, 'mProj');

worldMatrix = new Float32Array(16);
viewMatrix = new Float32Array(16);
projMatrix = new Float32Array(16);

mat4.identity(worldMatrix);
mat4.lookAt(viewMatrix, [0, 0, -8], [0, 0, 0], [0, 1, 0]);
mat4.perspective(projMatrix, glMatrix.toRadian(45), Canvas.width / Canvas.height, 0.1, 1000.0);

gl.uniformMatrix4fv(cubeMatWorldUniformLocation, gl.FALSE, worldMatrix);
gl.uniformMatrix4fv(cubeMatViewUniformLocation, gl.FALSE, viewMatrix);
gl.uniformMatrix4fv(cubeMatProjUniformLocation, gl.FALSE, projMatrix);

最后每次我渲染这个运行:..

gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
gl.vertexAttribPointer(texCoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexBufferObject);
gl.vertexAttribPointer(texCoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ARRAY_BUFFER, textureLookUpBuffer);
gl.vertexAttribPointer(textureLookUpAttribute, 1, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBufferObject);

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.uniform1i(faces.front, 0);

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, grass);
gl.uniform1i(faces.back, 1); 

gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.uniform1i(faces.top, 2);

gl.activeTexture(gl.TEXTURE3);
gl.bindTexture(gl.TEXTURE_2D, grass);
gl.uniform1i(faces.bottom, 3);

gl.activeTexture(gl.TEXTURE4);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.uniform1i(faces.right, 4);

gl.activeTexture(gl.TEXTURE5);
gl.bindTexture(gl.TEXTURE_2D, grass);
gl.uniform1i(faces.left, 5);

gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);

它给了我错误消息。当我稍微更改代码时(当我试图修复它时)它们的不同之处,这就是为什么我没有确切的错误消息。如果您需要多维数据集的不同数组,我可以发布它们。我正在阅读有关如何执行此操作的在线教程(一般情况下),但显然你可以看到它没有用。

1 个答案:

答案 0 :(得分:3)

纹理每边不同面的立方体的最常用方法是使用texture atlas。将所有面放在1个纹理中,并使用纹理坐标为每个面选择正确的纹理部分。

See the bottom of this article

优点是有1个纹理。 1个纹理单元来设置。 1制服设定。更多的采样器留给其他东西(法线贴图等)。一个运行得更快的简单着色器。