glsl 高性能原子計數器

主要講解知識點:
1.GL_ATOMIC_COUNTER_BUFFER 使用。
2.採用原子計數器記錄片元中的紅色通道分量大於綠色分量的個數。
效果驗證圖:
這裏寫圖片描述
可以看到統計結果,並且得出當我們放大圖片的時候,處理的片元數量是增大的,縮小的時候GPU處理的片元數量減少。

實現
初始化原子緩存對象

glBindBuffer(GL_ARRAY_BUFFER, 0);
    GLuint *counters;
    glGenBuffers(1, &_actomCounterBuf);
    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _actomCounterBuf);

    glBufferData(GL_ATOMIC_COUNTER_BUFFER, 2 * sizeof(GLuint), NULL, GL_DYNAMIC_COPY);

    counters = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY);
    counters[0] = 0;
    counters[1] = 1;
    glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
    //將原子緩存對象,與原子換成指定目標點進行綁定。
    glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _actomCounterBuf);

每次渲染完成後對統計結果進行回讀(從GPU讀取到CPU)

glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _actomCounterBuf);
    GLuint * cont = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);

    char buffer[50];
    sprintf(buffer, "red_texels: %d \n green_texels: %d\n", cont[0],cont[1]);
    _m_simpleStats->SetString(buffer);

    glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);

原子計數器片元着色器的實現

//glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _actomCounterBuf);
//這裏對應綁定點0 ,這裏的偏移量指定的爲字節偏移量大小
layout(binding = 0, offset = 0) uniform atomic_uint red_texels;
layout(binding = 0, offset = 4) uniform atomic_uint green_texels;
layout(binding = 0) uniform sampler2D my_texture;
#UNIFORMS

layout(location = 1) in block{
    vec2 texCoord;
} In;

layout(location = 0) out vec4 fragment_color;

void main(void)
{
    vec4 texel_color = texture(my_texture, In.texCoord);

    if (texel_color.r > texel_color.g)
    {
    //採用高效的原子計數,目的是防止不同的片源在同一個時刻訪問或修改同一塊顯存位置。
        atomicCounterIncrement(red_texels);
    }
    else
    {
        atomicCounterIncrement(green_texels);
    }

    fragment_color = texel_color;
}

總結:
我們可以利用原子計數器做一些片源統計方面的工作。或是其它一些用途。

完整源碼文件下載:
https://t.zsxq.com/qrvJiYB

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章