You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:20:35