extract includes
This commit is contained in:
parent
0c3d5bc1ac
commit
c4b74458a8
|
@ -0,0 +1,28 @@
|
||||||
|
// view space axes
|
||||||
|
uniform vec3 _w;
|
||||||
|
uniform vec3 _u;
|
||||||
|
uniform vec3 _v;
|
||||||
|
|
||||||
|
uniform mat4 _cameraInverseProjection;
|
||||||
|
uniform vec3 _camh;
|
||||||
|
uniform vec3 _camv;
|
||||||
|
uniform vec3 _camll;
|
||||||
|
uniform vec3 _cpos;
|
||||||
|
uniform vec3 _tpos;
|
||||||
|
|
||||||
|
Ray createCameraRay(vec2 uv)
|
||||||
|
{
|
||||||
|
// transform -1..1 -> 0..1
|
||||||
|
uv = uv*0.5+0.5;
|
||||||
|
|
||||||
|
vec3 target = vec3(0,0,0);
|
||||||
|
|
||||||
|
vec3 dir;
|
||||||
|
dir = uv.x*_camh + uv.y*_camv;
|
||||||
|
dir = _camll + uv.x*_camh + uv.y*_camv;
|
||||||
|
dir = normalize(dir);
|
||||||
|
|
||||||
|
Ray ray = createRay(_cpos, dir);
|
||||||
|
|
||||||
|
return ray;
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
const float INF = 1000.0;
|
||||||
|
const float PI = 3.14159;
|
|
@ -0,0 +1,4 @@
|
||||||
|
float sdot(vec3 x, vec3 y, float f = 1.0)
|
||||||
|
{
|
||||||
|
return clamp(dot(x,y)*f,0.0,1.0);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
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;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
|
||||||
|
{
|
||||||
|
vec3 c = sphere.cr.xyz;
|
||||||
|
float r = sphere.cr.w;
|
||||||
|
|
||||||
|
vec3 d = ray.origin-c;
|
||||||
|
float p1 = -dot(ray.direction,d);
|
||||||
|
float p2sqr = p1*p1-dot(d,d)+r*r;
|
||||||
|
|
||||||
|
if (p2sqr < 0) return;
|
||||||
|
|
||||||
|
float p2 = sqrt(p2sqr);
|
||||||
|
float t = p1-p2 > 0 ? p1-p2 : p1+p2;
|
||||||
|
if (t > 0 && t < bestHit.distance)
|
||||||
|
{
|
||||||
|
bestHit.distance = t;
|
||||||
|
bestHit.position = ray.origin + t * ray.direction;
|
||||||
|
bestHit.normal = normalize(bestHit.position-c);
|
||||||
|
bestHit.albedo = sphere.albedo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void intersectPlane(Ray ray, inout RayHit bestHit, vec3 p, vec3 normal)
|
||||||
|
{
|
||||||
|
//normal = vec3(0.0,0.0,1.0);
|
||||||
|
float denom = dot(normal, ray.direction);
|
||||||
|
|
||||||
|
if (abs(denom) > 0.0001)
|
||||||
|
{
|
||||||
|
float t = dot(p-ray.origin, normal) / denom;
|
||||||
|
if (t >= 0 && t < bestHit.distance)
|
||||||
|
{
|
||||||
|
bestHit.distance = t;
|
||||||
|
bestHit.position = ray.origin + t*ray.direction;
|
||||||
|
bestHit.normal = normal;
|
||||||
|
bestHit.albedo = vec3(1.0,1.0,1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
mat3 getTangentSpace(vec3 normal)
|
||||||
|
{
|
||||||
|
vec3 helper = abs(normal.x) > 0.99
|
||||||
|
? vec3(1.0,0.0,0.0)
|
||||||
|
: vec3(0.0,0.0,1.0);
|
||||||
|
|
||||||
|
vec3 tangent = normalize(cross(normal, helper));
|
||||||
|
vec3 binormal = normalize(cross(normal, tangent));
|
||||||
|
|
||||||
|
return mat3(tangent, binormal, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 sampleHemisphere(vec3 normal)
|
||||||
|
{
|
||||||
|
vec2 uv = pixelUv();
|
||||||
|
uv += _seed.xy;
|
||||||
|
|
||||||
|
vec4 noise = sampleNoise(uv);;
|
||||||
|
|
||||||
|
float cosTheta = random(normalize(normal.xy+noise.xy));
|
||||||
|
float sinTheta = sqrt(max(0.0,1.0-cosTheta*cosTheta));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 scatterLambert(inout Ray ray, RayHit hit)
|
||||||
|
{
|
||||||
|
ray.origin = hit.position + hit.normal*0.001;
|
||||||
|
ray.direction = sampleHemisphere(hit.normal);
|
||||||
|
ray.energy *= 2.0 * hit.albedo * sdot(hit.normal, ray.direction);
|
||||||
|
|
||||||
|
return vec3(0.0);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
uniform vec4 _seed;
|
||||||
|
layout(binding=1) uniform sampler2D _noise; // noise texture
|
||||||
|
|
||||||
|
vec4 sampleNoise(vec2 st)
|
||||||
|
{
|
||||||
|
return texture(_noise, st);
|
||||||
|
}
|
||||||
|
|
||||||
|
float random(vec2 st)
|
||||||
|
{
|
||||||
|
vec2 nuv = sampleNoise(st.xy).xy;
|
||||||
|
|
||||||
|
return fract(sin(dot(nuv,vec2(12.9898,78.233)))*43758.5453123);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
struct Ray
|
||||||
|
{
|
||||||
|
vec3 origin;
|
||||||
|
vec3 direction;
|
||||||
|
vec3 energy;
|
||||||
|
};
|
||||||
|
Ray createRay(vec3 origin, vec3 direction)
|
||||||
|
{
|
||||||
|
Ray ray;
|
||||||
|
|
||||||
|
ray.origin = origin;
|
||||||
|
ray.direction = direction;
|
||||||
|
ray.energy = vec3(1.0,1.0,1.0);
|
||||||
|
|
||||||
|
return ray;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RayHit
|
||||||
|
{
|
||||||
|
vec3 position;
|
||||||
|
float distance;
|
||||||
|
vec3 normal;
|
||||||
|
vec3 albedo;
|
||||||
|
};
|
||||||
|
RayHit createRayHit()
|
||||||
|
{
|
||||||
|
RayHit hit;
|
||||||
|
|
||||||
|
hit.position = vec3(0.0,0.0,0.0);
|
||||||
|
// TODO: this might not be defined
|
||||||
|
hit.distance = INF;
|
||||||
|
hit.normal = vec3(0.0,0.0,0.0);
|
||||||
|
hit.albedo = vec3(0.0,0.0,0.0);
|
||||||
|
|
||||||
|
return hit;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
RayHit trace(Ray ray)
|
||||||
|
{
|
||||||
|
RayHit hit = createRayHit();
|
||||||
|
|
||||||
|
Sphere s;
|
||||||
|
s.cr = vec4(0.0,0.0,0.0,2.0);
|
||||||
|
s.albedo = vec3(1.0,0.0,0.0);
|
||||||
|
|
||||||
|
intersectPlane(ray, hit, vec3(0.0,-1.5,0.0),vec3(0.0,1.0,0.0));
|
||||||
|
|
||||||
|
for (int i = 0; i < _activeSpheres; i++)
|
||||||
|
{
|
||||||
|
intersectSphere(ray, hit, _spheres[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hit;
|
||||||
|
}
|
|
@ -4,3 +4,8 @@ struct Sphere
|
||||||
vec4 cr;
|
vec4 cr;
|
||||||
vec3 albedo;
|
vec3 albedo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 253 is the maximum?? TODO: use uniform buffer objects
|
||||||
|
const int SPHERES = 250;
|
||||||
|
uniform int _activeSpheres;
|
||||||
|
layout (location = 1) uniform Sphere _spheres[SPHERES];
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
uniform vec4 _t;
|
|
@ -1,226 +1,23 @@
|
||||||
#version 430
|
#version 430
|
||||||
|
|
||||||
#include sphere.glsl
|
|
||||||
|
|
||||||
layout(local_size_x = 1, local_size_y = 1) in; // size of local work group - 1 pixel
|
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?
|
// final output
|
||||||
layout (location = 1) uniform vec4 _t;
|
|
||||||
|
|
||||||
layout (location = 2) uniform vec3 _w; // view space axes
|
|
||||||
layout (location = 3) uniform vec3 _u;
|
|
||||||
layout (location = 4) uniform vec3 _v;
|
|
||||||
|
|
||||||
layout (location = 5) uniform mat4 _cameraInverseProjection;
|
|
||||||
layout (location = 6) uniform vec3 _camh;
|
|
||||||
layout (location = 7) uniform vec3 _camv;
|
|
||||||
layout (location = 8) uniform vec3 _camll;
|
|
||||||
layout (location = 9) uniform vec3 _cpos;
|
|
||||||
layout (location = 10) uniform vec3 _tpos; // target
|
|
||||||
|
|
||||||
// 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(rgba32f, binding = 0) uniform image2D img_output; // rgba32f defines internal format, image2d for random write to output texture
|
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;
|
// TODO: some of these depend on each other!! need be be in this order for now c:
|
||||||
const float PI = 3.14159;
|
#include func.glsl
|
||||||
|
#include constants.glsl
|
||||||
struct Ray
|
#include time.glsl
|
||||||
{
|
#include sphere.glsl
|
||||||
vec3 origin;
|
#include ray.glsl
|
||||||
vec3 direction;
|
#include intersect.glsl
|
||||||
vec3 energy;
|
#include random.glsl
|
||||||
};
|
#include camera.glsl
|
||||||
Ray createRay(vec3 origin, vec3 direction)
|
#include image.glsl
|
||||||
{
|
// scene.glsl includes scene trace function
|
||||||
Ray ray;
|
#include scene.glsl
|
||||||
|
#include lighting.glsl
|
||||||
ray.origin = origin;
|
|
||||||
ray.direction = direction;
|
|
||||||
ray.energy = vec3(1.0,1.0,1.0);
|
|
||||||
|
|
||||||
return ray;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RayHit
|
|
||||||
{
|
|
||||||
vec3 position;
|
|
||||||
float distance;
|
|
||||||
vec3 normal;
|
|
||||||
vec3 albedo;
|
|
||||||
};
|
|
||||||
RayHit createRayHit()
|
|
||||||
{
|
|
||||||
RayHit hit;
|
|
||||||
|
|
||||||
hit.position = vec3(0.0,0.0,0.0);
|
|
||||||
hit.distance = INF;
|
|
||||||
hit.normal = vec3(0.0,0.0,0.0);
|
|
||||||
hit.albedo = vec3(0.0,0.0,0.0);
|
|
||||||
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
|
|
||||||
{
|
|
||||||
vec3 c = sphere.cr.xyz;
|
|
||||||
float r = sphere.cr.w;
|
|
||||||
|
|
||||||
vec3 d = ray.origin-c;
|
|
||||||
float p1 = -dot(ray.direction,d);
|
|
||||||
float p2sqr = p1*p1-dot(d,d)+r*r;
|
|
||||||
|
|
||||||
if (p2sqr < 0) return;
|
|
||||||
|
|
||||||
float p2 = sqrt(p2sqr);
|
|
||||||
float t = p1-p2 > 0 ? p1-p2 : p1+p2;
|
|
||||||
if (t > 0 && t < bestHit.distance)
|
|
||||||
{
|
|
||||||
bestHit.distance = t;
|
|
||||||
bestHit.position = ray.origin + t * ray.direction;
|
|
||||||
bestHit.normal = normalize(bestHit.position-c);
|
|
||||||
bestHit.albedo = sphere.albedo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void intersectPlane(Ray ray, inout RayHit bestHit, vec3 p, vec3 normal)
|
|
||||||
{
|
|
||||||
//normal = vec3(0.0,0.0,1.0);
|
|
||||||
float denom = dot(normal, ray.direction);
|
|
||||||
|
|
||||||
if (abs(denom) > 0.0001)
|
|
||||||
{
|
|
||||||
float t = dot(p-ray.origin, normal) / denom;
|
|
||||||
if (t >= 0 && t < bestHit.distance)
|
|
||||||
{
|
|
||||||
bestHit.distance = t;
|
|
||||||
bestHit.position = ray.origin + t*ray.direction;
|
|
||||||
bestHit.normal = normal;
|
|
||||||
bestHit.albedo = vec3(1.0,1.0,1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ray createCameraRay(vec2 uv)
|
|
||||||
{
|
|
||||||
// transform -1..1 -> 0..1
|
|
||||||
uv = uv*0.5+0.5;
|
|
||||||
//uv.x=1-uv.x;
|
|
||||||
|
|
||||||
vec3 target = vec3(0,0,0);
|
|
||||||
|
|
||||||
vec3 dir;
|
|
||||||
dir = uv.x*_camh + uv.y*_camv;
|
|
||||||
dir = _camll + uv.x*_camh + uv.y*_camv;
|
|
||||||
dir = normalize(dir);
|
|
||||||
|
|
||||||
Ray ray = createRay(_cpos, dir);
|
|
||||||
|
|
||||||
return ray;
|
|
||||||
};
|
|
||||||
|
|
||||||
RayHit trace(Ray ray)
|
|
||||||
{
|
|
||||||
RayHit hit = createRayHit();
|
|
||||||
|
|
||||||
// TODO: intersect something other than spheres
|
|
||||||
|
|
||||||
Sphere s;
|
|
||||||
s.cr = vec4(0.0,0.0,0.0,2.0);
|
|
||||||
s.albedo = vec3(1.0,0.0,0.0);
|
|
||||||
|
|
||||||
intersectPlane(ray, hit, vec3(0.0,-1.5,0.0),vec3(0.0,1.0,0.0));
|
|
||||||
|
|
||||||
for (int i = 0; i < _activeSpheres; i++)
|
|
||||||
{
|
|
||||||
intersectSphere(ray, hit, _spheres[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//intersectSphere(ray, hit, s);
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
vec2 uv = pixelUv();
|
|
||||||
uv += _seed.xy;
|
|
||||||
|
|
||||||
return texture(_noise, uv);
|
|
||||||
}
|
|
||||||
|
|
||||||
float random(vec2 st)
|
|
||||||
{
|
|
||||||
//st += gl_GlobalInvocationID.xy;
|
|
||||||
//st += _seed.xy;
|
|
||||||
//st += _seed.zw;
|
|
||||||
//normalize(st);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return clamp(dot(x,y)*f,0.0,1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
mat3 getTangentSpace(vec3 normal)
|
|
||||||
{
|
|
||||||
vec3 helper = abs(normal.x) > 0.99
|
|
||||||
? vec3(1.0,0.0,0.0)
|
|
||||||
: vec3(0.0,0.0,1.0);
|
|
||||||
|
|
||||||
vec3 tangent = normalize(cross(normal, helper));
|
|
||||||
vec3 binormal = normalize(cross(normal, tangent));
|
|
||||||
|
|
||||||
return mat3(tangent, binormal, normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sampleHemisphere(vec3 normal)
|
|
||||||
{
|
|
||||||
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(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 scatterLambert(inout Ray ray, RayHit hit)
|
|
||||||
{
|
|
||||||
ray.origin = hit.position + hit.normal*0.001;
|
|
||||||
ray.direction = sampleHemisphere(hit.normal);
|
|
||||||
ray.energy *= 2.0 * hit.albedo * sdot(hit.normal, ray.direction);
|
|
||||||
|
|
||||||
return vec3(0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 shade(inout Ray ray, RayHit hit)
|
vec3 shade(inout Ray ray, RayHit hit)
|
||||||
{
|
{
|
||||||
|
@ -229,8 +26,6 @@ vec3 shade(inout Ray ray, RayHit hit)
|
||||||
return scatterLambert(ray, hit);
|
return scatterLambert(ray, hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ray.energy = vec3(0.0);
|
|
||||||
|
|
||||||
// sky color
|
// sky color
|
||||||
return vec3(0.68,0.85,0.9);
|
return vec3(0.68,0.85,0.9);
|
||||||
}
|
}
|
||||||
|
@ -239,8 +34,6 @@ void main()
|
||||||
{
|
{
|
||||||
// base pixel colour for the image
|
// base pixel colour for the image
|
||||||
vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
|
vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
// get index in global work group ie xy position
|
|
||||||
ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy);
|
|
||||||
|
|
||||||
vec2 uv = pixelUv();
|
vec2 uv = pixelUv();
|
||||||
|
|
||||||
|
@ -262,16 +55,8 @@ void main()
|
||||||
if (length(ray.energy) < 0.001) break;
|
if (length(ray.energy) < 0.001) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pixel.xyz /= samples;
|
pixel.xyz /= samples;
|
||||||
|
|
||||||
// TODO: write depth to texture
|
|
||||||
//float depth = hit.distance/INF;
|
|
||||||
//pixel = vec4(hit.albedo,1.0);
|
|
||||||
//pixel *= (1.0-depth);
|
|
||||||
|
|
||||||
//pixel = texture(_noise, uv);
|
|
||||||
|
|
||||||
// output to a specific pixel in the image
|
// output to a specific pixel in the image
|
||||||
imageStore(img_output, pixel_coords, pixel);
|
imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#version 430
|
||||||
|
|
||||||
|
#include sphere.glsl
|
26
src/main.c
26
src/main.c
|
@ -11,6 +11,12 @@ const int HEIGHT = 420;
|
||||||
|
|
||||||
void updateUniforms(GLuint shaderProgram);
|
void updateUniforms(GLuint shaderProgram);
|
||||||
|
|
||||||
|
struct TextureIDs
|
||||||
|
{
|
||||||
|
GLuint output; // the texture that ultimately gets rendered
|
||||||
|
GLuint noise;
|
||||||
|
} textureIds;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
printf("GL_TEXTURE0: %d\n", GL_TEXTURE0);
|
printf("GL_TEXTURE0: %d\n", GL_TEXTURE0);
|
||||||
|
@ -21,8 +27,6 @@ int main()
|
||||||
// create a window and opengl context
|
// create a window and opengl context
|
||||||
SDL_Window* window = gfxInit(WIDTH, HEIGHT);
|
SDL_Window* window = gfxInit(WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// compile shader programs
|
// compile shader programs
|
||||||
unsigned int computeProgram = compileComputeShaderProgram(
|
unsigned int computeProgram = compileComputeShaderProgram(
|
||||||
"bin/rt.compute");
|
"bin/rt.compute");
|
||||||
|
@ -31,13 +35,13 @@ int main()
|
||||||
"bin/shader.frag");
|
"bin/shader.frag");
|
||||||
|
|
||||||
// generate noise
|
// generate noise
|
||||||
GLuint noise = createNoiseTexture(WIDTH, HEIGHT);
|
textureIds.noise = createNoiseTexture(WIDTH, HEIGHT);
|
||||||
glBindTexture(GL_TEXTURE_2D, noise);
|
glBindTexture(GL_TEXTURE_2D,textureIds.noise);
|
||||||
int noiseLoc = glGetUniformLocation(computeProgram, "_noise");
|
int noiseLoc = glGetUniformLocation(computeProgram, "_noise");
|
||||||
glUniform1i(noiseLoc, noise);
|
glUniform1i(noiseLoc, textureIds.noise);
|
||||||
|
|
||||||
// create a texture for the compute shader to write to
|
// create a texture for the compute shader to write to
|
||||||
GLuint textureOutput = createWriteOnlyTexture(WIDTH, HEIGHT);
|
textureIds.output = createWriteOnlyTexture(WIDTH, HEIGHT);
|
||||||
printWorkGroupLimits();
|
printWorkGroupLimits();
|
||||||
|
|
||||||
// initialise quad
|
// initialise quad
|
||||||
|
@ -60,7 +64,7 @@ int main()
|
||||||
glUseProgram(quadProgram);
|
glUseProgram(quadProgram);
|
||||||
|
|
||||||
// bind texture written to by compute stage to 2d target
|
// bind texture written to by compute stage to 2d target
|
||||||
glBindTexture(GL_TEXTURE_2D, textureOutput);
|
glBindTexture(GL_TEXTURE_2D, textureIds.output);
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
// swip swap
|
// swip swap
|
||||||
|
@ -91,17 +95,19 @@ void updateUniforms(GLuint shaderProgram)
|
||||||
int loc = glGetUniformLocation(shaderProgram, "_seed");
|
int loc = glGetUniformLocation(shaderProgram, "_seed");
|
||||||
glUniform4fv(loc, 1, seed);
|
glUniform4fv(loc, 1, seed);
|
||||||
|
|
||||||
|
// update time
|
||||||
float t = now();
|
float t = now();
|
||||||
float sin_t = sin(t);
|
float sin_t = sin(t);
|
||||||
int tLocation = glGetUniformLocation(shaderProgram, "_t");
|
loc = glGetUniformLocation(shaderProgram, "_t");
|
||||||
glUniform4f(tLocation, t, sin_t, (1.0 + sin_t)*0.5, 0.0f);
|
glUniform4f(loc, t, sin_t, (1.0 + sin_t)*0.5, 0.0f);
|
||||||
|
|
||||||
|
// update camera
|
||||||
float aspect = (float)WIDTH/(float)HEIGHT;
|
float aspect = (float)WIDTH/(float)HEIGHT;
|
||||||
updateCameraUniforms(shaderProgram, aspect);
|
updateCameraUniforms(shaderProgram, aspect);
|
||||||
|
|
||||||
|
// make and update spheres
|
||||||
const int sphereCount = 42;
|
const int sphereCount = 42;
|
||||||
struct Sphere spheres[sphereCount];
|
struct Sphere spheres[sphereCount];
|
||||||
makeSpheres(spheres, sphereCount);
|
makeSpheres(spheres, sphereCount);
|
||||||
|
|
||||||
updateSphereUniforms(shaderProgram, spheres, sphereCount);
|
updateSphereUniforms(shaderProgram, spheres, sphereCount);
|
||||||
}
|
}
|
||||||
|
|
1
todo.md
1
todo.md
|
@ -1,6 +1,7 @@
|
||||||
* [-] preprocessor
|
* [-] preprocessor
|
||||||
* [x] #include directives
|
* [x] #include directives
|
||||||
* [ ] keep track of previously included files to avoid redefinitions
|
* [ ] keep track of previously included files to avoid redefinitions
|
||||||
|
* [ ] include as submodule
|
||||||
* [-] render image with compute shader
|
* [-] render image with compute shader
|
||||||
* [x] render a texture to a full-screen quad
|
* [x] render a texture to a full-screen quad
|
||||||
* [x] pass uniforms to shader to animate it
|
* [x] pass uniforms to shader to animate it
|
||||||
|
|
Loading…
Reference in New Issue