Javascript can';在webgl中,不能将画布渲染为纹理,但会渲染蓝色

Javascript can';在webgl中,不能将画布渲染为纹理,但会渲染蓝色,javascript,webgl2,Javascript,Webgl2,我正在尝试在webgl中将画布渲染为纹理 代码如下: gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture); // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255])); 第一行,texture是

我正在尝试在webgl中将画布渲染为纹理

代码如下:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture);
// gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
                 new Uint8Array([0, 0, 255, 255]));
第一行,
texture
是一个canvas dom元素,用红色填充,如果我将它附加到
document.body
中,它会呈现良好的效果。但这一行不会在webgl上呈现任何内容

如果我取消注释第二行,它会呈现蓝色

constfshadersource=`#版本300 es
精密中泵浮子;
外显vec4外显色;
均匀的二维u_纹理;
void main(){
outColor=纹理(u_纹理,vec2(0.0));
}
`;
const vShaderSource=`#版本300 es
精密中泵浮子;
在vec2 a_位置;
void main(){
gl_位置=vec4(a_位置,0,1);
}
`;
main(document.getElementById('app'));
主要功能(要素){
const canvas=document.createElement('canvas'),
gl=canvas.getContext('webgl2');
元素。追加(画布);
const displayWidth=canvas.clientWidth,
displayHeight=canvas.clientHeight;
canvas.width=显示宽度;
canvas.height=显示高度;
let graphics=新图形({width:displayWidth,height:displayHeight},gl);
新循环(()=>{
graphics.render();
}).start();
}
功能图形(状态,gl){
常数{宽度,高度}=状态;
让vShader=createShader(gl,gl.VERTEX_着色器,vShaderSource);
设fShader=createShader(gl,gl.FRAGMENT_着色器,fShaderSource);
让程序=创建程序(gl、vShader、fShader);
设posAttrLocation=gl.getAttriblLocation(程序,“a_位置”);
设posBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,posBuffer);
/*
(-1, 1).( 1, 1)
.
(-1,-1).( 1,-1)
*/
让位置=[
-1, 1,
-1, -1,
1, -1,
-1, 1,
1,-1,
1, 1
];
总账缓冲数据(总账数组缓冲区、新Float32Array(位置)、总账静态绘图);
设vao=gl.createVertexArray();
bindVertexArray总帐(vao);
gl.EnableVertexAttributeArray(posAttrLocation);
设大小为2,
类型=gl.FLOAT,
正常化=错误,
步幅=0,
偏移量=0;
总账VertexAttributePointer(posAttrLocation,
大小,
类型,
规范化
大步走
抵消);
设glTexture=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,glTexture);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_字节,canvasTexture());
//gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,1,1,0,gl.RGBA,gl.UNSIGNED_字节,新的Uint8Array([0,0,255,255]);
让resUniformLocation=gl.getUniformLocation(程序,“u_分辨率”);
设texUniformLocation=gl.getUniformLocation(程序,“u_纹理”);
gl.clearColor(0,0,0,0);
this.render=()=>{
总图视口(0,0,总图画布宽度,总图画布高度);
总账清除(总账颜色缓冲位);
gl.useProgram(程序);
gl.uniform2f(重新聚合位置,gl.canvas.width,gl.canvas.height);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D,glTexture);
bindVertexArray总帐(vao);
gl.绘图阵列(gl.三角形,0,6);
};
}
函数canvasTexture(){
返回CanVastexture(256,256,(宽,高,画布,ctx)=>{
ctx.fillStyle='红色';
ctx.fillRect(0,0,w,h);
ctx.font='50pt漫画版';
ctx.fillStyle='白色';
ctx.textAlign='中心';
ctx.textb基线='中间';
ctx.fillText(“标签”,w/2,50);
返回画布;
});
具有CanVasTexture(宽度、高度、f)的函数{
var canvas=document.createElement('canvas');
画布宽度=宽度;
canvas.height=高度;
f(宽度、高度、画布、canvas.getContext('2d'));
const纹理=画布;
document.body.append(画布);
返回纹理;
}
}
函数createShader(gl、类型、源){
让着色器=gl.createShader(类型);
gl.shaderSource(着色器,源);
gl.compileShader(着色器);
让success=gl.getShaderParameter(着色器,gl.COMPILE\u状态);
如果(成功){
返回着色器;
}
console.error(gl.getShaderInfoLog(着色器));
gl.deleteShader(着色器);
返回null;
};
函数createProgram(gl、vShader、fShader){
让程序=gl.createProgram();
gl.attachShader(程序,vShader);
gl.attachShader(程序,fShader);
总账链接程序(程序);
让success=gl.getProgramParameter(程序,gl.LINK\u状态);
如果(成功){
返回程序;
}
控制台错误(gl.getProgramInfoLog(程序));
总账删除程序(程序);
返回null;
}
//循环库
函数循环(fn){
const perf=window.performance!==未定义?window.performance:日期;
const now=()=>perf.now();
const raf=window.requestAnimationFrame;
让running=false,
lastUpdate=now(),
帧=0;
this.start=()=>{
如果(正在运行){
归还这个;
}
运行=真;
lastUpdate=now();
帧=raf(刻度);
归还这个;
};
this.stop=()=>{
运行=错误;
如果(帧!=0){
取消(帧);
}
帧=0;
归还这个;
};
常数滴答=()=>{
帧=raf(刻度);
常数时间=现在();
const dt=时间-上次更新;
fn(dt);
lastUpdate=时间;
};
}
#应用程序画布{
位置:固定;
最高:50%;
底部:0;
左:50%;
右:0;
宽度:100vmin;
高度:70vmin;
转换:翻译(-50%,-25%);
图像渲染:优化速度;
光标:无;
保证金:自动;
}

您没有正确设置筛选

要渲染没有mips的纹理,必须将“最小过滤器”设置为“线性”或“最近”,因为这些模式不尝试使用mips

 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
或者你需要提供mips

 gl.generateMipmap(gl.TEXTURE_2D);

您没有正确设置筛选

要渲染没有mips的纹理,必须将“最小过滤器”设置为“线性”或“最近”,因为这些模式不尝试使用mips

 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
或者你需要提供mips

 gl.generateMipmap(gl.TEXTURE_2D);
纹理不是“mipmap complete”。设置
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MIN\u过滤器,gl.LINEAR)。附注a 1