Skip to content

Commit

Permalink
generate noise texture and sample for randomness
Browse files Browse the repository at this point in the history
  • Loading branch information
ktyldev committed Aug 9, 2021
1 parent c848616 commit 7f84ffd
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 20 deletions.
56 changes: 41 additions & 15 deletions shader/root/rt.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include sphere.glsl

layout(local_size_x = 1, local_size_y = 1) in; // size of local work group - 1 pixel

// TODO: do i actually need explicit location descriptors?
layout (location = 1) uniform vec4 _t;

Expand All @@ -16,14 +18,17 @@ layout (location = 8) uniform vec3 _camll;
layout (location = 9) uniform vec3 _cpos;
layout (location = 10) uniform vec3 _tpos; // target

const int SPHERES = 250; // 253 is the maximum?? TODO: use uniform buffer objects
// 253 is the maximum?? TODO: use uniform buffer objects
const int SPHERES = 250;

layout (location = 12) uniform int _activeSpheres;
layout (location = 13) uniform Sphere _spheres[SPHERES];

uniform vec4 _seed;

layout(local_size_x = 1, local_size_y = 1) in; // size of local work group - 1 pixel

layout(rgba32f, binding = 0) uniform image2D img_output; // rgba32f defines internal format, image2d for random write to output texture
layout(binding=1) uniform sampler2D _noise; // noise texture

const float INF = 1000.0;
const float PI = 3.14159;
Expand Down Expand Up @@ -144,14 +149,34 @@ RayHit trace(Ray ray)
return hit;
}

vec2 pixelUv()
{
ivec2 pixelCoords = ivec2(gl_GlobalInvocationID.xy);

ivec2 dims = imageSize(img_output);

vec2 uv;
uv.x = (float(pixelCoords.x * 2 - dims.x) / dims.x) * dims.x/dims.y; // account for aspect ratio
uv.y = (float(pixelCoords.y * 2 - dims.y) / dims.y);

return uv;
}

vec4 sampleNoise()
{
return texture(_noise, pixelUv());
}

float random(vec2 st)
{
st += gl_GlobalInvocationID.xy;
st += _seed.xy;
st += _seed.zw;
normalize(st);
//st += gl_GlobalInvocationID.xy;
//st += _seed.xy;
//st += _seed.zw;
//normalize(st);

return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);
vec2 nuv = texture(_noise, st.xy).xy;

return fract(sin(dot(nuv,vec2(12.9898,78.233)))*43758.5453123);
}

float sdot(vec3 x, vec3 y, float f = 1.0)
Expand All @@ -173,15 +198,17 @@ mat3 getTangentSpace(vec3 normal)

vec3 sampleHemisphere(vec3 normal)
{
float cosTheta = random(normal.xy);
vec4 noise = sampleNoise();

float cosTheta = random(normalize(normal.xy+noise.xy));
float sinTheta = sqrt(max(0.0,1.0-cosTheta*cosTheta));

float phi = 2.0*PI*random(normal.yx);
float phi = 2.0*PI*random(normalize(normal.yz+noise.xw));
vec3 tangentSpaceDir = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);

// convert direction from tangent space to world space
mat3 ts = getTangentSpace(normal);
return ts* tangentSpaceDir;
return ts * tangentSpaceDir;
}

vec3 scatterLambert(inout Ray ray, RayHit hit)
Expand Down Expand Up @@ -213,13 +240,10 @@ void main()
// get index in global work group ie xy position
ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy);

ivec2 dims = imageSize(img_output); // fetch image dimensions
vec2 uv;
uv.x = (float(pixel_coords.x * 2 - dims.x) / dims.x) * dims.x/dims.y; // account for aspect ratio
uv.y = (float(pixel_coords.y * 2 - dims.y) / dims.y);
vec2 uv = pixelUv();

int samples = 2;
int bounces = 3;
int bounces = 2;

for (int i = 0; i < samples; i++)
{
Expand All @@ -244,6 +268,8 @@ void main()
//pixel = vec4(hit.albedo,1.0);
//pixel *= (1.0-depth);

//pixel = texture(_noise, uv);

// output to a specific pixel in the image
imageStore(img_output, pixel_coords, pixel);
}
37 changes: 37 additions & 0 deletions src/gfx.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "gfx.h"
#include "random.h"
#include "stb_image.h"

float vertices[] = {
Expand Down Expand Up @@ -58,6 +59,10 @@ SDL_Window* gfxInit(int width, int height)
glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &uniformLocations);
printf("max uniform locations %d\n", uniformLocations);

int imageUnits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &imageUnits);
printf("max texture image units %d\n", imageUnits);

return sdlWindow;
}

Expand Down Expand Up @@ -191,6 +196,38 @@ void createTextureFromFile(const char* imagePath)
stbi_image_free(data);
}

// creates a noise texture in active texture 1
GLuint createNoiseTexture(int width, int height)
{
// same init steps as with a regular texture
GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_REPEAT);

int channels = 4; // rgba
int length = width*height*channels;
printf("generating %d random floats\n", length);

float data[width*height*channels];

for (int i = 0; i < length; i++)
{
data[i] = randomFloat();
}

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data);
glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
glGenerateMipmap(GL_TEXTURE_2D);

return texture;
}

GLuint createWriteOnlyTexture(int width, int height)
{
GLuint texture;
Expand Down
2 changes: 2 additions & 0 deletions src/gfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#include <SDL2/SDL_opengl.h>

#include "io.h"
#include "random.h"

SDL_Window* gfxInit(int width, int height);

unsigned int compileQuadShaderProgram(const char* vsPath, const char* fsPath);
unsigned int compileComputeShaderProgram();

GLuint createNoiseTexture(int width, int height);
void createTextureFromFile(const char* path);
GLuint createWriteOnlyTexture(int width, int height);
void printWorkGroupLimits();
Expand Down
26 changes: 21 additions & 5 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ void updateUniforms(GLuint shaderProgram);

int main()
{
randomInit();

// create a window and opengl context
SDL_Window* window = gfxInit(WIDTH, HEIGHT);

// generate noise
GLuint noise = createNoiseTexture(WIDTH, HEIGHT);

// create a texture for the compute shader to write to
GLuint textureOutput = createWriteOnlyTexture(WIDTH, HEIGHT);
printWorkGroupLimits();
Expand All @@ -27,34 +32,45 @@ int main()
"bin/shader.vert",
"bin/shader.frag");

glBindTexture(GL_TEXTURE_2D, noise);
int noiseLoc = glGetUniformLocation(computeProgram, "_noise");
glUniform1i(noiseLoc, noise);

// initialise quad
initBuffers();
setVertexAttributes();

int frames = 0;
// render loop
while (!checkQuit())
{
// dispatch compute shader
glUseProgram(computeProgram);

updateUniforms(computeProgram);

// dispatch compute shader
glDispatchCompute((GLuint)WIDTH, (GLuint)HEIGHT, 1);

// make sure we're finished writing to the texture before trying to read it
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

// normal drawing pass
glUseProgram(quadProgram);
glActiveTexture(GL_TEXTURE0); // use computed texture
glBindTexture(GL_TEXTURE_2D, textureOutput);

// bind texture written to by compute stage to 2d target
glBindTexture(GL_TEXTURE_2D, textureOutput);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

// swip swap
SDL_GL_SwapWindow(window);

frames++;
}

float elapsed = now();
printf("%d frames in %f seconds (avg: %f fps)\n",
frames,
elapsed,
(float)frames/elapsed);

return 0;
}

Expand Down

0 comments on commit 7f84ffd

Please sign in to comment.