繁体   English   中英

如何在GLSL / WebGL的浮点数中存储状态标志

[英]How to store state flags in floating point numbers for GLSL / WebGL

我最近了解了有关使用位掩码将布尔标志存储为整数的信息 我想知道如何执行此操作以将布尔标志存储到JavaScript中或从JavaScript中检索布尔标志,以及将标志存储到GLSL中或从中检索标志。 我认为这需要浮点位掩码 ,而不是整数位掩码。 这样,我可以在JavaScript中对某些状态标志进行纹理编码,然后在GLSL中解压缩它们。 同样,如果我将数据作为状态标志写入GLSL中的像素,则可以在JavaScript中读取它们。

在WebGL2的GLSL ES 3.0中,就像大多数语言一样,也有位操作

uint flags = ??;

...

bool flag1 = (flags & 0x1) > 0;
bool flag2 = (flags & 0x2) > 0;
bool flag3 = (flags & 0x4) > 0;

在WebGL1中,您可以修改最大值

float flags = ??;

bool flag1 = mod(flags, 2.0) > 0.;
bool flag2 = mod(floor(flags / 2.0), 2.0) > 0.;
bool flag3 = mod(floor(flags / 4.0), 2.0) > 0.;

只要flagshighp值并且是正整数,就应该对前23位有效。

当然,这取决于flags来源。 例如,如果您在纹理或属性中将标志存储为UNSIGNED_BYTE ,则将其作为每个通道的8位值(红色,绿色,蓝色,alpha)拉出。 8位小于23位限制,例如

vec4 flags = texture2D(textureWithFlags, someUV) * 255.0;

现在flags.rflags[0]是前8位, flags.g是后8位, flags.g

要么

attribute vec4 flags;

在其中使用UNSIGNED_BYTE值设置属性并进行normalize = false的设置,就像在每个标志通道上方都是原始数据的8位一样

GLSL不建议分支。 通常,如果您想做2个或更多不同的事情,而不是添加标志,请为每个变体编写或生成着色器。 这是大多数3D引擎所做的工作,包括Unity,Unreal,Three.js等。

另一方面,有时可以在适当时执行诸如stepmix类的事情,而不是分支。 例如

vec4 color1 = ??
vec4 color2 = ??
float useColor2 = mod(flags, 2.0);  // will be 0.0 or 1.0
vec4 color = mix(color1, color2, useColor2);

上面的代码中没有分支。

用同样的方式

vec4 color;
if (x < 100.0)
  color = color1;
} else {
  color = color2;
}

可以翻译成

vec4 color = mix(color1, color2, step(100.0, x));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM