Skip to content

Commit

Permalink
better terrain
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass committed Dec 8, 2023
1 parent 263ca78 commit 451b074
Show file tree
Hide file tree
Showing 17 changed files with 722 additions and 382 deletions.
6 changes: 0 additions & 6 deletions assets/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@
"b": 0.47983873,
"a": 1.0
},
"border_col": {
"r": 0.27822578,
"g": 0.23231916,
"b": 0.14584415,
"a": 1.0
},
"roof_col": {
"r": 0.2627451,
"g": 0.21314174,
Expand Down
18 changes: 16 additions & 2 deletions assets/shaders/terrain.frag.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ struct FragmentOutput {
@location(0) out_color: vec4<f32>,
}

struct LevelData {
lod: u32,
resolution: u32,
}

@group(1) @binding(0) var<uniform> params: RenderParams;

@group(2) @binding(0) var t_terraindata: texture_2d<f32>;
@group(2) @binding(1) var s_terraindata: sampler;
@group(2) @binding(2) var t_grass: texture_2d<f32>;
@group(2) @binding(3) var s_grass: sampler;
@group(2) @binding(4) var<uniform> ldata: LevelData;

@group(3) @binding(0) var t_ssao: texture_2d<f32>;
@group(3) @binding(1) var s_ssao: sampler;
Expand Down Expand Up @@ -108,9 +114,13 @@ fn textureNoTile(tex: texture_2d<f32>, samp: sampler, uv: vec2<f32>) -> vec4<f32
}

@fragment
fn frag(@location(0) in_normal: vec3<f32>,
fn frag(@builtin(position) position: vec4<f32>,
@location(0) in_normal: vec3<f32>,
@location(1) in_wpos: vec3<f32>,
@builtin(position) position: vec4<f32>) -> FragmentOutput {
#ifdef DEBUG
@location(2) debug: f32,
#endif
) -> FragmentOutput {
var ssao = 1.0;
#ifdef SSAO
ssao = textureSample(t_ssao, s_ssao, position.xy / params.viewport).r;
Expand Down Expand Up @@ -140,6 +150,10 @@ fn frag(@location(0) in_normal: vec3<f32>,
let normal: vec3<f32> = normalize(in_normal);
let F_spec: vec3<f32> = F0; // simplified with constant folding: fresnelSchlickRoughness(max(dot(normal, V), 0.0), F0, roughness);

#ifdef DEBUG
c = 0.05 * vec3(0.0, 0.0, debug);
#endif

let final_rgb: vec3<f32> = render(params.sun,
V,
position.xy,
Expand Down
75 changes: 64 additions & 11 deletions assets/shaders/terrain.vert.wgsl
Original file line number Diff line number Diff line change
@@ -1,37 +1,90 @@
#include "render_params.wgsl"

struct Uniforms {
u_view_proj: mat4x4<f32>,
}

struct VertexOutput {
@location(0) out_normal: vec3<f32>,
@location(1) out_wpos: vec3<f32>,
#ifdef DEBUG
@location(2) debug: f32,
#endif
@builtin(position) member: vec4<f32>,
}

struct LevelData {
lod: u32,
resolution: u32,
distance_lod_cutoff: f32, // max distance at which to switch to the next lod to have smooth transitions
cell_size: f32,
inv_cell_size: f32,
}

@group(0) @binding(0) var<uniform> global: Uniforms;

@group(2) @binding(0) var t_terraindata: texture_2d<f32>;
@group(1) @binding(0) var<uniform> params: RenderParams;

@group(2) @binding(0) var t_terraindata: texture_2d<u32>;
@group(2) @binding(1) var s_terraindata: sampler;
@group(2) @binding(4) var<uniform> ldata: LevelData;

/*
normal: vec3(self.cell_size * scale as f32, 0.0, hx - height)
.cross(vec3(0.0, self.cell_size * scale as f32, hy - height))
.normalize(),
*/

const CELL_SIZE: f32 = 1024.0 / 32.0; // chunk size / chunk resolution
const MAX_HEIGHT: f32 = 1024.0;
const MAX_DIFF: f32 = 32.0;

fn unpack_height(h: u32) -> f32 {
return ((f32(h) - 32768.0) / 32767.0 ) * MAX_HEIGHT;
}

fn unpack_diffs(v: u32) -> vec2<f32> {
let x = v & 0xFFu;
let y = (v & 0xFF00u) >> 8u;
return vec2<f32>((f32(x) - 128.0) / 127.0 * MAX_DIFF,
(f32(y) - 128.0) / 127.0 * MAX_DIFF);
}

@vertex
fn vert(@location(0) in_position: vec2<f32>, @location(1) in_off: vec2<f32>) -> VertexOutput {
let tpos: vec2<i32> = vec2<i32>((in_position + in_off) / CELL_SIZE);
let height: f32 = textureLoad(t_terraindata, tpos, 0).r;
fn vert(@builtin(vertex_index) vid: u32, @location(0) in_position: vec2<f32>, @location(1) in_off: vec2<f32>) -> VertexOutput {
let tpos: vec2<i32> = vec2<i32>((in_position + in_off) * ldata.inv_cell_size);

let texLoad: vec2<u32> = textureLoad(t_terraindata, tpos, 0).rg;

let height: f32 = unpack_height(texLoad.r);
let diffs: vec2<f32> = unpack_diffs(texLoad.g);

let step: i32 = i32(pow(2.0, f32(ldata.lod)));

let zf_off: vec2<i32> = vec2( step * (i32(vid % ldata.resolution) % 2),
step * (i32(vid / ldata.resolution) % 2));

let world_pos: vec3<f32> = vec3(in_position + in_off, height);

//let dist_to_cam: f32 = length(params.cam_pos.xyz - vec3(pos.xy, 0.0));
//let transition_alpha: f32 = smoothstep(ldata.distance_lod_cutoff * 0.8, ldata.distance_lod_cutoff, dist_to_cam);

var out_normal: vec3<f32> = normalize(vec3(diffs.x, diffs.y, ldata.cell_size * 2.0)); // https://stackoverflow.com/questions/49640250/calculate-normals-from-heightmap

let position: vec4<f32> = global.u_view_proj * vec4(world_pos, 1.0);

let hx: f32 = textureLoad(t_terraindata, vec2<i32>(1, 0) + tpos, 0).r;
let hy: f32 = textureLoad(t_terraindata, vec2<i32>(0, 1) + tpos, 0).r;
#ifdef DEBUG
var debug = f32(ldata.lod);

let pos: vec3<f32> = vec3(in_position + in_off, height);
let out_normal: vec3<f32> = normalize(cross(vec3(CELL_SIZE, 0.0, hx - height), vec3(0.0, CELL_SIZE, hy - height)));
let position: vec4<f32> = global.u_view_proj * vec4(pos, 1.0);
if(height >= MAX_HEIGHT) {
debug = diffs.x;
}
#endif

return VertexOutput(out_normal, pos, position);
return VertexOutput(
out_normal,
world_pos,
#ifdef DEBUG
debug,
#endif
position);
}
Loading

0 comments on commit 451b074

Please sign in to comment.