Closed w0rm closed 7 years ago
This is looking very good!
However, I'm a bit worried about performance. Let's take the create example to illustrate:
[ renderBox
[ depth depthOptions ]
(...)
, renderFloor
[ depth { depthOptions | mask = False }
, stencil { stencilOptions | ref = 1, zpass = replace }
]
(...)
, renderBox
[ stencil { stencilOptions | func = equal, ref = 1, writeMask = 0 }
, depth depthOptions
]
(...)
]
This will produce the following gl*
calls:
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(WebGL.Constants.less);
gl.depthMask(True);
gl.depthRange(0, 1);
// draw box
gl.disable(gl.DEPTH_TEST);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(WebGL.Constants.less);
gl.depthMask(False);
gl.depthRange(0, 1);
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(WebGL.Constants.always, 1, 4294967295);
gl.stencilOp(WebGL.Constants.keep, WebGL.Constants.keep, WebGL.Constants.replace);
gl.stencilMask(4294967295);
// draw floor
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(WebGL.Constants.less);
gl.depthMask(True);
gl.depthRange(0, 1);
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(WebGL.Constants.equal, 1, 4294967295);
gl.stencilOp(WebGL.Constants.keep, WebGL.Constants.keep, WebGL.Constants.keep);
gl.stencilMask(0);
// draw box
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
...
// next iteration would repeat the above
While ideally, it would only produce these calls:
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(WebGL.Constants.less);
gl.depthMask(True);
gl.depthRange(0, 1);
// draw box
gl.depthMask(False);
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(WebGL.Constants.always, 1, 4294967295);
gl.stencilOp(WebGL.Constants.keep, WebGL.Constants.keep, WebGL.Constants.replace);
gl.stencilMask(4294967295);
// draw floor
gl.depthMask(True);
gl.stencilFunc(WebGL.Constants.equal, 1, 4294967295);
gl.stencilMask(0);
// draw box
gl.disable(gl.STENCIL_TEST);
...
// next iteration:
// draw box
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(WebGL.Constants.always, 1, 4294967295);
gl.stencilMask(4294967295);
// draw floor
gl.stencilFunc(WebGL.Constants.equal, 1, 4294967295);
gl.stencilMask(0);
// draw box
gl.disable(gl.STENCIL_TEST);
To accomplish that, we'd have to keep track of which settings are currently active and only do a call if something changes.
Whether this will be worth it would have to be benchmarked of course, but this link suggests that it's worth it. Except that this is for openGl and pretty old. But I suspect it would be similar with WebGL
@Zinggi I think this is not important at the current stage. We can add this optimisation later if needed, and it will be a patch change.
That's true. I will experiment with it once 2.0 is out, and if it does make a significant difference, we can patch it.
This is WIP on grouping settings, so we can be clever about enabling/disabling gl features and explicit about the default values.
Before, each function call would modify the environment for the next renderable. With these changes, we won't need to call
gl.enable/disable
, as we were doing in thecrate.elm
example that now has cool reflection effect thanks to @Zinggi.