aboutsummaryrefslogtreecommitdiff
path: root/BuddhaTest
diff options
context:
space:
mode:
Diffstat (limited to 'BuddhaTest')
-rw-r--r--BuddhaTest/Shaders/BuddhaCompute.glsl66
-rw-r--r--BuddhaTest/Shaders/BuddhaFragment.glsl12
-rw-r--r--BuddhaTest/src/BuddhaTest.cpp13
3 files changed, 83 insertions, 8 deletions
diff --git a/BuddhaTest/Shaders/BuddhaCompute.glsl b/BuddhaTest/Shaders/BuddhaCompute.glsl
index 1903505..ebfdb29 100644
--- a/BuddhaTest/Shaders/BuddhaCompute.glsl
+++ b/BuddhaTest/Shaders/BuddhaCompute.glsl
@@ -7,6 +7,12 @@ layout(std430, binding=2) restrict buffer renderedDataRed
restrict uint counts_SSBO[];
};
+layout(std430, binding=3) restrict buffer brightnessData
+{
+ restrict uint brightness;
+};
+
+/** Data stored in the state buffer. */
struct individualData
{
uint phase;
@@ -28,12 +34,38 @@ uniform uvec4 orbitLength;
uniform uint iterationsPerDispatch;
uniform uint totalIterations;
+/** Data stored in shared memory. Used to reduce register pressure. Read at beginning from buffer (if needed), written back at end. */
+struct workerState
+{
+ uint brightness;
+};
+
+/** Storage in shared memory. Used to reduce register pressure. */
+shared workerState[gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z] localStore;
+
+void uintMaxIP(inout uint modified, const uint constant)
+{
+ modified = modified < constant ? constant : modified;
+}
+
+void uintMaxIP(inout uvec3 modified, const uvec3 constant)
+{
+ for(int i = 0; i < 3 ; ++i)
+ uintMaxIP(modified[i],constant[i]);
+}
+
void addToColorOfCell(uvec2 cell, uvec3 toAdd)
{
uint firstIndex = 3*(cell.x + cell.y * width);
- atomicAdd(counts_SSBO[firstIndex],toAdd.x);
- atomicAdd(counts_SSBO[firstIndex+1],toAdd.y);
- atomicAdd(counts_SSBO[firstIndex+2],toAdd.z);
+ uvec3 b;
+ b.x = atomicAdd(counts_SSBO[firstIndex],toAdd.x);
+ b.y = atomicAdd(counts_SSBO[firstIndex+1],toAdd.y);
+ b.z = atomicAdd(counts_SSBO[firstIndex+2],toAdd.z);
+ for(int i = 0; i < 3;++i)
+ {
+ if(localStore[gl_LocalInvocationIndex].brightness < b[i])
+ localStore[gl_LocalInvocationIndex].brightness = b[i];
+ }
}
uvec2 getCell(vec2 complex)
@@ -225,6 +257,8 @@ vec2 getCurrentOrbitOffset(const uint orbitNumber, const uint totalWorkers, cons
}
void main() {
+ localStore[gl_LocalInvocationIndex].brightness = 0;
+
//we need to know how many total work groups are running this iteration
const uvec3 totalWorkersPerDimension = gl_WorkGroupSize * gl_NumWorkGroups;
const uint totalWorkers = totalWorkersPerDimension.x*totalWorkersPerDimension.y*totalWorkersPerDimension.z;
@@ -288,5 +322,31 @@ void main() {
}
}
}
+
stateArray[uniqueWorkerID] = state;
+
+
+ //use divide et impera to get the real maximum brightness of this local group
+ barrier();
+ if(bool(localStore.length() & 1) && gl_LocalInvocationIndex == 0)
+ {
+ uintMaxIP(localStore[0].brightness, localStore[localStore.length()-1].brightness);
+ }
+ for(int step = localStore.length()/2;step >= 1;step = step/2)
+ {
+ barrier();
+ if(gl_LocalInvocationIndex < step)
+ {
+ uintMaxIP(localStore[gl_LocalInvocationIndex].brightness,localStore[gl_LocalInvocationIndex+step].brightness);
+ if(bool(step & 1) && gl_LocalInvocationIndex == 0)
+ {
+ uintMaxIP(localStore[0].brightness, localStore[step-1].brightness);
+ }
+ }
+ }
+ barrier();
+ if(gl_LocalInvocationIndex == 0)
+ {
+ atomicMax(brightness, localStore[0].brightness);
+ }
}
diff --git a/BuddhaTest/Shaders/BuddhaFragment.glsl b/BuddhaTest/Shaders/BuddhaFragment.glsl
index a6f47c1..ad184e6 100644
--- a/BuddhaTest/Shaders/BuddhaFragment.glsl
+++ b/BuddhaTest/Shaders/BuddhaFragment.glsl
@@ -6,11 +6,17 @@ out vec3 color;
layout(std430, binding=2) restrict readonly buffer renderedDataRed
{
- restrict readonly uint counts_SSBO[];
+ restrict readonly uint counts_SSBO[];
+};
+layout(std430, binding=3) restrict readonly buffer brightnessData
+{
+ restrict readonly uint brightness;
};
uniform uint width;
uniform uint height;
+uniform float gamma;
+uniform float colorScale;
uvec3 getColorAt(vec2 fragCoord)
{
@@ -22,8 +28,6 @@ uvec3 getColorAt(vec2 fragCoord)
void main(){
uvec3 totalCount = getColorAt(uv);
- uvec3 brightness = getColorAt(vec2(-0.245,0));
-
- vec3 scaled = vec3(totalCount)/max(length(vec3(brightness)),1.0);
+ vec3 scaled = pow(min(vec3(1.0),colorScale*vec3(totalCount)/max(float(brightness),1.0)),vec3(gamma));
color = scaled;
}
diff --git a/BuddhaTest/src/BuddhaTest.cpp b/BuddhaTest/src/BuddhaTest.cpp
index 0ae94b0..2064d06 100644
--- a/BuddhaTest/src/BuddhaTest.cpp
+++ b/BuddhaTest/src/BuddhaTest.cpp
@@ -118,7 +118,13 @@ int main(int argc, char * argv[])
glBufferData(GL_SHADER_STORAGE_BUFFER, 4 *3* pixelCount, nullptr, GL_DYNAMIC_COPY);
glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8,GL_RED,GL_UNSIGNED_INT,nullptr);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, drawBuffer);
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+
+ GLuint brightnessBuffer;
+ glGenBuffers(1,&brightnessBuffer);
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, brightnessBuffer);
+ glBufferData(GL_SHADER_STORAGE_BUFFER, 4,nullptr, GL_DYNAMIC_COPY);
+ glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8,GL_RED,GL_UNSIGNED_INT,nullptr);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, brightnessBuffer);
//the state buffer is special. While making each entry 8 bytes large and using std430 layout, the data is never read back,
//so we can get away with being more lenient and allowing the compiler to choose layout without much extra work.
@@ -157,8 +163,13 @@ int main(int argc, char * argv[])
glUseProgram(VertexAndFragmentShaders);
GLint widthUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "width");
GLint heightUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "height");
+ GLint gammaUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "gamma");
+ GLint colorScaleUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "colorScale");
glUniform1ui(widthUniformFragmentHandle, settings.imageWidth);
glUniform1ui(heightUniformFragmentHandle, bufferHeight);
+ glUniform1f(gammaUniformFragmentHandle, float(settings.pngGamma));
+ glUniform1f(colorScaleUniformFragmentHandle,float(settings.pngColorScale));
+
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
uint32_t iterationsPerFrame = 1;