我有六个纹理,我试图将其映射到一个3D立方体,每张面都有一张图片。我已将所有6个图像的url存储在一个数组中,并将所有6个图像绑定到webgl。但是,只有我的url数组的第一个图像被映射到所有6个面。我似乎正在正确地增加纹理单位,可能是我为每个面使用相同的纹理坐标?任何帮助表示赞赏。感谢
TexturedCube.js
var gl;
var canvas;
var program;
var points = [];
var colors = [];
var texCoordsArray = [];
var loadedImageCount = 0;
var fs_textureLoc;
var objOffset = 0;
var twoTriangles = 36;
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = 0;
var theta = [ 0, 0, 0 ];
var near = 0.3;
var far = 3.0;
var fovy = 45.0;
var aspect;
var VMatrixLoc, PMatrixLoc;
var vs_ViewMatrix, vs_ProjMatrix;
var imageTextures = [
"https://c1.staticflickr.com/5/4625/26712799268_7c59b1e10e_q.jpg",
"https://c1.staticflickr.com/5/4665/40543467892_1aef2f9307_q.jpg",
"https://c1.staticflickr.com/5/4787/40556861052_7982f5ca6e_q.jpg",
"https://c1.staticflickr.com/5/4756/40543466622_a0f7c22346_q.jpg",
"https://c1.staticflickr.com/5/4716/38775586080_cc55674d74_q.jpg",
"https://c1.staticflickr.com/5/4714/39875195484_003850f098_q.jpg"
];
var faceColors = [
[ 0.0, 0.0, 0.0, 1.0 ], // black
[ 1.0, 0.0, 0.0, 1.0 ], // red
[ 1.0, 1.0, 0.0, 1.0 ], // yellow
[ 0.0, 1.0, 0.0, 1.0 ], // green
[ 0.0, 0.0, 1.0, 1.0 ], // blue
[ 1.0, 0.0, 1.0, 1.0 ], // magenta
[ 0.0, 1.0, 1.0, 1.0 ], // cyan
[ 1.0, 1.0, 1.0, 1.0 ] // white
];
window.onload = function init()
{
canvas = document.getElementById("gl-canvas");
gl = WebGLUtils.setupWebGL(canvas);
if (!gl){ alert("not available."); }
buildCube();
gl.viewport(0, 0, canvas.height, canvas.width);
gl.clearColor(1.0, 1.0, 1.0, 1);
gl.enable(gl.DEPTH_TEST);
program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
document.getElementById( "xButton" ).onclick = function () {
axis = xAxis;
};
document.getElementById( "yButton" ).onclick = function () {
axis = yAxis;
};
document.getElementById( "zButton" ).onclick = function () {
axis = zAxis;
};
initializeImages();
loadBuffers();
setViewProjection();
render();
}
function initializeImages()
{
loadedImageCount = 0;
for (var i = 0; i < imageTextures.length; ++i)
{
loadImage(program, imageTextures[i], i);
}
}
function loadImage(program, url, txtUnit)
{
var texture = gl.createTexture();
fs_textureLoc = gl.getUniformLocation(program, "fs_texture");
var image = new Image();
image.onload = function(){
loadTexture(image, texture, txtUnit);
};
image.crossOrigin = "anonymous";
image.src = url;
}
function loadTexture(image, texture, txtUnit)
{
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
gl.activeTexture(gl.TEXTURE0 + txtUnit);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
loadedImageCount += 1;
}
function loadBuffers()
{
// Load the colors for the triangles and enable the attribute vColor
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
// Load the vertices for the triangles and enable the attribute vPosition
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var tBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );
var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
}
function buildCube()
{
buildFace(1, 0, 3, 2);
buildFace(2, 3, 7, 6);
buildFace(3, 0, 4, 7);
buildFace(6, 5, 1, 2);
buildFace(4, 5, 6, 7);
buildFace(5, 4, 0, 1);
}
function buildFace(a, b, c, d)
{
var verts = [
vec4( -0.5, -0.5, 0.5, 1.0),
vec4( -0.5, 0.5, 0.5, 1.0),
vec4( 0.5, 0.5, 0.5, 1.0),
vec4( 0.5, -0.5, 0.5, 1.0),
vec4( -0.5, -0.5, -0.5, 1.0),
vec4( -0.5, 0.5, -0.5, 1.0),
vec4( 0.5, 0.5, -0.5, 1.0),
vec4( 0.5, -0.5, -0.5, 1.0)
];
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
let indices = [a, b, c, a, c, d];
let texIndices = [1, 0, 3, 1, 3, 2];
for (var i = 0; i < indices.length; ++i)
{
points.push(verts[indices[i]]);
texCoordsArray.push(texCoord[texIndices[i]]);
numVertices += 1;
colors.push(faceColors[7]);
}
}
function setViewProjection()
{
VMatrixLoc = gl.getUniformLocation(program, "vs_ViewMatrix");
PMatrixLoc = gl.getUniformLocation(program, "vs_ProjMatrix");
if (!VMatrixLoc || !PMatrixLoc){ console.log("failed"); }
eyePt = vec3(0, 0, 5);
atPt = vec3(0, 0, 0);
upVec = vec3(0, 1, 0);
vs_ViewMatrix = lookAt(eyePt, atPt, upVec);
vs_ViewMatrix = mult(vs_ViewMatrix, rotate(theta[xAxis], [1, 0, 0]));
vs_ViewMatrix = mult(vs_ViewMatrix, rotate(theta[yAxis], [0, 1, 0]));
vs_ViewMatrix = mult(vs_ViewMatrix, rotate(theta[zAxis], [0, 0, 1]));
fovy = 50;
aspect = canvas.width/canvas.height;
near = 1;
far = 100;
vs_ProjMatrix = perspective(fovy, aspect, near, far);
gl.uniformMatrix4fv(VMatrixLoc, false, flatten(vs_ViewMatrix));
gl.uniformMatrix4fv(PMatrixLoc, false, flatten(vs_ProjMatrix));
}
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.clearColor(0.0, 0.0, 0.0, 0.1);
theta[axis] += 2.0;
objOffSet = 0;
if (loadedImageCount == imageTextures.length)
{
for (var txtUnit = 0; txtUnit < 6; ++txtUnit)
{
gl.uniform1i(fs_textureLoc, txtUnit);
gl.drawArrays(gl.TRIANGLES, objOffSet, twoTriangles);
objOffset += twoTriangles;
}
}
requestAnimFrame( render );
}
TexturedCube.html
<!DOCTYPE html>
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
attribute vec2 vTexCoord;
varying vec2 fTexCoord;
varying vec4 fColor;
uniform mat4 vs_ViewMatrix;
uniform mat4 vs_ProjMatrix;
void main()
{
fColor = vColor;
fTexCoord = vTexCoord;
gl_Position = vs_ProjMatrix * vs_ViewMatrix * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform sampler2D fs_texture;
void main()
{
gl_FragColor = fColor * texture2D(fs_texture, fTexCoord);
}
</script>
<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="TexturedCube.js"></script>
<body>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
<br/>
<button id= "xButton">Rotate X</button>
<button id= "yButton">Rotate Y</button>
<button id= "zButton">Rotate Z</button>
<input id="eyesliderx" type="range" min="-5" max="5" value="0" class="slider">
<input id="eyeslidery" type="range" min="-5" max="5" value="0" class="slider">
<input id="eyesliderz" type="range" min="-5" max="5" value="2" class="slider">
<input id="atsliderx" type="range" min="-5" max="5" value="0" class="slider">
<input id="atslidery" type="range" min="-5" max="5" value="0" class="slider">
<input id="atsliderz" type="range" min="-100" max="100" value="0" class="slider">
<input id="upsliderx" type="range" min="-1" max="1" value="0" class="slider">
<input id="upslidery" type="range" min="-1" max="1" value="1" class="slider">
<input id="upsliderz" type="range" min="-1" max="1" value="0" class="slider">
</body>
</html>
答案 0 :(得分:1)
36是多维数据集的所有6个边的索引数。 6将是2个三角形的索引数。
更改var
var twoTriangles = 36;
到
var twoTriangles = 6;
但这不是唯一的问题。可能你从6变为36,因为twoTriangles = 6
只能看到立方体的第一面。这是因为循环中出现了一个区分大小写的拼写错误,它会绘制多维数据集的6个边:
objOffset = 0; // <------ "objOffset" instead of "objOffSet"
for (var txtUnit = 0; txtUnit < 6; ++txtUnit)
{
gl.uniform1i(fs_textureLoc, txtUnit);
gl.drawArrays(gl.TRIANGLES, objOffset, twoTriangles);
objOffset += twoTriangles;
}