GLSL - imageAtomicRGBA8Avg и альфа-канал - PullRequest
0 голосов
/ 20 июня 2020

Я пытаюсь получить atomi c усреднение, работающее над шейдером вокселизации на основе https://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf

Код шейдера:

#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);
}

Насколько Насколько я понимаю, он использует альфа-значение в качестве счетчика для скользящего среднего компонентов xyz. Что, если я все еще хочу, чтобы исходное альфа-значение записывалось в тексель?

Я попытался добавить это в конец функции imageatomicrgba8avg:

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

Но приложение почти мгновенно вылетает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...