Skip to content

Commit

Permalink
ported scene_cube_directional test of directional lighting
Browse files Browse the repository at this point in the history
  • Loading branch information
schell committed Dec 17, 2023
1 parent e6ec7f9 commit 2293435
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 56 deletions.
1 change: 1 addition & 0 deletions crates/renderling-shader/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::slab::Slabbed;

/// Used to debug shaders by early exiting the shader and attempting to display
/// the value as shaded colors.
// TODO: Change DebugChannel to DebugMode and remove the previous DebugMode.
#[repr(u32)]
#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
#[derive(Clone, Copy, PartialEq, PartialOrd)]
Expand Down
14 changes: 9 additions & 5 deletions crates/renderling-shader/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,15 @@ impl<T> Default for Id<T> {

impl<T> core::fmt::Debug for Id<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!(
"Id<{}>({})",
&core::any::type_name::<T>(),
&self.0
))
if self.is_none() {
f.write_fmt(format_args!("Id<{}>(null)", &core::any::type_name::<T>(),))
} else {
f.write_fmt(format_args!(
"Id<{}>({})",
&core::any::type_name::<T>(),
&self.0
))
}
}
}

Expand Down
44 changes: 34 additions & 10 deletions crates/renderling-shader/src/pbr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@
//! * https://learnopengl.com/PBR/Theory
//! * https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/5b1b7f48a8cb2b7aaef00d08fdba18ccc8dd331b/source/Renderer/shaders/pbr.frag
//! * https://github.khronos.org/glTF-Sample-Viewer-Release/
use renderling_derive::Slabbed;
use glam::{Vec2, Vec3, Vec4, Vec4Swizzles};
use renderling_derive::Slabbed;
#[cfg(target_arch = "spirv")]
use spirv_std::num_traits::Float;
use spirv_std::{
image::{Cubemap, Image2d},
Sampler,
};

use glam::{Vec2, Vec3, Vec4, Vec4Swizzles};

use crate::{
self as renderling_shader,
Expand Down Expand Up @@ -154,21 +149,42 @@ fn outgoing_radiance(
metalness: f32,
roughness: f32,
) -> Vec3 {
crate::println!("outgoing_radiance");
crate::println!(" light_color: {light_color:?}");
crate::println!(" albedo: {albedo:?}");
crate::println!(" attenuation: {attenuation:?}");
crate::println!(" v: {v:?}");
crate::println!(" l: {l:?}");
crate::println!(" n: {n:?}");
crate::println!(" metalness: {metalness:?}");
crate::println!(" roughness: {roughness:?}");

let f0 = Vec3::splat(0.4).lerp(albedo, metalness);
crate::println!(" f0: {f0:?}");
let radiance = light_color.xyz() * attenuation;
crate::println!(" radiance: {radiance:?}");
let h = (v + l).alt_norm_or_zero();
crate::println!(" h: {h:?}");
// cook-torrance brdf
let ndf: f32 = normal_distribution_ggx(n, h, roughness);
crate::println!(" ndf: {ndf:?}");
let g: f32 = geometry_smith(n, v, l, roughness);
crate::println!(" g: {g:?}");
let f: Vec3 = fresnel_schlick(h.dot(v).max(0.0), f0);
crate::println!(" f: {f:?}");

let k_s = f;
let k_d = (Vec3::splat(1.0) - k_s) * (1.0 - metalness);
crate::println!(" k_s: {k_s:?}");

let numerator: Vec3 = ndf * g * f;
crate::println!(" numerator: {numerator:?}");
let n_dot_l = n.dot(l).max(0.0);
crate::println!(" n_dot_l: {n_dot_l:?}");
let denominator: f32 = 4.0 * n.dot(v).max(0.0) * n_dot_l + 0.0001;
crate::println!(" denominator: {denominator:?}");
let specular: Vec3 = numerator / denominator;
crate::println!(" specular: {specular:?}");

(k_d * albedo / core::f32::consts::PI + specular) * radiance * n_dot_l
}
Expand Down Expand Up @@ -349,7 +365,9 @@ pub fn stage_shade_fragment(
) -> Vec4 {
let n = in_norm.alt_norm_or_zero();
let v = (camera_pos - in_pos).alt_norm_or_zero();

crate::println!("lights: {lights:?}");
crate::println!("n: {n:?}");
crate::println!("v: {v:?}");
// reflectance
let mut lo = Vec3::ZERO;
for i in 0..lights.len() {
Expand Down Expand Up @@ -405,9 +423,12 @@ pub fn stage_shade_fragment(

LightStyle::Directional => {
let dir_light = slab.read(light.into_directional_id());
let l = (-dir_light.direction).alt_norm_or_zero();
let l = -dir_light.direction.alt_norm_or_zero();
let attenuation = dir_light.intensity;
lo += outgoing_radiance(
crate::println!("dir_light: {dir_light:?}");
crate::println!("l: {l:?}");
crate::println!("attenuation: {attenuation:?}");
let radiance = outgoing_radiance(
dir_light.color,
albedo,
attenuation,
Expand All @@ -417,10 +438,13 @@ pub fn stage_shade_fragment(
metallic,
roughness,
);
crate::println!("radiance: {radiance:?}");
lo += radiance;
}
}
}

crate::println!("lo: {lo:?}");
// calculate reflectance at normal incidence; if dia-electric (like plastic) use
// F0 of 0.04 and if it's a metal, use the albedo color as F0 (metallic
// workflow)
Expand Down
124 changes: 119 additions & 5 deletions crates/renderling-shader/src/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,14 +506,18 @@ pub struct DrawIndirect {
pub base_instance: u32,
}

fn texture_color(
fn texture_color<T, S>(
texture_id: Id<GpuTexture>,
uv: Vec2,
atlas: &Image2d,
sampler: &Sampler,
atlas: &T,
sampler: &S,
atlas_size: UVec2,
textures: &[GpuTexture],
) -> Vec4 {
) -> Vec4
where
T: Sample2d<Sampler = S>,
S: IsSampler,
{
let texture = if texture_id.is_none() {
GpuTexture::default()
} else {
Expand Down Expand Up @@ -636,6 +640,65 @@ pub fn main_fragment_scene(
output: &mut Vec4,
brigtness: &mut Vec4,
) {
main_fragment_impl(
atlas,
atlas_sampler,
irradiance,
irradiance_sampler,
prefiltered,
prefiltered_sampler,
brdf,
brdf_sampler,
constants,
lights,
materials,
textures,
in_material,
in_color,
in_uv0,
in_uv1,
in_norm,
in_tangent,
in_bitangent,
in_pos,
output,
brigtness,
);
}

/// Scene fragment shader, callable from the CPU or GPU.
pub fn main_fragment_impl<T, C, S>(
atlas: &T,
atlas_sampler: &S,

irradiance: &C,
irradiance_sampler: &S,
prefiltered: &C,
prefiltered_sampler: &S,
brdf: &T,
brdf_sampler: &S,

constants: &GpuConstants,
lights: &[GpuLight],
materials: &[pbr::PbrMaterial],
textures: &[GpuTexture],

in_material: u32,
in_color: Vec4,
in_uv0: Vec2,
in_uv1: Vec2,
in_norm: Vec3,
in_tangent: Vec3,
in_bitangent: Vec3,
in_pos: Vec3,

output: &mut Vec4,
brigtness: &mut Vec4,
) where
T: Sample2d<Sampler = S>,
C: SampleCube<Sampler = S>,
S: IsSampler,
{
let material = if in_material == ID_NONE || !constants.toggles.get_use_lighting() {
// without an explicit material (or if the entire render has no lighting)
// the entity will not participate in any lighting calculations
Expand Down Expand Up @@ -871,6 +934,12 @@ pub fn main_fragment_scene(
}

/// A camera used for transforming the stage during rendering.
///
/// Use `Camera::new(projection, view)` to create a new camera.
/// Or use `Camera::default` followed by `Camera::with_projection_and_view`
/// to set the projection and view matrices. Using the `with_*` or `set_*`
/// methods is preferred over setting the fields directly because they will
/// also update the camera's position.
#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
#[repr(C)]
#[derive(Default, Clone, Copy, PartialEq, Slabbed)]
Expand All @@ -880,6 +949,41 @@ pub struct Camera {
pub position: Vec3,
}

impl Camera {
pub fn new(projection: Mat4, view: Mat4) -> Self {
Camera::default().with_projection_and_view(projection, view)
}

pub fn set_projection_and_view(&mut self, projection: Mat4, view: Mat4) {
self.projection = projection;
self.view = view;
self.position = view.inverse().transform_point3(Vec3::ZERO);
}

pub fn with_projection_and_view(mut self, projection: Mat4, view: Mat4) -> Self {
self.set_projection_and_view(projection, view);
self
}

pub fn set_projection(&mut self, projection: Mat4) {
self.set_projection_and_view(projection, self.view);
}

pub fn with_projection(mut self, projection: Mat4) -> Self {
self.set_projection(projection);
self
}

pub fn set_view(&mut self, view: Mat4) {
self.set_projection_and_view(self.projection, view);
}

pub fn with_view(mut self, view: Mat4) -> Self {
self.set_view(view);
self
}
}

/// Holds important info about the stage.
///
/// This should be the first struct in the stage's slab.
Expand Down Expand Up @@ -1212,14 +1316,18 @@ pub fn stage_fragment_impl<T, C, S>(
C: SampleCube<Sampler = S>,
S: IsSampler,
{
let legend = get_stage_legend(slab);
crate::println!("legend: {:?}", legend);
let StageLegend {
atlas_size,
debug_mode,
has_skybox: _,
has_lighting,
light_array,
} = get_stage_legend(slab);
} = legend;

let material = get_material(in_material, has_lighting, slab);
crate::println!("material: {:?}", material);

let albedo_tex_uv = if material.albedo_tex_coord == 0 {
in_uv0
Expand All @@ -1234,6 +1342,7 @@ pub fn stage_fragment_impl<T, C, S>(
atlas_size,
slab,
);
crate::println!("albedo_tex_color: {:?}", albedo_tex_color);

let metallic_roughness_uv = if material.metallic_roughness_tex_coord == 0 {
in_uv0
Expand All @@ -1248,6 +1357,10 @@ pub fn stage_fragment_impl<T, C, S>(
atlas_size,
slab,
);
crate::println!(
"metallic_roughness_tex_color: {:?}",
metallic_roughness_tex_color
);

let normal_tex_uv = if material.normal_tex_coord == 0 {
in_uv0
Expand All @@ -1262,6 +1375,7 @@ pub fn stage_fragment_impl<T, C, S>(
atlas_size,
slab,
);
crate::println!("normal_tex_color: {:?}", normal_tex_color);

let ao_tex_uv = if material.ao_tex_coord == 0 {
in_uv0
Expand Down
2 changes: 1 addition & 1 deletion crates/renderling/src/atlas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ impl Atlas {

#[cfg(test)]
impl Atlas {
fn atlas_img(&self, device: &wgpu::Device, queue: &wgpu::Queue) -> RgbaImage {
pub fn atlas_img(&self, device: &wgpu::Device, queue: &wgpu::Queue) -> RgbaImage {
let buffer = crate::Texture::read(
&self.texture.texture,
device,
Expand Down
Loading

0 comments on commit 2293435

Please sign in to comment.