mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Various fixes for shadows.
This commit is contained in:
parent
bbbe4ea368
commit
ffa8f29732
@ -1,3 +1,3 @@
|
||||
vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) {
|
||||
return texture(src_color, fragCoord / resolution);
|
||||
return texture(sampler2D(tex, smplr), fragCoord / resolution);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#define FIGURE_SHADER
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
@ -95,7 +95,7 @@ void main() {
|
||||
#endif
|
||||
|
||||
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||
vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||
vec4 f_shadow = textureBicubic(t_horizon, s_horizon, pos_to_tex(f_pos.xy));
|
||||
float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||
#elif (SHADOW_MODE == SHADOW_MODE_NONE)
|
||||
float sun_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -14,7 +14,7 @@ uniform u_light_shadows {
|
||||
layout(set = 1, binding = 2)
|
||||
uniform texture2D t_directed_shadow_maps;
|
||||
layout(set = 1, binding = 3)
|
||||
uniform sampler s_directed_shadow_maps;
|
||||
uniform samplerShadow s_directed_shadow_maps;
|
||||
// uniform sampler2DArrayShadow t_directed_shadow_maps;
|
||||
|
||||
// uniform samplerCubeArrayShadow t_shadow_maps;
|
||||
@ -23,7 +23,7 @@ uniform sampler s_directed_shadow_maps;
|
||||
layout(set = 1, binding = 0)
|
||||
uniform textureCube t_point_shadow_maps;
|
||||
layout(set = 1, binding = 1)
|
||||
uniform sampler s_point_shadow_maps;
|
||||
uniform samplerShadow s_point_shadow_maps;
|
||||
// uniform samplerCube t_shadow_maps;
|
||||
|
||||
// uniform sampler2DArray t_directed_shadow_maps;
|
||||
@ -42,9 +42,13 @@ float VectorToDepth (vec3 Vec)
|
||||
|
||||
// float NormZComp = (screen_res.w+screen_res.z) / (screen_res.w-screen_res.z) - (2*screen_res.w*screen_res.z)/(screen_res.w-screen_res.z)/LocalZcomp;
|
||||
// float NormZComp = 1.0 - shadow_proj_factors.y / shadow_proj_factors.x / LocalZcomp;
|
||||
// -(1 + 2n/(f-n)) - 2(1 + n/(f-n)) * n/z
|
||||
// -(1 + n/(f-n)) - (1 + n/(f-n)) * n/z
|
||||
// f/(f-n) - f
|
||||
float NormZComp = shadow_proj_factors.x - shadow_proj_factors.y / LocalZcomp;
|
||||
// NormZComp = -1000.0 / (NormZComp + 10000.0);
|
||||
return (NormZComp + 1.0) * 0.5;
|
||||
// return (NormZComp + 1.0) * 0.5;
|
||||
return NormZComp;
|
||||
|
||||
// float NormZComp = length(LocalZcomp);
|
||||
// NormZComp = -NormZComp / screen_res.w;
|
||||
@ -161,7 +165,76 @@ float ShadowCalculationDirected(in vec3 fragPos)//in vec4 /*light_pos[2]*/sun_po
|
||||
} */
|
||||
// vec3 fragPos = sun_pos.xyz;// / sun_pos.w;//light_pos[lightIndex].xyz;
|
||||
// sun_pos.z += sun_pos.w * bias;
|
||||
vec4 sun_pos = texture_mat * vec4(fragPos, 1.0);
|
||||
vec4 sun_pos = texture_mat/*shadowMatrices*/ * vec4(fragPos, 1.0);
|
||||
// sun_pos.xyz /= abs(sun_pos.w);
|
||||
// sun_pos.w = sign(sun_pos.w);
|
||||
// sun_pos.xy = (sun_pos.xy + 1.0) * 0.5;
|
||||
// vec4 orig_pos = warpViewMat * lightViewMat * vec4(fragPos, 1.0);
|
||||
//
|
||||
// vec4 shadow_pos;
|
||||
// shadow_pos.xyz = (warpProjMat * orig_pos).xyz:
|
||||
// shadow_pos.w = orig_pos.y;
|
||||
//
|
||||
// sun_pos.xy = 0.5 * (shadow_pos.xy + shadow_pos.w) = 0.5 * (shadow_pos.xy + orig_pos.yy);
|
||||
// sun_pos.z = shadow_pos.z;
|
||||
//
|
||||
// sun_pos.w = sign(shadow_pos.w) = sign(orig_pos.y);
|
||||
// sun_pos.xyz = sun_pos.xyz / shadow_pos.w = vec3(0.5 * shadow_pos.xy / orig_pos.yy + 0.5, shadow_pos.z / orig_pos.y)
|
||||
// = vec3(0.5 * (2.0 * warp_pos.xy / orig_pos.yy - (max_warp_pos + min_warp_pos).xy) / (max_warp_pos - min_warp_pos).xy + 0.5,
|
||||
// -(warp_pos.z / orig_pos.y - min_warp_pos.z) / (max_warp_pos - min_warp_pos).z )
|
||||
// = vec3((warp_pos.x / orig_pos.y - min_warp_pos.x) / (max_warp_pos - min_warp_pos).x,
|
||||
// (warp_pos.y / orig_pos.y - min_warp_pos.y) / (max_warp_pos - min_warp_pos).y,
|
||||
// -(warp_pos.z / orig_pos.y - min_warp_pos.z) / (max_warp_pos - min_warp_pos).z )
|
||||
// = vec3((near * orig_pos.x / orig_pos.y - min_warp_pos.x) / (max_warp_pos - min_warp_pos).x,
|
||||
// (((far+near) - 2.0 * near * far / orig_pos.y)/(far-near) - min_warp_pos.y) / (max_warp_pos - min_warp_pos).y,
|
||||
// -(near * orig_pos.z / orig_pos.y - min_warp_pos.z) / (max_warp_pos - min_warp_pos).z )
|
||||
// = vec3((near * orig_pos.x / orig_pos.y - min_warp_pos.x) / (max_warp_pos - min_warp_pos).x,
|
||||
// (2.0 * (1.0 - far / orig_pos.y)*near/(far-near) + 1.0 - min_warp_pos.y) / (max_warp_pos - min_warp_pos).y,
|
||||
// -(near * orig_pos.z / orig_pos.y - min_warp_pos.z) / (max_warp_pos - min_warp_pos).z )
|
||||
// = vec3((near * orig_pos.x / orig_pos.y - min_warp_pos.x) / (max_warp_pos - min_warp_pos).x,
|
||||
// (2.0 * (1.0 - far / orig_pos.y)*near/(far-near) + 1.0 - 0.0) / (1.0 - 0.0),
|
||||
// -(near * orig_pos.z / orig_pos.y - min_warp_pos.z) / (max_warp_pos - min_warp_pos).z )
|
||||
// = vec3((near * orig_pos.x / orig_pos.y - min_warp_pos.x) / (max_warp_pos - min_warp_pos).x,
|
||||
// 2.0 * (1.0 - far / orig_pos.y)*near/(far-near) + 1.0,
|
||||
// -(near * orig_pos.z / orig_pos.y - min_warp_pos.z) / (max_warp_pos - min_warp_pos).z )
|
||||
//
|
||||
// orig_pos.y = n: warp_pos.y = 2*(1-f/n)*n/(f-n) + 1 = 2*(n-f)/(f-n) + 1 = 2 * -1 + 1 = -1, sun_pos.y = (-1 - -1) / 2 = 0
|
||||
// orig_pos.y = f: warp_pos.y = 2*(1-f/f)*n/(f-n) + 1 = 2*(1-1)*n/(f-n) + 1 = 2 * 0 * n/(f-n) + 1 = 1, sun_pos.y = (1 - -1) / 2 = 1
|
||||
//
|
||||
// 2*(1-64/(1/((0-1)*63/2-1/64)))*1/63+1
|
||||
//
|
||||
// 2*(1-f/x)*n/(f-n) + 1 = 0
|
||||
// 2*(1-f/x)*n/(f-n) = -1
|
||||
//
|
||||
// (1-f/x) = -(f-n)/(2*n)
|
||||
// 1 + (f-n)/(2*n) = f/x
|
||||
// x = f/(1 + 0.5 * (f-n)/n)
|
||||
// = 2*f/(1 + f/n)
|
||||
// = 2*f*n/(f + n)
|
||||
// = 2/(1/n + 1/f)
|
||||
//
|
||||
// 2/(1/(64/1) + 1/64) = 64 (but has n = f = 64)
|
||||
// 2/(1/(64/3) + 1/64) = 32
|
||||
// 2/(1/(64/7) + 1/64) = 16
|
||||
// 2/(1/(64/15) + 1/64) = 8
|
||||
// 2/(1/(64/31) + 1/64) = 4
|
||||
// 2/(1/(64/63) + 1/64) = 2
|
||||
// 2/(1/(64/127) + 1/64) = 1 (but has f < n)
|
||||
//
|
||||
// 2*(1-64/(64/127))*64/127/(64-64/127)+1
|
||||
//
|
||||
// (with normed n)
|
||||
// = 2/(1/n + 1/(1+n))
|
||||
// = 2*n*(1+n)/(1+2n)
|
||||
// = 1/((1 +2n)/(2n(1+n)))
|
||||
// = 1/(1/(2n(1+n)) + 1/(1+n))
|
||||
// = (1 + n)/(1 + 0.5/n)
|
||||
// 2*64*1/(64+1)
|
||||
//
|
||||
// 2*(1-64/(64/(1 + 0.5 * 63/1)))*1/63+1
|
||||
//
|
||||
// sun_pos.xy = sun_pos.w - sun_pos.xy;
|
||||
// sun_pos.xy = sun_pos.xy * 0.5 + 0.5;
|
||||
// sun_pos.z -= sun_pos.w * bias;
|
||||
float visibility = textureProj(sampler2DShadow(t_directed_shadow_maps, s_directed_shadow_maps), sun_pos);
|
||||
/* float visibilityLeft = textureProj(t_directed_shadow_maps, sun_shadow.texture_mat * vec4(fragPos + vec3(0.0, -diskRadius, 0.0), 1.0));
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// However, in the future we might apply some depth transforms here.
|
||||
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
#include <constants.glsl>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
#include <constants.glsl>
|
||||
@ -36,9 +36,10 @@ uniform u_light_shadows {
|
||||
*
|
||||
* */
|
||||
|
||||
layout(location = 1) in uint v_pos_norm;
|
||||
layout(location = 0) in uint v_pos_norm;
|
||||
// in uint v_col_light;
|
||||
// in vec4 v_pos;
|
||||
// layout(location = 1) in uint v_atlas_pos;
|
||||
|
||||
// Light projection matrices.
|
||||
layout (std140, set = 1, binding = 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
#define FIGURE_SHADER
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// However, in the future we might apply some depth transforms here.
|
||||
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
#include <constants.glsl>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
#include <constants.glsl>
|
||||
@ -43,7 +43,7 @@ uniform u_locals {
|
||||
const int EXTRA_NEG_Z = 32768;
|
||||
|
||||
layout( push_constant ) uniform PointLightMatrix {
|
||||
vec4 lightShadowMatrix;
|
||||
mat4 lightShadowMatrix;
|
||||
};
|
||||
|
||||
void main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
// #extension GL_ARB_texture_storage : require
|
||||
|
||||
#include <constants.glsl>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <globals.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 420 core
|
||||
|
||||
#include <globals.glsl>
|
||||
|
||||
|
@ -126,8 +126,8 @@ impl Globals {
|
||||
0,
|
||||
],
|
||||
shadow_proj_factors: [
|
||||
(shadow_planes.y + shadow_planes.x) / (shadow_planes.y - shadow_planes.x),
|
||||
(2.0 * shadow_planes.y * shadow_planes.x) / (shadow_planes.y - shadow_planes.x),
|
||||
shadow_planes.y / (shadow_planes.y - shadow_planes.x),
|
||||
shadow_planes.y * shadow_planes.x / (shadow_planes.y - shadow_planes.x),
|
||||
0.0,
|
||||
0.0,
|
||||
],
|
||||
|
@ -141,7 +141,7 @@ impl ShadowFigurePipeline {
|
||||
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Shadow figure pipeline layout"),
|
||||
label: Some("Directed figure shadow pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[&global_layout.globals, &figure_layout.locals],
|
||||
});
|
||||
@ -155,7 +155,7 @@ impl ShadowFigurePipeline {
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Shadow figure pipeline"),
|
||||
label: Some("Directed shadow figure pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
@ -167,7 +167,7 @@ impl ShadowFigurePipeline {
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
cull_mode: wgpu::CullMode::Front,
|
||||
polygon_mode: wgpu::PolygonMode::Fill,
|
||||
clamp_depth: true,
|
||||
depth_bias: 0,
|
||||
@ -217,7 +217,7 @@ impl ShadowPipeline {
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Shadow pipeline layout"),
|
||||
label: Some("Directed shadow pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[&global_layout.globals, &terrain_layout.locals],
|
||||
});
|
||||
@ -231,7 +231,7 @@ impl ShadowPipeline {
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Shadow pipeline"),
|
||||
label: Some("Directed shadow pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
@ -243,7 +243,7 @@ impl ShadowPipeline {
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
cull_mode: wgpu::CullMode::Front,
|
||||
polygon_mode: wgpu::PolygonMode::Fill,
|
||||
clamp_depth: true,
|
||||
depth_bias: 0,
|
||||
@ -292,7 +292,7 @@ impl PointShadowPipeline {
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Shadow pipeline layout"),
|
||||
label: Some("Point shadow pipeline layout"),
|
||||
push_constant_ranges: &[wgpu::PushConstantRange {
|
||||
stages: wgpu::ShaderStage::all(),
|
||||
range: 0..64,
|
||||
@ -309,7 +309,7 @@ impl PointShadowPipeline {
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Shadow pipeline"),
|
||||
label: Some("Point shadow pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
@ -321,9 +321,9 @@ impl PointShadowPipeline {
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
cull_mode: wgpu::CullMode::Front,
|
||||
polygon_mode: wgpu::PolygonMode::Fill,
|
||||
clamp_depth: true,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
|
@ -2106,7 +2106,7 @@ fn create_pipelines(
|
||||
|
||||
let figure_vert_mod = create_shader("figure-vert", ShaderKind::Vertex)?;
|
||||
|
||||
let terrain_point_shadow_vert_mod = create_shader("light-shadows-vert", ShaderKind::Vertex)?;
|
||||
let terrain_point_shadow_vert_mod = create_shader("point-light-shadows-vert", ShaderKind::Vertex)?;
|
||||
|
||||
let terrain_directed_shadow_vert_mod =
|
||||
create_shader("light-shadows-directed-vert", ShaderKind::Vertex)?;
|
||||
|
@ -11,7 +11,7 @@ use super::{
|
||||
},
|
||||
Renderer, ShadowMapRenderer,
|
||||
};
|
||||
use std::{ops::Range};
|
||||
use core::{num::NonZeroU32, ops::Range};
|
||||
use vek::Aabr;
|
||||
|
||||
pub struct Drawer<'a> {
|
||||
@ -156,9 +156,8 @@ impl<'a> Drawer<'a> {
|
||||
|
||||
pub fn draw_point_shadow<'b: 'a>(
|
||||
&mut self,
|
||||
model: &'b Model<terrain::Vertex>,
|
||||
locals: &'b terrain::BoundLocals,
|
||||
matrices: &[shadow::PointLightMatrix; 126],
|
||||
chunks: impl Clone + Iterator<Item=(&'b Model<terrain::Vertex>, &'b terrain::BoundLocals)>,
|
||||
) {
|
||||
if let Some(ref shadow_renderer) = self.renderer.shadow_map {
|
||||
const STRIDE: usize = std::mem::size_of::<shadow::PointLightMatrix>();
|
||||
@ -172,12 +171,12 @@ impl<'a> Drawer<'a> {
|
||||
.create_view(&wgpu::TextureViewDescriptor {
|
||||
label: Some("Point shadow cubemap face"),
|
||||
format: None,
|
||||
dimension: Some(wgpu::TextureViewDimension::D2Array),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
level_count: None,
|
||||
base_array_layer: face,
|
||||
array_layer_count: None,
|
||||
array_layer_count: NonZeroU32::new(1),
|
||||
});
|
||||
|
||||
let mut render_pass =
|
||||
@ -200,18 +199,20 @@ impl<'a> Drawer<'a> {
|
||||
|
||||
render_pass.set_pipeline(&shadow_renderer.point_pipeline.pipeline);
|
||||
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
||||
render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
||||
render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||
|
||||
for point_light in 0..20 {
|
||||
(0../*20*/1).for_each(|point_light| {
|
||||
render_pass.set_push_constants(
|
||||
wgpu::ShaderStage::all(),
|
||||
0,
|
||||
&data[(6 * point_light * STRIDE + face as usize * STRIDE)
|
||||
..(6 * point_light * STRIDE + (face + 1) as usize * STRIDE)],
|
||||
);
|
||||
render_pass.draw(0..model.len() as u32, 0..1);
|
||||
}
|
||||
chunks.clone().for_each(|(model, locals)| {
|
||||
render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
||||
render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||
render_pass.draw(0..model.len() as u32, 0..1);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ pub fn calc_view_frustum_world_coord<T: Float + MulAdd<T, T, Output = T>>(
|
||||
inv_proj_view: Mat4<T>,
|
||||
) -> [Vec3<T>; 8] {
|
||||
let mut world_pts = aabb_to_points(Aabb {
|
||||
min: -Vec3::one(),
|
||||
min: Vec3::new(-T::one(), -T::one(), T::zero()),
|
||||
max: Vec3::one(),
|
||||
});
|
||||
mat_mul_points(inv_proj_view, &mut world_pts, |p| Vec3::from(p) / p.w);
|
||||
|
@ -695,7 +695,8 @@ impl Scene {
|
||||
// to transform it correctly into texture coordinates, as well as
|
||||
// OpenGL coordinates. Note that the matrix for directional light
|
||||
// is *already* linear in the depth buffer.
|
||||
let texture_mat = Mat4::scaling_3d(0.5f32) * Mat4::translation_3d(1.0f32);
|
||||
let texture_mat = Mat4::<f32>::scaling_3d::<Vec3<f32>>(Vec3::new(0.5, 0.5, 1.0))
|
||||
* Mat4::translation_3d(Vec3::new(1.0, 1.0, 0.0));
|
||||
// We need to compute these offset matrices to transform world space coordinates
|
||||
// to the translated ones we use when multiplying by the light space
|
||||
// matrix; this helps avoid precision loss during the
|
||||
@ -881,10 +882,10 @@ impl Scene {
|
||||
);
|
||||
let s_x = 2.0 / (xmax - xmin);
|
||||
let s_y = 2.0 / (ymax - ymin);
|
||||
let s_z = 2.0 / (zmax - zmin);
|
||||
let s_z = 1.0 / (zmax - zmin);
|
||||
let o_x = -(xmax + xmin) / (xmax - xmin);
|
||||
let o_y = -(ymax + ymin) / (ymax - ymin);
|
||||
let o_z = -(zmax + zmin) / (zmax - zmin);
|
||||
let o_z = -zmin / (zmax - zmin);
|
||||
let directed_proj_mat = Mat4::new(
|
||||
s_x, 0.0, 0.0, o_x, 0.0, s_y, 0.0, o_y, 0.0, 0.0, s_z, o_z, 0.0, 0.0, 0.0, 1.0,
|
||||
);
|
||||
@ -907,202 +908,7 @@ impl Scene {
|
||||
// Now, construct the full projection matrices in the first two directed light
|
||||
// slots.
|
||||
let mut shadow_mats = Vec::with_capacity(6 * (lights.len() + 1));
|
||||
shadow_mats.extend(directed_shadow_mats.iter().enumerate().map(
|
||||
move |(idx, &light_view_mat)| {
|
||||
if idx >= NUM_DIRECTED_LIGHTS {
|
||||
return PointLightMatrix::new(Mat4::identity());
|
||||
}
|
||||
|
||||
let v_p_orig =
|
||||
math::Vec3::from(light_view_mat * math::Vec4::from_direction(new_dir));
|
||||
let mut v_p = v_p_orig.normalized();
|
||||
let cos_gamma = new_dir
|
||||
.map(f64::from)
|
||||
.dot(directed_light_dir.map(f64::from));
|
||||
let sin_gamma = (1.0 - cos_gamma * cos_gamma).sqrt();
|
||||
let gamma = sin_gamma.asin();
|
||||
let view_mat = math::Mat4::from_col_array(view_mat.into_col_array());
|
||||
let bounds1 = math::fit_psr(
|
||||
view_mat.map_cols(math::Vec4::from),
|
||||
visible_light_volume.iter().copied(),
|
||||
math::Vec4::homogenized,
|
||||
);
|
||||
let n_e = f64::from(-bounds1.max.z);
|
||||
let factor = compute_warping_parameter_perspective(
|
||||
gamma,
|
||||
n_e,
|
||||
f64::from(fov),
|
||||
f64::from(aspect_ratio),
|
||||
);
|
||||
|
||||
v_p.z = 0.0;
|
||||
v_p.normalize();
|
||||
let l_r: math::Mat4<f32> = if factor > EPSILON_UPSILON {
|
||||
math::Mat4::look_at_rh(math::Vec3::zero(), -math::Vec3::unit_z(), v_p)
|
||||
} else {
|
||||
math::Mat4::identity()
|
||||
};
|
||||
let directed_proj_mat = math::Mat4::new(
|
||||
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0,
|
||||
1.0,
|
||||
);
|
||||
|
||||
let light_all_mat = l_r * directed_proj_mat * light_view_mat;
|
||||
let bounds0 = math::fit_psr(
|
||||
light_all_mat,
|
||||
visible_light_volume.iter().copied(),
|
||||
math::Vec4::homogenized,
|
||||
);
|
||||
// Vague idea: project z_n from the camera view to the light view (where it's
|
||||
// tilted by γ).
|
||||
let (z_0, z_1) = {
|
||||
let p_z = bounds1.max.z;
|
||||
let p_y = bounds0.min.y;
|
||||
let p_x = bounds0.center().x;
|
||||
let view_inv = view_mat.inverted();
|
||||
let light_all_inv = light_all_mat.inverted();
|
||||
|
||||
let view_point = view_inv * math::Vec4::new(0.0, 0.0, p_z, 1.0);
|
||||
let view_plane =
|
||||
view_inv * math::Vec4::from_direction(math::Vec3::unit_z());
|
||||
|
||||
let light_point = light_all_inv * math::Vec4::new(0.0, p_y, 0.0, 1.0);
|
||||
let light_plane =
|
||||
light_all_inv * math::Vec4::from_direction(math::Vec3::unit_y());
|
||||
|
||||
let shadow_point = light_all_inv * math::Vec4::new(p_x, 0.0, 0.0, 1.0);
|
||||
let shadow_plane =
|
||||
light_all_inv * math::Vec4::from_direction(math::Vec3::unit_x());
|
||||
|
||||
let solve_p0 = math::Mat4::new(
|
||||
view_plane.x,
|
||||
view_plane.y,
|
||||
view_plane.z,
|
||||
-view_plane.dot(view_point),
|
||||
light_plane.x,
|
||||
light_plane.y,
|
||||
light_plane.z,
|
||||
-light_plane.dot(light_point),
|
||||
shadow_plane.x,
|
||||
shadow_plane.y,
|
||||
shadow_plane.z,
|
||||
-shadow_plane.dot(shadow_point),
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
);
|
||||
|
||||
let p0_world = solve_p0.inverted() * math::Vec4::unit_w();
|
||||
let p0 = light_all_mat * p0_world;
|
||||
let mut p1 = p0;
|
||||
p1.y = bounds0.max.y;
|
||||
|
||||
let view_from_light_mat = view_mat * light_all_inv;
|
||||
let z0 = view_from_light_mat * p0;
|
||||
let z1 = view_from_light_mat * p1;
|
||||
|
||||
(f64::from(z0.z), f64::from(z1.z))
|
||||
};
|
||||
|
||||
let mut light_focus_pos: math::Vec3<f32> = math::Vec3::zero();
|
||||
light_focus_pos.x = bounds0.center().x;
|
||||
light_focus_pos.y = bounds0.min.y;
|
||||
light_focus_pos.z = bounds0.center().z;
|
||||
|
||||
let d = f64::from(bounds0.max.y - bounds0.min.y).abs();
|
||||
|
||||
let w_l_y = d;
|
||||
|
||||
// NOTE: See section 5.1.2.2 of Lloyd's thesis.
|
||||
let alpha = z_1 / z_0;
|
||||
let alpha_sqrt = alpha.sqrt();
|
||||
let directed_near_normal = if factor < 0.0 {
|
||||
// Standard shadow map to LiSPSM
|
||||
(1.0 + alpha_sqrt - factor * (alpha - 1.0))
|
||||
/ ((alpha - 1.0) * (factor + 1.0))
|
||||
} else {
|
||||
// LiSPSM to PSM
|
||||
((alpha_sqrt - 1.0) * (factor * alpha_sqrt + 1.0)).recip()
|
||||
};
|
||||
|
||||
// Equation 5.14 - 5.16
|
||||
let y_ = |v: f64| w_l_y * (v + directed_near_normal).abs();
|
||||
let directed_near = y_(0.0) as f32;
|
||||
let directed_far = y_(1.0) as f32;
|
||||
light_focus_pos.y = if factor > EPSILON_UPSILON {
|
||||
light_focus_pos.y - directed_near
|
||||
} else {
|
||||
light_focus_pos.y
|
||||
};
|
||||
let w_v: math::Mat4<f32> = math::Mat4::translation_3d(-math::Vec3::new(
|
||||
light_focus_pos.x,
|
||||
light_focus_pos.y,
|
||||
light_focus_pos.z,
|
||||
));
|
||||
let shadow_view_mat: math::Mat4<f32> = w_v * light_all_mat;
|
||||
let w_p: math::Mat4<f32> = {
|
||||
if factor > EPSILON_UPSILON {
|
||||
// Projection for y
|
||||
let near = directed_near;
|
||||
let far = directed_far;
|
||||
let left = -1.0;
|
||||
let right = 1.0;
|
||||
let bottom = -1.0;
|
||||
let top = 1.0;
|
||||
let s_x = 2.0 * near / (right - left);
|
||||
let o_x = (right + left) / (right - left);
|
||||
let s_z = 2.0 * near / (top - bottom);
|
||||
let o_z = (top + bottom) / (top - bottom);
|
||||
|
||||
let s_y = (far + near) / (far - near);
|
||||
let o_y = -2.0 * far * near / (far - near);
|
||||
|
||||
math::Mat4::new(
|
||||
s_x, o_x, 0.0, 0.0, 0.0, s_y, 0.0, o_y, 0.0, o_z, s_z, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
)
|
||||
} else {
|
||||
math::Mat4::identity()
|
||||
}
|
||||
};
|
||||
|
||||
let shadow_all_mat: math::Mat4<f32> = w_p * shadow_view_mat;
|
||||
let math::Aabb::<f32> {
|
||||
min:
|
||||
math::Vec3 {
|
||||
x: xmin,
|
||||
y: ymin,
|
||||
z: zmin,
|
||||
},
|
||||
max:
|
||||
math::Vec3 {
|
||||
x: xmax,
|
||||
y: ymax,
|
||||
z: zmax,
|
||||
},
|
||||
} = math::fit_psr(
|
||||
shadow_all_mat,
|
||||
visible_light_volume.iter().copied(),
|
||||
math::Vec4::homogenized,
|
||||
);
|
||||
let s_x = 2.0 / (xmax - xmin);
|
||||
let s_y = 2.0 / (ymax - ymin);
|
||||
let s_z = 2.0 / (zmax - zmin);
|
||||
let o_x = -(xmax + xmin) / (xmax - xmin);
|
||||
let o_y = -(ymax + ymin) / (ymax - ymin);
|
||||
let o_z = -(zmax + zmin) / (zmax - zmin);
|
||||
let directed_proj_mat = Mat4::new(
|
||||
s_x, 0.0, 0.0, o_x, 0.0, s_y, 0.0, o_y, 0.0, 0.0, s_z, o_z, 0.0, 0.0, 0.0,
|
||||
1.0,
|
||||
);
|
||||
|
||||
let shadow_all_mat: Mat4<f32> =
|
||||
Mat4::from_col_arrays(shadow_all_mat.into_col_arrays());
|
||||
|
||||
PointLightMatrix::new(directed_proj_mat * shadow_all_mat)
|
||||
},
|
||||
));
|
||||
shadow_mats.resize_with(6, PointLightMatrix::default);
|
||||
// Now, we tackle point lights.
|
||||
// First, create a perspective projection matrix at 90 degrees (to cover a whole
|
||||
// face of the cube map we're using).
|
||||
|
@ -1453,15 +1453,10 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// NOTE: We don't bother retaining chunks unless they cast sun shadows, so we
|
||||
// don't use `shadow_chunks` here.
|
||||
light_data.iter().take(1).for_each(|_light| {
|
||||
chunk_iter.clone().for_each(|chunk| {
|
||||
if chunk.can_shadow_point {
|
||||
drawer.draw_point_shadow(
|
||||
&chunk.opaque_model,
|
||||
&chunk.locals,
|
||||
&global.point_light_matrices,
|
||||
);
|
||||
}
|
||||
});
|
||||
drawer.draw_point_shadow(
|
||||
&global.point_light_matrices,
|
||||
chunk_iter.clone().filter(|chunk| chunk.can_shadow_point).map(|chunk| (&chunk.opaque_model, &chunk.locals)),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1426,6 +1426,14 @@ impl PlayState for SessionState {
|
||||
client.get_tick(),
|
||||
&scene_data,
|
||||
);
|
||||
|
||||
self.scene.render_figure_shadows(
|
||||
&mut drawer,
|
||||
client.state(),
|
||||
client.entity(),
|
||||
client.get_tick(),
|
||||
&scene_data,
|
||||
);
|
||||
});
|
||||
|
||||
self.scene.render_point_shadows(
|
||||
@ -1436,15 +1444,6 @@ impl PlayState for SessionState {
|
||||
&scene_data,
|
||||
);
|
||||
|
||||
drawer.shadow_pass().map(|mut drawer| {
|
||||
self.scene.render_figure_shadows(
|
||||
&mut drawer,
|
||||
client.state(),
|
||||
client.entity(),
|
||||
client.get_tick(),
|
||||
&scene_data,
|
||||
);
|
||||
});
|
||||
self.scene.render(
|
||||
&mut drawer.first_pass(),
|
||||
client.state(),
|
||||
|
Loading…
Reference in New Issue
Block a user