aboutsummaryrefslogtreecommitdiff
path: root/BuddhaTest/Shaders
diff options
context:
space:
mode:
Diffstat (limited to 'BuddhaTest/Shaders')
-rw-r--r--BuddhaTest/Shaders/BuddhaCompute.glsl538
-rw-r--r--BuddhaTest/Shaders/BuddhaFragment.glsl74
-rw-r--r--BuddhaTest/Shaders/BuddhaVertex.glsl20
3 files changed, 316 insertions, 316 deletions
diff --git a/BuddhaTest/Shaders/BuddhaCompute.glsl b/BuddhaTest/Shaders/BuddhaCompute.glsl
index c94df12..61bbb6d 100644
--- a/BuddhaTest/Shaders/BuddhaCompute.glsl
+++ b/BuddhaTest/Shaders/BuddhaCompute.glsl
@@ -1,269 +1,269 @@
-//commented out, added by c-code that loads this shader.
-//#version 430
-//layout (local_size_x = 1024) in; //to be safe, we limit our local work group size to 1024. That's the minimum a GL 4.3 capable driver must support.
-
-layout(std430, binding=2) restrict buffer renderedDataRed
-{
- restrict uint counts_SSBORed[];
-};
-layout(std430, binding=3) restrict buffer renderedDataGreen
-{
- restrict uint counts_SSBOGreen[];
-};
-layout(std430, binding=4) restrict buffer renderedDataBlue
-{
- restrict uint counts_SSBOBlue[];
-};
-
-struct individualData
-{
- uint phase;
- uint orbitNumber;
- uint doneIterations;
- vec2 lastPosition;
-};
-
-layout(std430, binding=5) restrict buffer statusBuffer
-{
- restrict individualData state[];
-};
-
-uniform uint width;
-uniform uint height;
-
-uniform uvec3 orbitLength;
-
-uniform uint iterationsPerDispatch;
-
-void addToColorOfCell(uvec2 cell, uvec3 toAdd)
-{
- uint firstIndex = (cell.x + cell.y * width);
- atomicAdd(counts_SSBORed[firstIndex],toAdd.x);
- atomicAdd(counts_SSBOGreen[firstIndex],toAdd.y);
- atomicAdd(counts_SSBOBlue[firstIndex],toAdd.z);
-}
-
-uvec2 getCell(vec2 complex)
-{
- vec2 uv = clamp(vec2((complex.x+2.5)/3.5, (abs(complex.y))),vec2(0.0),vec2(1.0));
- return uvec2(width * uv.x, height * uv.y);
-}
-
-void addToColorAt(vec2 complex, uvec3 toAdd)
-{
- uvec2 cell = getCell(complex);
- addToColorOfCell(cell,toAdd);
-}
-
-uint intHash(uint x) {
- x = ((x >> 16) ^ x) * 0x45d9f3bU;
- x = ((x >> 16) ^ x) * 0x45d9f3bU;
- x = (x >> 16) ^ x;
- return x;
-}
-
-float hash1(uint seed, out uint hash)
-{
- hash = intHash(seed);
- return float(hash)/float(0xffffffffU);
-}
-
-vec2 compSqr(in vec2 v)
-{
- return vec2(v.x*v.x-v.y*v.y, 2.0*v.x*v.y);
-}
-
-bool isInMainCardioid(vec2 v)
-{
- /*
- The condition that a point c is in the main cardioid is that its orbit has
- an attracting fixed point. In other words, it must fulfill
- z**2 -z + v = 0 (z**2+v has a fixed point at z)
- and
- d/dz(z**2+v) < 1 (fixed point at z is attractive)
- Solving these equations yields
- v = u/2*(1-u/2), where u is a complex number inside the unit circle
-
- Sadly we only know v, not u, and inverting this formula leads to a complex square root.
- This is the old code that uses the compSqrt method, which is rather slow...
-
- vec2 toRoot = (vec2(1.0,0.0)-vec2(4.0)*v);
- vec2 root = compSqrt(toRoot);
- vec2 t1,t2;
- t1=vec2(1,0)-root;
- t2=vec2(1,0)+root;
- float retval = step(dot(t1,t1),0.99999);
- retval += step(dot(t2,t2),0.99999);
- retval = min(retval,1.0);
- return retval;
-
- On several websites (and several mandelbrot-related shaders on ShaderToy) one can
- find various faster formulas that check the same inequality.
- What however is hard to find is the actual derivation of those formulas,
- and they are not as trivial as one might think at first.
- That's why I'm writing this lengthy comment, to preserve the scrap notes I made
- for future reuse by myself and others...
-
- Now the actual derivation looks like this:
- We start with the following line
- u = 1 +- sqrt(1-4*v)
- don't mind the +-, that's just me being too lazy to check which solution is the right one
- We know that |u| < 1, and we immediately square the whole beast to get rid of the root
- Some definitions: r := sqrt(1-4*v), z = 1-4*v
-
- 1 > Re(u)**2+Im(u)**2 = (1 +- Re(r))**2+Im(r)**2
- 1 > 1 +- 2*Re(r) + Re(r)**2+Im(r)**2
- 1 > 1 +- 2*Re(r) + |r|**2
- For complex values the square root of the norm is the same as the norm of the square root
- 1 > 1 +- 2*Re(r) + |z|
- +-2*Re(r) > |z|
- 4*Re(r)**2 > |z|**2
- This step is now a bit arcane. If one solves the two coupled equations
- (a+i*b) = (x+i*y)*(x+i*y) component-wise for x and y,
- one can see that x**2 = (|a+i*b|+a)/2
- With this follows
- 2*(|z|+Re(z)) > |z|**2
- |z| > 1/2*|z|**2-Re(z)
- |z|**2 > (1/2*|z|**2-Re(z))**2
-
- And long story short, the result is the following few operations.
- */
- vec2 z = vec2(1.0,0.0)-4.0*v;
- float zNormSqr = dot(z,z);
- float rhsSqrt = 0.5*zNormSqr - z.x;
- return rhsSqrt*rhsSqrt<zNormSqr;
-}
-
-bool isInMainBulb(vec2 v)
-{
- //The condition for this is that f(f(z)) = z
- //where f(z) = z*z+v
- //This is an equation of fourth order, but two solutions are the same as
- //for f(z) = z, which has been solved for the cardioid above.
- //Factoring those out, you end up with a second order equation.
- //Again, the solutions need to be attractive (|d/dz f(f(z))| < 1)
- //Well, after a bit of magic one finds out it's a circle around -1, radius 1/4.
- vec2 shifted = v + vec2(1,0);
- float sqrRadius = dot(shifted,shifted);
- return sqrRadius<0.062499999;
-}
-
-bool isGoingToBeDrawn(in vec2 offset, in uint totalIterations, inout vec2 lastVal, inout uint iterationsLeftThisFrame, inout uint doneIterations, out bool result)
-{
- uint endCount = doneIterations + iterationsLeftThisFrame > totalIterations ? totalIterations : doneIterations + iterationsLeftThisFrame;
- for(uint i = doneIterations; i < endCount;++i)
- {
- lastVal = compSqr(lastVal) + offset;
- if(dot(lastVal,lastVal) > 4.0)
- {
- result = true;
- iterationsLeftThisFrame -= ((i+1)-doneIterations);
- doneIterations = i+1;
- return true;
- }
- }
- iterationsLeftThisFrame -= (endCount - doneIterations);
- doneIterations = endCount;
- result = false;
- return endCount == totalIterations;
-}
-
-bool drawOrbit(in vec2 offset, in uint totalIterations, inout vec2 lastVal, inout uint iterationsLeftThisFrame, inout uint doneIterations)
-{
- uint endCount = doneIterations + iterationsLeftThisFrame > totalIterations ? totalIterations : doneIterations + iterationsLeftThisFrame;
- for(uint i = doneIterations; i < endCount;++i)
- {
- lastVal = compSqr(lastVal) + offset;
- if(dot(lastVal,lastVal) > 20.0)
- {
- iterationsLeftThisFrame -= ((i+1)-doneIterations);
- doneIterations = i+1;
- return true; //done.
- }
- if(lastVal.x > -2.5 && lastVal.x < 1.0 && lastVal.y > -1.0 && lastVal.y < 1.0)
- {
- addToColorAt(lastVal,uvec3(i < orbitLength.r,i < orbitLength.g,i < orbitLength.b));
- }
- }
- iterationsLeftThisFrame -= (endCount - doneIterations);
- doneIterations = endCount;
- return endCount == totalIterations;
-}
-
-vec2 getCurrentOrbitOffset(const uint orbitNumber, const uint totalWorkers, const uint uniqueWorkerID)
-{
- uint seed = orbitNumber * totalWorkers + uniqueWorkerID;
- float x = hash1(seed,seed);
- 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);
-}
-
-void main() {
- //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;
-
- const uint uniqueWorkerID = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*totalWorkersPerDimension.x + gl_GlobalInvocationID.z*(totalWorkersPerDimension.x * totalWorkersPerDimension.y);
-
- const uint _totalIterations = orbitLength.x > orbitLength.y ? orbitLength.x : orbitLength.y;
- const uint totalIterations = _totalIterations > orbitLength.z ? _totalIterations : orbitLength.z;
-
- //getIndividualState(in uint CellID, out vec2 offset, out vec2 coordinates, out uint phase, out uint orbitNumber, out uint doneIterations)
- uint iterationsLeftToDo = iterationsPerDispatch;
- vec2 offset = getCurrentOrbitOffset(state[uniqueWorkerID].orbitNumber, totalWorkers, uniqueWorkerID);
-
- while(iterationsLeftToDo != 0)
- {
- if(state[uniqueWorkerID].phase == 0)
- {
- //new orbit:
- //we know that iterationsLeftToDo is at least 1 by the while condition.
- --iterationsLeftToDo; //count this as 1 iteration.
- offset = getCurrentOrbitOffset(state[uniqueWorkerID].orbitNumber, totalWorkers, uniqueWorkerID);
- if(isInMainBulb(offset) || isInMainCardioid(offset))
- {
- // do not waste time drawing this orbit
- ++state[uniqueWorkerID].orbitNumber;
- }
- else
- {
- //cool orbit!
- state[uniqueWorkerID].lastPosition = vec2(0);
- state[uniqueWorkerID].phase = 1;
- state[uniqueWorkerID].doneIterations = 0;
- }
- }
- if(state[uniqueWorkerID].phase == 1)
- {
- //check if this orbit is going to be drawn
- bool result;
- if(isGoingToBeDrawn(offset,totalIterations, state[uniqueWorkerID].lastPosition, iterationsLeftToDo, state[uniqueWorkerID].doneIterations , result))
- {
- if(result)
- {
- //on to step 2: drawing
- state[uniqueWorkerID].phase = 2;
- state[uniqueWorkerID].lastPosition = vec2(0);
- state[uniqueWorkerID].doneIterations = 0;
- }
- else
- {
- //back to step 0
- ++state[uniqueWorkerID].orbitNumber;
- state[uniqueWorkerID].phase = 0;
- }
- }
- }
- if(state[uniqueWorkerID].phase == 2)
- {
- if(drawOrbit(offset, totalIterations, state[uniqueWorkerID].lastPosition, iterationsLeftToDo, state[uniqueWorkerID].doneIterations))
- {
- ++state[uniqueWorkerID].orbitNumber;
- state[uniqueWorkerID].phase = 0;
- }
- }
- }
-}
+//commented out, added by c-code that loads this shader.
+//#version 430
+//layout (local_size_x = 1024) in; //to be safe, we limit our local work group size to 1024. That's the minimum a GL 4.3 capable driver must support.
+
+layout(std430, binding=2) restrict buffer renderedDataRed
+{
+ restrict uint counts_SSBORed[];
+};
+layout(std430, binding=3) restrict buffer renderedDataGreen
+{
+ restrict uint counts_SSBOGreen[];
+};
+layout(std430, binding=4) restrict buffer renderedDataBlue
+{
+ restrict uint counts_SSBOBlue[];
+};
+
+struct individualData
+{
+ uint phase;
+ uint orbitNumber;
+ uint doneIterations;
+ vec2 lastPosition;
+};
+
+layout(std430, binding=5) restrict buffer statusBuffer
+{
+ restrict individualData state[];
+};
+
+uniform uint width;
+uniform uint height;
+
+uniform uvec3 orbitLength;
+
+uniform uint iterationsPerDispatch;
+
+void addToColorOfCell(uvec2 cell, uvec3 toAdd)
+{
+ uint firstIndex = (cell.x + cell.y * width);
+ atomicAdd(counts_SSBORed[firstIndex],toAdd.x);
+ atomicAdd(counts_SSBOGreen[firstIndex],toAdd.y);
+ atomicAdd(counts_SSBOBlue[firstIndex],toAdd.z);
+}
+
+uvec2 getCell(vec2 complex)
+{
+ vec2 uv = clamp(vec2((complex.x+2.5)/3.5, (abs(complex.y))),vec2(0.0),vec2(1.0));
+ return uvec2(width * uv.x, height * uv.y);
+}
+
+void addToColorAt(vec2 complex, uvec3 toAdd)
+{
+ uvec2 cell = getCell(complex);
+ addToColorOfCell(cell,toAdd);
+}
+
+uint intHash(uint x) {
+ x = ((x >> 16) ^ x) * 0x45d9f3bU;
+ x = ((x >> 16) ^ x) * 0x45d9f3bU;
+ x = (x >> 16) ^ x;
+ return x;
+}
+
+float hash1(uint seed, out uint hash)
+{
+ hash = intHash(seed);
+ return float(hash)/float(0xffffffffU);
+}
+
+vec2 compSqr(in vec2 v)
+{
+ return vec2(v.x*v.x-v.y*v.y, 2.0*v.x*v.y);
+}
+
+bool isInMainCardioid(vec2 v)
+{
+ /*
+ The condition that a point c is in the main cardioid is that its orbit has
+ an attracting fixed point. In other words, it must fulfill
+ z**2 -z + v = 0 (z**2+v has a fixed point at z)
+ and
+ d/dz(z**2+v) < 1 (fixed point at z is attractive)
+ Solving these equations yields
+ v = u/2*(1-u/2), where u is a complex number inside the unit circle
+
+ Sadly we only know v, not u, and inverting this formula leads to a complex square root.
+ This is the old code that uses the compSqrt method, which is rather slow...
+
+ vec2 toRoot = (vec2(1.0,0.0)-vec2(4.0)*v);
+ vec2 root = compSqrt(toRoot);
+ vec2 t1,t2;
+ t1=vec2(1,0)-root;
+ t2=vec2(1,0)+root;
+ float retval = step(dot(t1,t1),0.99999);
+ retval += step(dot(t2,t2),0.99999);
+ retval = min(retval,1.0);
+ return retval;
+
+ On several websites (and several mandelbrot-related shaders on ShaderToy) one can
+ find various faster formulas that check the same inequality.
+ What however is hard to find is the actual derivation of those formulas,
+ and they are not as trivial as one might think at first.
+ That's why I'm writing this lengthy comment, to preserve the scrap notes I made
+ for future reuse by myself and others...
+
+ Now the actual derivation looks like this:
+ We start with the following line
+ u = 1 +- sqrt(1-4*v)
+ don't mind the +-, that's just me being too lazy to check which solution is the right one
+ We know that |u| < 1, and we immediately square the whole beast to get rid of the root
+ Some definitions: r := sqrt(1-4*v), z = 1-4*v
+
+ 1 > Re(u)**2+Im(u)**2 = (1 +- Re(r))**2+Im(r)**2
+ 1 > 1 +- 2*Re(r) + Re(r)**2+Im(r)**2
+ 1 > 1 +- 2*Re(r) + |r|**2
+ For complex values the square root of the norm is the same as the norm of the square root
+ 1 > 1 +- 2*Re(r) + |z|
+ +-2*Re(r) > |z|
+ 4*Re(r)**2 > |z|**2
+ This step is now a bit arcane. If one solves the two coupled equations
+ (a+i*b) = (x+i*y)*(x+i*y) component-wise for x and y,
+ one can see that x**2 = (|a+i*b|+a)/2
+ With this follows
+ 2*(|z|+Re(z)) > |z|**2
+ |z| > 1/2*|z|**2-Re(z)
+ |z|**2 > (1/2*|z|**2-Re(z))**2
+
+ And long story short, the result is the following few operations.
+ */
+ vec2 z = vec2(1.0,0.0)-4.0*v;
+ float zNormSqr = dot(z,z);
+ float rhsSqrt = 0.5*zNormSqr - z.x;
+ return rhsSqrt*rhsSqrt<zNormSqr;
+}
+
+bool isInMainBulb(vec2 v)
+{
+ //The condition for this is that f(f(z)) = z
+ //where f(z) = z*z+v
+ //This is an equation of fourth order, but two solutions are the same as
+ //for f(z) = z, which has been solved for the cardioid above.
+ //Factoring those out, you end up with a second order equation.
+ //Again, the solutions need to be attractive (|d/dz f(f(z))| < 1)
+ //Well, after a bit of magic one finds out it's a circle around -1, radius 1/4.
+ vec2 shifted = v + vec2(1,0);
+ float sqrRadius = dot(shifted,shifted);
+ return sqrRadius<0.062499999;
+}
+
+bool isGoingToBeDrawn(in vec2 offset, in uint totalIterations, inout vec2 lastVal, inout uint iterationsLeftThisFrame, inout uint doneIterations, out bool result)
+{
+ uint endCount = doneIterations + iterationsLeftThisFrame > totalIterations ? totalIterations : doneIterations + iterationsLeftThisFrame;
+ for(uint i = doneIterations; i < endCount;++i)
+ {
+ lastVal = compSqr(lastVal) + offset;
+ if(dot(lastVal,lastVal) > 4.0)
+ {
+ result = true;
+ iterationsLeftThisFrame -= ((i+1)-doneIterations);
+ doneIterations = i+1;
+ return true;
+ }
+ }
+ iterationsLeftThisFrame -= (endCount - doneIterations);
+ doneIterations = endCount;
+ result = false;
+ return endCount == totalIterations;
+}
+
+bool drawOrbit(in vec2 offset, in uint totalIterations, inout vec2 lastVal, inout uint iterationsLeftThisFrame, inout uint doneIterations)
+{
+ uint endCount = doneIterations + iterationsLeftThisFrame > totalIterations ? totalIterations : doneIterations + iterationsLeftThisFrame;
+ for(uint i = doneIterations; i < endCount;++i)
+ {
+ lastVal = compSqr(lastVal) + offset;
+ if(dot(lastVal,lastVal) > 20.0)
+ {
+ iterationsLeftThisFrame -= ((i+1)-doneIterations);
+ doneIterations = i+1;
+ return true; //done.
+ }
+ if(lastVal.x > -2.5 && lastVal.x < 1.0 && lastVal.y > -1.0 && lastVal.y < 1.0)
+ {
+ addToColorAt(lastVal,uvec3(i < orbitLength.r,i < orbitLength.g,i < orbitLength.b));
+ }
+ }
+ iterationsLeftThisFrame -= (endCount - doneIterations);
+ doneIterations = endCount;
+ return endCount == totalIterations;
+}
+
+vec2 getCurrentOrbitOffset(const uint orbitNumber, const uint totalWorkers, const uint uniqueWorkerID)
+{
+ uint seed = orbitNumber * totalWorkers + uniqueWorkerID;
+ float x = hash1(seed,seed);
+ 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);
+}
+
+void main() {
+ //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;
+
+ const uint uniqueWorkerID = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*totalWorkersPerDimension.x + gl_GlobalInvocationID.z*(totalWorkersPerDimension.x * totalWorkersPerDimension.y);
+
+ const uint _totalIterations = orbitLength.x > orbitLength.y ? orbitLength.x : orbitLength.y;
+ const uint totalIterations = _totalIterations > orbitLength.z ? _totalIterations : orbitLength.z;
+
+ //getIndividualState(in uint CellID, out vec2 offset, out vec2 coordinates, out uint phase, out uint orbitNumber, out uint doneIterations)
+ uint iterationsLeftToDo = iterationsPerDispatch;
+ vec2 offset = getCurrentOrbitOffset(state[uniqueWorkerID].orbitNumber, totalWorkers, uniqueWorkerID);
+
+ while(iterationsLeftToDo != 0)
+ {
+ if(state[uniqueWorkerID].phase == 0)
+ {
+ //new orbit:
+ //we know that iterationsLeftToDo is at least 1 by the while condition.
+ --iterationsLeftToDo; //count this as 1 iteration.
+ offset = getCurrentOrbitOffset(state[uniqueWorkerID].orbitNumber, totalWorkers, uniqueWorkerID);
+ if(isInMainBulb(offset) || isInMainCardioid(offset))
+ {
+ // do not waste time drawing this orbit
+ ++state[uniqueWorkerID].orbitNumber;
+ }
+ else
+ {
+ //cool orbit!
+ state[uniqueWorkerID].lastPosition = vec2(0);
+ state[uniqueWorkerID].phase = 1;
+ state[uniqueWorkerID].doneIterations = 0;
+ }
+ }
+ if(state[uniqueWorkerID].phase == 1)
+ {
+ //check if this orbit is going to be drawn
+ bool result;
+ if(isGoingToBeDrawn(offset,totalIterations, state[uniqueWorkerID].lastPosition, iterationsLeftToDo, state[uniqueWorkerID].doneIterations , result))
+ {
+ if(result)
+ {
+ //on to step 2: drawing
+ state[uniqueWorkerID].phase = 2;
+ state[uniqueWorkerID].lastPosition = vec2(0);
+ state[uniqueWorkerID].doneIterations = 0;
+ }
+ else
+ {
+ //back to step 0
+ ++state[uniqueWorkerID].orbitNumber;
+ state[uniqueWorkerID].phase = 0;
+ }
+ }
+ }
+ if(state[uniqueWorkerID].phase == 2)
+ {
+ if(drawOrbit(offset, totalIterations, state[uniqueWorkerID].lastPosition, iterationsLeftToDo, state[uniqueWorkerID].doneIterations))
+ {
+ ++state[uniqueWorkerID].orbitNumber;
+ state[uniqueWorkerID].phase = 0;
+ }
+ }
+ }
+}
diff --git a/BuddhaTest/Shaders/BuddhaFragment.glsl b/BuddhaTest/Shaders/BuddhaFragment.glsl
index 24edcd9..b33ee1d 100644
--- a/BuddhaTest/Shaders/BuddhaFragment.glsl
+++ b/BuddhaTest/Shaders/BuddhaFragment.glsl
@@ -1,37 +1,37 @@
-#version 430 core
-
-in vec2 uv;
-
-out vec3 color;
-
-layout(std430, binding=2) restrict readonly buffer renderedDataRed
-{
- restrict readonly uint counts_SSBORed[];
-};
-layout(std430, binding=3) restrict readonly buffer renderedDataGreen
-{
- restrict readonly uint counts_SSBOGreen[];
-};
-layout(std430, binding=4) restrict readonly buffer renderedDataBlue
-{
- restrict readonly uint counts_SSBOBlue[];
-};
-
-uniform uint width;
-uniform uint height;
-
-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 firstIndex = (xIndex + yIndex * width);
- return uvec3(counts_SSBORed[firstIndex],counts_SSBOGreen[firstIndex],counts_SSBOBlue[firstIndex]);
-}
-
-void main(){
- uvec3 totalCount = getColorAt(uv);
- uvec3 brightness = getColorAt(vec2(-0.2390625,0));
-
- vec3 scaled = vec3(totalCount)/max(length(vec3(brightness)),1.0);
- color = scaled;
-}
+#version 430 core
+
+in vec2 uv;
+
+out vec3 color;
+
+layout(std430, binding=2) restrict readonly buffer renderedDataRed
+{
+ restrict readonly uint counts_SSBORed[];
+};
+layout(std430, binding=3) restrict readonly buffer renderedDataGreen
+{
+ restrict readonly uint counts_SSBOGreen[];
+};
+layout(std430, binding=4) restrict readonly buffer renderedDataBlue
+{
+ restrict readonly uint counts_SSBOBlue[];
+};
+
+uniform uint width;
+uniform uint height;
+
+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 firstIndex = (xIndex + yIndex * width);
+ return uvec3(counts_SSBORed[firstIndex],counts_SSBOGreen[firstIndex],counts_SSBOBlue[firstIndex]);
+}
+
+void main(){
+ uvec3 totalCount = getColorAt(uv);
+ uvec3 brightness = getColorAt(vec2(-0.2390625,0));
+
+ vec3 scaled = vec3(totalCount)/max(length(vec3(brightness)),1.0);
+ color = scaled;
+}
diff --git a/BuddhaTest/Shaders/BuddhaVertex.glsl b/BuddhaTest/Shaders/BuddhaVertex.glsl
index 686eeb4..58ae10d 100644
--- a/BuddhaTest/Shaders/BuddhaVertex.glsl
+++ b/BuddhaTest/Shaders/BuddhaVertex.glsl
@@ -1,11 +1,11 @@
-#version 430 core
-
-layout(location = 0) in vec3 vertexPosition_modelspace;
-
-out vec2 uv;
-
-void main(){
- gl_Position.xyz = vertexPosition_modelspace;
- gl_Position.w = 1.0;
- uv = gl_Position.xy;
+#version 430 core
+
+layout(location = 0) in vec3 vertexPosition_modelspace;
+
+out vec2 uv;
+
+void main(){
+ gl_Position.xyz = vertexPosition_modelspace;
+ gl_Position.w = 1.0;
+ uv = gl_Position.xy;
} \ No newline at end of file