【发布时间】:2018-11-23 21:49:49
【问题描述】:
对于一个与荣誉学分无关的课程项目,我需要使用 WebGL 来显示我选择用作纹理的图像,然后变形纹理以使其看起来像是在以某种方式移动或变化。
为此,我选择对雨滴纹理进行变形,使其看起来像雨滴从屏幕上落下。我有一个风景背景纹理(一个 .jpg 图像),我想用雨滴纹理(一个 .png 图像)覆盖它,但我不知道如何覆盖背景纹理,以便我可以在同时。我现在拥有的代码仅显示背景图像。
谁能帮我解释一下我做错了什么,以及我该如何解决这个问题?如果您需要我上传我的部分代码来查看,请告诉我。我几乎不了解 WebGL,所以我不知道要显示代码的哪个区域以查看我哪里出错了。据我所知,整个事情可能都是错误的。
编辑:我被告知要添加代码,所以由于我不知道要显示什么 sn-p,所以这是我的整个 javascript 和 html 文件:
还请注意:此代码仅适用于 FireFox!谷歌浏览器会报错! (虽然我认为它会给出一个错误,因为我没有给出.html文件中引用的文件)*
var canvas;
var gl;
var Index = 0;
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 1),
vec2(1, 0),
vec2(0, 0)
];
var vertices = [
vec2( -1, -1 ),
vec2( -1, 1 ),
vec2( 1, 1 ),
vec2( 1, 1 ),
vec2( 1, -1 ),
vec2( -1, -1 )
];
var pointsArray = [];
//PROGRAMS
var program1; //for background
var program2; //for rain texture
var program3; //for rain texture updates
//TEXTURES
var texture1; //background image (STATIC IMAGE)
var texture2; // Raindrop texture (bounce between 2 and 3)
var texture3; // Raindrop texture (transform to be sent between 2 and 3)
//BUFFERS--------------------------------------------------------------------
var framebuffer;
var buffer1; //buffer for static background (texture1) vertices
var buffer2; //buffer for static background (texture1) texcoordinates
var buffer3; //buffer for raindrops (texture2) vertices
var buffer4; //buffer for raindrops (texture2) texcoordinates
var buffer5; //buffer for texture3 vertices
var buffer6; //buffer for texture3 texcoordinates
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
//----------------------------------------------------------------------------------------------------------------------------------------
//BACKGROUND texture
texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
// Fill the texture with a blue screen (fill canvas) FILLER!!!
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2048, 1024, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([0, 0, 255, 255]));
// load image
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1);
// Get the IMG tag by its ID
var bgpic = document.getElementById("background");
gl.bindTexture(gl.TEXTURE_2D, texture1);
// Load data from the IMG
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bgpic);
gl.generateMipmap(gl.TEXTURE_2D);
//------------------------------------------------------------------------------------------------------------------------------------------
//RAINDROP TEXTURE
texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);
// Fill the texture with a blue screen (fill canvas) FILLER!!!
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2048, 1024, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array([0, 0, 255, 255]));
// load image
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1);
// Get the IMG tag by its ID
var rainPic = document.getElementById("raindrop");
gl.bindTexture(gl.TEXTURE_2D, texture2);
// Load data from the IMG
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, rainPic);
gl.generateMipmap(gl.TEXTURE_2D);
//------------------------------------------------------------------------------------------------------------------------------------------
//EMPTY TEXTURE TO PASS TEXTURE2 TO
texture3 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2048, 1024, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
//------------------------------------------------------------------------------------------------------------------------------------------
// Allocate a frame buffer object
framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
framebuffer.width = 4096;
framebuffer.height = 2048;
//------------------------------------------------------------------------------------------------------------------------------------------
// Attach color buffer
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture1, 0);
//------------------------------------------------------------------------------------------------------------------------------------------
// check for completeness
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if(status != gl.FRAMEBUFFER_COMPLETE) alert('Frame Buffer Not Complete');
//------------------------------------------------------------------------------------------------------------------------------------------
//
// Load shaders and initialize attribute buffers
//
program1 = initShaders( gl, "vertex-shader1", "fragment-shader1" );
program2 = initShaders( gl, "vertex-shader2", "fragment-shader2" );
program3 = initShaders(gl, "vertex-shader3","fragment-shader3");
//------------------------------------------------------------------------------------------------------------------------------------------
//PROGRAM 1 CODE
gl.useProgram( program1 );
gl.useProgram(program1);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture1);
// send data to GPU for normal render
buffer1 = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, buffer1);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW);
var vPosition = gl.getAttribLocation( program1, "vPosition" );
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
buffer2 = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, buffer2);
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoord), gl.STATIC_DRAW);
var vTexCoord = gl.getAttribLocation( program1, "vTexCoord");
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
gl.uniform1i( gl.getUniformLocation(program1, "texture1"), 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.viewport(0, 0, 2048, 1024);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
//------------------------------------------------------------------------------------------------------------------------------------------
//PROGRAM 2 CODE
gl.useProgram(program2);
// Create and initialize a buffer object
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture2);
buffer3 = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, buffer3 );
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program2, "vPosition" );
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
// Bind FBO and render
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.viewport(0, 0, 2048, 1024);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT );
// gl.drawArrays(gl.TRIANGLES, 0, numVertices);
// Bind to window system frame buffer, unbind the texture
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
//------------------------------------------------------------------------------------------------------------------------------------------
//PROGRAM 3 CODE
gl.useProgram(program3);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture3);
// send data to GPU for normal render
buffer5 = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, buffer5);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW);
var vPosition = gl.getAttribLocation( program3, "vPosition" );
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
buffer6 = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, buffer6);
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoord), gl.STATIC_DRAW);
var vTexCoord = gl.getAttribLocation( program3, "vTexCoord");
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
gl.uniform1i( gl.getUniformLocation(program3, "texture2"), 0);
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.viewport(0, 0, 2048, 1024);
render();
}
function render() {
// render to texture
//------------------------------------------------------------------------------------------------------------------------------------------
// SECTION FOR BACKGROUND TEXTURE!
//BACKGROUND TEXTURE: USE PROGRAM 1
gl.useProgram(program1);
gl.clear( gl.COLOR_BUFFER_BIT );
gl.drawArrays( gl.TRIANGLES, 0, 6 );
gl.bindFramebuffer( gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.clear( gl.COLOR_BUFFER_BIT );
gl.drawArrays(gl.TRIANGLES, 0, 6);
//------------------------------------------------------------------------------------------------------------------------------------------
//RAIN TEXTURE: USE PROGRAM 2
gl.useProgram(program2);
gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer);
if(flag) {
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture3, 0);
}
else {
gl.bindTexture(gl.TEXTURE_2D, texture3);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture2, 0);
}
//------------------------------------------------------------------------------------------------------------------------------------------
// RAIN TEXTURE: USE PROGRAM 3
gl.useProgram(program3);
gl.drawArrays( gl.TRIANGLES, 0, 6 );
gl.bindFramebuffer( gl.FRAMEBUFFER, null);
if(flag) gl.bindTexture(gl.TEXTURE_2D, texture2);
else gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.clear( gl.COLOR_BUFFER_BIT );
gl.drawArrays(gl.TRIANGLES, 0, 6);
flag = !flag
requestAnimFrame(render);
}
<!DOCTYPE html>
<html>
<script id="vertex-shader1" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 vTexCoord;
varying vec2 fTexCoord;
void main()
{
gl_Position = vPosition;
fTexCoord= vTexCoord;
}
</script>
<script id="vertex-shader2" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 vTexCoord;
varying vec2 fTexCoord;
void main()
{
gl_Position = vPosition;
fTexCoord= vTexCoord;
}
</script>
<script id="vertex-shader3" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 vTexCoord;
varying vec2 fTexCoord;
void main()
{
gl_Position = vPosition;
fTexCoord = vTexCoord;
}
</script>
<script id="fragment-shader1" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D texture1;
varying vec2 fTexCoord;
void
main()
{
gl_FragColor= texture2D(texture1, fTexCoord);
}
</script>
<script id="fragment-shader2" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D texture2;
varying vec2 fTexCoord;
void main()
{
gl_FragColor= texture2D(texture2, fTexCoord);
}
</script>
<script id="fragment-shader3" type="x-shader/x-fragment">
precision mediump float;
varying vec2 fTexCoord;
uniform sampler2D texture2;
void main()
{
float y= fTexCoord.y - 0.1;
float x= fTexCoord.x;
if(y < 0.0) {
y = 1.0;
x = fTexCoord.x + 0.1 ;
}
if(x > 1.0){
x = 0.0;
}
gl_FragColor = texture2D( texture2, vec2(x,y));
}
</script>
<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/InitShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="testingBG.js"></script>
<img src="Raindrops_scaled.png" id="raindrop" hidden />
<img src="Background.jpg" id="background" hidden />
<body>
<canvas id="gl-canvas" width="2048" height="1024">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
【问题讨论】:
-
您还应该在帖子中包含代码和输出。
标签: javascript html webgl textures