<script src="glMatrix-0.9.6.min.js"></script>
<script>
let vertexstring = `
attribute vec4 a_position;
uniform mat4 proj;
attribute vec2 outUV;
varying vec2 inUV;
void main(void){
gl_Position = proj * a_position;
inUV = outUV;
}
`;
let fragmentstring = `
precision mediump float;
uniform sampler2D texture;
uniform sampler2D texture1;
uniform float anim;
varying vec2 inUV;
void main(void){
vec4 color1 =texture2D(texture,inUV);
vec4 color2 =texture2D(texture1, vec2(inUV.x + anim, inUV.y));
gl_FragColor = color1 + color2 ;
}
`;
var projMat4 = mat4.create();
var webgl;
var uniformTexture = 0;
var uniformTexture1 = 0;
var uniformAnim = 0;
var count = 0;
var texture0;
var texture1;
function webglStart() {
init();
tick();
}
function tick() {
request(tick)
draw();
};
function init() {
initWebgl();
initShader();
initBuffer();
}
function initWebgl() {
let webglDiv = document.getElementById('myCanvas');
webgl = webglDiv.getContext("webgl");
webgl.viewport(0, 0, webglDiv.clientWidth, webglDiv.clientHeight);
mat4.ortho(0, webglDiv.clientWidth, webglDiv.clientHeight, 0, -1.0, 1.0, projMat4)
}
function initShader() {
let vsshader = webgl.createShader(webgl.VERTEX_SHADER);
let fsshader = webgl.createShader(webgl.FRAGMENT_SHADER);
webgl.shaderSource(vsshader, vertexstring);
webgl.shaderSource(fsshader, fragmentstring);
webgl.compileShader(vsshader);
webgl.compileShader(fsshader);
if (!webgl.getShaderParameter(vsshader, webgl.COMPILE_STATUS)) {
var err = webgl.getShaderInfoLog(vsshader);
alert(err);
return;
}
if (!webgl.getShaderParameter(fsshader, webgl.COMPILE_STATUS)) {
var err = webgl.getShaderInfoLog(fsshader);
alert(err);
return;
}
let program = webgl.createProgram();
webgl.attachShader(program, vsshader);
webgl.attachShader(program, fsshader)
webgl.linkProgram(program);
webgl.useProgram(program);
webgl.program = program
}
function initBuffer() {
let arr = [
0, 0, 0, 1, 0, 0,
0, 700, 0, 1, 0, 1,
700, 0, 0, 1, 1, 0,
700, 700, 0, 1, 1, 0,
]
*let index = [
0, 1, 2,
1, 2, 3
];**
let pointPosition = new Float32Array(arr);
let aPsotion = webgl.getAttribLocation(webgl.program, "a_position");
let triangleBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW);
webgl.enableVertexAttribArray(aPsotion);
webgl.vertexAttribPointer(aPsotion, 4, webgl.FLOAT, false, 6 * 4, 0);
let indexarr = new Uint8Array(index);// 这个地方 Uint16Array啥都不显示不出效果
let indexBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer);
webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, indexarr, webgl.STATIC_DRAW);
let uniformProj = webgl.getUniformLocation(webgl.program, "proj");
webgl.uniformMatrix4fv(uniformProj, false, projMat4);
attribOutUV = webgl.getAttribLocation(webgl.program, "outUV");
webgl.enableVertexAttribArray(attribOutUV);
webgl.vertexAttribPointer(attribOutUV, 2, webgl.FLOAT, false, 6 * 4, 4 * 4);
uniformTexture = webgl.getUniformLocation(webgl.program, "texture");
uniformTexture1 = webgl.getUniformLocation(webgl.program, "texture1");
texture1 = initTexture("fog.png");
texture0 = initTexture("山水.png");
}
function handleLoadedTexture(texture) {
webgl.bindTexture(webgl.TEXTURE_2D, texture);
webgl.texImage2D(webgl.TEXTURE_2D, 0, webgl.RGBA, webgl.RGBA, webgl.UNSIGNED_BYTE, texture.image);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MAG_FILTER, webgl.LINEAR);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MIN_FILTER, webgl.LINEAR);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.REPEAT);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.REPEAT);
}
function initTexture(imageFile, num) {
let textureHandle = webgl.createTexture();
textureHandle.image = new Image();
textureHandle.image.src = imageFile;
textureHandle.image.onload = function () {
handleLoadedTexture(textureHandle, num)
}
return textureHandle;
}
function draw() {
webgl.clearColor(0.0, 1.0, 0.0, 1.0);
webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);
webgl.enable(webgl.DEPTH_TEST);
//纹理变动
uniformAnim = webgl.getUniformLocation(webgl.program, "anim");
count = count + 0.01;
webgl.uniform1f(uniformAnim, count);
webgl.activeTexture(webgl.TEXTURE0);
webgl.bindTexture(webgl.TEXTURE_2D, texture0);
webgl.uniform1i(uniformTexture, 0);
webgl.activeTexture(webgl.TEXTURE1);
webgl.bindTexture(webgl.TEXTURE_2D, texture1);
webgl.uniform1i(uniformTexture1, 1);
**webgl.drawElements(webgl.TRIANGLES, 6, webgl.UNSIGNED_BYTE, 0);**
// webgl.drawArrays(webgl.TRIANGLES, 0, 6);
}
function request(callback) {
return window.requestAnimationFrame(callback);
};
</script>
</head>
<body onload="webglStart()">
<canvas id='myCanvas' width="1024" height='768'></canvas>
</body>
你好。一般在webgl遇到纹理花边这种问题,直接考虑两种情况。
情况一:
uv坐标错误:这个不言而喻,说明你uv坐标在映射到顶点的时候匹配的是不对的。我们来具体分析下你的代码
let arr = [
0, 0, 0, 1, 0, 0,
0, 700, 0, 1, 0, 1,
700, 0, 0, 1, 1, 0,
700, 700, 0, 1, 1, 0,
]
通过shader里面输入我们看到a_position
输入的是vec4
,所以定义的bufferdata中前4个值是顶点,同样的道理得到后2个就是uv坐标。我们观察uv明显是有问题的,我们绘制的是一个长方形,我们图片也是一个长方形,很明显最后一行700, 700, 0, 1, 1, 0,
是有问题的哈。
情况二:该情况一般在图片处理的时候存在问题,如下面代码
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MAG_FILTER, webgl.LINEAR);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MIN_FILTER, webgl.LINEAR);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.REPEAT);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.REPEAT);
webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.REPEAT);函数表示纹理映射方式,本质也是对于shader的封装,也是对于uv坐标的改变,封装成webglAPI。关键是第3个参数,REPEAT
,现在代表的是如果你的图片默认比你填充的范围小的话,它会重复进行填充。很明显按照正常逻辑你现在如果至少不会是这样“拉丝”,最不行也应该是纹理重复。当然有些情况我们也需要“拉丝”,这时候你需要用到APICLAMP_TO_EDGE
,使用该参数会达到你“拉丝”效果,也就是边缘拉伸效果哈。