Compare commits

...

29 Commits

Author SHA1 Message Date
8c62ce6bce feat: included glm to Cmake 2025-09-08 12:52:38 +02:00
1e918d5370 docs: updated toDos 2025-09-08 10:51:29 +00:00
a2ba43fe79 feat: further improvement of the build and compress script 2025-09-08 12:20:49 +02:00
dbca360da2 docs: updated toDos 2025-09-08 10:12:46 +00:00
627380e3e2 Update readme.md 2025-09-04 10:52:54 +00:00
12315d2791 fix: changes inf ray behaviour for better sky rendering 2025-09-04 12:51:27 +02:00
7cafe6544b feat: added Lzma compression to binary 2025-09-04 12:51:27 +02:00
545708571d fix: removed logging 2025-09-04 12:51:27 +02:00
4f71ecfd6d docu: updated toDo 2025-09-03 12:21:11 +00:00
4a57bb1357 feat: added FPS counter to terminal 2025-09-03 13:55:51 +02:00
a6cad08505 setup: defined cxx version in cmake 2025-09-03 13:55:17 +02:00
b5f6758400 feat: added sin distortions 2025-09-03 12:59:38 +02:00
8349039167 setup: renamed shader files for automatic syntax highlighting 2025-09-03 12:05:42 +02:00
053b13ed40 feat: added soft shadows without multi ray casts 2025-09-03 12:04:15 +02:00
c5b3c45d27 feat: added soft shadows by multi sampling the shadow 2025-08-28 16:48:31 +02:00
e3df77e2ec docs: updated To-Dos 2025-08-27 14:57:24 +00:00
8ae83ad7cd feat: aspect ration correction 2025-08-27 16:55:51 +02:00
83fb5cd587 feat: added shadows 2025-08-27 16:32:46 +02:00
1de2dae223 feat: added normal calc 2025-08-27 16:00:02 +02:00
fcbc6632e7 fix: removed sensless draw-call 2025-08-27 15:59:30 +02:00
80ec31a8ce style: fomatted to LLVM 2025-08-27 13:57:34 +02:00
ae44554bf4 feat: ray marching now works with ray structs, allowing for color 2025-08-27 13:57:34 +02:00
4044ad9b36 docs: updated ToDo 2025-08-26 13:31:32 +00:00
cb70a4972c setup: added neo-tree cache to gitignore 2025-08-26 09:40:20 +02:00
c87d5ddbc5 Feat: added compile error output for shaders and implementet first ray
march
2025-08-26 09:38:05 +02:00
4ccf3b4b0d setup: added vscode conf to git ignore 2025-08-25 12:01:14 +02:00
8459ad562e feat: excluded shaders to seperate files for readiblity 2025-08-25 12:00:43 +02:00
2a313fbc51 feat: added FullscreenQuad 2025-08-25 11:32:01 +02:00
2c76e41fbd fix: added Buffer resize at window rescale 2025-08-25 11:31:47 +02:00
9 changed files with 335 additions and 71 deletions

2
.gitignore vendored
View File

@@ -1 +1,3 @@
build/* build/*
.vscode
.cache

View File

@@ -4,8 +4,13 @@ project(64kDemo VERSION 0.1
DESCRIPTION "CPU SDF Renderer" DESCRIPTION "CPU SDF Renderer"
LANGUAGES CXX) LANGUAGES CXX)
set (CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
SET(CMAKE_CXX_FLAGS "-Os -s") SET(CMAKE_CXX_FLAGS "-Os -s")
add_executable(one main.cpp) add_executable(one main.cpp)
target_link_libraries(one m glfw GLEW GL) find_package(glm REQUIRED)
target_link_libraries(one m glfw GLEW GL glm::glm)

35
FullScreenQuad.hpp Normal file
View File

@@ -0,0 +1,35 @@
#include <GL/glew.h>
class FullScreenQuad {
private:
unsigned int vao;
public:
FullScreenQuad();
int getVAO() { return vao; }
};
FullScreenQuad::FullScreenQuad() {
float quadVertices[] = {// vertex attributes for a quad that fills the
// entire screen in Normalized Device Coordinates.
// positions // texCoords
-1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f,
0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f,
1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f};
unsigned int vbo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void *)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void *)(2 * sizeof(float)));
}

40
PerformanceAnalyser.hpp Normal file
View File

@@ -0,0 +1,40 @@
#include <GL/glew.h>
#include <cmath>
#include <iostream>
class PerformanceAnalyser {
private:
double lastFrameTime = 0;
int frameCount = 0;
double timeAcc = 0;
double lastFps = 0;
public:
PerformanceAnalyser(int framesToAcc = 10, bool autoPrint = true)
: framesToAcc(framesToAcc), autoPrint(autoPrint) {};
int framesToAcc;
bool autoPrint;
int getFPS() { return lastFps; }
void update(float time) {
timeAcc += (time - lastFrameTime);
lastFrameTime = time;
frameCount++;
if (frameCount == framesToAcc) {
lastFps = double(framesToAcc) / timeAcc;
if (autoPrint) {
std::cout << "Fps: " << std::round(lastFps * 10.0) * 0.1 << "\n"
<< std::flush;
}
frameCount = 0;
timeAcc = 0;
}
}
};

14
build.sh Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
cd build
cmake --build .
CMD="#!/bin/bash
dd bs=1 skip=%s<\$0|unlzma>/tmp/C;chmod +x /tmp/C;trap '' HUP;/tmp/C&"
COUNT=$(printf "$CMD" | wc -c)
EXTRA=$(printf "$COUNT" | wc -c)
COUNT=$((COUNT + EXTRA + 1))
echo "$CMD" | sed 's/%s/'"$COUNT"'/' > two
chmod +x two
sstrip one
lzma -9 one
cat one.lzma >> two
rm one.lzma

13
fsq.glsl Normal file
View File

@@ -0,0 +1,13 @@
R"###(
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 texCoords;
void main()
{
texCoords = aTexCoords;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}
)###";

116
main.cpp
View File

@@ -1,61 +1,29 @@
#include "FullScreenQuad.hpp"
#include "PerformanceAnalyser.hpp"
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <cstdio> #include <cstdio>
#include <iostream>
float vertices[] = { const char *vertexShaderSource =
-0.5f, -0.5f, 0.0f, #include "fsq.glsl"
0.5f, -0.5f, 0.0f, ;
0.0f, 0.5f, 0.0f
};
const char *fragmentShaderSource =
const char *vertexShaderSource = "#version 330 core\n" #include "sdf.glsl"
"layout (location = 0) in vec3 aPos;\n" ;
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
/*void framebuffer_size_callback(GLFWwindow* window, int width, int height) /*void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{ {
glViewport(0, 0, width, height); glViewport(0, 0, wdth, height);
}*/ }*/
float aspect = 1.0;
void processInput(GLFWwindow *window) void processInput(GLFWwindow *window) {
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, true);
} }
unsigned int initVBO() {
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
return VBO;
}
unsigned int initVAO() {
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// 2. copy our vertices array in a buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, initVBO());
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. then set our vertex attributes pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
return VAO;
}
unsigned int compVertexShader() { unsigned int compVertexShader() {
unsigned int vertexShader; unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER); vertexShader = glCreateShader(GL_VERTEX_SHADER);
@@ -69,6 +37,22 @@ unsigned int compFragmentShader() {
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader); glCompileShader(fragmentShader);
// Print shader comp error
GLint isCompiled = 0;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE) {
GLint maxLength = 0;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
// std::vector<GLchar> errorLog(maxLength);
char *errorLog = new char[maxLength]();
glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, errorLog);
printf("\nFrag Log: %s\n", errorLog);
}
return fragmentShader; return fragmentShader;
} }
@@ -87,12 +71,11 @@ unsigned int compShader() {
return shaderProgram; return shaderProgram;
} }
void linkVBO() { void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glViewport(0, 0, width, height);
glEnableVertexAttribArray(0); aspect = float(width) / height;
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
GLFWwindow *window; GLFWwindow *window;
@@ -100,10 +83,9 @@ int main(int argc, char** argv) {
if (!glfwInit()) if (!glfwInit())
return -1; return -1;
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL);
if (!window) if (!window) {
{
glfwTerminate(); glfwTerminate();
return -1; return -1;
} }
@@ -116,26 +98,39 @@ int main(int argc, char** argv) {
return 1; return 1;
} }
glViewport(0, 0, 800, 600); glViewport(0, 0, 800, 600);
unsigned int shaderProgramm = compShader(); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
unsigned int VAO = initVAO();
unsigned int shaderProgram = compShader();
FullScreenQuad fsq{};
PerformanceAnalyser perf{};
double time = glfwGetTime();
while (!glfwWindowShouldClose(window)) {
time = glfwGetTime();
perf.update(time);
while (!glfwWindowShouldClose(window))
{
processInput(window); processInput(window);
/* Render here */ /* Render here */
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glUseProgram(shaderProgramm); int aspectLocation = glGetUniformLocation(shaderProgram, "aspect");
glUniform1f(aspectLocation, aspect);
int timeLocation = glGetUniformLocation(shaderProgram, "t");
glUniform1f(timeLocation, 2. * time);
glBindVertexArray(fsq.getVAO());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* Poll for and process events */ /* Poll for and process events */
glfwPollEvents(); glfwPollEvents();
@@ -144,4 +139,3 @@ int main(int argc, char** argv) {
glfwTerminate(); glfwTerminate();
} }

View File

@@ -8,10 +8,13 @@
- [ ] Shader Management - [ ] Shader Management
- [ ] Configure Preprocessor - [ ] Configure Preprocessor
- [ ] Shader Storage - [ ] Shader Storage
- [x] Binary compression
- [x] C++ Math Lib
- [ ] SDF - [ ] SDF
- [ ] Basic Shape Rendering - [ ] Basic Shape Rendering
- [ ] Sphere - [x] Sphere
- [ ] Box - [ ] Box
- [ ] Inf Cylinder - [ ] Inf Cylinder
- [ ] Capsule - [ ] Capsule
@@ -25,7 +28,7 @@
- [ ] Rounding - [ ] Rounding
- [ ] Boolean - [ ] Boolean
- [ ] Infinite - [ ] Infinite
- [ ] Displacement - [x] Displacement
- [ ] Twist - [ ] Twist
- [ ] Bend - [ ] Bend
@@ -33,7 +36,7 @@
- [ ] Renderer - [ ] Renderer
- [ ] Deferred lighting - [ ] Deferred lighting
- [ ] Shadow Projection - [x] Shadow Projection
- [ ] Setup Post Processing Pipeline - [ ] Setup Post Processing Pipeline
- [ ] Post Processing Effects - [ ] Post Processing Effects

158
sdf.glsl Normal file
View File

@@ -0,0 +1,158 @@
R"###(
#version 330 core
out vec4 FragColor;
in vec2 texCoords;
uniform float aspect;
uniform float t;
vec3 center = vec3(0.0,-4.0,20.0);
float radius = 5.0;
float planeHeight = -7.0;
struct SmallHit {
float min;
float len;
bool firstHP;
};
struct Ray {
vec3 dir;
vec3 pos;
float min;
float len;
SmallHit small;
vec3 color;
};
Ray createRay(vec3 dir, vec3 pos){
return Ray(dir, pos, .0, .0, SmallHit(80.,0.,false), vec3(1.0));
}
Ray applyMin(Ray ray, float min) {
vec3 off = ray.dir * min;
ray.pos = ray.pos + off;
ray.len = ray.len + min;
if( (min < ray.min) && !ray.small.firstHP ){
ray.small.firstHP = true;
}
ray.min = min;
if((ray.min < ray.small.min) && ray.small.firstHP){
ray.small.min = ray.min;
ray.small.len = ray.len;
}
return ray;
}
float planeMin(vec3 pos){
return pos.y - planeHeight+ 0.2*sin(5*pos.x+t)*sin(5*pos.y+t)*sin(5*pos.z+t);
}
float sphereMin(vec3 pos){
return length(pos - center) - radius;
}
Ray minFn(Ray ray){
float sp = sphereMin(ray.pos);
float pl = planeMin(ray.pos);
float min;
if (sp < pl){
ray.color = vec3(1.0, 0.5, 0.2);
min = sp;
} else {
ray.color = vec3(0.2, 0.3, 0.3);
min = pl;
}
return applyMin(ray,min);
}
float minFn(vec3 pos){
float sp = sphereMin(pos);
float pl = planeMin(pos);
if (sp < pl){
return sp;
} else {
return pl;
}
}
Ray march(Ray ray){
//ray.min = minFn(ray.pos);
ray = minFn(ray);
int c = 0;
while(( c < 1000) && (ray.min < 100.0f) && (ray.min > 0.01f) ) {
ray = minFn(ray);
c++;
}
if(ray.min > 0.01){
ray.color = vec3(1.0);
}
return ray;
}
vec3 calcNormal(Ray ray){
float h = 0.001;
float m = sphereMin(ray.pos);
vec3 n = vec3(
minFn(ray.pos + vec3( h,.0,.0)) - minFn(ray.pos - vec3( h,.0,.0)),
minFn(ray.pos + vec3(.0, h,.0)) - minFn(ray.pos - vec3(.0, h,.0)),
minFn(ray.pos + vec3(.0,.0, h)) - minFn(ray.pos - vec3(.0,.0, h))
);
return normalize(n);
}
void main()
{
vec3 dir = vec3((texCoords - 0.5)*2,1.0);
dir.x *= aspect;
vec3 pos = dir;
Ray ray = createRay(normalize(dir),pos);
ray = march(ray);
vec3 normal = calcNormal(ray);
vec3 lighDir = normalize(vec3(.5,-1.0,0.5));
float light = (- min(dot(normal,lighDir),0.0))*0.85;
float shLeve = 1.0;
Ray shRay = createRay(lighDir * (-1.0), ray.pos + (-0.5)*lighDir);
shRay = march(shRay);
if( dot(lighDir,normal) < 0. ){
if( shRay.len <80){
shLeve = .0;//shRay.len*0.02 , 0.0;
}
else {
shLeve = shRay.small.min / shRay.small.len;
shLeve *= 9.0;
//shLeve = pow(shLeve*10.0,0.5);
}
}
shLeve = min(max(shLeve, 0.0),1.0);
light *= shLeve;
Ray reflectR = createRay(reflect(ray.dir,normal),ray.pos + 0.1* normal);
reflectR = march(reflectR);
if(ray.min <= 0.2){
//FragColor = vec4(0,1,0,1.0);
FragColor = vec4(mix(ray.color,reflectR.color,0.3) * (light+0.3), 1.0);
} else {
FragColor = vec4(ray.color,1.0);
}
}
)###";