永远无法弄清楚如何在 twgl 中做纹理工作
cannot ever figure out how to do texture jobs in twgl
这是我为 vs/fs 准备的代码和一个我想放在 canvas 上的简单立方体。篇幅省略部分内容
<script id="cube-vs" type="notjs">
precision highhp float;
attribute vec3 vpos;
attribute vec3 vnormal;
attribute vec2 vtex;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform mat4 view;
uniform mat4 proj;
uniform mat4 model;
uniform vec3 lightdir;
uniform vec3 cubecolor;
void main(void) {
gl_Position = proj * view * model * vec4(vpos, 1.0);
vec4 normal = normalize(model * vec4(vnormal,0.0));
float diffuse = .2 + abs(dot(normal, vec4(lightdir,0.0)));
fColor = (cubecolor * diffuse);
fTexCoord = vtex;
}
</script>
<script id="cube-fs" type="notjs">
precision highhp float;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2d(texSampler, fTexCoord);
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
}
</script>
立方体
...
Cube.prototype.init = function(drawingState) {
var gl=drawingState.gl;
// create the shaders once - for all cubes
if (!shaderProgram) {
shaderProgram = twgl.createProgramInfo(gl, ["tree-vs", "tree-fs"]);
}
if (!buffers) {
var arrays = {
vpos : { numComponents: 3, data: [...] },
vnormal : {numComponents:3, data: [...]},
vtex : {numComponents:2, data: [
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
]},
indices : {[...]}
};
buffers = twgl.createBufferInfoFromArrays(gl,arrays);
}
if (!texture) {
texture = twgl.createTexture(gl, {src:textures/tree.jpg});
}
};
Cube.prototype.draw = function(drawingState) {
var modelM = twgl.m4.scaling([this.size*1.4,this.size*1.4,this.size*1.4]);
twgl.m4.setTranslation(modelM,this.position,modelM);
var gl = drawingState.gl;
gl.useProgram(shaderProgram.program);
twgl.setBuffersAndAttributes(gl,shaderProgram,buffers);
twgl.setUniforms(shaderProgram,{
view:drawingState.view, proj:drawingState.proj, lightdir:drawingState.sunDirection,
cubecolor:this.color, model: modelM, texSampler: texture);
twgl.drawBufferInfo(gl, gl.TRIANGLES, buffers);
};
立方体在没有纹理的情况下工作正常
但是当我试着贴上纹理时,它从来没有用过
我几乎尝试了所有方法,但仍然不知道如何添加纹理。
那么,我怎样才能贴上纹理?
如有任何提示,我们将不胜感激。
*********编辑
我已经成功上传了纹理坐标和制服
但是图像没有显示出来,立方体是浅蓝色的。
任何建议将不胜感激。
如果您能提供一个工作示例而不只是部分代码,那就太好了。上面的代码中有几个错别字。例如,在 setUniforms
部分没有结束 }
。在 createTexture
部分,url 没有引号。您将 highp
拼写为 highhp
,将 texture2D
拼写为 texture2d
。我假设如果你说它是 运行 虽然没有纹理那只是转录错误因为如果不是你应该在 JavaScript 控制台中看到非常明显的错误。
不清楚哪里出了问题,但在调试 WebGL 时,我首先要做的是检查 JavaScript 控制台。是否有关于不可渲染纹理的消息?
没有?接下来我要做的就是将片段着色器更改为纯色
<script id="cube-fs" type="notjs">
precision highhp float;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2d(texSampler, fTexCoord);
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
gl_FragColor = vec4(1,0,0,1); // -------ADDED-------------------------
}
</script>
如果您看到立方体,那么是的,问题与纹理有关。如果不是,则问题出在其他地方。
假设您看到一个红色立方体。好的,接下来是检查纹理坐标。我会将片段着色器更改为此
<script id="cube-fs" type="notjs">
precision highhp float;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2d(texSampler, fTexCoord);
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
gl_FragColor = vec4(fTexCoord,0,1); // -------CHANGED-------------------------
}
</script>
您现在应该看到立方体带有红色->绿色阴影。否则你的纹理坐标不好。
如果看起来正确,我可能会尝试的下一件事是将着色器恢复到原来的状态,然后检查变量 texture
是否实际设置。
有很多方法可以检查这个。
使用标准 JavaScript 调试器。在 setUniforms
部分放置一个断点。检查变量
做这样的事情
var uniforms = {
view:drawingState.view,
proj:drawingState.proj,
lightdir:drawingState.sunDirection,
cubecolor:this.color,
model: modelM,
texSampler: texture,
};
window.u = uniforms;
twgl.setUniforms(shaderProgram, uniforms);
现在打开 JavaScript 控制台并输入 u.texSampler
。它应该打印类似
WebGLTexture {}
如果不是,那么可能 texture
不是您认为的变量
另一个问题是您是否经常使用 requestAnimationFrame 进行渲染,如
function render() {
// draw stuff like maybe call someCube.draw(drawingState)
...
requestAnimationFrame(render);
}
requestAnimationFrame(render);
我问是因为纹理是异步加载的,所以如果您只渲染一次,那么您将看不到任何纹理,因为它们尚未加载。
你有几个选择。
不断渲染(如上例)
twgl 将默认为 1x1 像素纹理,因此渲染应该可以进行。然后图像最终加载它会更新纹理
等待纹理加载。
如果您不想在纹理准备好之前渲染,那么您可以向 twgl.createTexture
添加一个回调,它会在纹理准备好时回调您。
另一件事是从工作样本开始
var m4 = twgl.m4; // <!------------ ADDED
var v3 = twgl.v3; // <!------------ ADDED
// not sure why these are globals?!???!
var shaderProgram; // <!------------ ADDED
var texture; // <!------------ ADDED
var buffers; // <!------------ ADDED
var canvas = document.querySelector("canvas"); // <!------------ ADDED
var drawingState = { // <!------------ ADDED
gl: canvas.getContext("webgl"), // <!------------ ADDED
view: m4.inverse(m4.lookAt([3,3,6], [0, 0, 0], [0, 1, 0])), // <!------------ ADDED
proj: m4.perspective( // <!------------ ADDED
Math.PI * 0.3, // <!------------ ADDED
canvas.clientWidth / canvas.clientHeight, // <!------------ ADDED
0.1, 10), // <!------------ ADDED
sunDirection: v3.normalize([2,3,-2]), // <!------------ ADDED
}; // <!------------ ADDED
function Cube() { // <!-------------------------------------- ADDED
this.size = 1; // <!-------------------------------------- ADDED
this.position = [0, 0, 0]; // <!-------------------------------------- ADDED
this.color = [1, 1, 1]; // <!-------------------------------------- ADDED
} // <!-------------------------------------- ADDED
Cube.prototype.init = function(drawingState) {
var gl=drawingState.gl;
// create the shaders once - for all cubes
if (!shaderProgram) {
shaderProgram = twgl.createProgramInfo(gl, ["cube-vs", "cube-fs"]); // <!---- CHANGED
}
if (!buffers) {
var arrays = {
vpos: { numComponents: 3, data: [1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1], },
vnormal: { numComponents: 3, data: [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1], },
vtex: { numComponents: 2, data: [1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1], },
indices: [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23],
};
buffers = twgl.createBufferInfoFromArrays(gl,arrays);
}
if (!texture) {
texture = twgl.createTexture(gl, {
src: "https://farm6.staticflickr.com/5795/21506301808_efb27ed699_q_d.jpg",
crossOrigin: "", // <!--------- not needed if on same server which "texture/tree.jpg" is
});
}
};
Cube.prototype.draw = function(drawingState) {
var modelM = twgl.m4.scaling([this.size*1.4,this.size*1.4,this.size*1.4]);
twgl.m4.setTranslation(modelM,this.position,modelM);
var gl = drawingState.gl;
gl.useProgram(shaderProgram.program);
twgl.setBuffersAndAttributes(gl,shaderProgram,buffers);
twgl.setUniforms(shaderProgram,{
view:drawingState.view, proj:drawingState.proj, lightdir:drawingState.sunDirection,
cubecolor:this.color, model: modelM, texSampler: texture});
twgl.drawBufferInfo(gl, gl.TRIANGLES, buffers);
};
var cube = new Cube(); // <!------------ ADDED
cube.init(drawingState); // <!------------ ADDED
function render() { // <!------------ ADDED
var gl = drawingState.gl // <!------------ ADDED
gl.enable(gl.DEPTH_TEST); // <!------------ ADDED
cube.draw(drawingState); // <!------------ ADDED
requestAnimationFrame(render); // <!------------ ADDED
} // <!------------ ADDED
requestAnimationFrame(render); // <!------------ ADDED
canvas { border: 1px solid black; }
<script id="cube-vs" type="notjs">
//precision highp float; <!---------------- CHANGED
attribute vec3 vpos;
attribute vec3 vnormal;
attribute vec2 vtex;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform mat4 view;
uniform mat4 proj;
uniform mat4 model;
uniform vec3 lightdir;
uniform vec3 cubecolor;
void main(void) {
gl_Position = proj * view * model * vec4(vpos, 1.0);
vec4 normal = normalize(model * vec4(vnormal,0.0));
float diffuse = .2 + abs(dot(normal, vec4(lightdir,0.0)));
fColor = (cubecolor * diffuse);
fTexCoord = vtex;
}
</script>
<script id="cube-fs" type="notjs">
precision highp float; // <!--------- CHANGED (should probably use mediump though)
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2D(texSampler, fTexCoord); // < !-------- CHANGED
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
}
</script>
<canvas></canvas>
<script src="https://twgljs.org/dist/twgl-full.min.js"></script>
还有一个问题,您 运行 是网络服务器吗? WebGL 需要一个网络服务器来读取纹理。请注意,运行 Web 服务器是微不足道的。 A really good one is here. Just download the version for your OS 然后
path/to/devd-download/devd path/to/project
然后去http://localhost:8000/nameOfYourHtmlFile.html
我假设这不是问题,因为如果是的话,您会在 JavaScript 控制台中看到一个关于无法加载纹理的明显错误,但您没有提到错误JavaScript 控制台
这是我为 vs/fs 准备的代码和一个我想放在 canvas 上的简单立方体。篇幅省略部分内容
<script id="cube-vs" type="notjs">
precision highhp float;
attribute vec3 vpos;
attribute vec3 vnormal;
attribute vec2 vtex;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform mat4 view;
uniform mat4 proj;
uniform mat4 model;
uniform vec3 lightdir;
uniform vec3 cubecolor;
void main(void) {
gl_Position = proj * view * model * vec4(vpos, 1.0);
vec4 normal = normalize(model * vec4(vnormal,0.0));
float diffuse = .2 + abs(dot(normal, vec4(lightdir,0.0)));
fColor = (cubecolor * diffuse);
fTexCoord = vtex;
}
</script>
<script id="cube-fs" type="notjs">
precision highhp float;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2d(texSampler, fTexCoord);
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
}
</script>
立方体
...
Cube.prototype.init = function(drawingState) {
var gl=drawingState.gl;
// create the shaders once - for all cubes
if (!shaderProgram) {
shaderProgram = twgl.createProgramInfo(gl, ["tree-vs", "tree-fs"]);
}
if (!buffers) {
var arrays = {
vpos : { numComponents: 3, data: [...] },
vnormal : {numComponents:3, data: [...]},
vtex : {numComponents:2, data: [
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
1,0,0,0,0,1,1,1,
]},
indices : {[...]}
};
buffers = twgl.createBufferInfoFromArrays(gl,arrays);
}
if (!texture) {
texture = twgl.createTexture(gl, {src:textures/tree.jpg});
}
};
Cube.prototype.draw = function(drawingState) {
var modelM = twgl.m4.scaling([this.size*1.4,this.size*1.4,this.size*1.4]);
twgl.m4.setTranslation(modelM,this.position,modelM);
var gl = drawingState.gl;
gl.useProgram(shaderProgram.program);
twgl.setBuffersAndAttributes(gl,shaderProgram,buffers);
twgl.setUniforms(shaderProgram,{
view:drawingState.view, proj:drawingState.proj, lightdir:drawingState.sunDirection,
cubecolor:this.color, model: modelM, texSampler: texture);
twgl.drawBufferInfo(gl, gl.TRIANGLES, buffers);
};
立方体在没有纹理的情况下工作正常 但是当我试着贴上纹理时,它从来没有用过 我几乎尝试了所有方法,但仍然不知道如何添加纹理。 那么,我怎样才能贴上纹理?
如有任何提示,我们将不胜感激。
*********编辑 我已经成功上传了纹理坐标和制服 但是图像没有显示出来,立方体是浅蓝色的。 任何建议将不胜感激。
如果您能提供一个工作示例而不只是部分代码,那就太好了。上面的代码中有几个错别字。例如,在 setUniforms
部分没有结束 }
。在 createTexture
部分,url 没有引号。您将 highp
拼写为 highhp
,将 texture2D
拼写为 texture2d
。我假设如果你说它是 运行 虽然没有纹理那只是转录错误因为如果不是你应该在 JavaScript 控制台中看到非常明显的错误。
不清楚哪里出了问题,但在调试 WebGL 时,我首先要做的是检查 JavaScript 控制台。是否有关于不可渲染纹理的消息?
没有?接下来我要做的就是将片段着色器更改为纯色
<script id="cube-fs" type="notjs">
precision highhp float;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2d(texSampler, fTexCoord);
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
gl_FragColor = vec4(1,0,0,1); // -------ADDED-------------------------
}
</script>
如果您看到立方体,那么是的,问题与纹理有关。如果不是,则问题出在其他地方。
假设您看到一个红色立方体。好的,接下来是检查纹理坐标。我会将片段着色器更改为此
<script id="cube-fs" type="notjs">
precision highhp float;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2d(texSampler, fTexCoord);
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
gl_FragColor = vec4(fTexCoord,0,1); // -------CHANGED-------------------------
}
</script>
您现在应该看到立方体带有红色->绿色阴影。否则你的纹理坐标不好。
如果看起来正确,我可能会尝试的下一件事是将着色器恢复到原来的状态,然后检查变量 texture
是否实际设置。
有很多方法可以检查这个。
使用标准 JavaScript 调试器。在
setUniforms
部分放置一个断点。检查变量做这样的事情
var uniforms = { view:drawingState.view, proj:drawingState.proj, lightdir:drawingState.sunDirection, cubecolor:this.color, model: modelM, texSampler: texture, }; window.u = uniforms; twgl.setUniforms(shaderProgram, uniforms);
现在打开 JavaScript 控制台并输入
u.texSampler
。它应该打印类似WebGLTexture {}
如果不是,那么可能
texture
不是您认为的变量
另一个问题是您是否经常使用 requestAnimationFrame 进行渲染,如
function render() {
// draw stuff like maybe call someCube.draw(drawingState)
...
requestAnimationFrame(render);
}
requestAnimationFrame(render);
我问是因为纹理是异步加载的,所以如果您只渲染一次,那么您将看不到任何纹理,因为它们尚未加载。
你有几个选择。
不断渲染(如上例)
twgl 将默认为 1x1 像素纹理,因此渲染应该可以进行。然后图像最终加载它会更新纹理
等待纹理加载。
如果您不想在纹理准备好之前渲染,那么您可以向
twgl.createTexture
添加一个回调,它会在纹理准备好时回调您。
另一件事是从工作样本开始
var m4 = twgl.m4; // <!------------ ADDED
var v3 = twgl.v3; // <!------------ ADDED
// not sure why these are globals?!???!
var shaderProgram; // <!------------ ADDED
var texture; // <!------------ ADDED
var buffers; // <!------------ ADDED
var canvas = document.querySelector("canvas"); // <!------------ ADDED
var drawingState = { // <!------------ ADDED
gl: canvas.getContext("webgl"), // <!------------ ADDED
view: m4.inverse(m4.lookAt([3,3,6], [0, 0, 0], [0, 1, 0])), // <!------------ ADDED
proj: m4.perspective( // <!------------ ADDED
Math.PI * 0.3, // <!------------ ADDED
canvas.clientWidth / canvas.clientHeight, // <!------------ ADDED
0.1, 10), // <!------------ ADDED
sunDirection: v3.normalize([2,3,-2]), // <!------------ ADDED
}; // <!------------ ADDED
function Cube() { // <!-------------------------------------- ADDED
this.size = 1; // <!-------------------------------------- ADDED
this.position = [0, 0, 0]; // <!-------------------------------------- ADDED
this.color = [1, 1, 1]; // <!-------------------------------------- ADDED
} // <!-------------------------------------- ADDED
Cube.prototype.init = function(drawingState) {
var gl=drawingState.gl;
// create the shaders once - for all cubes
if (!shaderProgram) {
shaderProgram = twgl.createProgramInfo(gl, ["cube-vs", "cube-fs"]); // <!---- CHANGED
}
if (!buffers) {
var arrays = {
vpos: { numComponents: 3, data: [1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1], },
vnormal: { numComponents: 3, data: [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1], },
vtex: { numComponents: 2, data: [1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1], },
indices: [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23],
};
buffers = twgl.createBufferInfoFromArrays(gl,arrays);
}
if (!texture) {
texture = twgl.createTexture(gl, {
src: "https://farm6.staticflickr.com/5795/21506301808_efb27ed699_q_d.jpg",
crossOrigin: "", // <!--------- not needed if on same server which "texture/tree.jpg" is
});
}
};
Cube.prototype.draw = function(drawingState) {
var modelM = twgl.m4.scaling([this.size*1.4,this.size*1.4,this.size*1.4]);
twgl.m4.setTranslation(modelM,this.position,modelM);
var gl = drawingState.gl;
gl.useProgram(shaderProgram.program);
twgl.setBuffersAndAttributes(gl,shaderProgram,buffers);
twgl.setUniforms(shaderProgram,{
view:drawingState.view, proj:drawingState.proj, lightdir:drawingState.sunDirection,
cubecolor:this.color, model: modelM, texSampler: texture});
twgl.drawBufferInfo(gl, gl.TRIANGLES, buffers);
};
var cube = new Cube(); // <!------------ ADDED
cube.init(drawingState); // <!------------ ADDED
function render() { // <!------------ ADDED
var gl = drawingState.gl // <!------------ ADDED
gl.enable(gl.DEPTH_TEST); // <!------------ ADDED
cube.draw(drawingState); // <!------------ ADDED
requestAnimationFrame(render); // <!------------ ADDED
} // <!------------ ADDED
requestAnimationFrame(render); // <!------------ ADDED
canvas { border: 1px solid black; }
<script id="cube-vs" type="notjs">
//precision highp float; <!---------------- CHANGED
attribute vec3 vpos;
attribute vec3 vnormal;
attribute vec2 vtex;
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform mat4 view;
uniform mat4 proj;
uniform mat4 model;
uniform vec3 lightdir;
uniform vec3 cubecolor;
void main(void) {
gl_Position = proj * view * model * vec4(vpos, 1.0);
vec4 normal = normalize(model * vec4(vnormal,0.0));
float diffuse = .2 + abs(dot(normal, vec4(lightdir,0.0)));
fColor = (cubecolor * diffuse);
fTexCoord = vtex;
}
</script>
<script id="cube-fs" type="notjs">
precision highp float; // <!--------- CHANGED (should probably use mediump though)
varying vec3 fColor;
varying vec3 fNormal;
varying vec2 fTexCoord;
uniform sampler2D texSampler;
void main(void) {
vec4 texColor = texture2D(texSampler, fTexCoord); // < !-------- CHANGED
gl_FragColor = vec4(fColor*texColor.xyz,1.0);
}
</script>
<canvas></canvas>
<script src="https://twgljs.org/dist/twgl-full.min.js"></script>
还有一个问题,您 运行 是网络服务器吗? WebGL 需要一个网络服务器来读取纹理。请注意,运行 Web 服务器是微不足道的。 A really good one is here. Just download the version for your OS 然后
path/to/devd-download/devd path/to/project
然后去http://localhost:8000/nameOfYourHtmlFile.html
我假设这不是问题,因为如果是的话,您会在 JavaScript 控制台中看到一个关于无法加载纹理的明显错误,但您没有提到错误JavaScript 控制台