Commit 9a21859b authored by Bastian Krayer's avatar Bastian Krayer

added gpu trace exercise

parent 8c5e7332
cmake_minimum_required(VERSION 2.8)
include(${CMAKE_MODULE_PATH}/DefaultExecutable.cmake)
\ No newline at end of file
#include "Material.h"
\ No newline at end of file
#ifndef GPU_TRACE_MATERIAL_H
#define GPU_TRACE_MATERIAL_H
#include <glm/glm.hpp>
struct Material {
// TODO
// fill with correct members
};
#endif
\ No newline at end of file
#include "Object.h"
\ No newline at end of file
#ifndef GPU_TRACE_OBJECT_H
#define GPU_TRACE_OBJECT_H
struct Object {
// TODO
// fill with correct members
};
#endif
\ No newline at end of file
#ifndef GPU_TRACE_POINTLIGHT_H
#define GPU_TRACE_POINTLIGHT_H
#include <glm/glm.hpp>
struct PointLight {
// TODO
// fill with correct members
};
#endif
\ No newline at end of file
#include "Sphere.h"
\ No newline at end of file
#ifndef GPU_TRACE_SPHERE_H
#define GPU_TRACE_SPHERE_H
#include <glm/glm.hpp>
struct Sphere {
// TODO
// fill with correct members
};
#endif
\ No newline at end of file
CVK_2
\ No newline at end of file
#include "Material.h"
#include "Object.h"
#include "PointLight.h"
#include "Sphere.h"
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <CVK_2/CVK_CompatibilityTools.h>
#include <CVK_2/CVK_ShaderSet.h>
#include <CVK_2/CVK_Trackball.h>
#include <memory>
#include <vector>
int width = 800;
int height = 800;
const int SPHERE_TYPE = 0;
int main() {
// Data for fullscreen quad
std::vector<glm::vec2> quadData = {{-1.0, -1.0}, {1.0, -1.0}, {-1.0, 1.0},
{-1.0, 1.0}, {1.0, -1.0}, {1.0, 1.0}};
// Init
glfwInit();
CVK::useOpenGL33CoreProfile();
GLFWwindow* window =
glfwCreateWindow(width, height, "GPU Raytracer", nullptr, nullptr);
glfwSetWindowPos(window, 600, 50);
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize OpenGL context" << std::endl;
return -1;
}
// compile a shader program
std::vector<std::string> shadernames = {
CVK::State::getInstance()->getShaderPath() + "/GPUTrace/simple.vert",
CVK::State::getInstance()->getShaderPath() + "/GPUTrace/trace.frag"};
std::unique_ptr<CVK::ShaderSet> shader = std::make_unique<CVK::ShaderSet>(
VERTEX_SHADER_BIT | FRAGMENT_SHADER_BIT, shadernames);
// VAO and VBO for fullscreen quad
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * quadData.size(),
quadData.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Set Shader and get uniforms
shader->useProgram();
GLint pLoc = glGetUniformLocation(shader->getProgramID(), "P");
GLint vLoc = glGetUniformLocation(shader->getProgramID(), "V");
// trackball camera
CVK::Perspective proj(glm::radians(45.0f), float(width) / float(height),
0.01f, 100.0f);
CVK::Trackball cam(window, width, height, &proj);
cam.setRadius(20);
// Vector containing ssbo ids
std::vector<GLuint> ssbos(4);
glGenBuffers(4, ssbos.data());
// vectors containing scene data
std::vector<Object> objects;
std::vector<PointLight> pointlights;
std::vector<Material> mats;
std::vector<Sphere> spheres;
// TODO
// fill buffers with objects
// Bind and upload data for buffers
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbos[0]);
glBufferData(GL_SHADER_STORAGE_BUFFER, objects.size() * sizeof(Object),
objects.data(), GL_STATIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbos[0]);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbos[1]);
glBufferData(GL_SHADER_STORAGE_BUFFER, mats.size() * sizeof(Material),
mats.data(), GL_STATIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbos[1]);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbos[2]);
glBufferData(GL_SHADER_STORAGE_BUFFER,
pointlights.size() * sizeof(PointLight), pointlights.data(),
GL_STATIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbos[2]);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbos[3]);
glBufferData(GL_SHADER_STORAGE_BUFFER, spheres.size() * sizeof(Sphere),
spheres.data(), GL_STATIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbos[3]);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 3);
double lastTime = glfwGetTime();
double deltaTime = 0, nowTime = 0;
while (!glfwWindowShouldClose(window) &&
glfwGetKey(window, GLFW_KEY_Q) != GLFW_PRESS) {
nowTime = glfwGetTime();
deltaTime = nowTime - lastTime;
lastTime = nowTime;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
cam.update(deltaTime);
glUniformMatrix4fv(pLoc, 1, GL_FALSE,
glm::value_ptr(cam.getProjection().getProjMatrix()));
glUniformMatrix4fv(vLoc, 1, GL_FALSE, glm::value_ptr(cam.getView()));
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &vao);
glDeleteVertexArrays(1, &vao);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
#version 330 core
layout(location = 0) in vec4 position;
out vec2 px;
void main() {
gl_Position = position;
px = position.xy;
}
\ No newline at end of file
#version 430
out vec4 fragmentColor;
uniform mat4 V;
uniform mat4 P;
in vec2 px;
const float INFINITY = 1E+37;
// TODO check structs for better layout
struct PointLight {
vec3 pos;
vec3 col;
};
struct Object {
int type;
int matIndex;
int geoIndex;
};
struct Material {
float kd;
float ks;
vec3 diffuse;
vec3 specular;
float specExponent;
int mirror;
};
const int SPHERE_TYPE = 0;
struct Sphere {
vec3 pos;
float r;
};
layout(std430, binding = 0) readonly buffer objects_ssbo { Object objects[]; };
layout(std430, binding = 1) readonly buffer material_ssbo {
Material materials[];
};
layout(std430, binding = 2) readonly buffer pointlights_ssbo {
PointLight pointlights[];
};
layout(std430, binding = 3) readonly buffer spheres_ssbo { Sphere spheres[]; };
void getCameraRay(in vec2 pxNDS, out vec3 from, out vec3 dir) {
mat4 PInv = inverse(P);
mat4 VInv = inverse(V);
vec3 pointNDS = vec3(pxNDS, -1.0);
vec4 pointNDSH = vec4(pointNDS, 1.0);
vec4 dirEye = PInv * pointNDSH;
dirEye.w = 0.0;
vec3 dirWorld = (VInv * dirEye).xyz;
from = VInv[3].xyz;
dir = normalize(dirWorld);
}
vec3 normalSphere(Sphere s, vec3 p) { return normalize(p - s.pos); }
vec3 normal(int objIndex, vec3 p) {
Object o = objects[objIndex];
if (o.type == SPHERE_TYPE) {
return normalSphere(spheres[o.geoIndex], p);
}
return vec3(0.0);
}
bool intersectSphere(Sphere s, vec3 from, vec3 dir, out float t) {
vec3 oc = from - s.pos;
float loc = dot(dir, oc);
float discr = loc * loc - dot(oc, oc) + s.r * s.r;
if (discr < 0.0)
return false;
float tIn, tOut;
if (abs(discr) < 0.00001) {
tIn = -loc;
tOut = tIn;
} else {
float sq = sqrt(discr);
tIn = -loc - sq;
tOut = -loc + sq;
}
t = tIn >= 0.0 ? tIn : tOut;
return t >= 0.0;
}
bool closestIntersection(vec3 from, vec3 dir, out float t, out int id) {
float minT = INFINITY;
int minObj = -1;
for (int i = 0; i < objects.length(); i++) {
Object o = objects[i];
float ot = INFINITY;
if (o.type == SPHERE_TYPE) {
if (!intersectSphere(spheres[o.geoIndex], from, dir, ot)) {
continue;
}
}
if (ot < minT) {
minT = ot;
minObj = i;
}
}
id = minObj;
t = minT;
return minObj >= 0;
}
float shadow(vec3 from, vec3 dir, float maxT) {
for (int i = 0; i < objects.length(); i++) {
Object o = objects[i];
float ot;
if (o.type == SPHERE_TYPE) {
if (!intersectSphere(spheres[o.geoIndex], from, dir, ot)) {
continue;
}
}
if (ot < maxT) {
return 0.0;
}
}
return 1.0;
}
vec3 shade(vec3 p, vec3 V, vec3 N, Material mat) {
vec3 col = vec3(0.0);
for (int i = 0; i < pointlights.length(); i++) {
PointLight pl = pointlights[i];
vec3 poffset = p + 0.001 * N;
vec3 l = pl.pos - poffset;
float ll = length(l);
vec3 L = l / ll;
float shadow = shadow(poffset, L, ll);
vec3 lcol = vec3(0.0);
float dotLN = dot(L, N);
lcol += dotLN * mat.diffuse * mat.kd;
;
vec3 R = reflect(-L, N);
lcol += pow(max(dot(R, V), 0.0), mat.specExponent) * mat.specular *
mat.ks * float(dotLN > 0.0);
col += pl.col * lcol * shadow;
}
return col;
}
vec3 trace(vec3 from, vec3 dir, int maxIt) {
// TODO
return vec3(0.0);
}
void main() {
// Generates a camera ray
vec3 from = vec3(0.0);
vec3 dir = vec3(0.0, 0.0, 1.0);
getCameraRay(px, from, dir);
// Traces the image
vec3 col = trace(from, dir, 5);
fragmentColor = vec4(col, 1.0);
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment