pass spheres to shader as array
This commit is contained in:
parent
9a14ab8283
commit
5cc2c3d92b
|
@ -1,8 +1,6 @@
|
||||||
struct Sphere
|
struct Sphere
|
||||||
{
|
{
|
||||||
vec3 center;
|
// (c.x,c.y,c.z,r)
|
||||||
float radius;
|
vec4 cr;
|
||||||
vec3 albedo;
|
vec3 albedo;
|
||||||
vec3 specular;
|
|
||||||
vec3 emission;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 430
|
#version 430
|
||||||
|
|
||||||
|
#include sphere.glsl
|
||||||
|
|
||||||
// TODO: do i actually need explicit location descriptors?
|
// TODO: do i actually need explicit location descriptors?
|
||||||
layout (location = 1) uniform vec4 _t;
|
layout (location = 1) uniform vec4 _t;
|
||||||
|
|
||||||
|
@ -14,12 +16,15 @@ layout (location = 8) uniform vec3 _camll;
|
||||||
layout (location = 9) uniform vec3 _cpos;
|
layout (location = 9) uniform vec3 _cpos;
|
||||||
layout (location = 10) uniform vec3 _tpos; // target
|
layout (location = 10) uniform vec3 _tpos; // target
|
||||||
|
|
||||||
|
const int SPHERES = 250; // 253 is the maximum?? TODO: use uniform buffer objects
|
||||||
|
layout (location = 12) uniform int _activeSpheres;
|
||||||
|
layout (location = 13) uniform Sphere _spheres[SPHERES];
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
const float INF = 30.0;
|
const float INF = 20.0;
|
||||||
|
const float PI = 3.14159;
|
||||||
#include sphere.glsl
|
|
||||||
|
|
||||||
struct Ray
|
struct Ray
|
||||||
{
|
{
|
||||||
|
@ -37,9 +42,12 @@ struct RayHit
|
||||||
|
|
||||||
void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
|
void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
|
||||||
{
|
{
|
||||||
vec3 d = ray.origin-sphere.center;
|
vec3 c = sphere.cr.xyz;
|
||||||
|
float r = sphere.cr.w;
|
||||||
|
|
||||||
|
vec3 d = ray.origin-c;
|
||||||
float p1 = -dot(ray.direction,d);
|
float p1 = -dot(ray.direction,d);
|
||||||
float p2sqr = p1*p1-dot(d,d)+sphere.radius*sphere.radius;
|
float p2sqr = p1*p1-dot(d,d)+r*r;
|
||||||
|
|
||||||
if (p2sqr < 0) return;
|
if (p2sqr < 0) return;
|
||||||
|
|
||||||
|
@ -49,7 +57,7 @@ void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
|
||||||
{
|
{
|
||||||
bestHit.distance = t;
|
bestHit.distance = t;
|
||||||
bestHit.position = ray.origin + t*ray.direction;
|
bestHit.position = ray.origin + t*ray.direction;
|
||||||
bestHit.normal = normalize(bestHit.position-sphere.center);
|
bestHit.normal = normalize(bestHit.position-c);
|
||||||
bestHit.albedo = sphere.albedo;
|
bestHit.albedo = sphere.albedo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,19 +70,6 @@ Ray createCameraRay(vec2 uv)
|
||||||
|
|
||||||
vec3 target = vec3(0,0,0);
|
vec3 target = vec3(0,0,0);
|
||||||
|
|
||||||
// transform camera origin to world space
|
|
||||||
// TODO: c2w matrix!! for now we just assume the camera is at the origin
|
|
||||||
// float3 origin = mul(_CameraToWorld, float4(0.0,0.0,0.0,1.0)).xyz;
|
|
||||||
|
|
||||||
// TODO: offset from centre of the lens for depth of field
|
|
||||||
// float2 rd = _CameraLensRadius * randomInUnitDisk();
|
|
||||||
// float3 offset = _CameraU * rd.x + _CameraV * rd.y;
|
|
||||||
|
|
||||||
// invert perspective projection of view space position
|
|
||||||
//vec3 dir = mul(_cameraInverseProjection, float4(uv, 0.0, 1.0)).xyz;
|
|
||||||
|
|
||||||
// TODO: transform direction from camera to world space (move camera around!)
|
|
||||||
|
|
||||||
vec3 dir;
|
vec3 dir;
|
||||||
dir = uv.x*_camh + uv.y*_camv;
|
dir = uv.x*_camh + uv.y*_camv;
|
||||||
dir = _camll + uv.x*_camh + uv.y*_camv;
|
dir = _camll + uv.x*_camh + uv.y*_camv;
|
||||||
|
@ -111,30 +106,10 @@ void main()
|
||||||
hit.normal = vec3(0.0,0.0,0.0);
|
hit.normal = vec3(0.0,0.0,0.0);
|
||||||
hit.albedo = vec3(0.0,0.0,0.0);
|
hit.albedo = vec3(0.0,0.0,0.0);
|
||||||
|
|
||||||
vec3 spheresCenter = vec3(0.0,0.0,0.0);
|
for (int i = 0; i < _activeSpheres; i++)
|
||||||
|
{
|
||||||
float t = _t.x;
|
intersectSphere(ray, hit, _spheres[i]);
|
||||||
Sphere s1;
|
}
|
||||||
s1.center = spheresCenter+vec3(sin(t),0.0,cos(t))*2.5;
|
|
||||||
s1.radius = 2.0;
|
|
||||||
s1.albedo = vec3(1.0,0.0,0.0);
|
|
||||||
|
|
||||||
t+=3.1415/1.5;
|
|
||||||
Sphere s2;
|
|
||||||
s2.center = spheresCenter+vec3(sin(t),0.0,cos(t))*2.5;
|
|
||||||
s2.radius = 2.0;
|
|
||||||
s2.albedo = vec3(0.0,1.0,0.0);
|
|
||||||
|
|
||||||
t+=3.1415/1.5;
|
|
||||||
Sphere s3;
|
|
||||||
s3.center = spheresCenter+vec3(sin(t),0.0,cos(t))*2.5;
|
|
||||||
s3.radius = 2.0;
|
|
||||||
s3.albedo = vec3(0.0,0.0,1.0);
|
|
||||||
|
|
||||||
// ray-sphere intersection
|
|
||||||
intersectSphere(ray, hit, s1);
|
|
||||||
intersectSphere(ray, hit, s2);
|
|
||||||
intersectSphere(ray, hit, s3);
|
|
||||||
|
|
||||||
// TODO: write depth to texture
|
// TODO: write depth to texture
|
||||||
float depth = hit.distance/INF;
|
float depth = hit.distance/INF;
|
||||||
|
|
|
@ -54,6 +54,10 @@ SDL_Window* gfxInit(int width, int height)
|
||||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &availableAttributes);
|
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &availableAttributes);
|
||||||
printf("max vertex attributes %d\n", availableAttributes);
|
printf("max vertex attributes %d\n", availableAttributes);
|
||||||
|
|
||||||
|
int uniformLocations;
|
||||||
|
glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &uniformLocations);
|
||||||
|
printf("max uniform locations %d\n", uniformLocations);
|
||||||
|
|
||||||
return sdlWindow;
|
return sdlWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
58
src/main.c
58
src/main.c
|
@ -1,6 +1,8 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#include "sphere.h"
|
||||||
|
|
||||||
const int WIDTH = 420;
|
const int WIDTH = 420;
|
||||||
const int HEIGHT = 420;
|
const int HEIGHT = 420;
|
||||||
|
|
||||||
|
@ -15,6 +17,8 @@ float time();
|
||||||
void updateUniforms(GLuint shaderProgram);
|
void updateUniforms(GLuint shaderProgram);
|
||||||
void updateCameraUniforms(GLuint shaderProgram);
|
void updateCameraUniforms(GLuint shaderProgram);
|
||||||
|
|
||||||
|
void updateSphereUniform(GLuint shaderProgram, struct Sphere sphere);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// create a window and opengl context
|
// create a window and opengl context
|
||||||
|
@ -62,6 +66,48 @@ int main()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void makeSpheres(struct Sphere *spheres, int count)
|
||||||
|
{
|
||||||
|
float t = time();
|
||||||
|
|
||||||
|
vec3 albedos[] =
|
||||||
|
{
|
||||||
|
{0.0,0.0,1.0},
|
||||||
|
{0.0,1.0,0.0},
|
||||||
|
{0.0,1.0,1.0},
|
||||||
|
{1.0,0.0,0.0},
|
||||||
|
{1.0,0.0,1.0},
|
||||||
|
{1.0,1.0,0.0},
|
||||||
|
{1.0,1.0,1.0}
|
||||||
|
};
|
||||||
|
|
||||||
|
// distance from center
|
||||||
|
float d = 6.0;
|
||||||
|
float radius = 0.5;
|
||||||
|
float x;
|
||||||
|
vec3 sc = {0.0,0.0,1.0};
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
x = t*0.1 + 2.0*CGLM_PI * i/(float)count;
|
||||||
|
sc[0] = sin(x)*d;
|
||||||
|
sc[2] = cos(x)*d;
|
||||||
|
|
||||||
|
float ic = i/(float)count;
|
||||||
|
float r = sin(ic);
|
||||||
|
float g = sin(ic+1.0);
|
||||||
|
float b = sin(ic+2.0);
|
||||||
|
g = 1.0;
|
||||||
|
b = 1.0;
|
||||||
|
|
||||||
|
vec3 col = {r,g,b};
|
||||||
|
glm_vec3_scale(col, 0.5, col);
|
||||||
|
glm_vec3_adds(col, 0.5, col);
|
||||||
|
|
||||||
|
spheres[i] = makeSphere(sc,radius,col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void updateUniforms(GLuint shaderProgram)
|
void updateUniforms(GLuint shaderProgram)
|
||||||
{
|
{
|
||||||
float t = time(); // time
|
float t = time(); // time
|
||||||
|
@ -70,13 +116,19 @@ void updateUniforms(GLuint shaderProgram)
|
||||||
glUniform4f(tLocation, t, sin_t, (1.0 + sin_t)*0.5, 0.0f);
|
glUniform4f(tLocation, t, sin_t, (1.0 + sin_t)*0.5, 0.0f);
|
||||||
|
|
||||||
updateCameraUniforms(shaderProgram);
|
updateCameraUniforms(shaderProgram);
|
||||||
|
|
||||||
|
const int sphereCount = 42;
|
||||||
|
struct Sphere spheres[sphereCount];
|
||||||
|
makeSpheres(spheres, sphereCount);
|
||||||
|
|
||||||
|
updateSphereUniforms(shaderProgram, spheres, sphereCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateCameraUniforms(GLuint shaderProgram)
|
void updateCameraUniforms(GLuint shaderProgram)
|
||||||
{
|
{
|
||||||
// set up perspective projection matrix and its inverse
|
// set up perspective projection matrix and its inverse
|
||||||
mat4 proj, proji;
|
mat4 proj, proji;
|
||||||
float fovy = 60.0; // vertical field of view in deg
|
float fovy = 90.0; // vertical field of view in deg
|
||||||
float near = 0.1;
|
float near = 0.1;
|
||||||
float far = 1000.0;
|
float far = 1000.0;
|
||||||
float aspect = (float)WIDTH/(float)HEIGHT;
|
float aspect = (float)WIDTH/(float)HEIGHT;
|
||||||
|
@ -93,7 +145,8 @@ void updateCameraUniforms(GLuint shaderProgram)
|
||||||
|
|
||||||
// lookat vector and view matrix
|
// lookat vector and view matrix
|
||||||
float d = 10.0 + sin(t);
|
float d = 10.0 + sin(t);
|
||||||
vec3 cpos = {sin(-t)*d,cos(0.5*t)*5.0,cos(-t)*d}; // camera pos
|
float pt = -t*0.1;
|
||||||
|
vec3 cpos = {sin(pt)*d,cos(0.5*t)*5.0,cos(pt)*d}; // camera pos
|
||||||
vec3 tpos = {0.0,0.0,0.0}; // target pos
|
vec3 tpos = {0.0,0.0,0.0}; // target pos
|
||||||
glm_vec3_sub(cpos,tpos,cdir); // look dir (inverted cause opengl noises)
|
glm_vec3_sub(cpos,tpos,cdir); // look dir (inverted cause opengl noises)
|
||||||
glm_vec3_normalize(cdir);
|
glm_vec3_normalize(cdir);
|
||||||
|
@ -159,6 +212,7 @@ void updateCameraUniforms(GLuint shaderProgram)
|
||||||
glUniform3f(camllLocation, camll[0], camll[1], camll[2]);
|
glUniform3f(camllLocation, camll[0], camll[1], camll[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float time()
|
float time()
|
||||||
{
|
{
|
||||||
// ms / 1000.0 = seconds since start
|
// ms / 1000.0 = seconds since start
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "sphere.h"
|
||||||
|
|
||||||
|
struct Sphere makeSphere(vec3 center, float radius, vec3 albedo)
|
||||||
|
{
|
||||||
|
struct Sphere s;
|
||||||
|
|
||||||
|
s.cr[0] = center[0];
|
||||||
|
s.cr[1] = center[1];
|
||||||
|
s.cr[2] = center[2];
|
||||||
|
s.cr[3] = radius;
|
||||||
|
|
||||||
|
glm_vec3_copy(albedo, s.albedo);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSphereUniform(GLuint shaderProgram, struct Sphere sphere)
|
||||||
|
{
|
||||||
|
int scrloc, saloc;
|
||||||
|
scrloc = glGetUniformLocation(shaderProgram, "_sphere.cr");
|
||||||
|
saloc = glGetUniformLocation(shaderProgram, "_sphere.albedo");
|
||||||
|
|
||||||
|
glUniform4fv(scrloc, 1, sphere.cr);
|
||||||
|
glUniform3fv(saloc, 1, sphere.albedo);
|
||||||
|
|
||||||
|
updateSphereUniforms(shaderProgram, &sphere, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSphereUniforms(GLuint shaderProgram, struct Sphere *spheres, int count)
|
||||||
|
{
|
||||||
|
// set sphere count
|
||||||
|
int loc = glGetUniformLocation(shaderProgram, "_activeSpheres");
|
||||||
|
glUniform1i(loc, count);
|
||||||
|
|
||||||
|
// each sphere takes up two uniform locations
|
||||||
|
const int stride = 2;
|
||||||
|
|
||||||
|
// first location in the array
|
||||||
|
loc = glGetUniformLocation(shaderProgram, "_spheres[0].cr");
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
struct Sphere s = spheres[i];
|
||||||
|
glUniform4fv(loc+i*stride, 1, s.cr);
|
||||||
|
glUniform3fv(loc+i*stride+1, 1, s.albedo);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#include <cglm/vec3.h>
|
||||||
|
|
||||||
|
struct Sphere
|
||||||
|
{
|
||||||
|
vec4 cr;
|
||||||
|
vec3 albedo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Sphere makeSphere(vec3 center, float radius, vec3 albedo);
|
||||||
|
void updateSphereUniform(GLuint shaderProgram, struct Sphere sphere);
|
||||||
|
void updateSphereUniforms(GLuint shaderProgram, struct Sphere *spheres, int count);
|
6
todo.md
6
todo.md
|
@ -7,10 +7,14 @@
|
||||||
* [x] compile processed shaders
|
* [x] compile processed shaders
|
||||||
* [-] 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 texture to animate it
|
* [x] pass uniforms to shader to animate it
|
||||||
|
* [x] pass structed uniform buffers
|
||||||
* [-] ray tracing time
|
* [-] ray tracing time
|
||||||
* [x] perspective
|
* [x] perspective
|
||||||
* [x] camera lookat
|
* [x] camera lookat
|
||||||
|
* [ ] do a bounce
|
||||||
|
* [ ] do a 'flect
|
||||||
|
* [ ] do a 'fract
|
||||||
* [-] depth
|
* [-] depth
|
||||||
* [x] acquire value
|
* [x] acquire value
|
||||||
* [ ] depth texture
|
* [ ] depth texture
|
||||||
|
|
Loading…
Reference in New Issue