簡體   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