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

GLSL Compute Shader生成Worley纹理出现块状损坏问题求助

GLSL Compute Shader实现Worley纹理出现块状损坏纹理

我在实现Worley纹理生成时遇到问题:HLSL版本的算法运行完全正常,但GLSL Compute Shader版本生成的纹理出现异常的块状损坏。

以下是相关代码:

GLSL Compute Shader代码

#version 450 core

layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;

layout(rgba32f, binding = 0) uniform image3D imgOutput;

uniform float resolution;
uniform uint  num_blocks_A;

layout(std140, binding = 3) buffer points_A{
    vec3 points[];
}points;


const vec3 offset[] =
{
    // center
    vec3(0,0,0),
    // front face
    vec3(-1, -1, 1),
    vec3(-1,  0, 1),
    vec3(-1,  1, 1),
    vec3(0,  -1, 1),
    vec3(0,   0, 1),
    vec3(0,   1, 1),
    vec3(1,  -1, 1),
    vec3(1,   0, 1),
    vec3(1,   1, 1),

    vec3(-1, -1, 0),
    vec3(-1,  0, 0),
    vec3(-1,  1, 0),
    vec3(0,  -1, 0),
    vec3(0,   1, 0),
    vec3(1,  -1, 0),
    vec3(1,   0, 0),
    vec3(1,   1, 0),

    vec3(-1, -1, -1),
    vec3(-1,  0, -1),
    vec3(-1,  1, -1),
    vec3(0,  -1, -1),
    vec3(0,   0, -1),
    vec3(0,   1, -1),
    vec3(1,  -1, -1),
    vec3(1,   0, -1),
    vec3(1,   1, -1)

};


float max_component(vec3 vec) {
    return max(vec.x, max(vec.y, vec.z));
}

float min_component(vec3 vec) {
    return min(vec.x, min(vec.y, vec.z));
}


float Worley( uint num_blocks, vec3 pos) {

    vec3 block_pos = floor(pos * num_blocks);
    float min_distance_square = 1;

    for (int i = 0; i < 27; i++){
        vec3 neighbor_block_pos = block_pos + offset[i];

        if (min_component(neighbor_block_pos) == -1 || max_component(neighbor_block_pos) == num_blocks) {
            vec3 wrap_block_pos = mod(neighbor_block_pos + num_blocks, num_blocks);
            int  wrap_block_id  = int(wrap_block_pos.x + num_blocks * (wrap_block_pos.y + num_blocks * wrap_block_pos.z));

            vec3 wrap_point  =  points.points[wrap_block_id];
            
            for (int j = 0; j < 27; j++){
                vec3 distance_vector = pos - (wrap_point + offset[j]);
                min_distance_square = min(min_distance_square, dot(distance_vector, distance_vector));
            }
        }
        else {
            int  neighbor_block_id       = int(neighbor_block_pos.x + num_blocks * (neighbor_block_pos.y + num_blocks * neighbor_block_pos.z));
            vec3 neighbor_block_point    = points.points[neighbor_block_id];
            vec3 distance_vector         = pos - neighbor_block_point;
            min_distance_square          = min(min_distance_square, dot(distance_vector, distance_vector));
        }

    }

    return sqrt(min_distance_square);
}

void main() {
    vec4 value = vec4(1.0, 0.0, 0.0, 1.0);
    ivec3 texelCoord = ivec3(gl_GlobalInvocationID.xyz);
    
    float u = gl_GlobalInvocationID.x / resolution;
    float v = gl_GlobalInvocationID.y / resolution;
    float w = gl_GlobalInvocationID.z / resolution;

    vec3 pos = vec3(u,v,w);

    float min_distance_A = 1 - Worley(num_blocks_A, pos) * 4;
    float final_color = min_distance_A;

    value = vec4(vec3(min_distance_A), 1.0f);

    imageStore(imgOutput, texelCoord, value);
}

C++/OpenGL相关代码

纹理生成方法

void GenWorleyCloudBaseTexture(int width, int height, int depth) {
    texture3D->SetDim(width, height, depth, GL_RGBA32F, GL_RGBA);

    unsigned int num_blocks_A = 8;
    auto points_A = GenWorleyPoints(num_blocks_A);

    std::unique_ptr<StorageBuffer> buffer = std::make_unique<StorageBuffer>(points_A.data(), sizeof(glm::vec3) * points_A.size(), 3);
    buffer->Bind();

    compute_program->uniform("num_blocks_A", num_blocks_A);
    compute_program->uniform("resolution", (float) width);

    compute_program->Dispatch(texture3D.get(), width/8 , height/8, depth/8, GL_RGBA32F);
}

Compute Shader类的Dispatch方法

void Dispatch(tex3D* t, int num_groups_x, int num_groups_y, int num_groups_z, GLuint internalFormat = GL_RGBA32F) {
    use();
    glBindImageTexture(0, t->ogl_texture_3D, 0, GL_TRUE, 0, GL_WRITE_ONLY, internalFormat);
    glDispatchCompute((unsigned int)num_groups_x, (unsigned int)num_groups_y, (unsigned int)num_groups_z);
    
    glMemoryBarrier(GL_ALL_BARRIER_BITS);
}

内容的提问来源于stack exchange,提问作者John1337

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:40:04