[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