GLSL顶点着色器如何传入uint_fast64_t?求替代实现方案
解决GLSL 330 Core无法使用64位整数顶点属性的问题
GLSL 330 Core版本不支持原生64位整数类型,也无法将64位整数作为顶点属性输入,你可以通过以下两种方式实现原有逻辑:
方案1:直接拆分数据为独立顶点属性
既然最终需要提取多个分量,不如直接将这些分量作为单独的顶点属性传入,省去位运算开销,代码更简洁:
#version 330 core #define CHUNK_SIZE 16 #define BLOCK_SIZE_X 0.1 #define BLOCK_SIZE_Y 0.1 #define BLOCK_SIZE_Z 0.1 // 直接传入拆分后的各个分量 layout(location = 0) in uint x_axis; // 原4位x轴坐标 layout(location = 1) in uint y_axis; // 原8位y轴坐标 layout(location = 2) in uint z_axis; // 原4位z轴坐标 layout(location = 3) in uint index_x; // 原24位x索引 layout(location = 4) in uint index_z; // 原24位z索引 layout(location = 5) in vec2 vertexUV; out vec2 UV; uniform mat4 MVP; void main() { float x = (x_axis + index_x * CHUNK_SIZE) * BLOCK_SIZE_X; float y = y_axis * BLOCK_SIZE_Y; float z = (z_axis + index_z * CHUNK_SIZE) * BLOCK_SIZE_Z; gl_Position = MVP * vec4(x, y, z, 1.0); UV = vertexUV; }
CPU端准备顶点数据时,直接将原本从64位整数中提取的各个分量,分别填入对应的顶点属性通道即可,无需再打包成64位整数。
方案2:拆分为两个32位uint模拟64位位运算
如果必须保留数据打包的方式,可将64位整数拆分为低32位和高32位两个uint传入,手动实现64位位运算逻辑:
#version 330 core #define CHUNK_SIZE 16 #define BLOCK_SIZE_X 0.1 #define BLOCK_SIZE_Y 0.1 #define BLOCK_SIZE_Z 0.1 // 传入64位整数的低32位与高32位 layout(location = 0) in uint pos_low32; layout(location = 1) in uint pos_high32; layout(location = 2) in vec2 vertexUV; out vec2 UV; uniform mat4 MVP; int getAxis(uint low, uint high, int choice) { switch (choice) { // x轴:原64位的bit59-62 → 对应高32位的bit27-30 case 0: return int((high >> 27) & 0xF); // y轴:原64位的bit23-30 → 对应低32位的bit23-30 case 1: return int((low >> 23) & 0xFF); // z轴:原64位的bit55-58 → 对应高32位的bit23-26 case 2: return int((high >> 23) & 0xF); // index_x:原64位的bit0-23 → 对应低32位的bit0-23 case 3: return int(low & 0x807FFFFF); // index_z:原64位的bit32-55 → 对应高32位的bit0-23 case 4: return int(high & 0x807FFFFF); default: return 0; } } void main() { int x_axis = getAxis(pos_low32, pos_high32, 0); int y_axis = getAxis(pos_low32, pos_high32, 1); int z_axis = getAxis(pos_low32, pos_high32, 2); int idx_x = getAxis(pos_low32, pos_high32, 3); int idx_z = getAxis(pos_low32, pos_high32, 4); float x = (x_axis + idx_x * CHUNK_SIZE) * BLOCK_SIZE_X; float y = y_axis * BLOCK_SIZE_Y; float z = (z_axis + idx_z * CHUNK_SIZE) * BLOCK_SIZE_Z; gl_Position = MVP * vec4(x, y, z, 1.0); UV = vertexUV; }
CPU端处理时,将原uint64_t数据拆分为低32位和高32位:
uint64_t original_value = ...; uint32_t low = static_cast<uint32_t>(original_value); uint32_t high = static_cast<uint32_t>(original_value >> 32);
再将这两个值分别传入对应的顶点属性通道。
内容的提问来源于stack exchange,提问作者Mike Kaipis
相关产品推荐
相关产品推荐

