Skip to content

Commit

Permalink
progress on offscreen rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass committed Feb 13, 2024
1 parent 5356b46 commit 3ba2fa0
Show file tree
Hide file tree
Showing 34 changed files with 636 additions and 312 deletions.
1 change: 1 addition & 0 deletions assets/generated/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
4 changes: 2 additions & 2 deletions assets/models/bakery.glb
Git LFS file not shown
4 changes: 2 additions & 2 deletions assets/models/cinema.glb
Git LFS file not shown
95 changes: 55 additions & 40 deletions assets/shaders/pbr/render.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,56 @@ fn calc_light(Lo: vec3<f32>,
return Lo + (kD * albedo * (0.7 + ssao * 0.3) / PI + specular_light) * shadow_v * col * NdotL;
}

struct LightData {
data: vec4<u32>,
data2: vec4<u32>,
chunk_id: vec2<u32>,
};

fn get_lightdata(t_lightdata: texture_2d<u32>, t_lightdata2: texture_2d<u32>, wpos: vec3<f32>) -> LightData {
let chunk_id: vec2<u32> = vec2<u32>(u32(wpos.x / LIGHTCHUNK_SIZE), u32(wpos.y / LIGHTCHUNK_SIZE));
let lightdata: vec4<u32> = textureLoad(t_lightdata, chunk_id, 0);
var lightdata2: vec4<u32>;
if(lightdata.w != 0u) {
lightdata2 = textureLoad(t_lightdata2, chunk_id, 0);
} else {
lightdata2 = vec4<u32>(0u);
}
return LightData(lightdata, lightdata2, chunk_id);
}

fn calc_packed_light(Lo_: vec3<f32>,
chunk_id: vec2<u32>,
data: vec4<u32>,
V: vec3<f32>,
normal: vec3<f32>,
albedo: vec3<f32>,
metallic: f32,
roughness: f32,
F0: vec3<f32>,
wpos: vec3<f32>,
ssao: f32,
) -> vec3<f32> {
var Lo = Lo_;
if(data.x != 0u) {
let light = decodeLight(chunk_id, data.x);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, vec3(lightPower(wpos, light)), 1.0, ssao);
}
if(data.y != 0u) {
let light = decodeLight(chunk_id, data.y);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, vec3(lightPower(wpos, light)), 1.0, ssao);
}
if(data.z != 0u) {
let light = decodeLight(chunk_id, data.z);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, vec3(lightPower(wpos, light)), 1.0, ssao);
}
if(data.w != 0u) {
let light = decodeLight(chunk_id, data.w);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, vec3(lightPower(wpos, light)), 1.0, ssao);
}
return Lo;
}

fn render(sun: vec3<f32>,
V: vec3<f32>,
position: vec2<f32>,
Expand All @@ -105,59 +155,24 @@ fn render(sun: vec3<f32>,
roughness: f32,
shadow_v: f32,
ssao: f32,
t_lightdata: texture_2d<u32>,
t_lightdata2: texture_2d<u32>,
lightdata: LightData,
wpos: vec3<f32>,
fog: vec3<f32>,
) -> vec3<f32> {
let chunk_id: vec2<u32> = vec2<u32>(u32(wpos.x / LIGHTCHUNK_SIZE), u32(wpos.y / LIGHTCHUNK_SIZE));
let lightdata: vec4<u32> = textureLoad(t_lightdata, chunk_id, 0);


var Lo: vec3<f32> = vec3(0.0);

if(sun.z >= 0.0) {
Lo = calc_light(vec3(0.0), sun, V, normal, albedo, metallic, roughness, F0, sun_col, shadow_v, ssao);
}
if(sun.z < 0.1) {
if(lightdata.x != 0u) {
let light = decodeLight(chunk_id, lightdata.x);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
}
if(lightdata.y != 0u) {
let light = decodeLight(chunk_id, lightdata.y);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
}
if(lightdata.z != 0u) {
let light = decodeLight(chunk_id, lightdata.z);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
}
if(lightdata.w != 0u) {
let light = decodeLight(chunk_id, lightdata.w);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
let lightdata2: vec4<u32> = textureLoad(t_lightdata2, chunk_id, 0);
if(lightdata2.x != 0u) {
let light = decodeLight(chunk_id, lightdata2.x);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
Lo = calc_packed_light(Lo, lightdata.chunk_id, lightdata.data, V, normal, albedo, metallic, roughness, F0, wpos, ssao);
if (lightdata.data.w != 0) {
Lo = calc_packed_light(Lo, lightdata.chunk_id, lightdata.data2, V, normal, albedo, metallic, roughness, F0, wpos, ssao);
}
if(lightdata2.y != 0u) {
let light = decodeLight(chunk_id, lightdata2.y);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
}
if(lightdata2.z != 0u) {
let light = decodeLight(chunk_id, lightdata2.z);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
}
if(lightdata2.w != 0u) {
let light = decodeLight(chunk_id, lightdata2.w);
Lo = calc_light(Lo, normalize(light - wpos), V, normal, albedo, metallic, roughness, F0, lightPower(wpos, light) * vec3(1.0), 1.0, ssao);
}
}
}

let dkS: vec3<f32> = F_spec;
var dkD: vec3<f32> = 1.0 - dkS;
dkD *= 1.0 - vec3(metallic);
let dkD: vec3<f32> = (1.0 - F_spec) * (1.0 - vec3(metallic));

let ambient: vec3<f32> = (0.2 * dkD * (0.04 + irradiance_diffuse) * albedo + specular) * ssao;
var color: vec3<f32> = ambient + Lo + fog;
Expand Down
48 changes: 32 additions & 16 deletions assets/shaders/pixel.frag.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,27 @@ struct MaterialParams {

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

@group(1) @binding(0) var t_ssao: texture_2d<f32>;
@group(1) @binding(1) var s_ssao: sampler;
@group(1) @binding(2) var t_fog: texture_2d<f32>;
@group(1) @binding(3) var s_fog: sampler;
@group(1) @binding(4) var t_bnoise: texture_2d<f32>;
@group(1) @binding(5) var s_bnoise: sampler;
@group(1) @binding(6) var t_sun_smap: texture_depth_2d_array;
@group(1) @binding(7) var s_sun_smap: sampler_comparison;
@group(1) @binding(8) var t_diffuse_irradiance: texture_cube<f32>;
@group(1) @binding(9) var s_diffuse_irradiance: sampler;
@group(1) @binding(10) var t_prefilter_specular: texture_cube<f32>;
@group(1) @binding(11) var s_prefilter_specular: sampler;
@group(1) @binding(12) var t_brdf_lut: texture_2d<f32>;
@group(1) @binding(13) var s_brdf_lut: sampler;
@group(1) @binding(0) var t_bnoise: texture_2d<f32>;
@group(1) @binding(1) var s_bnoise: sampler;
@group(1) @binding(2) var t_sun_smap: texture_depth_2d_array;
@group(1) @binding(3) var s_sun_smap: sampler_comparison;
@group(1) @binding(4) var t_diffuse_irradiance: texture_cube<f32>;
@group(1) @binding(5) var s_diffuse_irradiance: sampler;
@group(1) @binding(6) var t_prefilter_specular: texture_cube<f32>;
@group(1) @binding(7) var s_prefilter_specular: sampler;
@group(1) @binding(8) var t_brdf_lut: texture_2d<f32>;
@group(1) @binding(9) var s_brdf_lut: sampler;

#ifndef OFFSCREEN_RENDER
@group(1) @binding(10) var t_ssao: texture_2d<f32>;
@group(1) @binding(11) var s_ssao: sampler;
@group(1) @binding(12) var t_fog: texture_2d<f32>;
@group(1) @binding(13) var s_fog: sampler;
@group(1) @binding(14) var t_lightdata: texture_2d<u32>;
@group(1) @binding(15) var s_lightdata: sampler;
@group(1) @binding(16) var t_lightdata2: texture_2d<u32>;
@group(1) @binding(17) var s_lightdata2: sampler;
#endif

@group(2) @binding(0) var t_albedo: texture_2d<f32>;
@group(2) @binding(1) var s_albedo: sampler;
Expand All @@ -60,12 +63,18 @@ fn frag(@location(0) in_tint: vec4<f32>,
let albedo: vec4<f32> = textureSample(t_albedo, s_albedo, in_uv);
var ssao = 1.0;
#ifdef SSAO
#ifndef OFFSCREEN_RENDER
ssao = textureSample(t_ssao, s_ssao, position.xy / params.viewport).r;
#endif
#endif

var shadow_v: f32 = 1.0;
if (params.shadow_mapping_resolution != 0) {
#ifdef OFFSCREEN_RENDER
shadow_v = sampleFirstShadow(in_wpos);
#else
shadow_v = sampleShadow(in_wpos);
#endif
}

var normal = in_normal;
Expand Down Expand Up @@ -106,6 +115,7 @@ fn frag(@location(0) in_tint: vec4<f32>,

var fog = vec3(0.0);
#ifdef FOG
#ifndef OFFSCREEN_RENDER
var fogdist: vec4<f32> = textureSampleLevel(t_fog, s_fog, position.xy / params.viewport, 0.0);

if (abs(fogdist.a - dist) > 100.0) {
Expand All @@ -118,6 +128,13 @@ fn frag(@location(0) in_tint: vec4<f32>,
fog = fogdist.rgb;
}

#endif
#endif

#ifdef OFFSCREEN_RENDER
let lightdata = LightData(vec4(0), vec4(0), vec2(0));
#else
let lightdata = get_lightdata(t_lightdata, t_lightdata2, in_wpos);
#endif

let final_rgb: vec3<f32> = render(params.sun,
Expand All @@ -134,8 +151,7 @@ fn frag(@location(0) in_tint: vec4<f32>,
roughness,
shadow_v,
ssao,
t_lightdata,
t_lightdata2,
lightdata,
in_wpos,
fog
);
Expand Down
6 changes: 5 additions & 1 deletion assets/shaders/shadow.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ fn sampleShadow(in_wpos: vec3<f32>) -> f32 {
return mix(s1, s2, blend);
}

fn sampleFirstShadow(in_wpos: vec3<f32>) -> f32 {
return sampleOneShadow(in_wpos, 0);
}

fn sampleOneShadow(in_wpos: vec3<f32>, index: i32) -> f32 {
let light_local: vec4<f32> = params.sunproj[index] * vec4(in_wpos, 1.0);

Expand All @@ -42,7 +46,7 @@ fn sampleOneShadow(in_wpos: vec3<f32>, index: i32) -> f32 {
for (var y = -1 ; y <= 1 ; y++) {
x = -1;
for (; x <= 1; x++) {
let shadow_coord: vec3<f32> = corrected + vec3(f32(x), f32(y), -1.0) * offset;
let shadow_coord: vec3<f32> = corrected + vec3(f32(x), f32(y), 0.0) * offset;
total += textureSampleCompare(t_sun_smap, s_sun_smap, shadow_coord.xy, index, shadow_coord.z);
}
}
Expand Down
34 changes: 17 additions & 17 deletions assets/shaders/terrain/terrain.frag.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ struct ChunkData {
@group(1) @binding(7) var s_cliff: sampler;
@group(1) @binding(8) var<uniform> cdata: ChunkData;

@group(2) @binding(0) var t_ssao: texture_2d<f32>;
@group(2) @binding(1) var s_ssao: sampler;
@group(2) @binding(2) var t_fog: texture_2d<f32>;
@group(2) @binding(3) var s_fog: sampler;
@group(2) @binding(4) var t_bnoise: texture_2d<f32>;
@group(2) @binding(5) var s_bnoise: sampler;
@group(2) @binding(6) var t_sun_smap: texture_depth_2d_array;
@group(2) @binding(7) var s_sun_smap: sampler_comparison;
@group(2) @binding(8) var t_diffuse_irradiance: texture_cube<f32>;
@group(2) @binding(9) var s_diffuse_irradiance: sampler;
@group(2) @binding(10) var t_prefilter_specular: texture_cube<f32>;
@group(2) @binding(11) var s_prefilter_specular: sampler;
@group(2) @binding(12) var t_brdf_lut: texture_2d<f32>;
@group(2) @binding(13) var s_brdf_lut: sampler;
@group(2) @binding(0) var t_bnoise: texture_2d<f32>;
@group(2) @binding(1) var s_bnoise: sampler;
@group(2) @binding(2) var t_sun_smap: texture_depth_2d_array;
@group(2) @binding(3) var s_sun_smap: sampler_comparison;
@group(2) @binding(4) var t_diffuse_irradiance: texture_cube<f32>;
@group(2) @binding(5) var s_diffuse_irradiance: sampler;
@group(2) @binding(6) var t_prefilter_specular: texture_cube<f32>;
@group(2) @binding(7) var s_prefilter_specular: sampler;
@group(2) @binding(8) var t_brdf_lut: texture_2d<f32>;
@group(2) @binding(9) var s_brdf_lut: sampler;
@group(2) @binding(10) var t_ssao: texture_2d<f32>;
@group(2) @binding(11) var s_ssao: sampler;
@group(2) @binding(12) var t_fog: texture_2d<f32>;
@group(2) @binding(13) var s_fog: sampler;
@group(2) @binding(14) var t_lightdata: texture_2d<u32>;
@group(2) @binding(15) var s_lightdata: sampler;
@group(2) @binding(16) var t_lightdata2: texture_2d<u32>;
Expand Down Expand Up @@ -195,9 +195,10 @@ fn frag(@builtin(position) position: vec4<f32>,
} else {
fog = fogdist.rgb;
}

#endif

let lightdata = get_lightdata(t_lightdata, t_lightdata2, in_wpos);

let final_rgb: vec3<f32> = render(params.sun,
V,
position.xy,
Expand All @@ -212,8 +213,7 @@ fn frag(@builtin(position) position: vec4<f32>,
roughness,
shadow_v,
ssao,
t_lightdata,
t_lightdata2,
lightdata,
in_wpos,
fog
);
Expand Down
4 changes: 0 additions & 4 deletions assets/shaders/water.frag.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ struct FragmentOutput {
@group(3) @binding(0) var t_fog: texture_2d<f32>;
@group(3) @binding(1) var s_fog: sampler;

fn sample_depth(coords: vec2<i32>) -> f32 {
return textureLoad(t_depth, coords, 0).r;
}

// wave is (length, amplitude, dir)
fn gerstnerWaveNormal(p: vec2<f32>, t: f32) -> vec3<f32> {
let N_WAVES: i32 = 5;
Expand Down
12 changes: 12 additions & 0 deletions common/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ use rustc_hash::FxHasher;
use std::any::TypeId;
use std::hash::{BuildHasher, Hash, Hasher};

pub fn hash_iter<I>(iter: I) -> u64
where
I: IntoIterator,
I::Item: Hash,
{
let mut hasher = FxHasher::default();
for item in iter {
item.hash(&mut hasher);
}
hasher.finish()
}

#[inline]
pub fn hash_u64<T>(obj: T) -> u64
where
Expand Down
2 changes: 1 addition & 1 deletion engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ profiling = { version = "1.0.1", default-features = false }
rayon = "1.6"
beul = "1.0.0"
slotmapd = "1.0"
inline_tweak = "1.0.8"
inline_tweak = { version = "1.0.8", features = ["derive"] }
egui-wgpu = { git = "https://github.com/emilk/egui" }
cpal = "0.15.0"
lewton = "0.10.2"
Expand Down
4 changes: 2 additions & 2 deletions engine/src/drawables/instanced_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Drawable for InstancedMesh {
for (mat, indices) in &lod_select.primitives {
let mat = gfx.material(*mat);
let pipeline = gfx.get_pipeline(MeshPipeline {
format: None,
offscreen_render: false,
instanced: true,
alpha: false,
smap: false,
Expand Down Expand Up @@ -128,7 +128,7 @@ impl Drawable for InstancedMesh {
for (mat, indices) in &lod_select.primitives {
let mat = gfx.material(*mat);
rp.set_pipeline(gfx.get_pipeline(MeshPipeline {
format: None,
offscreen_render: false,
instanced: true,
alpha: mat.transparent,
smap: shadow_cascade.is_some(),
Expand Down
Loading

0 comments on commit 3ba2fa0

Please sign in to comment.