javascript - 在 WebGL 中渲染多个对象

标签 javascript rendering webgl

我已尝试按照 this questions 的答案给出的建议进行操作但我仍然无法弄清楚 WebGL 程序的“渲染流程”到底是如何工作的。
我只是想在 Canvas 上绘制两个三 Angular 形,它以一种相当不确定的方式工作:有时两个三 Angular 形都被渲染,有时只有第二个三 Angular 形(第二个最后一个绘制的一个)被渲染。

Lucky run

Out of luck

(它似乎取决于渲染时间:奇怪的是,它花费的时间越长,最终渲染两个三 Angular 形的可能性就越大)编辑:不正确,尝试一遍又一遍地刷新,两个三 Angular 形有时会出现在非常快速的渲染上(〜55毫秒),有时会出现在运行时间较长的渲染上(〜120毫秒)。 似乎是一种重复出现的模式,在页面第一次呈现时,两个三 Angular 形会显示,而在随后的重复刷新中,红色三 Angular 形要么显示正常,要么显示很短的时间时间,然后闪烁消失。
显然我在这里遗漏了一些东西,让我用伪代码解释我的程序流程(如果需要可以包括真实代码),看看我是否做错了什么:

var canvas = new Canvas(/*...*/);
var redTriangle = new Shape(/* vertex positions & colors */);
var blueTriangle = new Shape(/* vertex positions & colors */);
canvas.add(redTriangle, blueTriangle);

canvas.init(); //compiles and links shaders, calls gl.enableVertexAttribArray()
               //for vertex attributes "position" and "color"

for(shape in canvas) {
    for(bufferType in [PositionBuffer, ColorBuffer]) {
        shape.bindBuffer(bufferType); //calls gl.bindBuffer() and gl.bufferData()
                                      //This is equivalent to the initBuffers()
                                      //function in the tutorial
    }
}

for(shape in canvas) {
    shape.draw();
    //calls:
    //-gl.bindBuffer() and gl.vertexAttribPointer() for each buffer (position & color),
    //-setMatrixUniforms()
    //-drawArrays()
    //This is equivalent to the drawScene() function in the tutorial
}

尽管我已经将指令包装在对象方法中,试图使 WebGL 的使用更加面向对象,但在我看来,我已经完全遵守了 this lesson 上的指令。 (比较类(class)的源代码和我自己的代码),因此我无法弄清楚我做错了什么。
我什至尝试只使用一个 for(shape in canvas) 循环,如下所示:

for(shape in canvas) {
    for(bufferType in [PositionBuffer, ColorBuffer]) {
        shape.bindBuffer(bufferType); //calls gl.bindBuffer() and gl.bufferData()
                                      //This is equivalent to the initBuffers()
                                      //function in the tutorial
    }
    shape.draw();
    //calls:
    //-gl.bindBuffer() and gl.vertexAttribPointer() for each buffer (position & color),
    //-setMatrixUniforms()
    //-drawArrays()
    //This is equivalent to the drawScene() function in the tutorial
}

但是好像没有什么效果。 有什么线索吗?

最佳答案

我猜问题是默认情况下 WebGL Canvas 在每次合成时都会被清除

尝试将 WebGL 上下文创建更改为

var gl = someCanvas.getContext("webgl", { preserveDrawingBuffer: true });

我只是猜测您的应用程序正在异步执行操作,这意味着每个三 Angular 形都是为了响应某些事件而绘制的?因此,如果两个事件碰巧发生得足够快(在单个合成之间),那么您就会得到两个三 Angular 形。如果它们出现在不同的复合 Material 上,那么您只会看到第二个。

preserveDrawingBuffer: true 表示“每次合成后不清除”。清除是默认设置,因为它允许对某些设备(特别是 iOS)进行某些优化,并且大多数 WebGL 应用程序会在每次绘制操作开始时清除。少数不清除的应用可以设置 preserveDrawingBuffer: true

在您的特定情况下,angulargl-canvas.js的第21行

options = {alpha: false, premultipliedAlpha: false};

尝试将其更改为

options = {alpha: false, premultipliedAlpha: false, preserveDrawingBuffer: true};

关于javascript - 在 WebGL 中渲染多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25834400/

相关文章:

javascript - typescript : Is there a way to get all the keys in a Javascript object with nested properties?

javascript - Textarea 在 IE7 中不呈现

java - 光滑的 2d unicode 字体有问题

javascript - WebGL 中的索引缓冲区?

javascript - Javascript 中的返回函数及其工作原理?

javascript - 在 HTML5 中选择多个

javascript - Object.assign 和 just assign 的区别

javascript - Angular 7 3D 模型查看器

javascript - 如何在 JavaScript 中向窗口公开 Math 对象属性?

带有命令行 Blender 参数的 Python 脚本