Skip to content

Commit

Permalink
Merge pull request #25 from gue-ni/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
gue-ni authored Feb 24, 2024
2 parents 84935b1 + ce22ddf commit b596a74
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 172 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ pre-commit.ps1
CMakeSettings.json
NOTES.txt
imgui.ini
terrain/generated/
24 changes: 24 additions & 0 deletions terrain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,27 @@ target_include_directories(terrain PUBLIC
"${glm_SOURCE_DIR}"
"${SDL2_INCLUDE_DIRS}"
)

set(SHADER_SOURCE
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/sky.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/sky.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/terrain.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/terrain.frag"
)
set(SHADER_GEN
"${CMAKE_CURRENT_SOURCE_DIR}/generated/sky.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/sky.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/terrain.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/terrain.frag"
)

add_custom_command(
OUTPUT ${SHADER_GEN}
COMMAND ${CMAKE_COMMAND} -DSHADER_DIR="${CMAKE_CURRENT_SOURCE_DIR}" -P ${CMAKE_CURRENT_SOURCE_DIR}/parse_shader.cmake
DEPENDS ${SHADER_SOURCE}
COMMENT "Generate shaders"
)

add_custom_target(shaders DEPENDS ${SHADER_GEN})

add_dependencies(terrain shaders)
191 changes: 19 additions & 172 deletions terrain/TerrainRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,181 +13,23 @@
#define ENABLE_SKYBOX 1
#define ENABLE_SMART_LOD 1

const std::string shader_vert = R"(
#version 430
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec2 a_tex;
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_proj;
uniform float u_height_scaling_factor;
uniform vec2 u_height_uv_min;
uniform vec2 u_height_uv_max;
uniform sampler2D u_height_texture;
uniform uint u_zoom;
out vec2 uv;
out vec4 world_pos;
float altitude_from_color(vec4 color) {
return (color.r + color.g / 255.0);
}
float altitude_from_color_2(vec4 color) {
return color.r;
}
vec2 map_range(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) {
return out_min + (value - in_min) * (out_max - out_min) / (in_max - in_min);
}
void main() {
uv = a_tex;
world_pos = u_model * vec4(a_pos, 1.0);
vec2 scaled_uv = map_range(uv, vec2(0), vec2(1), u_height_uv_min, u_height_uv_max);
vec4 height_sample = texture(u_height_texture, scaled_uv);
float height = altitude_from_color_2(height_sample);
world_pos.y = height * u_height_scaling_factor;
// skirts on tiles
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
world_pos.y = -2.0;
}
gl_Position = u_proj * u_view * world_pos;
}
)";

const std::string shader_frag = R"(
#version 430
in vec2 uv;
in vec4 world_pos;
out vec4 frag_color;
uniform vec2 u_albedo_uv_min;
uniform vec2 u_albedo_uv_max;
uniform sampler2D u_albedo_texture;
uniform vec3 u_fog_color;
uniform float u_fog_near;
uniform float u_fog_far;
uniform float u_fog_density;
uniform vec3 u_camera_position;
uniform uint u_zoom;
uniform bool u_debug_view;
uint compute_hash(uint a)
{
uint b = (a+2127912214u) + (a<<12u);
b = (b^3345072700u) ^ (b>>19u);
b = (b+374761393u) + (b<<5u);
b = (b+3551683692u) ^ (b<<9u);
b = (b+4251993797u) + (b<<3u);
b = (b^3042660105u) ^ (b>>16u);
return b;
}
vec3 color_from_uint(uint a) {
uint hash = compute_hash(a);
return vec3(float(hash & 255u), float((hash >> 8u) & 255u), float((hash >> 16u) & 255u)) / 255.0;
}
vec2 map_range(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) {
return out_min + (value - in_min) * (out_max - out_min) / (in_max - in_min);
}
void main() {
vec2 scaled_uv = map_range(uv, vec2(0), vec2(1), u_albedo_uv_min, u_albedo_uv_max);
vec3 color = texture(u_albedo_texture, scaled_uv).rgb;
/* clang-format off */
const char* shader_vert =
#include "generated/terrain.vert"
;

#if 0
color = mix(color, vec3(scaled_uv.xy, 0), 0.5);
#endif
if (u_fog_color != vec3(0)) {
vec3 camera_dir = normalize(u_camera_position - world_pos.xyz);
float camera_dist = length(world_pos.xyz - u_camera_position);
float dist_ratio = 4.0 * camera_dist / u_fog_far;
float fog_factor = 1.0 - exp(-dist_ratio * u_fog_density);
vec3 sun_dir = normalize(vec3(0, 1, 2));
vec3 sun_color = vec3(1.0, 0.9, 0.7);
float sun_factor = max(dot(camera_dir, sun_dir), 0.0);
//vec3 fog_color = mix(u_fog_color, sun_color, pow(sun_factor, 8.0));
vec3 fog_color = u_fog_color;
color = mix(color, fog_color, fog_factor);
}
if (u_debug_view) {
color = mix(color_from_uint(u_zoom), color, 0.5);
}
frag_color = vec4(color, 1);
}
)";

const std::string skybox_vert = R"(
#version 430
layout (location = 0) in vec3 a_pos;
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_proj;
out vec3 uv;
const char* shader_frag =
#include "generated/terrain.frag"
;

void main() {
uv = a_pos;
vec4 pos = u_proj * u_view * vec4(a_pos, 1.0);
gl_Position = pos.xyww;
}
)";

const std::string skybox_frag = R"(
#version 430
uniform vec3 u_sky_color_1;
uniform vec3 u_sky_color_2;
out vec4 frag_color;
in vec3 uv;
#define sq(x) (x * x)
vec3 map_cube_to_sphere(vec3 point_on_cube) {
float x = point_on_cube.x, y = point_on_cube.y, z = point_on_cube.z;
vec3 point_on_sphere;
point_on_sphere.x = x * sqrt(1.0f - (sq(y) / 2.0f) - (sq(z) / 2.0f) + ((sq(y) * sq(z)) / 3.0f));
point_on_sphere.y = y * sqrt(1.0f - (sq(z) / 2.0f) - (sq(x) / 2.0f) + ((sq(z) * sq(x)) / 3.0f));
point_on_sphere.z = z * sqrt(1.0f - (sq(x) / 2.0f) - (sq(y) / 2.0f) + ((sq(x) * sq(y)) / 3.0f));
return point_on_sphere;
}
void main() {
vec3 spherical = map_cube_to_sphere(uv);
vec3 color = mix(u_sky_color_1, u_sky_color_2, spherical.y);
vec3 sun_dir = normalize(vec3(0, 1, 2));
vec3 sun_color = vec3(1.0, 0.9, 0.7);
float sun_factor = max(dot(spherical, sun_dir), 0.0);
const char* skybox_vert =
#include "generated/sky.vert"
;

//color = mix(color, sun_color, pow(sun_factor, 8.0));
frag_color = vec4(color, 1);
}
)";
const char* skybox_frag =
#include "generated/sky.frag"
;
/* clang-format on */

AABB aabb_from_node(const Node* node)
{
Expand Down Expand Up @@ -438,6 +280,11 @@ void TerrainRenderer::render(const Camera& camera)
if (albedo && heightmap) {
m_shader->set_uniform("u_zoom", node->depth);

const float pixel_per_tile = 256;
const float root_tile_width = 0;
float tile_width = wms::tile_width(wms::tiley2lat(tile_id.y, tile_id.zoom), tile_id.zoom);
m_shader->set_uniform("u_pixel_resolution", tile_width / pixel_per_tile);

albedo->bind(0);
m_shader->set_uniform("u_albedo_texture", 0);
m_shader->set_uniform("u_albedo_uv_min", albedo_uv.min);
Expand Down
22 changes: 22 additions & 0 deletions terrain/parse_shader.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function(make_includable input_file output_file)
file(READ ${input_file} content)
set(delim "")
set(content "R\"${delim}(\n${content})${delim}\"")
file(WRITE ${output_file} "${content}")
endfunction(make_includable)

make_includable(
"${SHADER_DIR}/shaders/sky.frag"
"${SHADER_DIR}/generated/sky.frag")

make_includable(
"${SHADER_DIR}/shaders/sky.vert"
"${SHADER_DIR}/generated/sky.vert")

make_includable(
"${SHADER_DIR}/shaders/terrain.vert"
"${SHADER_DIR}/generated/terrain.vert")

make_includable(
"${SHADER_DIR}/shaders/terrain.frag"
"${SHADER_DIR}/generated/terrain.frag")
33 changes: 33 additions & 0 deletions terrain/shaders/sky.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#version 430

uniform vec3 u_sky_color_1;
uniform vec3 u_sky_color_2;

out vec4 frag_color;
in vec3 uv;

#define sq(x) (x * x)

vec3 map_cube_to_sphere(vec3 point_on_cube) {
float x = point_on_cube.x, y = point_on_cube.y, z = point_on_cube.z;

vec3 point_on_sphere;
point_on_sphere.x = x * sqrt(1.0f - (sq(y) / 2.0f) - (sq(z) / 2.0f) + ((sq(y) * sq(z)) / 3.0f));
point_on_sphere.y = y * sqrt(1.0f - (sq(z) / 2.0f) - (sq(x) / 2.0f) + ((sq(z) * sq(x)) / 3.0f));
point_on_sphere.z = z * sqrt(1.0f - (sq(x) / 2.0f) - (sq(y) / 2.0f) + ((sq(x) * sq(y)) / 3.0f));
return point_on_sphere;
}

void main() {
vec3 spherical = map_cube_to_sphere(uv);

vec3 color = mix(u_sky_color_1, u_sky_color_2, spherical.y);

vec3 sun_dir = normalize(vec3(0, 1, 2));
vec3 sun_color = vec3(1.0, 0.9, 0.7);
float sun_factor = max(dot(spherical, sun_dir), 0.0);

color = mix(color, sun_color, pow(sun_factor, 8.0));

frag_color = vec4(color, 1);
}
14 changes: 14 additions & 0 deletions terrain/shaders/sky.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#version 430
layout (location = 0) in vec3 a_pos;

uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_proj;

out vec3 uv;

void main() {
uv = a_pos;
vec4 pos = u_proj * u_view * vec4(a_pos, 1.0);
gl_Position = pos.xyww;
}
71 changes: 71 additions & 0 deletions terrain/shaders/terrain.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#version 430

in vec2 uv;
in vec4 world_pos;
out vec3 out_normal;

out vec4 frag_color;

uniform vec2 u_albedo_uv_min;
uniform vec2 u_albedo_uv_max;
uniform sampler2D u_albedo_texture;
uniform vec3 u_fog_color;
uniform float u_fog_near;
uniform float u_fog_far;
uniform float u_fog_density;
uniform vec3 u_camera_position;
uniform uint u_zoom;
uniform bool u_debug_view;

uint compute_hash(uint a) {
uint b = (a+2127912214u) + (a<<12u);
b = (b^3345072700u) ^ (b>>19u);
b = (b+374761393u) + (b<<5u);
b = (b+3551683692u) ^ (b<<9u);
b = (b+4251993797u) + (b<<3u);
b = (b^3042660105u) ^ (b>>16u);
return b;
}

vec3 color_from_uint(uint a) {
uint hash = compute_hash(a);
return vec3(float(hash & 255u), float((hash >> 8u) & 255u), float((hash >> 16u) & 255u)) / 255.0;
}

vec2 map_range(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) {
return out_min + (value - in_min) * (out_max - out_min) / (in_max - in_min);
}

void main() {
vec2 scaled_uv = map_range(uv, vec2(0), vec2(1), u_albedo_uv_min, u_albedo_uv_max);

vec3 color = texture(u_albedo_texture, scaled_uv).rgb;

#if 0
color = mix(color, vec3(scaled_uv.xy, 0), 0.5);
#endif

if (u_fog_color != vec3(0)) {
vec3 camera_dir = normalize(u_camera_position - world_pos.xyz);
float camera_dist = length(world_pos.xyz - u_camera_position);
float dist_ratio = 4.0 * camera_dist / u_fog_far;
float fog_factor = 1.0 - exp(-dist_ratio * u_fog_density);

vec3 sun_dir = normalize(vec3(0, 1, 2));
vec3 sun_color = vec3(1.0, 0.9, 0.7);
float sun_factor = max(dot(camera_dir, sun_dir), 0.0);

//vec3 fog_color = mix(u_fog_color, sun_color, pow(sun_factor, 8.0));
vec3 fog_color = u_fog_color;

color = mix(color, fog_color, fog_factor);
}

if (u_debug_view) {
color = mix(color_from_uint(u_zoom), color, 0.5);
}

// color = out_normal;

frag_color = vec4(color, 1);
}
Loading

0 comments on commit b596a74

Please sign in to comment.