GLSL - imageAtomicRGBA8Avg and alpha channel

0

I am trying to get atomic averaging working on a voxelization shader based on https://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf

Shader code:

#version 440 core
#extension GL_ARB_shader_image_load_store : require

layout(binding = 0) uniform sampler2D albedo;
layout(r32ui, binding = 1) uniform volatile uimage3D voxels;
layout(binding = 2) uniform sampler2DShadow shadowMap;

in vec2 uv;
in flat int axis;
in vec4 depthPosition;

vec4 convRGBA8ToVec4(uint val)
{
    return vec4(float((val & 0x000000FF)), 
    float((val & 0x0000FF00) >> 8U), 
    float((val & 0x00FF0000) >> 16U), 
    float((val & 0xFF000000) >> 24U));
}

uint convVec4ToRGBA8(vec4 val)
{
    return (uint(val.w) & 0x000000FF) << 24U | 
    (uint(val.z) & 0x000000FF) << 16U | 
    (uint(val.y) & 0x000000FF) << 8U | 
    (uint(val.x) & 0x000000FF);
}

void imageAtomicRGBA8Avg(layout(r32ui) volatile coherent     uimage3D grid, ivec3 coords, vec4 value)
{
    value.rgb *= 255.0;                 
    // optimize following calculations
    uint newVal = convVec4ToRGBA8(value);
    uint prevStoredVal = 0;
    uint curStoredVal;

    while((curStoredVal = imageAtomicCompSwap(grid, coords,     prevStoredVal, newVal)) 
        != prevStoredVal) {
        prevStoredVal = curStoredVal;
        vec4 rval = convRGBA8ToVec4(curStoredVal);
        rval.rgb = (rval.rgb * rval.a); // Denormalize
        vec4 curValF = rval + value;    // Add
        curValF.rgb /= curValF.a;       // Renormalize
        newVal = convVec4ToRGBA8(curValF);
    }
}

void main() {
    vec4 sampled = texture(albedo, uv);
    const int dim = imageSize(voxels).x;

    // TODO: uniform bias and stuff
    float shadowAmount = texture(shadowMap, vec3(depthPosition.xy, (depthPosition.z - 0.001)/depthPosition.w));

    ivec3 camPos = ivec3(gl_FragCoord.x, gl_FragCoord.y, dim * gl_FragCoord.z);
    ivec3 voxelPosition;
    if(axis == 1) {
        voxelPosition.x = dim - camPos.z;
        voxelPosition.z = camPos.x;
        voxelPosition.y = camPos.y;
    }
    else if(axis == 2) {
        voxelPosition.z = camPos.y;
        voxelPosition.y = dim - camPos.z;
        voxelPosition.x = camPos.x;
} else {
    voxelPosition = camPos;
}

    voxelPosition.z = dim - voxelPosition.z - 1;
    vec4 writeVal = vec4(sampled.rgb * shadowAmount, sampled.a);
    imageAtomicRGBA8Avg(voxels, voxelPosition, writeVal);
}

As far as I understand, it uses the alpha value as counter for a moving average of the xyz components. What if I still want original alpha value written to the texel?

I have tried adding this to the end of the imageatomicrgba8avg function:

 vec4 finalVal = convRGBA8ToVec4(curStoredVal);
 finalVal.a = value.a;
 uint finalValu8 = convVec4ToRGBA8(finalVal);
 imageAtomicCompSwap(grid, coords, curStoredVal, finalValu8);

But the application almost instantly crashes.

c++
opengl
glsl
voxel
asked on Stack Overflow Jun 20, 2020 by Nico van Bentum • edited Jun 21, 2020 by Nico van Bentum

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0