【问题标题】:Texture splatting more than 5 textures纹理喷溅超过 5 个纹理
【发布时间】:2017-05-03 14:45:32
【问题描述】:

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

【问题讨论】:

  • 我不知道你在说什么。
  • 为什么要同时使用 OpenGL 和 DirectX 标签?什么是喷溅? Didi你的意思是混合吗?你知道通常有不止一个纹理单元...您可以通过混合和渲染所有的东西来组合更多纹理,每次通过不同的纹理...或者使用纹理组合单元或着色器代码一次使用更多纹理单元.我同意目前还不清楚你想要什么,所以 +Close 暂时...
  • 我已经编辑了我的帖子 :)
  • (1) 你为什么不使用数组纹理来代替——这样会容易得多。进行过滤。 (2) 你打算在三个或四个纹理相遇的地方做什么?

标签: opengl graphics directx textures shader


【解决方案1】:

所以你得到了地图(左纹理/图像),其中 ID's 表面类型存储每个地形段。比您拥有带有 16x16=256 纹理的纹理图集(右纹理)并且想要生成用于地形着色的组合纹素(下图)。

  1. 贴图纹理

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

  2. 编码/解码

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

    对于所有这些,您需要对地图纹理进行整数采样,以防万一,请参阅:

    而不是浮动r,g,b 值。 r8g8b8a8 格式的 5 IDs GPU 解码 的整数数学方程可能如下所示(未经测试,仅供说明):

    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 值匹配。

【讨论】:

  • 谢谢,很有帮助:)
猜你喜欢
  • 1970-01-01
  • 2013-09-23
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多