[英]cannot ever figure out how to do texture jobs in twgl
This is the code I have for vs/fs and a simple cube that I want to put on to my canvas. 这是我为vs / fs编写的代码,以及我想要放在画布上的简单多维数据集。 some of the part is omitted for the sake of lengthiness.
为了冗长,省略了一些部分。
<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>
the cube 立方体
...
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);
};
the cube worked fine without texture but when I tried to put texture on, it never works I tried almost everything and I still can't figure out how to put texture on. 这个立方体工作得很好而没有纹理,但是当我试图将纹理打开时,它从不起作用我几乎尝试了所有东西,我仍然无法弄清楚如何将纹理放在上面。 so, how can i put texture on?
所以,我怎么能把纹理放在上面?
any hints would be very much appreciated. 任何提示都将非常感激。
*********edit I have managed to successfully upload the texture coordinates and uniforms but the image does not show up and the cube is colored light blue. *********编辑我已成功上传纹理坐标和制服,但图像没有显示,立方体颜色为浅蓝色。 any suggestions would be very much appreciated.
任何建议将非常感谢。
It would be nice if you could provide a working example instead of just parts of the code. 如果您能提供一个工作示例而不仅仅是代码的一部分,那将是很好的。 There's several typos in the code above.
上面的代码中有几个拼写错误。 For example in the
setUniforms
part there's no closing }
. 例如,在
setUniforms
部分中没有关闭}
。 In the createTexture
part there's no quotes on the url. 在
createTexture
部分中,url上没有引号。 You spelled highp
as highhp
and texture2D
as texture2d
. 你将
highp
拼写为highhp
,将texture2D
拼写为texture2d
。 I assume if you say it's running though without textures those are just transcription errors because if not you should see very clear errors in the JavaScript console. 我假设如果你说没有纹理它正在运行那些只是转录错误,因为如果不是你应该在JavaScript控制台中看到非常明显的错误。
It's not clear what's wrong but when debugging WebGL the first I'd do is check the JavaScript console. 目前尚不清楚是什么问题,但在调试WebGL时,我要做的第一件事就是检查JavaScript控制台。 Are there any messages about un-renderable textures?
是否有关于不可渲染纹理的消息?
No? 没有? Then the next thing i'd do is change the fragment shader to a solid color
接下来我要做的就是将片段着色器更改为纯色
<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>
If you see your cube then yes, the issue is related to the texture. 如果你看到你的立方体然后是,那么问题与纹理有关。 If not the issue is somewhere else.
如果不是,问题就在其他地方。
Let's assume you see a red cube. 我们假设你看到一个红色的立方体。 Ok, next thing is to check the texture coordinates.
好的,接下来要检查纹理坐标。 I'd change the fragment shader to this
我将片段着色器更改为此
<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>
You should see the cube now with red->green shading. 您现在应该使用红色 - >绿色阴影看到立方体。 If not you've got bad texture coordinates.
如果不是你的纹理坐标不好。
If that looks correct the next thing I might try is put the shader back the way it was originally then check if the variable texture
is actually set. 如果看起来正确,我可能尝试的下一件事就是将着色器放回原来的样式,然后检查是否实际设置了变量
texture
。
There's a bunch of ways I could check this. 有很多方法可以检查这个。
Use the WebGL Inspector 使用WebGL检查器
Use the standard JavaScript debugger. 使用标准的JavaScript调试器。 Put a breakpoint on the
setUniforms
part. 在
setUniforms
部分放置一个断点。 Inspect the variables 检查变量
Do something like this 做这样的事情
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);
Now open the JavaScript console and type u.texSampler
. 现在打开JavaScript控制台并输入
u.texSampler
。 It should print something like 它应该打印出类似的东西
WebGLTexture {}
If it doesn't then probably texture
is not the variable you think it is 如果没有那么
texture
可能不是你认为的变量
One other question is are you rendering constantly using requestAnimationFrame as in 另一个问题是你是否经常使用requestAnimationFrame进行渲染
function render() {
// draw stuff like maybe call someCube.draw(drawingState)
...
requestAnimationFrame(render);
}
requestAnimationFrame(render);
I ask because textures are loaded asynchronously so if you are only rendering once then you won't see any textures because they have not yet been loaded. 我问,因为纹理是异步加载的,所以如果你只渲染一次,那么你将看不到任何纹理,因为它们还没有被加载。
You have a few options. 你有几个选择。
Render constantly (like the example above) 不断渲染(如上例所示)
twgl will default to a 1x1 pixel texture so rendering should work. twgl将默认为1x1像素纹理,因此渲染应该有效。 Then the image is finally loaded it will update the texture
然后图像最终加载它将更新纹理
Wait for the texture to load. 等待纹理加载。
If you don't want to render until the texture is ready then you can add a callback to twgl.createTexture
and it will call you back when the texture is ready. 如果您不希望渲染直到纹理准备就绪,那么您可以向
twgl.createTexture
添加回调,它会在纹理准备好时回调您。
The other thing to do is to start with a working sample 另一件事是从一个工作样本开始
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>
One more question, are you running a webserver? 还有一个问题,你在运行网络服务器吗? WebGL requires a web server to read textures.
WebGL需要Web服务器来读取纹理。 Note, running a web server is trival.
请注意,运行Web服务器很简单。 A really good one is here .
一个非常好的是在这里 。 Just download the version for your OS then
只需下载适用于您的操作系统的版本
path/to/devd-download/devd path/to/project
Then go to http://localhost:8000/nameOfYourHtmlFile.html
然后转到
http://localhost:8000/nameOfYourHtmlFile.html
I'm assuming this was not the issue because if it was you'd have seen a clear error in the JavaScript console about not being able to load the texture but you haven't mentioned errors in the JavaScript console 我假设这不是问题,因为如果是这样你在JavaScript控制台中看到一个明显的错误,即无法加载纹理,但你没有在JavaScript控制台中提到错误
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.