Mic*_*rer 5 shader webgl rust webgl2
问题描述
你好!在我们的 WebGL 应用程序中,我们绘制了许多(甚至数十万)个形状,我们想发现当前鼠标下方的形状。我正在寻找一种有效的方法。
细节
这些形状是用Signed Distance Functions定义的。每个形状都是通过将预定义的 sdf 片段着色器应用于方形多边形(2 个三角形)来绘制的。每个形状都uint
在 Rust 端分配了一个唯一的 ID ( )(我们在这里使用 WASM)。这个想法是将场景渲染两次(在 WebGL 1.0 中)或一次到多个渲染目标(在 WebGL 2.0 中),其中一个目标是编码为颜色的 ID。然后我们可以使用readPixels
查询颜色并获取鼠标下形状的ID。不幸的是,我们尝试的每个解决方案都有一些缺点。
要求
到目前为止他所尝试的
RGBA32UI
纹理类型。在这个解决方案中,我们每个通道使用 32 位,因此我们可以使用 2 个通道来表示我们的 ID。不幸的是,混合仅适用于 RGBA 模式,并且仅当颜色缓冲区具有定点或浮点格式时才适用。我们需要某种形式的混合,因为在绘制形状(如圆形)时,某些部分需要透明。在 ID 颜色输出的情况下,我们的 alpha 始终为 0 或 1。RGBA
的质地和转换uint
到float
通过使用GLSL intBitsToFloat然后回float
至uint
在生锈。不幸的是,这在 GLSL 330 中可用,而我们仅限于 WebGL 中的 GLSL 300。RGB32UI
纹理并discard
用于某些像素。这会起作用,但它会导致性能问题,我们宁愿不喜欢使用它。float
,使用它代替uint
,并将其渲染为RGBA
纹理,然后将其转换回uint
Rust 端。这个解决方案的问题是它非常复杂,我们不能使用所有的 32 位(我们需要对可能的 NAN 编码格外小心),我们觉得应该有更好的方法来做到这一点。混合被认为是需要浮点值的每片段函数的一部分,因此在渲染到非标准化整数纹理时它没有效果。
规范第 4.1节列出了像素/片段发生的 9 种操作。
第 4.1.7 节“混合”是 9 个操作中的第 7 个操作,表示
仅当颜色缓冲区具有定点格式时才应用混合。如果颜色缓冲区具有整数格式,则继续下一步操作。
换句话说,如果您使用整数格式,则会跳过混合操作。
discard
相反,如果 alpha 值低于给定阈值,您可以简单地提取片段。
if(alpha < 0.5) discard;
output_id = uvec4(input_symbol_id,input_instance_id,0,1);
Run Code Online (Sandbox Code Playgroud)