[osg-users] passing uniforms to compute shader

Mary-Ann Zorra rebebaba2 at gmail.com
Mon Oct 31 03:43:34 PDT 2016


Hi,

ok, maybe it is easier in that way.

Here are the uniforms of the compute shader:

Code:

struct PointLight {
        vec4 position;
        vec4 color;
        vec4 paddingAndRadius;
};

// Shader storage buffer objects
layout(std140) uniform LightBuffer {
        PointLight data[1024];
} ;
layout (binding = 0, r32f) writeonly uniform  image2D targetTex;

// Uniforms
uniform sampler2D depthMap;
uniform vec2 screenSize;
uniform int lightCount;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;

// Shared values between all the threads in the group
shared uint minDepthInt;
shared uint maxDepthInt;
shared uint visibleLightCount;
shared vec4 frustumPlanes[6];
shared mat4 viewProjection;

#define TILE_SIZE 1
layout(local_size_x = TILE_SIZE, local_size_y = TILE_SIZE, local_size_z = 1) in;



And the uniforms of the fragment shader:

Code:


struct PointLight {
        vec4 position;
        vec4 color;
        vec4 paddingAndRadius;
};

// Shader storage buffer objects
layout(std140) uniform LightBuffer{
        PointLight data[1024];
} ;

uniform sampler2D VisibleLightIndicesBuffer;
uniform int numberOfTilesX;
uniform int totalLightCount;



And how I bind them to the compute shader: 

Code:

computeShaderStateset->addUniform(new osg::Uniform("depthMap",2));
    computeShaderStateset->setTextureAttributeAndModes(2,depthTexture, osg::StateAttribute::ON);
    computeShaderStateset->addUniform(new osg::Uniform("screenSize", osg::Vec2(windowWidth, windowHeight)));
    computeShaderStateset->addUniform(new osg::Uniform("lightCount", (int) lights->size()));
    computeShaderStateset->getOrCreateUniform("projectionMatrix", osg::Uniform::FLOAT_MAT4)->set(projectionMatrix);
    computeShaderStateset->getOrCreateUniform("viewMatrix", osg::Uniform::FLOAT_MAT4)->set(viewMatrix);

    //indices
    osg::ref_ptr<osg::Texture2D> indexTexture = new osg::Texture2D;
    indexTexture->setTextureSize(1024, 1024);
    indexTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture2D::LINEAR);
    indexTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture2D::LINEAR);
    indexTexture->setInternalFormat(GL_R32F);
    indexTexture->setSourceFormat(GL_RED);
    indexTexture->setSourceType(GL_FLOAT);
    indexTexture->bindToImageUnit(0, osg::Texture::WRITE_ONLY);
    computeShaderStateset->addUniform(new osg::Uniform("targetTex", (int)0));
    computeShaderStateset->setTextureAttributeAndModes(0, indexTexture.get());

//lights
    std::vector<char> byteLights = convertLightVector(lights);
    osg::ByteArray* bytes = new osg::ByteArray(&byteLights[0], &byteLights[sizeof(byteLights) * sizeof(char) * byteLights.size()]);
    osg::UniformBufferObject* uboLights = new osg::UniformBufferObject;
    uboLights->setUsage(GL_STATIC_DRAW);
    uboLights->setDataVariance(osg::Object::STATIC);
    bytes->setBufferObject(uboLights);
    osg::UniformBufferBinding* ubbLights = new osg::UniformBufferBinding(10, uboLights, 0, bytes->size());
    computeShaderStateset->setAttributeAndModes(ubbLights, osg::StateAttribute::ON);
    computeShaderProgram->addBindUniformBlock("LightBuffer", 10);



And to the fragment shader:


Code:
 //Uniforms
    mStateset->addUniform(new osg::Uniform("numberOfTilesX", (int) ((windowWidth + (windowWidth % 16)) / 16) ));
    mStateset->addUniform(new osg::Uniform("totalLightCount", (int) lights->size()));
    //indices
    mStateset->addUniform(new osg::Uniform("VisibleLightIndicesBuffer",1));
    mStateset->setTextureAttributeAndModes(1,indices, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

 //lights
    std::vector<char> byteLights = convertLightVector(lights);
    osg::ByteArray* bytes = new osg::ByteArray(&byteLights[0], &byteLights[sizeof(byteLights) * sizeof(char) * byteLights.size()]);
    osg::UniformBufferObject* uboLights = new osg::UniformBufferObject;
    uboLights->setUsage(GL_STATIC_DRAW);
    uboLights->setDataVariance(osg::Object::STATIC);
    bytes->setBufferObject(uboLights);
    osg::UniformBufferBinding* ubbLights = new osg::UniformBufferBinding(0, uboLights, 0, bytes->size());
    mStateset->setAttributeAndModes(ubbLights, osg::StateAttribute::ON);
    lightShader->addBindUniformBlock("LightBuffer", 0);



The part how I pass the lights is the same, but in the case of compute shader nothing happens, no light arrives. All uniforms have a reasonable value in the fragment shader, but they are always 0 (or empty), except the image2D targetTex object,  in the compute shader. I checked all variables in the code, and I know, that their value is ok, so the mistake is surely in binding, but I don't know where.

Thank you for any help!

Cheers,
Mary-Ann

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=69184#69184








More information about the osg-users mailing list