gpt4 book ai didi

arrays - THREE.js - 作为 Uniform 的大型 int 数组

转载 作者:行者123 更新时间:2023-12-01 10:26:56 26 4
gpt4 key购买 nike

我想为 Three.js 编写一个片段着色器,它需要一个包含 10000 个整数的大数组。当我尝试在着色器的 glsl 代码中声明这样的数组时:

uniform int colorGrid[10000];

然后着色器渲染器抛出
ERROR: too many uniform

我还有什么其他选择 - 如何将如此大的数据块传递给片段着色器?

最佳答案

纹理是大数组。在纹理中传递整数有点困难,但并非不可能(对于 WebGL2,见下文)。您要么需要将整数值拆分为纹理的红色、绿色、蓝色和 alpha channel ,要么使用 FLOAT 纹理,这将为您提供高达 2^24 的整数值

要将整数打包到纹理中,您可以执行以下操作

// assumes unsigned ints
setPixelFromInt(pixels, width, x, y, intValue) {
var r = (intValue >> 24) & 0xFF;
var g = (intValue >> 16) & 0xFF;
var b = (intValue >> 8) & 0xFF;
var a = (intValue >> 0) & 0xFF;
var offset = (y * width + x) * 4;
pixels[offset + 0] = r;
pixels[offset + 1] = g;
pixels[offset + 2] = b;
pixels[offset + 3] = a;
}

var width = 100;
var height = 100;
var pixels = new Uint8Array(width * height * 4);

...

要在着色器中取回您的值,请执行以下操作?
uniform vec2 textureDimensions;
uniform sampler2D arrayTexture;

int getValueFromTexture(sampler2D arrayTexture, vec2 textureDimensions, int index) {
float x = mod(float(index), textureDimensions.x);
float y = floor(float(index) / textureDimensions.x);
vec2 uv = (vec2(x, y) + .5) / textureDimensions;
vec4 color = texture2D(arrayTexture, uv);
return int(color.r * 256.0 * 256.0 * 256.0 +
color.b * 256.0 * 256.0 +
color.g * 256.0 +
color.a);
}

确保将过滤设置为 gl.NEAREST

注意:我实际上并没有运行该代码,但它说明了这个想法

在 WebGL2 中,您可以拥有 8、16 或 32 位的整数纹理,并且在着色器中有 texelFetch 函数,该函数将提取特定 lod 的特定 texel 的值,因此无需过滤。还有一个 textureSize 函数,因此您不必手动传递统一的纹理大小。
  const int lod = 0
ivec2 textureDimensions = textureSize(arrayTexture, lod);
int x = index % textureDimensions.x;
int y = index / textureDimensions.x;
ivec4 color = texelFetch(arrayTexture, ivec2(x,y), lod);

关于arrays - THREE.js - 作为 Uniform 的大型 int 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31276114/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com