永远都不知道如何在twgl中进行纹理工作
cannot ever figure out how to do texture jobs in twgl
这是我为vs/fs编写的代码,也是我想放在画布上的一个简单立方体。为了长度起见,省略了部分。
<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
是否真的设置好了。
我有很多方法可以检查这个。
使用WebGL检查器
使用标准的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服务器来读取纹理。请注意,运行web服务器是很麻烦的。一个非常好的在这里。只需下载操作系统的版本,然后
path/to/devd-download/devd path/to/project
然后转到http://localhost:8000/nameOfYourHtmlFile.html
我认为这不是问题所在,因为如果是这样的话,你会在JavaScript控制台中看到一个关于无法加载纹理的明显错误,但你没有在JavaScript控制台中提到错误
- Javascript:selenium Web驱动程序isDisplayed()不工作
- jQuery UI自动完成突然停止工作
- AngularJS UI路由器不能像ng路由器那样工作
- HTML5音频加载和播放获胜'我不能在iPad上工作
- JavaScript打印功能使日历停止工作
- Javascript.getHours()工作不正常
- 为什么这在IE中的工作方式与在Firefox中不同
- 视频HTML没有'无法在Internet Explorer 11上工作
- 扩展移相器按钮类不工作
- Firebase迁移-简单的Firebase.set没有'不再工作了——旧的还是新的
- 谷歌地图不是以HTML显示,而是在JS Fiddle上工作
- 正在尝试使用if和else添加类,但无法正常工作
- Jquery FadeIn FadeOut 只工作一次
- Foreach无法在Typescript中工作
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- 为什么不是't窗口.恢复正常工作吗?(javascript/jquery)
- JS可以在Chrome中工作,但不能在Firefox中工作
- ajaxToolkit PopupControlExtender不工作.过时的
- 永远都不知道如何在twgl中进行纹理工作
- 使用Three.js对球体进行纹理处理;不能在智能手机上工作