【发布时间】:2016-07-13 16:48:25
【问题描述】:
我是 WebGL 编程的初学者。
我在 Three.JS 中制作了一个 Web 应用程序,它在画布上绘制了一个正弦波,偶尔会有噪音。在它们被绘制之后,我将它们淡化。最终效果如下所示:
由于 Three.JS 的速度问题,我正在尝试在 WebGL 中制作应用程序。我可以在 WebGL 中绘制一个普通的正弦波,但不知道如何达到相同的效果,我可以绘制一个波,以某种方式将其保存在缓冲区中,然后将其淡出。
这是我目前拥有的(在 WebGL 中):
另外,这里是相关代码:
this.gl;
try {
this.gl = this.canvas.getContext('experimental-webgl',{antialias: false});
} catch (e) {
alert('WebGL not supported.');
}
//set position of vertices in clip coordinates
this.vtxShaderSrc = "\n\
attribute vec2 position;\n\
uniform vec2 viewport;\n\
\n\
void main(void){\n\
\n\
gl_Position = vec4((position/viewport)*2.0-1.0, 0.0, 1.0);\n\
}";
//fragment shader returns the color of pixel
this.fmtShaderSrc = "\n\
precision mediump float;\n\
\n\
\n\
\n\
void main(void){\n\
int r = 255;\n\
int g = 255;\n\
int b = 255;\n\
gl_FragColor = vec4(r/255,g/255,b/255,1.);\n\
}";
this.getShader = function(source, type){
var shader = this.gl.createShader(type);
this.gl.shaderSource(shader, source);
this.gl.compileShader(shader);
return shader;
}
this.vtxShader = this.getShader(this.vtxShaderSrc, this.gl.VERTEX_SHADER);
this.fmtShader = this.getShader(this.fmtShaderSrc, this.gl.FRAGMENT_SHADER);
this.program = this.gl.createProgram();
//attach fragment and vertex shader to program
this.gl.attachShader(this.program, this.vtxShader);
this.gl.attachShader(this.program, this.fmtShader);
//link program to WebGL
this.gl.linkProgram(this.program);
//get position attribute and enable it in vertex shader
this._position = this.gl.getAttribLocation(this.program, 'position');
this.gl.enableVertexAttribArray(this._position);
//tell WebGL to use this program
this.gl.useProgram(this.program);
//create buffers
this.vertexBuffer = this.gl.createBuffer();
this.facesBuffer = this.gl.createBuffer();
this.lineVertices = [];
this.faceCount = [];
//bind them to WebGL
this.bindVertexBuffer = function(){
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.lineVertices), this.gl.STREAM_DRAW);
}
this.bindFacesBuffer = function(){
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.facesBuffer);
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.faceCount), this.gl.STREAM_DRAW);
}
this.bindVertexBuffer();
this.bindFacesBuffer();
//set background color to black
this.gl.clearColor(0.0,0.0,0.0,1.0);
//draw on canvas
this.draw = function(){
this.gl.enable(this.gl.BLEND);
this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
this.gl.vertexAttribPointer(this._position, 2, this.gl.FLOAT, false, 8*2, 0);
var loc = this.gl.getUniformLocation(this.program, 'viewport');
this.gl.uniform2f(loc, this.canvas.width, this.canvas.height);
//draw only if number of lines is greater than 0
if(this.faceCount.length > 0){
this.gl.drawElements(this.gl.LINE_STRIP, this.faceCount.length/4, this.gl.UNSIGNED_SHORT, 0);
}
this.gl.disable(this.gl.BLEND);
}
//update vertices and faces so next call to this.draw() updates the wave
this.update = function(newPts){
this.lineVertices = newPts;
this.bindVertexBuffer();
var faces = [];
for(var i = 0; i < this.lineVertices.length; i++) faces.push(i);
this.faceCount = faces;
this.bindFacesBuffer();
}
感谢任何帮助/指针。谢谢
【问题讨论】:
-
有趣。如果我可以问的话,three.js 实现的瓶颈是什么?
-
@user01 我用来在three.js 中渲染线条的方法会绘制额外的线条,并在绘制更多线条时应用较低的不透明度。它适用于一个甚至两个波(比如 sin 和 cos 波)。但是,我计划在一张画布上重叠更多的波浪。随着传入点数增加到数万,这开始显着降低 FPS。直接处理 WebGL 显然会将此性能提高 20-50 倍。我正在尝试模仿此人使用的渲染方法:codeflow.org/entries/2013/feb/04/high-performance-js-heatmaps
-
跟踪亮度变量或类似的东西。它应该从 1.0 开始,然后随着时间的推移将其降低到 0。将其发送到 GPU 并将
gl_FragColor乘以亮度。也可以将亮度降低完全移至 GPU,但我不确定这是否是您正在寻找的。span>
标签: javascript canvas webgl