Javascript WebGL纹理创建问题

Javascript WebGL纹理创建问题,javascript,google-chrome,firefox,opengl-es,webgl,Javascript,Google Chrome,Firefox,Opengl Es,Webgl,我正在编写一个光线跟踪程序,其主要思想是将.obj模型的三角形和索引保存到2个纹理中: a) 顶点纹理 b) 指数纹理 我这样做是为了在我的GLSL片段着色器中进行光线三角形相交,浏览器告诉我纹理有这个问题: a) Mozilla Firefox: 错误#1(具有顶点纹理):错误:WebGL:texImage2D:无效类型0x1406 错误#2(带索引纹理):错误:WebGL:texImage2D:无效类型0x1403 b) 谷歌浏览器: 两种纹理均出现错误:webgl无效\u枚举teximag

我正在编写一个光线跟踪程序,其主要思想是将.obj模型的三角形和索引保存到2个纹理中:

a) 顶点纹理 b) 指数纹理

我这样做是为了在我的GLSL片段着色器中进行光线三角形相交,浏览器告诉我纹理有这个问题:

a) Mozilla Firefox

错误#1(具有顶点纹理):错误:WebGL:texImage2D:无效类型0x1406

错误#2(带索引纹理):错误:WebGL:texImage2D:无效类型0x1403

b) 谷歌浏览器

两种纹理均出现错误:webgl无效\u枚举teximage2d无效纹理类型

代码如下:

Obj.prototype.initTextures = function(){

this.vertexTexture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, this.vertexTexture);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, this.vertexSize, 1, 0, gl.RGB, gl.FLOAT, new Float32Array(this.vertexArray));
gl.bindTexture(gl.TEXTURE_2D, null);

this.trianglesTexture = gl.createTexture();
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, this.trianglesTexture);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, this.faceSize, 1, 0, gl.RGB,  gl.UNSIGNED_SHORT, new Uint16Array(this.faceArray));
gl.bindTexture(gl.TEXTURE_2D, null);
}


出于显而易见的原因,this.vertexArray和this.faceArray都带有数据。

gl.RGB
/
gl.FLOAT
仅当您检查并启用浮点纹理时才允许使用纹理

var floatTextures = gl.getExtension('OES_texture_float');
if (!floatTextures) {
    alert('no floating point texture support');
    return;
}

gl.RGB
/
gl.UNSIGNED\u SHORT
纹理在WebGL上不存在。您可以尝试将无符号短值编码为
R*256+G*65536
或类似代码。或者也可以在这里使用浮动

注意:过滤浮动,如
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MIN\u FILTER,gl.LINEAR)
,是一个单独的扩展
OES\u TEXTURE\u float\u LINEAR
,但在您的情况下,因为您只使用
gl.NEAREST
,所以不需要检查该扩展

至于在纹理中放置顶点数据,您可能会发现您必须做一些工作来提取正确的值

要索引纹理中的值,需要计算一个纹理坐标,该坐标将访问正确的纹理。为此,您需要从第一个texel的中间访问到最后一个texel的中间

换句话说,如果我们有3个值(因此有3个texel),我们就会有这样的结果

     ------3x1 ----- texels ----------
     [         ][         ][         ]
 0.0 |<----------------------------->| 1.0
这正好在texel之间,所以我们添加一个half texel来得到这个

     [         ][         ][         ]
          |          |          |
        0.167       0.5       0.833
希望这是有道理的。这里有一个片段

var gl=document.querySelector(“canvas”).getContext(“webgl”);
var ext=gl.getExtension(“OES_纹理_浮动”);
如果(!ext){
警报(“需要OES_纹理_浮动扩展,因为我很懒”);
//返回;
}
if(gl.getParameter(gl.MAX_顶点_纹理_图像_单位)<2){
警报(“需要能够从顶点着色器访问纹理”);
//返回;
}
var m4=twgl.m4;
var v3=twgl.v3;
var program=twgl.createProgramFromScripts(gl,[“vshader”,“fshader”]);
var positionIndexLoc=gl.GetAttriblLocation(程序,“a_positionIndex”);
var normalIndexLoc=gl.getAttribLocation(程序,“a_normalIndex”);
var colorLoc=gl.getUniformLocation(程序,“u_颜色”);
var mvpMatrixLoc=gl.getUniformLocation(程序,“u_mvpMatrix”);
var mvMatrixLoc=gl.getUniformLocation(程序,“u_mvMatrix”);
var lightDirLoc=gl.getUniformLocation(
节目“u_lightDirection”);
变量u_位置SLOC=gl.getUniformLocation(
项目“u_位置”);
变量u_normalsLoc=gl.getUniformLocation(
程序,“u_法线”);
gl.uniform1i(u_位置sloc,0);//对位置使用纹理单元0
gl.uniform1i(u_normalsLoc,1);//对法线使用纹理单元1
//立方体数据
变量位置=[
-1,-1,-1,//0磅
+1,-1,-1,//1 rbb 2---3
-1,+1,-1,//2 ltb/|/|
+1,+1,-1,//3 RTB6---7|
-1,-1,+1,//4磅力|
+1,-1,+1,//5RBF | 0-|-1
-1,+1,+1,//6 ltf |/|/
+1,+1,+1,//7RTF4--5
];
风险价值指数=[
3,7,5,3,5,1,//对
6,2,0,6,0,4,//左
6,7,3,6,3,2,//顶部
0,1,5,0,5,4,//底部
7,6,4,7,4,5,//前面
2,3,1,2,1,0,//返回
];
变量法线=[
+1,  0,  0,
-1,  0,  0,
0, +1,  0,
0, -1,  0,
0,  0, +1,
0,  0, -1,
]
var指数=[
0,0,0,0,0,0,0,//对
1,1,1,1,1,1,//左
2,2,2,2,2,2,//顶部
3,3,3,3,3,3,//底部
4,4,4,4,4,4,//前面
5,5,5,5,5,5,//回来
];
功能除雾器(度){
返回度*数学PI/180;
}
函数上传索引(loc、数据、索引){
//将索引缩放到纹理坐标中
var scaledDices=新的Float32Array(index.length);
//要索引纹理中的值,我们需要
//计算将访问的纹理坐标
//正确的texel。要做到这一点,我们需要从
//从第一个texel的中间到第一个texel的中间
//最后一个特克斯。
//
//换句话说,如果我们有3个值(因此
//3特克斯)我们会有这样的
//
//----3x1----texel----------
//     [         ][         ][         ]
// 0.0 || 1.0
//
//如果我们只做索引/numvalue,我们会得到
//
//     [         ][         ][         ]
//     |          |          |
//     0.0       0.333       0.666
//
//正好在texel之间,所以我们添加了一个
//一个半特克塞尔来得到这个
//
//     [         ][         ][         ]
//          |          |          |
//        0.167       0.5       0.833
变量大小=data.length/3;
var-texel=1/尺寸;
var halfTexel=texel/2;
对于(var ii=0;ii     [         ][         ][         ]
          |          |          |
        0.167       0.5       0.833