terrain

Real-time terrain generation using marching cubes
git clone git://git.christianermann.dev/terrain
Log | Files | Refs | README | LICENSE

commit 1ae6960c52fd10d39c232361c8e31cc4a31e626f
parent 908b28bb971310e20d375f941df806e1dcf63e19
Author: Christian Ermann <christianermann@gmail.com>
Date:   Mon, 16 Aug 2021 14:50:36 -0500

Flat-shaded perlin caves

Diffstat:
Mshaders/basic.fs | 35++++++++++++++++++++++++++++++++---
Mshaders/basic.vs | 6+++---
Msrc/main.c | 26++++++++++++++++++++------
3 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/shaders/basic.fs b/shaders/basic.fs @@ -1,10 +1,39 @@ #version 330 core -in vec4 position; +in vec3 frag_pos; -out vec4 out_color; +out vec4 frag_color; + +const vec3 light_color = vec3(1.0, 1.0, 1.0); + +uniform vec3 view_pos; +uniform vec3 pointlight_pos; void main() { - out_color = vec4(1.0, 0.8, 0.6, 1.0); + vec3 dx = dFdx(frag_pos); + vec3 dy = dFdy(frag_pos); + vec3 normal = normalize(cross(dy, dx)); + + float slope = (normal.y + 1.0) * 0.5; + vec3 object_color = mix(vec3(1.0, 0.8, 0.6), vec3(0.7, 0.7, 0.7), slope); + + float d = length(pointlight_pos - frag_pos); + float attenuation = 1.0 / (1.0 + 0.07 * d + 0.017 * d * d); + + vec3 light_dir = normalize(frag_pos - pointlight_pos); + vec3 view_dir = normalize(view_pos - frag_pos); + vec3 reflect_dir = reflect(-light_dir, normal); + + float ambient_strength = 0.1; + vec3 ambient = ambient_strength * light_color * attenuation; + + float diffuse_strength = max(dot(normal, light_dir), 0.0); + vec3 diffuse = diffuse_strength * light_color * attenuation; + + float specular_strength = 0.5; + float spec = pow(max(dot(view_dir, reflect_dir), 0.0), 32); + vec3 specular = specular_strength * spec * light_color * attenuation; + + frag_color = vec4((ambient + diffuse + specular) * object_color, 1.0); } diff --git a/shaders/basic.vs b/shaders/basic.vs @@ -2,12 +2,12 @@ layout(location = 0) in vec3 in_position; -out vec4 position; +out vec3 frag_pos; uniform mat4 camera; void main() { - position = camera * vec4(in_position, 1.0); - gl_Position = position; + frag_pos = in_position; + gl_Position = camera * vec4(in_position, 1.0); } diff --git a/src/main.c b/src/main.c @@ -1,6 +1,7 @@ #include "camera.h" #include "chunk_manager.h" #include "glh/shader.h" +#include "perlin.h" #include "glad/glad.h" @@ -27,6 +28,13 @@ void Camera_update(Camera* camera) Camera_updateMatrix(camera); } +float perlinSDF(const Vec3 p) +{ + return perlin(p[0] * 0.01f, p[1] * 0.01f, p[2] * 0.01f) + + 0.5f * perlin(p[0] * 0.05f, p[1] * 0.05f, p[2] * 0.05f) + + 0.1f * perlin(p[0] * 0.1f, p[1] * 0.1f, p[2] * 0.1f); +} + float sphereSDF(const float p[3]) { return sqrtf(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]) - 25.0f; @@ -70,18 +78,21 @@ int main(int argc, char** argv) glViewport(0, 0, WIDTH, HEIGHT); glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); - glClearColor(0.4f, 0.4f, 0.6f, 1.0f); - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - sphereSDF(camera.position); - ChunkManager chunk_manager = ChunkManager_create(camera.position, 1, - sphereSDF, 0.0f); + ChunkManager chunk_manager = ChunkManager_create(camera.position, 2, + perlinSDF, 0.0f); Shader shader = Shader_create("shaders/basic.vs", "shaders/basic.fs"); glUseProgram(shader.program); + GLint view_pos_loc = glGetUniformLocation(shader.program, "view_pos"); + + GLint pointlight_pos_loc = glGetUniformLocation(shader.program, + "pointlight_pos"); + GLint cam_loc = glGetUniformLocation(shader.program, "camera"); SDL_Event window_event; @@ -112,6 +123,9 @@ int main(int argc, char** argv) Camera_update(&camera); glUniformMatrix4fv(cam_loc, 1, GL_FALSE, camera.matrix[0]); + glUniform3fv(view_pos_loc, 1, camera.position); + glUniform3fv(pointlight_pos_loc, 1, camera.position); + ChunkManager_recenter(&chunk_manager, camera.position); ChunkManager_drawChunks(&chunk_manager);