Flickering of SSBO data from Fragment shader

Hi there!

For some reason the scene that should display data from SSBO looks really strange: random colors flickering and I don’t understand why.

I’ve recorded the screen to demonstrate the process (https://drive.google.com/file/d/18b0yG1Jhv1DchH0J5-XjkYFM399acn6e/view?usp=sharing) - the initial scene is on the left, the puzzled scene is on the right. Any help is appreciated!

Code:

#define PRINT_VAR(x) std::cout<<#x<<" == "<<x<<std::endl;

 void checkGLError(std::string op);
// camera
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));

int main( void )
{
	// Initialise GLFW
	if( !glfwInit() )
	{
		fprintf( stderr, "Failed to initialize GLFW\n" );
		getchar();
		return -1;
	}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// Open a window and create its OpenGL context
int width = SCR_WIDTH;
int height = SCR_HEIGHT;
window = glfwCreateWindow( width, height, "Tutorial 08 - Basic Shading", NULL, NULL);
if( window == NULL ){
	fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
	getchar();
	glfwTerminate();
	return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
	fprintf(stderr, "Failed to initialize GLEW\n");
	getchar();
	glfwTerminate();
	return -1;
}

// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Hide the mouse and enable unlimited mouvement
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

// Set the mouse at the center of the screen
glfwPollEvents();
glfwSetCursorPos(window, 1024/2, 768/2);

// Dark blue background
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS); 

// Cull triangles which normal is not towards the camera
glEnable(GL_CULL_FACE);

GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "StandardShading.vertexshader", "StandardShading.fragmentshader" );

// add shaders for stencil
	Shader shader("2.stencil_testing.vs", "2.stencil_testing.fs");
	Shader shaderSingleColor("2.stencil_testing.vs", "2.stencil_single_color.fs");

// Get a handle for our "MVP" uniform
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint ViewMatrixID = glGetUniformLocation(programID, "V");
GLuint ModelMatrixID = glGetUniformLocation(programID, "M");

// Load the texture
GLuint Texture = loadDDS("uvmap.DDS");

// Get a handle for our "myTextureSampler" uniform
GLuint TextureID  = glGetUniformLocation(programID, "myTextureSampler");

// Read our .obj file
std::vector<glm::vec3> vertices;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
std::vector<glm::vec3> colors;
bool res = loadOBJ("suzanne.obj", vertices, uvs, normals);

// compute gradient
for (size_t i=0; i<normals.size() - 1; i+=2){
	float A = compute_gradient(normals[i], normals[i+1]);
}

colors.resize(normals.size());

std::ofstream MyVerticesFile("vertices_data.txt");
std::ofstream MyUVSFile("uvs_data.txt");
std::ofstream MynNormalsFile("normals_data.txt");
	
for (size_t i=0; i<vertices.size(); ++i){
  		MyVerticesFile << glm::to_string(vertices[i]) << std::endl;
	if(!((i+1)%3))MyVerticesFile << std::endl;
}

for (size_t i=0; i<uvs.size(); ++i){
  		MyUVSFile << glm::to_string(uvs[i]) << std::endl;
	if(!((i+1)%3))MyUVSFile << std::endl;
}

for (size_t i=0; i<normals.size(); ++i){
  		MynNormalsFile << glm::to_string(normals[i]) << std::endl;
	if(!((i+1)%3))MynNormalsFile << std::endl;
}

std::vector<glm::vec3> standardColors(6);
standardColors[0]=glm::vec3(1.0,0,0);
standardColors[1]=glm::vec3(0,1.0,0);
standardColors[2]=glm::vec3(0,0,1.0);
standardColors[3]=glm::vec3(1.0,0,1.0);
standardColors[4]=glm::vec3(1.0,1.0,0);
standardColors[5]=glm::vec3(1.0,1.0,1.0);


for (size_t i=0; i<vertices.size(); i+=3){
	glm::vec3 clr = standardColors[rand()%6];
	colors[i] = clr;
	colors[i+1] = clr;
	colors[i+2] = clr;
}


MyVerticesFile.close();
MyUVSFile.close();
MynNormalsFile.close();

// Load it into a VBO

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);

GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);

GLuint normalbuffer;
glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);

GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &colors[0], GL_STATIC_DRAW);


GLuint imageBuffer;
std::vector<float> image;
image.resize(width*height*3);
cv::Mat img = cv::Mat(height, width, CV_32FC3);

std::cout<<"Creating image buffer"<<std::endl;
glCreateBuffers(1, &imageBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, imageBuffer);
glNamedBufferStorage(imageBuffer, // Name of the buffer
                        //width*height*sizeof(glm::vec3), // Storage size in bytes
                        width*height*sizeof(float)*3, // Storage size in bytes
                        img.data,//&image[0], //  initial data
                        GL_MAP_WRITE_BIT | GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT ); // Allow map for writing
glBufferData(GL_SHADER_STORAGE_BUFFER, /*width*height*sizeof(glm::vec3)*/width*height*sizeof(float)*3, /*&image[0]*/img.data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2/*see fragment shader binding*/, imageBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);



 GLuint depthBuffer;
    cv::Mat depth = cv::Mat(height, width, CV_32FC1);

std::cout<<"Creating depthBuffer buffer"<<std::endl;
glCreateBuffers(1, &depthBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, imageBuffer);
glNamedBufferStorage(depthBuffer, // Name of the buffer
                        //width*height*sizeof(glm::vec3), // Storage size in bytes
                        width*height*sizeof(float), // Storage size in bytes
                        depth.data,//&image[0], //  initial data
                        GL_MAP_WRITE_BIT | GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT ); // Allow map for writing
glBufferData(GL_SHADER_STORAGE_BUFFER, /*width*height*sizeof(glm::vec3)*/width*height*sizeof(float), /*&image[0]*/depth.data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1/*see fragment shader binding*/, depthBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

glUseProgram(programID)

std::cout<<"Initiating width/height uniform"<<std::endl;
GLuint imageHeightID = glGetUniformLocation(programID, "imageHeight");
GLuint imageWidthID = glGetUniformLocation(programID, "imageWidth");

glUniform1i(imageHeightID, height);
glUniform1i(imageWidthID, width);

int h,w;
glGetUniformiv(	programID, imageHeightID,&h);
glGetUniformiv(	programID, imageWidthID,&w);
PRINT_VAR(h);
PRINT_VAR(w);

// Get a handle for our "LightPosition" uniform
glUseProgram(programID);
GLuint LightID = glGetUniformLocation(programID, "LightPosition_worldspace");

//glEnable(GL_FRAMEBUFFER_SRGB);

std::cout<<"Creating buffers finished"<<std::endl;

glMemoryBarrier( GL_SHADER_STORAGE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT);
glEnable(GL_DEPTH_TEST);



int iImg = 0;
do{
	
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, imageBuffer);
    	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2/*see fragment shader binding*/, imageBuffer);

	// Clear the screen
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use our shader
	glUseProgram(programID);

	// Compute the MVP matrix from keyboard and mouse input
	computeMatricesFromInputs();
	glm::mat4 ProjectionMatrix = getProjectionMatrix();
	glm::mat4 ViewMatrix = getViewMatrix();
	glm::mat4 ModelMatrix = glm::mat4(1.0);
	glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

	// Send our transformation to the currently bound shader, 
	// in the "MVP" uniform
	glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
	glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
	glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);

	glm::vec3 lightPos = glm::vec3(4,4,4);
	glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);

	// Bind our texture in Texture Unit 0
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Texture);
	// Set our "myTextureSampler" sampler to use Texture Unit 0
	glUniform1i(TextureID, 0);

	// 1rst attribute buffer : vertices
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
	glVertexAttribPointer(
		0,                  // attribute
		3,                  // size
		GL_FLOAT,           // type
		GL_FALSE,           // normalized?
		0,                  // stride
		(void*)0            // array buffer offset
	);

	// color attribute buffer : normals
	GLuint colorAttribLocation = glGetAttribLocation(programID,"reqColor");
	glEnableVertexAttribArray(colorAttribLocation);
	glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
	glVertexAttribPointer(
		colorAttribLocation,              // attribute
		3,                                // size
		GL_FLOAT,                         // type
		GL_FALSE,                         // normalized?
		0,                                // stride
		(void*)0                          // array buffer offset
	);

	glDrawArrays(GL_TRIANGLES, 0, vertices.size() );

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	glDisableVertexAttribArray(2);
    
glFinish();

    // Get a pointer to the buffer's data store
    std::cout<<"Grabbing imageBuffer"<<std::endl;
   glBindBuffer(GL_SHADER_STORAGE_BUFFER, imageBuffer);
   void * ptr = glMapNamedBuffer(imageBuffer,GL_READ_ONLY);// GL_READ_WRITE);//

if(ptr != NULL)
   {
	 
	// Copy our data into it...
       memcpy(img.data, ptr,  width*height*sizeof(float)*3);

	// Tell OpenGL that we're done with the pointer
       glUnmapNamedBuffer(imageBuffer);
       glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

	cv::imshow("Suzane",img);
	std::stringstream ss;

	std::cout<<"Image read"<<std::endl;
	cv::waitKey(100);
	
	float zero = 0.0f;
	GLubyte val = 0;
	glClearNamedBufferData(imageBuffer, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, &val);
	checkGLError("Clear");

}
else
{
	checkGLError("Map returned NULL");
	glUnmapNamedBuffer(imageBuffer);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}

glBindBuffer(GL_SHADER_STORAGE_BUFFER, depthBuffer);
   ptr = glMapNamedBuffer(depthBuffer,GL_READ_ONLY);
if(ptr != NULL)
   {  
	// Copy our data into it...

       memcpy(depth.data, ptr,  width*height*sizeof(float));

	// Tell OpenGL that we're done with the pointer
       cv::imshow("Suzane deep",depth);
	checkGLError("Depth");
}
else
	checkGLError("Depth NULL");

glUnmapNamedBuffer(depthBuffer);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

GLubyte val = 0;
glClearNamedBufferData(depthBuffer, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE,&val);

	glFlush();
	// Swap buffers
	glfwSwapBuffers(window);
	glfwPollEvents();

} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
	   glfwWindowShouldClose(window) == 0 );

// Cleanup VBO and shader
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &uvbuffer);
glDeleteBuffers(1, &normalbuffer);
glDeleteProgram(programID);
glDeleteTextures(1, &Texture);
glDeleteVertexArrays(1, &VertexArrayID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}
void checkGLError(std::string op) {
        int error;
        while ((error = glGetError()) != GL_NO_ERROR) {
                std::cout<<"MyApp"<< op << ": glError " << error<<std::endl;
        }
}

Vertex Shader

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
layout(location = 2) in vec3 vertexNormal_modelspace;
layout(location = 3) in vec3 reqColor;


// Output data ; will be interpolated for each fragment.
out vec2 UV;
out vec3 Position_worldspace;
out vec3 Normal_cameraspace;
out vec3 EyeDirection_cameraspace;
out vec3 LightDirection_cameraspace;
out vec3 colorIn;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;
uniform mat4 V;
uniform mat4 M;
uniform vec3 LightPosition_worldspace;

void main(){

	// Output position of the vertex, in clip space : MVP * position
	gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
	
	// Position of the vertex, in worldspace : M * position
	Position_worldspace = (M * vec4(vertexPosition_modelspace,1)).xyz;
	
	// Vector that goes from the vertex to the camera, in camera space.
	// In camera space, the camera is at the origin (0,0,0).
	vec3 vertexPosition_cameraspace = ( V * M * vec4(vertexPosition_modelspace,1)).xyz;
	EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;

	// Vector that goes from the vertex to the light, in camera space. M is ommited because it's identity.
	vec3 LightPosition_cameraspace = ( V * vec4(LightPosition_worldspace,1)).xyz;
	LightDirection_cameraspace = LightPosition_cameraspace + EyeDirection_cameraspace;
	
	// Normal of the the vertex, in camera space
	Normal_cameraspace = ( V * M * vec4(vertexNormal_modelspace,0)).xyz; // Only correct if ModelMatrix does not scale the model ! Use its inverse transpose if not.
	
	// UV of the vertex. No special space for this one.
	UV = vertexUV;
	// coloring
	colorIn = reqColor;
}

Fragment Shader:

layout(early_fragment_tests) in;

// Interpolated values from the vertex shaders
in vec2 UV;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 LightDirection_cameraspace;
in vec3 colorIn;
layout(origin_upper_left) in vec4 gl_FragCoord ;

// Ouput data
out vec3 color;

// Values that stay constant for the whole mesh.
uniform sampler2D myTextureSampler;
uniform mat4 MVP;
uniform vec3 LightPosition_worldspace;
uniform int imageBufferID;
uniform int imageWidth;
uniform int imageHeight;

layout(std430, binding = 2) buffer imageLayout
{
    float image[];
} SharedBuffer;


layout(std430, binding = 1) buffer ImageDepthLayout
{
    float depth[];
} SharedDepthBuffer;

#define SIZE_OF_VEC3 12

void main(){
	vec3 LightColor = vec3(1,1,1);
	float LightPower = 50.0f;

// Material properties
vec3 MaterialDiffuseColor = texture( myTextureSampler, UV ).rgb;
vec3 MaterialAmbientColor = vec3(0.1,0.1,0.1) * MaterialDiffuseColor;
vec3 MaterialSpecularColor = vec3(0.3,0.3,0.3);

// Distance to the light
float distance = length( LightPosition_worldspace - Position_worldspace );

// Normal of the computed fragment, in camera space
vec3 n = normalize( Normal_cameraspace );
// Direction of the light (from the fragment to the light)
vec3 l = normalize( LightDirection_cameraspace );
float cosTheta = clamp( dot( n,l ), 0,1 );

// Eye vector (towards the camera)
vec3 E = normalize(EyeDirection_cameraspace);
// Direction in which the triangle reflects the light
vec3 R = reflect(-l,n);
// Cosine of the angle between the Eye vector and the Reflect vector,
// clamped to 0
//  - Looking into the reflection -> 1
//  - Looking elsewhere -> < 1
float cosAlpha = clamp( dot( E,R ), 0,1 );
memoryBarrierBuffer();
    vec4 xy = gl_FragCoord;
    highp int x = int(xy.x);
    highp int y = int(xy.y);
    int stride = imageWidth*3;//SIZE_OF_VEC3*imageWidth;
    int maxOffset = imageWidth*imageHeight*3;//*SIZE_OF_VEC3;

    int offset = int(3*x + y*stride);

if(offset>=maxOffset) offset= maxOffset-1;
int ind = offset;

int strideDepth = imageWidth;
    int offsetDepth = int(x + y*strideDepth);

if( (xy.z<SharedDepthBuffer.depth[offsetDepth]) || (SharedDepthBuffer.depth[offsetDepth] == 0))
{
	SharedDepthBuffer.depth[offsetDepth] = xy.z;

	SharedBuffer.image[offset] = colorIn.x;
	SharedBuffer.image[offset+1] = colorIn.y;
	SharedBuffer.image[offset+2] = colorIn.z;
}

	color = colorIn;
}

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.