纹理飞溅超过 5 个纹理
Texture splatting more than 5 textures
我正在寻找一种在一块地形中存储超过 5 个不同纹理的解决方案,但我只找到了该解决方案的一部分。我必须将我所有的纹理 (512x512) 打包到一个大纹理 (8192x8192) 中,然后在着色器中我必须使用来自 splat 纹理的 r、g、b 值计算纹理 id。但是如何根据 r、g、b 值计算此 id。什么是公式?
所以你得到了地图(左 texture/image),其中 ID 的 表面类型存储在每个地形段中。比起您拥有具有 16x16=256
纹理的纹理图集(右纹理),并希望为地形着色(下图)生成组合纹素。
贴图纹理
您没有指定其格式和编码,但我怀疑这是您要求的。所以你有 256
个纹理,这意味着你需要 8bit
每个 ID。如果您使用 32bit
RGBA 整数格式,您最多可以存储 4 个 ID's.
encoding/decoding
如果您需要更多,那么可以使用更多贴图纹理,或者喜欢地图集中的纹理数量。例如,对于 5 个 ID,你有 floor(32/5)=6 bits/ID
所以你需要在你的图集中有最大 64
个纹理(但仍然有 2 个备用位,所以一个 ID 可以仍然使用 256
或两个 ID 的 可以使用 128
纹理。)
当然,您需要对地图纹理进行整数采样,以防万一,请参阅:
- Precise control over texture bits in GLSL
而不是浮动 r,g,b
值。 5
IDs GPU decoding from r8g8b8a8
format 的整数数学方程可能看起来像这样(未经测试只是说明性的) :
uniform usampler2D tex;
uvec4 a=texture(tex, ...); // fetch 4x8 bits
uint b=0; // construct 32 bit int
b|=uint(a.r);
b|=uint(a.g)<<8;
b|=uint(a.b)<<16;
b|=uint(a.a)<<32;
uint ID1=(b )&0x3F; // decode ID's
uint ID2=(b>> 6)&0x3F;
uint ID3=(b>>12)&0x3F;
uint ID4=(b>>18)&0x3F;
uint ID5=(b>>24)&0x3F;
和类似的CPU编码:
uint a=0; // construct 32 bit int
a|=(ID1&0x3F);
a|=(ID2&0x3F)<< 6;
a|=(ID3&0x3F)<<12;
a|=(ID4&0x3F)<<18;
a|=(ID5&0x3F)<<24;
map_texture_data[...]=a;
代码未经过测试,因此可能会出现反向 RGBA 顺序或错误假定的 uint
位宽(它们应与 rem-ed 值匹配。
我正在寻找一种在一块地形中存储超过 5 个不同纹理的解决方案,但我只找到了该解决方案的一部分。我必须将我所有的纹理 (512x512) 打包到一个大纹理 (8192x8192) 中,然后在着色器中我必须使用来自 splat 纹理的 r、g、b 值计算纹理 id。但是如何根据 r、g、b 值计算此 id。什么是公式?
所以你得到了地图(左 texture/image),其中 ID 的 表面类型存储在每个地形段中。比起您拥有具有 16x16=256
纹理的纹理图集(右纹理),并希望为地形着色(下图)生成组合纹素。
贴图纹理
您没有指定其格式和编码,但我怀疑这是您要求的。所以你有
256
个纹理,这意味着你需要8bit
每个 ID。如果您使用32bit
RGBA 整数格式,您最多可以存储 4 个 ID's.encoding/decoding
如果您需要更多,那么可以使用更多贴图纹理,或者喜欢地图集中的纹理数量。例如,对于 5 个 ID,你有
floor(32/5)=6 bits/ID
所以你需要在你的图集中有最大64
个纹理(但仍然有 2 个备用位,所以一个 ID 可以仍然使用256
或两个 ID 的 可以使用128
纹理。)当然,您需要对地图纹理进行整数采样,以防万一,请参阅:
- Precise control over texture bits in GLSL
而不是浮动
r,g,b
值。5
IDs GPU decoding fromr8g8b8a8
format 的整数数学方程可能看起来像这样(未经测试只是说明性的) :uniform usampler2D tex; uvec4 a=texture(tex, ...); // fetch 4x8 bits uint b=0; // construct 32 bit int b|=uint(a.r); b|=uint(a.g)<<8; b|=uint(a.b)<<16; b|=uint(a.a)<<32; uint ID1=(b )&0x3F; // decode ID's uint ID2=(b>> 6)&0x3F; uint ID3=(b>>12)&0x3F; uint ID4=(b>>18)&0x3F; uint ID5=(b>>24)&0x3F;
和类似的CPU编码:
uint a=0; // construct 32 bit int a|=(ID1&0x3F); a|=(ID2&0x3F)<< 6; a|=(ID3&0x3F)<<12; a|=(ID4&0x3F)<<18; a|=(ID5&0x3F)<<24; map_texture_data[...]=a;
代码未经过测试,因此可能会出现反向 RGBA 顺序或错误假定的
uint
位宽(它们应与 rem-ed 值匹配。