[英]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.;
只要flags
是highp
值並且是正整數,就應該對前23位有效。
當然,這取決於flags
來源。 例如,如果您在紋理或屬性中將標志存儲為UNSIGNED_BYTE
,則將其作為每個通道的8位值(紅色,綠色,藍色,alpha)拉出。 8位小於23位限制,例如
vec4 flags = texture2D(textureWithFlags, someUV) * 255.0;
現在flags.r
或flags[0]
是前8位, flags.g
是后8位, flags.g
。
要么
attribute vec4 flags;
在其中使用UNSIGNED_BYTE值設置屬性並進行normalize = false的設置,就像在每個標志通道上方都是原始數據的8位一樣
GLSL不建議分支。 通常,如果您想做2個或更多不同的事情,而不是添加標志,請為每個變體編寫或生成着色器。 這是大多數3D引擎所做的工作,包括Unity,Unreal,Three.js等。
另一方面,有時可以在適當時執行諸如step
和mix
類的事情,而不是分支。 例如
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.