纹理喷溅超过5个纹理

时间:2017-05-02 01:16:07

标签: opengl graphics directx textures shader

我正在寻找一种解决方案,在一块地形中存储超过5种不同的纹理,我只找到了这个解决方案的一部分。我必须将所有纹理(512x512)打包成一个大纹理(8192x8192)然后在着色器中我必须使用来自splat纹理的r,g,b值来计算纹理id。但是如何从r,g,b值计算这个id。什么是配方? enter image description here

1 个答案:

答案 0 :(得分:2)

所以你得到了地图(左纹理/图像),其中每个地形段存储了 ID 的表面类型。比你有纹理图谱(右纹理)和16x16=256纹理,并希望为地形着色(底部图像)生成组合纹理。

  1. 地图纹理

    您没有指定其格式和编码,但我怀疑这是您要求的。因此,您获得256纹理意味着每个 ID 需要8bit。如果您使用32bit RGBA 整数格式,则最多可以存储4个 ID

  2. <强>编码/解码

    如果你需要更多,那么使用更多的地图纹理或更喜欢地图集中的纹理数量。例如,对于5个ID,您需要floor(32/5)=6 bits/ID,因此您需要在地图册中添加最多64个纹理(但仍有2个备用位,因此一个 ID 仍然可以使用{ {1}}或两个 ID 可以使用256纹理。)

    对于所有这些粗略的你需要对地图纹理进行整数采样,以防万一看:

    而不是浮动128值。 r,g,b格式的5 ID GPU解码的整数的数学公式看起来像这样(未经测试只是说明性的):

    r8g8b8a8

    同样 CPU编码

    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;
    

    未对代码进行测试,因此可能会出现反向 RGBA 顺序或错误假设的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; 位宽(它们应与重新调整的值匹配。