aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Grois <andi@grois.info>2018-03-23 23:14:50 +0100
committerAndreas Grois <andi@grois.info>2018-03-23 23:14:50 +0100
commit183f60d1305e4de6729882f18311090b33d5374b (patch)
tree1e0015ca056ca7a3621553cbe3390b10db934c4e
parentb8082e3ef23758ce0f3a541aecf5a87efe3c1d53 (diff)
Back to full image size buffers, and range support in shader
-rw-r--r--BuddhaTest/Shaders/BuddhaCompute.glsl24
-rw-r--r--BuddhaTest/Shaders/BuddhaFragment.glsl9
-rw-r--r--BuddhaTest/src/BuddhaTest.cpp17
-rw-r--r--BuddhaTest/src/Helpers.cpp35
4 files changed, 55 insertions, 30 deletions
diff --git a/BuddhaTest/Shaders/BuddhaCompute.glsl b/BuddhaTest/Shaders/BuddhaCompute.glsl
index 91c1195..8b342cc 100644
--- a/BuddhaTest/Shaders/BuddhaCompute.glsl
+++ b/BuddhaTest/Shaders/BuddhaCompute.glsl
@@ -12,6 +12,11 @@ layout(std430, binding=3) restrict buffer brightnessData
restrict uint brightness;
};
+layout(std430, binding=4) restrict buffer importanceMapBufferBlock
+{
+ restrict uint importanceMap[];
+};
+
/** Data stored in the state buffer. */
struct individualData
{
@@ -34,6 +39,8 @@ uniform uvec4 orbitLength;
uniform uint iterationsPerDispatch;
uniform uint totalIterations;
+uniform vec4 imageRange = vec4(-2.0,-1.125,2.0,1.125);
+
/** Data stored in shared memory. Used to reduce register pressure. Read at beginning from buffer (if needed), written back at end. */
struct workerState
{
@@ -54,6 +61,17 @@ void uintMaxIP(inout uvec3 modified, const uvec3 constant)
uintMaxIP(modified[i],constant[i]);
}
+void addToImportanceMap(vec2 orbitParameter)
+{
+ //as starting point values are in x [-2:2] and y [0:2], importance map has an aspect ratio of 2:1
+ float width = sqrt(float(2*(importanceMap.length() - 1)));
+ //float height = 0.5*width;
+ orbitParameter *= vec2(0.25,0.5);
+ orbitParameter.x += 0.5;
+ //now both components are between 0 and 1
+
+}
+
void addToColorOfCell(uvec2 cell, uvec3 toAdd)
{
uint firstIndex = 3*(cell.x + cell.y * width);
@@ -70,7 +88,7 @@ void addToColorOfCell(uvec2 cell, uvec3 toAdd)
uvec2 getCell(vec2 complex)
{
- vec2 uv = clamp(vec2((complex.x+2.5)/3.5, (abs(complex.y))),vec2(0.0),vec2(1.0));
+ vec2 uv = clamp(vec2((complex.x-imageRange[0])/(imageRange[2]-imageRange[0]), (complex.y-imageRange[1])/(imageRange[3]-imageRange[1])),vec2(0.0),vec2(1.0));
return uvec2(width * uv.x, height * uv.y);
}
@@ -236,7 +254,7 @@ bool drawOrbit(in vec2 offset, in uint totalIterations, inout vec2 lastVal, inou
doneIterations = i+1;
return true; //done.
}
- if(lastVal.x > -2.5 && lastVal.x < 1.0 && lastVal.y > -1.0 && lastVal.y < 1.0)
+ if(lastVal.x > imageRange[0] && lastVal.x < imageRange[2] && lastVal.y > imageRange[1] && lastVal.y < imageRange[3])
{
addToColorAt(lastVal,uvec3(i < orbitLength.r,i < orbitLength.g,i < orbitLength.b));
}
@@ -253,7 +271,7 @@ vec2 getCurrentOrbitOffset(const uint orbitNumber, const uint totalWorkers, cons
seed = (seed ^ (intHash(orbitNumber+totalWorkers)));
float y = hash1(seed,seed);
vec2 random = vec2(x,y);
- return vec2(random.x * 3.5-2.5,random.y*1.55);
+ return vec2(random.x * 4-2,random.y*2);
}
void main() {
diff --git a/BuddhaTest/Shaders/BuddhaFragment.glsl b/BuddhaTest/Shaders/BuddhaFragment.glsl
index 52a0354..ac8114b 100644
--- a/BuddhaTest/Shaders/BuddhaFragment.glsl
+++ b/BuddhaTest/Shaders/BuddhaFragment.glsl
@@ -21,14 +21,17 @@ uniform float colorScale;
uvec3 getColorAt(vec2 fragCoord)
{
uint xIndex = uint(max(0.0,(fragCoord.x+1.0)*0.5*width));
- uint yIndex = uint(max(0.0,abs(fragCoord.y)*height));
+ uint yIndex = uint(max(0.0,abs(fragCoord.y+1.0)*0.5*height));
uint firstIndex = 3*(xIndex + yIndex * width);
- return uvec3(counts_SSBO[firstIndex],counts_SSBO[firstIndex+1],counts_SSBO[firstIndex+2]);
+ uvec3 c1=uvec3(counts_SSBO[firstIndex],counts_SSBO[firstIndex+1],counts_SSBO[firstIndex+2]);
+ firstIndex = 3*(xIndex +(height-1 - yIndex) * width);
+ uvec3 c2=uvec3(counts_SSBO[firstIndex],counts_SSBO[firstIndex+1],counts_SSBO[firstIndex+2]);
+ return c1+c2;
}
void main(){
uvec3 totalCount = getColorAt(uv);
- vec3 scaled = pow(min(vec3(1.0),colorScale*vec3(totalCount)/max(float(brightness),1.0)),vec3(gamma));
+ vec3 scaled = pow(min(vec3(1.0),colorScale*0.5*vec3(totalCount)/max(float(brightness),1.0)),vec3(gamma));
color = scaled;
}
diff --git a/BuddhaTest/src/BuddhaTest.cpp b/BuddhaTest/src/BuddhaTest.cpp
index 2064d06..ac7cebe 100644
--- a/BuddhaTest/src/BuddhaTest.cpp
+++ b/BuddhaTest/src/BuddhaTest.cpp
@@ -26,8 +26,6 @@ int main(int argc, char * argv[])
return 2;
}
- unsigned int bufferHeight = settings.imageHeight/2;
-
GLFWwindow* window;
/* Initialize the library */
@@ -61,7 +59,7 @@ int main(int argc, char * argv[])
//we have a context. Let's check if input is sane.
//calcualte buffer size, and make sure it's allowed by the driver.
- const unsigned int pixelCount{(settings.imageWidth * bufferHeight)};
+ const unsigned int pixelCount{(settings.imageWidth * settings.imageHeight)};
if(!settings.CheckValidity())
{
glfwTerminate();
@@ -126,6 +124,13 @@ int main(int argc, char * argv[])
glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8,GL_RED,GL_UNSIGNED_INT,nullptr);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, brightnessBuffer);
+ GLuint importanceMapBuffer;
+ glGenBuffers(1,&importanceMapBuffer);
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,importanceMapBuffer);
+ glBufferData(GL_SHADER_STORAGE_BUFFER,4*8193,nullptr, GL_DYNAMIC_COPY); //128*64+1. one larger than the map itself -> max brightness. Aspect 2:1 because mandel is symmetric around x
+ glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8,GL_RED,GL_UNSIGNED_INT,nullptr);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 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.
//We need to query the size for allocation though.
@@ -155,7 +160,7 @@ int main(int argc, char * argv[])
GLint iterationsPerDispatchHandle = glGetUniformLocation(ComputeShader, "iterationsPerDispatch");
glUniform4ui(orbitLengthUniformHandle,settings.orbitLengthRed,settings.orbitLengthGreen,settings.orbitLengthBlue,settings.orbitLengthSkip);
glUniform1ui(widthUniformComputeHandle, settings.imageWidth);
- glUniform1ui(heightUniformComputeHandle, bufferHeight);
+ glUniform1ui(heightUniformComputeHandle, settings.imageHeight);
const uint32_t maxOrbitlength = std::max(std::max(settings.orbitLengthBlue,settings.orbitLengthGreen),settings.orbitLengthRed);
glUniform1ui(totalIterationsUniformHandle, maxOrbitlength);
@@ -166,7 +171,7 @@ int main(int argc, char * argv[])
GLint gammaUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "gamma");
GLint colorScaleUniformFragmentHandle = glGetUniformLocation(VertexAndFragmentShaders, "colorScale");
glUniform1ui(widthUniformFragmentHandle, settings.imageWidth);
- glUniform1ui(heightUniformFragmentHandle, bufferHeight);
+ glUniform1ui(heightUniformFragmentHandle, settings.imageHeight);
glUniform1f(gammaUniformFragmentHandle, float(settings.pngGamma));
glUniform1f(colorScaleUniformFragmentHandle,float(settings.pngColorScale));
@@ -251,7 +256,7 @@ int main(int argc, char * argv[])
Helpers::PrintBenchmarkScore(readBackBuffer);
if(!settings.pngFilename.empty())
- Helpers::WriteOutputPNG(settings.pngFilename,readBackBuffer,settings.imageWidth,bufferHeight, settings.pngGamma, settings.pngColorScale);
+ Helpers::WriteOutputPNG(settings.pngFilename,readBackBuffer,settings.imageWidth,settings.imageHeight, settings.pngGamma, settings.pngColorScale);
}
//a bit of cleanup
diff --git a/BuddhaTest/src/Helpers.cpp b/BuddhaTest/src/Helpers.cpp
index b4c39c0..bd667fb 100644
--- a/BuddhaTest/src/Helpers.cpp
+++ b/BuddhaTest/src/Helpers.cpp
@@ -169,9 +169,9 @@ namespace Helpers
void WriteOutputPNG(const std::string &path, const std::vector<uint32_t>& data, unsigned int width, unsigned int bufferHeight, double gamma, double colorScale)
{
- std::vector<png_byte> pngData(3*width*2*bufferHeight);
- std::vector<png_byte *> rows{2*bufferHeight};
- for(unsigned int i = 0; i < 2*bufferHeight ; ++i)
+ std::vector<png_byte> pngData(3*width*bufferHeight);
+ std::vector<png_byte *> rows{bufferHeight};
+ for(unsigned int i = 0; i < bufferHeight ; ++i)
{
rows[i] = pngData.data()+3*width*i;
}
@@ -181,22 +181,21 @@ namespace Helpers
{
maxValue = std::max(maxValue,data[i]);
}
- for(unsigned int i = 0; i < data.size();++i)
- {
- if(fabs(gamma - 1.0) > 0.0001 || fabs(colorScale - 1.0) > 0.0001)
- {
- pngData[data.size() + i] = static_cast<png_byte>(255.0 * pow(std::min(1.0,colorScale*static_cast<double>(data[i])/static_cast<double>(maxValue)),gamma));
- }
- else
- {
- pngData[data.size() + i] = (255*data[i] + (maxValue/2))/maxValue;
- }
- }
- for(unsigned int i = 0; i < bufferHeight;++i)
+ for(unsigned int row = 0; row < bufferHeight/2; ++row)
{
- for(unsigned int j = 0; j < width*3;++j)
+ unsigned int otherRow = bufferHeight - 1-row;
+ for(unsigned int col=0;col < width*3; ++col)
{
- rows[i][j] =rows[2*bufferHeight-i-1][j];
+ double c = 0.5*(data[col + row*width*3] + data[col + otherRow*width*3]);
+ if(fabs(gamma - 1.0) > 0.0001 || fabs(colorScale - 1.0) > 0.0001)
+ {
+ pngData[col + row*width*3] = static_cast<png_byte>(255.0 * pow(std::min(1.0,colorScale*c/static_cast<double>(maxValue)),gamma));
+ }
+ else
+ {
+ pngData[col + row*width*3] = (255*c + (maxValue/2))/maxValue;
+ }
+ pngData[col+otherRow*width*3] = pngData[col + row*width*3];
}
}
@@ -223,7 +222,7 @@ namespace Helpers
return;
}
png_init_io(png_ptr, fd.Get());
- png_set_IHDR(png_ptr, info_ptr, width, 2*bufferHeight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_set_IHDR(png_ptr, info_ptr, width, bufferHeight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
//header written.