mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Greedy messhing for shadows.
This commit is contained in:
parent
a4d87e1875
commit
560501df05
@ -76,6 +76,7 @@ void main() {
|
||||
// f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||
|
||||
gl_Position = all_mat * vec4(f_pos, 1);
|
||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ void main() {
|
||||
gl_Position =
|
||||
all_mat *
|
||||
vec4(f_pos, 1);
|
||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -32,10 +32,13 @@ float attenuation_strength(vec3 rpos) {
|
||||
uniform samplerCubeShadow t_shadow_maps;
|
||||
// uniform samplerCube t_shadow_maps;
|
||||
|
||||
// uniform sampler2DArray t_directed_shadow_maps;
|
||||
|
||||
float VectorToDepth (vec3 Vec)
|
||||
{
|
||||
vec3 AbsVec = abs(Vec);
|
||||
float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));
|
||||
// float LocalZcomp = length(Vec);
|
||||
|
||||
// Replace f and n with the far and near plane values you used when
|
||||
// you drew your cube map.
|
||||
@ -43,8 +46,15 @@ float VectorToDepth (vec3 Vec)
|
||||
// const float n = 1.0;
|
||||
|
||||
// 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;
|
||||
float NormZComp = shadow_proj_factors.x - shadow_proj_factors.y / LocalZcomp;
|
||||
// NormZComp = -1000.0 / (NormZComp + 10000.0);
|
||||
return (NormZComp + 1.0) * 0.5;
|
||||
|
||||
// float NormZComp = length(LocalZcomp);
|
||||
// NormZComp = -NormZComp / screen_res.w;
|
||||
// // return (NormZComp + 1.0) * 0.5;
|
||||
// return NormZComp;
|
||||
}
|
||||
|
||||
const vec3 sampleOffsetDirections[20] = vec3[]
|
||||
@ -59,27 +69,34 @@ const vec3 sampleOffsetDirections[20] = vec3[]
|
||||
|
||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
||||
{
|
||||
// float shadow = 0.0;
|
||||
float bias = 0.0;//-0.1;//0.0;//0.1
|
||||
// int samples = 20;
|
||||
if (lightIndex != 0u) {
|
||||
return 1.0;
|
||||
};
|
||||
|
||||
float shadow = 0.0;
|
||||
float bias = -0.015;//-0.05;//-0.1;//0.0;//0.1
|
||||
int samples = 20;
|
||||
// float lightDistance = length(fragToLight);
|
||||
// float viewDistance = length(cam_pos.xyz - fragPos);
|
||||
// // float diskRadius = 0.00001;
|
||||
// // float diskRadius = 1.0;
|
||||
// float diskRadius = (1.0 + (/*viewDistance*/viewDistance / screen_res.w)) / 2.0;
|
||||
// // float diskRadius = lightDistance;
|
||||
// for(int i = 0; i < samples; ++i)
|
||||
// {
|
||||
// float currentDepth = VectorToDepth(fragToLight + sampleOffsetDirections[i] * diskRadius) + bias;
|
||||
// // float closestDepth = texture(depthMap, fragToLight).r;
|
||||
// // closestDepth *= far_plane; // Undo mapping [0;1]
|
||||
// /* if(currentDepth - bias > closestDepth)
|
||||
// shadow += 1.0;*/
|
||||
// float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth));
|
||||
// shadow += visibility;
|
||||
// }
|
||||
// shadow /= float(samples);
|
||||
// // shadow = shadow * shadow * (3.0 - 2.0 * shadow);
|
||||
float viewDistance = length(cam_pos.xyz - fragPos);
|
||||
// float diskRadius = 0.00001;
|
||||
// float diskRadius = 1.0;
|
||||
// float diskRadius = 0.05;
|
||||
float diskRadius = (1.0 + (/*viewDistance*/viewDistance / screen_res.w)) / 25.0;
|
||||
// float diskRadius = lightDistance;
|
||||
for(int i = 0; i < samples; ++i)
|
||||
{
|
||||
float currentDepth = VectorToDepth(fragToLight + sampleOffsetDirections[i] * diskRadius) + bias;
|
||||
// float closestDepth = texture(depthMap, fragToLight).r;
|
||||
// closestDepth *= far_plane; // Undo mapping [0;1]
|
||||
/* if(currentDepth - bias > closestDepth)
|
||||
shadow += 1.0;*/
|
||||
float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth)/*, -2.5*/);
|
||||
shadow += visibility;
|
||||
// float closestDepth = texture(t_shadow_maps, vec3(fragToLight)/*, -2.5*/).r;
|
||||
// shadow += closestDepth > currentDepth ? 1.0 : 0.0;
|
||||
}
|
||||
shadow /= float(samples);
|
||||
// shadow = shadow * shadow * (3.0 - 2.0 * shadow);
|
||||
|
||||
// use the light to fragment vector to sample from the depth map
|
||||
// float bias = 0.0;///*0.05*/0.01;//0.05;// 0.05;
|
||||
@ -95,15 +112,11 @@ float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*
|
||||
// currentDepth += bias;
|
||||
// currentDepth = -1000.0 / (currentDepth + 10000.0);
|
||||
// currentDepth /= screen_res.w;
|
||||
float currentDepth = VectorToDepth(fragToLight) + bias;
|
||||
if (lightIndex != 0u) {
|
||||
return 1.0;
|
||||
};
|
||||
// float currentDepth = VectorToDepth(fragToLight) + bias;
|
||||
|
||||
float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth));// / (screen_res.w/* - screen_res.z*/)/*1.0 -bias*//*-(currentDepth - bias) / screen_res.w*//*-screen_res.w*/);
|
||||
|
||||
return visibility;
|
||||
// return shadow;
|
||||
// float visibility = texture(t_shadow_maps, vec4(fragToLight, 0.0), currentDepth);// / (screen_res.w/* - screen_res.z*/)/*1.0 -bias*//*-(currentDepth - bias) / screen_res.w*//*-screen_res.w*/);
|
||||
// return visibility;
|
||||
return shadow;
|
||||
}
|
||||
#else
|
||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
||||
@ -284,7 +297,7 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve
|
||||
// mix(cam_strength, strength, cam_distance_2 / (cam_distance_2 + distance_2));
|
||||
// max(cam_strength, strength);//mix(cam_strength, strength, clamp(distance_2 / /*pos_distance_2*/cam_distance_2, 0.0, 1.0));
|
||||
// float both_strength = mix(cam_strength, strength, cam_distance_2 / sqrt(cam_distance_2 + distance_2));
|
||||
max_light += /*max(1.0, cam_strength)*//*min(cam_strength, 1.0)*//*max*//*max(both_strength, 1.0) * *//*cam_strength*/computed_shadow * both_strength * square_factor * square_factor * PI * color;
|
||||
max_light += /*max(1.0, cam_strength)*//*min(cam_strength, 1.0)*//*max*//*max(both_strength, 1.0) * *//*cam_strength*//*computed_shadow * */both_strength * square_factor * square_factor * PI * color;
|
||||
// max_light += /*max(1.0, cam_strength)*//*min(cam_strength, 1.0)*//*max*/max(cam_strength, 1.0/*, strength*//*1.0*/) * square_factor * square_factor * PI * color;
|
||||
// light += color * (max(0, max(dot(normalize(difference), wnorm), 0.15)) + LIGHT_AMBIENCE);
|
||||
// Compute emiittance.
|
||||
|
@ -26,7 +26,7 @@
|
||||
// Currently, we only need lights for the light position
|
||||
#include <light.glsl>
|
||||
|
||||
// in vec3 FragPos; // FragPos from GS (output per emitvertex)
|
||||
in vec3 FragPos; // FragPos from GS (output per emitvertex)
|
||||
// flat in int FragLayer;
|
||||
|
||||
void main()
|
||||
@ -35,14 +35,14 @@ void main()
|
||||
// distance.
|
||||
/*if (FragLayer > 0) */{
|
||||
// get distance between fragment and light source
|
||||
// float lightDistance = length(FragPos - lights[((FragLayer - 1) & 31)].light_pos.xyz);
|
||||
// float lightDistance = length(FragPos - lights[((/*FragLayer*/1 - 1) & 31)].light_pos.xyz);
|
||||
|
||||
// map to [0;1] range by dividing by far_plane
|
||||
// lightDistance = lightDistance / /*FragPos.w;*/screen_res.w;
|
||||
// // map to [0;1] range by dividing by far_plane
|
||||
// lightDistance = lightDistance / screen_res.w;//FragPos.w;//screen_res.w;
|
||||
|
||||
// write this as modified depth
|
||||
// lightDistance = -1000.0 / (lightDistance + 10000.0);
|
||||
// lightDistance /= screen_res.w;
|
||||
// // write this as modified depth
|
||||
// // lightDistance = -1000.0 / (lightDistance + 10000.0);
|
||||
// // lightDistance /= screen_res.w;
|
||||
// gl_FragDepth = lightDistance;// / /*FragPos.w;*/screen_res.w;//-1000.0 / (lightDistance + 1000.0);//lightDistance
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,7 @@
|
||||
|
||||
layout (triangles/*, invocations = 6*/) in;
|
||||
|
||||
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*/96) out;
|
||||
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*//*96*/18) out;
|
||||
|
||||
struct ShadowLocals {
|
||||
mat4 shadowMatrices;
|
||||
@ -245,6 +245,10 @@ void main() {
|
||||
int layer_face = layer_base + face;
|
||||
gl_Layer = face;//layer_face; // built-in variable that specifies to which face we render.
|
||||
gl_Position = shadowMats[layer_face].shadowMatrices * vec4(FragPos, 1.0);
|
||||
// gl_Position.z = -((gl_Position.z + screen_res.z) / (screen_res.w - screen_res.z)) * lightDistance;
|
||||
// gl_Position.z = gl_Position.z / screen_res.w;
|
||||
// gl_Position.z = gl_Position.z / gl_Position.w;
|
||||
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
// lightDistance = -(lightDistance + screen_res.z) / (screen_res.w - screen_res.z);
|
||||
// gl_Position.z = lightDistance;
|
||||
EmitVertex();
|
||||
|
@ -27,7 +27,8 @@
|
||||
* */
|
||||
|
||||
in uint v_pos_norm;
|
||||
in uint v_col_light;
|
||||
// in uint v_col_light;
|
||||
// in vec4 v_pos;
|
||||
|
||||
// Light projection matrices.
|
||||
layout (std140)
|
||||
@ -42,11 +43,12 @@ const int EXTRA_NEG_Z = 32768;
|
||||
|
||||
void main() {
|
||||
vec3 f_chunk_pos = vec3(ivec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0xFFFFu)) - ivec3(0, 0, EXTRA_NEG_Z));
|
||||
// f_pos = f_chunk_pos + model_offs;
|
||||
// f_pos = v_pos;
|
||||
vec3 f_pos = f_chunk_pos + model_offs;
|
||||
// f_pos = v_pos;
|
||||
// vec3 f_pos = f_chunk_pos + model_offs;
|
||||
|
||||
gl_Position = /*all_mat * */vec4(f_pos/*, 1.0*/, /*float(((f_pos_norm >> 29) & 0x7u) ^ 0x1)*/uintBitsToFloat(v_pos_norm)/*1.0*/);
|
||||
// gl_Position = v_pos + vec4(model_offs, 0.0);
|
||||
gl_Position = /*all_mat * */vec4(f_pos/*, 1.0*/, /*float(((f_pos_norm >> 29) & 0x7u) ^ 0x1)*//*uintBitsToFloat(v_pos_norm)*/1.0);
|
||||
// shadowMapCoord = lights[gl_InstanceID].light_pos * gl_Vertex;
|
||||
// vec4(v_pos, 0.0, 1.0);
|
||||
}
|
||||
|
@ -298,9 +298,13 @@ void main() {
|
||||
|
||||
// f_ao = 1.0;
|
||||
// f_ao = dot(f_ao_vec, sqrt(1.0 - delta_sides * delta_sides));
|
||||
|
||||
f_ao = sqrt(dot(f_ao_vec * abs(voxel_norm), sqrt(1.0 - delta_sides * delta_sides)) / 3.0);
|
||||
// f_ao = dot(abs(voxel_norm), f_ao_vec);
|
||||
// voxel_norm = f_norm;
|
||||
|
||||
// vec3 ao_pos2 = min(fract(f_pos), 1.0 - fract(f_pos));
|
||||
// f_ao = sqrt(dot(ao_pos2, ao_pos2));
|
||||
// // f_ao = dot(abs(voxel_norm), f_ao_vec);
|
||||
// // voxel_norm = f_norm;
|
||||
|
||||
// Note: because voxels, we reduce the normal for reflections to just its z component, dpendng on distance to camera.
|
||||
// Idea: the closer we are to facing top-down, the more the norm should tend towards up-z.
|
||||
|
@ -95,6 +95,7 @@ void main() {
|
||||
proj_mat *
|
||||
view_mat *
|
||||
vec4(f_pos/*newRay*/, 1);
|
||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ void main() {
|
||||
gl_Position =
|
||||
all_mat *
|
||||
vec4(f_pos, 1);
|
||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -38,6 +38,15 @@ out vec4 tgt_color;
|
||||
#include <lod.glsl>
|
||||
|
||||
void main() {
|
||||
// vec4 light_col = vec4(
|
||||
// hash(floor(vec4(f_pos.x, 0, 0, 0))),
|
||||
// hash(floor(vec4(0, f_pos.y, 0, 1))),
|
||||
// hash(floor(vec4(0, 0, f_pos.z, 2))),
|
||||
// 1.0
|
||||
// );
|
||||
// vec3 f_col = light_col.rgb;//vec4(1.0, 0.0, 0.0, 1.0);
|
||||
// tgt_color = vec4(f_col, 1.0);
|
||||
// return;
|
||||
// tgt_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
// float sum = 0.0;
|
||||
// for (uint i = 0u; i < /* 6 * */light_shadow_count.x; i ++) {
|
||||
@ -62,10 +71,13 @@ void main() {
|
||||
// // vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
||||
|
||||
// // use the light to fragment vector to sample from the depth map
|
||||
// float bias = 0.05;//0.05;
|
||||
// float bias = 0.0;//0.05;//0.05;
|
||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i)/*, 0.0*//*, bias*/).r;
|
||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
||||
// float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i + 1)/*, bias*/).r;
|
||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i + 1)/*, bias*/).r;
|
||||
// float currentDepth = VectorToDepth(fragToLight) + bias;
|
||||
// float closestDepth = texture(t_shadow_maps, vec3(fragToLight)/*, -2.5*/).r;
|
||||
//
|
||||
// // float visibility = texture(t_shadow_maps, vec4(fragToLight, i + 1), -(length(fragToLight) - bias)/* / screen_res.w*/);
|
||||
// // it is currently in linear range between [0,1]. Re-transform back to original value
|
||||
// // closestDepth *= screen_res.w; // far plane
|
||||
@ -74,7 +86,8 @@ void main() {
|
||||
// // float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||
|
||||
// // tgt_color += light_col * vec4(vec3(/*closestDepth*/visibility/* + bias*//* / screen_res.w */) * 1.0 / light_shadow_count.x, 0.0);
|
||||
// tgt_color.rgb += light_col * vec3(closestDepth + 0.05 / screen_res.w) * 1.0 /*/ light_shadow_count.x*/ * light_strength;
|
||||
// // tgt_color.rgb += light_col * vec3(closestDepth + 0.05 / screen_res.w) * 1.0 /*/ light_shadow_count.x*/ * light_strength;
|
||||
// tgt_color.rgb += light_col * vec3(closestDepth) * 1.0 / screen_res.w /*/ light_shadow_count.x*/ * light_strength;
|
||||
// sum += light_strength;
|
||||
// }
|
||||
|
||||
|
@ -99,6 +99,8 @@ void main() {
|
||||
gl_Position =
|
||||
all_mat *
|
||||
vec4(f_pos/*newRay*/, 1);
|
||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -7,11 +7,16 @@ use crate::render::{self, Mesh};
|
||||
pub trait Meshable<'a, P: render::Pipeline, T: render::Pipeline> {
|
||||
type Pipeline: render::Pipeline;
|
||||
type TranslucentPipeline: render::Pipeline;
|
||||
type ShadowPipeline: render::Pipeline;
|
||||
type Supplement;
|
||||
|
||||
// Generate meshes - one opaque, one translucent
|
||||
// Generate meshes - one opaque, one translucent, one shadow
|
||||
fn generate_mesh(
|
||||
&'a self,
|
||||
supp: Self::Supplement,
|
||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>);
|
||||
) -> (
|
||||
Mesh<Self::Pipeline>,
|
||||
Mesh<Self::TranslucentPipeline>,
|
||||
Mesh<Self::ShadowPipeline>,
|
||||
);
|
||||
}
|
||||
|
@ -20,13 +20,20 @@ where
|
||||
* &'a V: BaseVol<Vox=Cell>, */
|
||||
{
|
||||
type Pipeline = FigurePipeline;
|
||||
type ShadowPipeline = FigurePipeline;
|
||||
type Supplement = (Vec3<f32>, Vec3<f32>);
|
||||
type TranslucentPipeline = FigurePipeline;
|
||||
|
||||
// TODO: Make sprites cast shadows?
|
||||
|
||||
fn generate_mesh(
|
||||
&'a self,
|
||||
(offs, scale): Self::Supplement,
|
||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
||||
) -> (
|
||||
Mesh<Self::Pipeline>,
|
||||
Mesh<Self::TranslucentPipeline>,
|
||||
Mesh<Self::ShadowPipeline>,
|
||||
) {
|
||||
let mut mesh = Mesh::new();
|
||||
|
||||
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
||||
@ -74,7 +81,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
(mesh, Mesh::new())
|
||||
(mesh, Mesh::new(), Mesh::new())
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,13 +93,20 @@ where
|
||||
* &'a V: BaseVol<Vox=Cell>, */
|
||||
{
|
||||
type Pipeline = SpritePipeline;
|
||||
type ShadowPipeline = SpritePipeline;
|
||||
type Supplement = (Vec3<f32>, Vec3<f32>);
|
||||
type TranslucentPipeline = SpritePipeline;
|
||||
|
||||
// TODO: Make sprites cast shadows?
|
||||
|
||||
fn generate_mesh(
|
||||
&'a self,
|
||||
(offs, scale): Self::Supplement,
|
||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
||||
) -> (
|
||||
Mesh<Self::Pipeline>,
|
||||
Mesh<Self::TranslucentPipeline>,
|
||||
Mesh<Self::ShadowPipeline>,
|
||||
) {
|
||||
let mut mesh = Mesh::new();
|
||||
|
||||
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
||||
@ -139,7 +153,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
(mesh, Mesh::new())
|
||||
(mesh, Mesh::new(), Mesh::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
mesh::{vol, Meshable},
|
||||
render::{self, FluidPipeline, Mesh, TerrainPipeline},
|
||||
render::{self, mesh::Quad, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
|
||||
};
|
||||
use common::{
|
||||
terrain::{Block, BlockKind},
|
||||
@ -12,6 +12,7 @@ use vek::*;
|
||||
|
||||
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
||||
type FluidVertex = <FluidPipeline as render::Pipeline>::Vertex;
|
||||
type ShadowVertex = <ShadowPipeline as render::Pipeline>::Vertex;
|
||||
|
||||
trait Blendable {
|
||||
fn is_blended(&self) -> bool;
|
||||
@ -202,13 +203,18 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||
Meshable<'a, TerrainPipeline, FluidPipeline> for VolGrid2d<V>
|
||||
{
|
||||
type Pipeline = TerrainPipeline;
|
||||
type ShadowPipeline = ShadowPipeline;
|
||||
type Supplement = Aabb<i32>;
|
||||
type TranslucentPipeline = FluidPipeline;
|
||||
|
||||
fn generate_mesh(
|
||||
&'a self,
|
||||
range: Self::Supplement,
|
||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
||||
) -> (
|
||||
Mesh<Self::Pipeline>,
|
||||
Mesh<Self::TranslucentPipeline>,
|
||||
Mesh<Self::ShadowPipeline>,
|
||||
) {
|
||||
let mut light = calc_light(range, self);
|
||||
|
||||
let mut lowest_opaque = range.size().d;
|
||||
@ -463,7 +469,84 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||
// opaque_mesh
|
||||
// });
|
||||
|
||||
(opaque_mesh, fluid_mesh)
|
||||
let mut shadow_mesh = Mesh::new();
|
||||
|
||||
let x_size = (range.size().w - 2) as usize;
|
||||
let y_size = (range.size().h - 2) as usize;
|
||||
let z_size = (z_end - z_start + 1) as usize;
|
||||
let draw_delta = Vec3::new(1, 1, z_start);
|
||||
let mesh_delta = Vec3::new(0, 0, z_start + range.min.z);
|
||||
|
||||
// x (u = y, v = z)
|
||||
greedy_mesh_cross_section(
|
||||
Vec3::new(y_size, z_size, x_size),
|
||||
|pos| {
|
||||
should_draw_greedy(
|
||||
Vec3::new(pos.z, pos.x, pos.y),
|
||||
draw_delta,
|
||||
Vec3::unit_x(), /* , pos.z, 0, x_size */
|
||||
|pos| flat_get(pos),
|
||||
)
|
||||
},
|
||||
|pos, dim, faces_forward| {
|
||||
shadow_mesh.push_quad(create_quad_greedy(
|
||||
Vec3::new(pos.z, pos.x, pos.y),
|
||||
mesh_delta,
|
||||
dim,
|
||||
Vec2::new(Vec3::unit_y(), Vec3::unit_z()),
|
||||
Vec3::unit_x(),
|
||||
faces_forward,
|
||||
));
|
||||
},
|
||||
);
|
||||
|
||||
// y (u = z, v = x)
|
||||
greedy_mesh_cross_section(
|
||||
Vec3::new(z_size, x_size, y_size),
|
||||
|pos| {
|
||||
should_draw_greedy(
|
||||
Vec3::new(pos.y, pos.z, pos.x),
|
||||
draw_delta,
|
||||
Vec3::unit_y(), /* , pos.z, 0, y_size */
|
||||
|pos| flat_get(pos),
|
||||
)
|
||||
},
|
||||
|pos, dim, faces_forward| {
|
||||
shadow_mesh.push_quad(create_quad_greedy(
|
||||
Vec3::new(pos.y, pos.z, pos.x),
|
||||
mesh_delta,
|
||||
dim,
|
||||
Vec2::new(Vec3::unit_z(), Vec3::unit_x()),
|
||||
Vec3::unit_y(),
|
||||
faces_forward,
|
||||
));
|
||||
},
|
||||
);
|
||||
|
||||
// z (u = x, v = y)
|
||||
greedy_mesh_cross_section(
|
||||
Vec3::new(x_size, y_size, z_size),
|
||||
|pos| {
|
||||
should_draw_greedy(
|
||||
Vec3::new(pos.x, pos.y, pos.z),
|
||||
draw_delta,
|
||||
Vec3::unit_z(), /* , pos.z, 0, z_size */
|
||||
|pos| flat_get(pos),
|
||||
)
|
||||
},
|
||||
|pos, dim, faces_forward| {
|
||||
shadow_mesh.push_quad(create_quad_greedy(
|
||||
Vec3::new(pos.x, pos.y, pos.z),
|
||||
mesh_delta,
|
||||
dim,
|
||||
Vec2::new(Vec3::unit_x(), Vec3::unit_y()),
|
||||
Vec3::unit_z(),
|
||||
faces_forward,
|
||||
));
|
||||
},
|
||||
);
|
||||
|
||||
(opaque_mesh, fluid_mesh, shadow_mesh)
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,6 +576,154 @@ fn faces_to_make<M: Clone>(
|
||||
]
|
||||
}
|
||||
|
||||
// Greedy meshing.
|
||||
fn greedy_mesh_cross_section(
|
||||
/* mask: &mut [bool], */
|
||||
dims: Vec3<usize>,
|
||||
// Should we draw a face here (below this vertex)? If so, is it front or back facing?
|
||||
draw_face: impl Fn(Vec3<usize>) -> Option<bool>,
|
||||
// Vertex, width and height, and whether it's front facing (face is implicit from the cross
|
||||
// section).
|
||||
mut push_quads: impl FnMut(Vec3<usize>, Vec2<usize>, bool),
|
||||
) {
|
||||
// mask represents which faces are either set while the other is unset, or unset
|
||||
// while the other is set.
|
||||
let mut mask = vec![None; dims.y * dims.x];
|
||||
(0..dims.z + 1).for_each(|d| {
|
||||
// Compute mask
|
||||
mask.iter_mut().enumerate().for_each(|(posi, mask)| {
|
||||
let i = posi % dims.x;
|
||||
let j = posi / dims.x;
|
||||
*mask = draw_face(Vec3::new(i, j, d));
|
||||
});
|
||||
|
||||
(0..dims.y).for_each(|j| {
|
||||
let mut i = 0;
|
||||
while i < dims.x {
|
||||
// Compute width (number of set x bits for this row and layer, starting at the
|
||||
// current minimum column).
|
||||
if let Some(ori) = mask[j * dims.x + i] {
|
||||
let width = 1 + mask[j * dims.x + i + 1..j * dims.x + dims.x]
|
||||
.iter()
|
||||
.take_while(move |&&mask| mask == Some(ori))
|
||||
.count();
|
||||
let max_x = i + width;
|
||||
// Compute height (number of rows having w set x bits for this layer, starting
|
||||
// at the current minimum column and row).
|
||||
let height = 1
|
||||
+ (j + 1..dims.y)
|
||||
.take_while(|h| {
|
||||
mask[h * dims.x + i..h * dims.x + max_x]
|
||||
.iter()
|
||||
.all(|&mask| mask == Some(ori))
|
||||
})
|
||||
.count();
|
||||
let max_y = j + height;
|
||||
// Add quad.
|
||||
push_quads(Vec3::new(i, j, d /* + 1 */), Vec2::new(width, height), ori);
|
||||
// Unset mask bits in drawn region, so we don't try to re-draw them.
|
||||
(j..max_y).for_each(|l| {
|
||||
mask[l * dims.x + i..l * dims.x + max_x]
|
||||
.iter_mut()
|
||||
.for_each(|mask| {
|
||||
*mask = None;
|
||||
});
|
||||
});
|
||||
// Update x value.
|
||||
i = max_x;
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn create_quad_greedy(
|
||||
origin: Vec3<usize>,
|
||||
mesh_delta: Vec3<i32>,
|
||||
dim: Vec2<usize>,
|
||||
uv: Vec2<Vec3<f32>>,
|
||||
norm: Vec3<f32>,
|
||||
faces_forward: bool,
|
||||
) -> Quad<ShadowPipeline> {
|
||||
let origin = origin.map(|e| e as i32) + mesh_delta;
|
||||
// let origin = (uv.x * origin.x + uv.y * origin.y + norm * origin.z) +
|
||||
// Vec3::new(0, 0, z_start + range.min.z - 1);//Vec3::new(-1, -1, z_start +
|
||||
// range.min.z - 1);
|
||||
let origin = origin.map(|e| e as f32); // + orientation.z;
|
||||
// let origin = uv.x * origin.x + uv.y * origin.y + norm * origin.z +
|
||||
// Vec3::new(0.0, 0.0, (z_start + range.min.z - 1) as f32);
|
||||
/* if (origin.x < 0.0 || origin.y < 0.0) {
|
||||
return;
|
||||
} */
|
||||
// let ori = if faces_forward { Vec3::new(u, v, norm) } else { Vec3::new(uv.y,
|
||||
// uv.x, -norm) };
|
||||
let dim = uv.map2(dim.map(|e| e as f32), |e, f| e * f);
|
||||
let (dim, norm) = if faces_forward {
|
||||
(dim, norm)
|
||||
} else {
|
||||
(Vec2::new(dim.y, dim.x), -norm)
|
||||
};
|
||||
// let (uv, norm, origin) = if faces_forward { (uv, norm, origin) } else {
|
||||
// (Vec2::new(uv.y, uv.x), -norm, origin) }; let (uv, norm, origin) = if
|
||||
// faces_forward { (uv, norm, origin) } else { (Vec2::new(uv.y, uv.x), -norm,
|
||||
// origin/* - norm*/) }; let origin = Vec3::new(origin.x as f32., origin.y
|
||||
// as f32, (origin.z + z_start) as f32); let norm = norm.map(|e| e as f32);
|
||||
Quad::new(
|
||||
ShadowVertex::new(origin, norm),
|
||||
ShadowVertex::new(origin + dim.x, norm),
|
||||
ShadowVertex::new(origin + dim.x + dim.y, norm),
|
||||
ShadowVertex::new(origin + dim.y, norm),
|
||||
)
|
||||
}
|
||||
|
||||
fn should_draw_greedy(
|
||||
pos: Vec3<usize>,
|
||||
draw_delta: Vec3<i32>,
|
||||
delta: Vec3<i32>,
|
||||
/* depth, min_depth, max_depth, */ flat_get: impl Fn(Vec3<i32>) -> Block,
|
||||
) -> Option<bool> {
|
||||
let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
||||
//
|
||||
/* if (depth as isize) <= min_depth {
|
||||
// let to = flat_get(pos).is_opaque();
|
||||
debug_assert!(depth <= max_depth);
|
||||
/* if depth >= max_depth - 1 {
|
||||
let from = flat_get(pos - delta).is_opaque();
|
||||
} else {
|
||||
None
|
||||
} */
|
||||
if flat_get(pos + delta).is_opaque() {
|
||||
Some(true)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else */
|
||||
{
|
||||
let from = flat_get(pos - delta).is_opaque(); // map(|v| v.is_opaque()).unwrap_or(false);
|
||||
//
|
||||
/* if depth > max_depth {
|
||||
if from {
|
||||
// Backward-facing
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else */
|
||||
{
|
||||
let to = flat_get(pos).is_opaque(); //map(|v| v.is_opaque()).unwrap_or(false);
|
||||
if from == to {
|
||||
None
|
||||
} else {
|
||||
// If going from transparent to opaque, forward facing; otherwise, backward
|
||||
// facing.
|
||||
Some(from)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl<V: BaseVol<Vox = Block> + ReadVol + Debug> Meshable for VolGrid3d<V> {
|
||||
type Pipeline = TerrainPipeline;
|
||||
|
@ -1,15 +1,20 @@
|
||||
use super::{
|
||||
super::{util::arr_to_mat, Pipeline, ShadowDepthStencilFmt, TerrainLocals},
|
||||
terrain::Vertex,
|
||||
Globals, Light, Shadow,
|
||||
};
|
||||
use gfx::{
|
||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||
gfx_pipeline_inner,
|
||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
gfx_defines! {
|
||||
vertex Vertex {
|
||||
// pos: [f32; 4] = "v_pos",
|
||||
pos_norm: u32 = "v_pos_norm",
|
||||
// col_light: u32 = "v_col_light",
|
||||
}
|
||||
|
||||
constant Locals {
|
||||
shadow_matrices: [[f32; 4]; 4] = "shadowMatrices",
|
||||
}
|
||||
@ -35,6 +40,39 @@ gfx_defines! {
|
||||
}
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
|
||||
let norm_bits = if norm.x != 0.0 {
|
||||
if norm.x < 0.0 { 0 } else { 1 }
|
||||
} else if norm.y != 0.0 {
|
||||
if norm.y < 0.0 { 2 } else { 3 }
|
||||
} else {
|
||||
if norm.z < 0.0 { 4 } else { 5 }
|
||||
};
|
||||
// let ao = 0xFFu32;
|
||||
// let light = 0xFFu32;
|
||||
// let col = Rgb::new(1.0f32, 0.0, 0.0);
|
||||
let meta = true;
|
||||
|
||||
const EXTRA_NEG_Z: f32 = 32768.0;
|
||||
|
||||
Self {
|
||||
pos_norm: 0
|
||||
| ((pos.x as u32) & 0x003F) << 0
|
||||
| ((pos.y as u32) & 0x003F) << 6
|
||||
| (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
||||
| if meta { 1 } else { 0 } << 28
|
||||
| (norm_bits & 0x7) << 29,
|
||||
/* col_light: 0
|
||||
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
||||
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
||||
| (((col.b * 255.0) as u32) & 0xFF) << 24
|
||||
| (ao >> 6) << 6
|
||||
| ((light >> 2) & 0x3F) << 0, */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Locals {
|
||||
pub fn new(shadow_mat: Mat4<f32>) -> Self {
|
||||
Self {
|
||||
|
@ -388,7 +388,7 @@ impl Renderer {
|
||||
),
|
||||
RenderError,
|
||||
> {
|
||||
let levels = 1;
|
||||
let levels = 1; //10;
|
||||
|
||||
/* let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
|
||||
>::get_channel_type();
|
||||
@ -420,7 +420,7 @@ impl Renderer {
|
||||
let shadow_tex = factory
|
||||
.create_texture(
|
||||
gfx::texture::Kind::/*CubeArray*/Cube(size / 4 /* size * 2*//*, 32 */),
|
||||
1 as gfx::texture::Level,
|
||||
levels as gfx::texture::Level,
|
||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
||||
gfx::memory::Usage::Data,
|
||||
Some(depth_stencil_cty),
|
||||
@ -431,18 +431,21 @@ impl Renderer {
|
||||
|
||||
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
||||
gfx::texture::FilterMethod::Bilinear,
|
||||
gfx::texture::WrapMode::Border,
|
||||
gfx::texture::WrapMode::Clamp, //Border,
|
||||
);
|
||||
sampler_info.comparison = Some(Comparison::LessEqual);
|
||||
sampler_info.comparison = Some(Comparison::Less);
|
||||
// sampler_info.lod_bias = (-3.0).into();
|
||||
// sampler_info.lod_range = (1.into(), (levels - 1).into());
|
||||
sampler_info.border = [1.0; 4].into();
|
||||
let shadow_tex_sampler = factory.create_sampler(sampler_info);
|
||||
/* let tgt_shadow_view = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||
let tgt_shadow_view = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||
&shadow_tex,
|
||||
0,
|
||||
Some(1),
|
||||
0, // levels,
|
||||
None, // Some(1),
|
||||
gfx::texture::DepthStencilFlags::empty(),
|
||||
)?; */
|
||||
let tgt_shadow_view = factory.view_texture_as_depth_stencil_trivial(&shadow_tex)?;
|
||||
)?;
|
||||
// let tgt_shadow_view =
|
||||
// factory.view_texture_as_depth_stencil_trivial(&shadow_tex)?;
|
||||
/* let tgt_shadow_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
||||
&tgt_color_tex,
|
||||
(0, levels - 1),
|
||||
@ -879,6 +882,7 @@ impl Renderer {
|
||||
/// frame.
|
||||
pub fn render_terrain_chunk(
|
||||
&mut self,
|
||||
// model: &Model<shadow::ShadowPipeline>,
|
||||
model: &Model<terrain::TerrainPipeline>,
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<terrain::Locals>,
|
||||
@ -921,7 +925,7 @@ impl Renderer {
|
||||
/// Queue the rendering of the player silhouette in the upcoming frame.
|
||||
pub fn render_shadow(
|
||||
&mut self,
|
||||
model: &Model<terrain::TerrainPipeline>,
|
||||
model: &Model<shadow::ShadowPipeline>,
|
||||
globals: &Consts<Globals>,
|
||||
terrain_locals: &Consts<terrain::Locals>,
|
||||
locals: &Consts<shadow::Locals>,
|
||||
@ -1506,14 +1510,14 @@ fn create_shadow_pipeline<P: gfx::pso::PipelineInit>(
|
||||
// Second-depth shadow mapping: should help reduce z-fighting provided all objects
|
||||
// are "watertight" (every triangle edge is shared with at most one other
|
||||
// triangle); this *should* be true for Veloren.
|
||||
cull_face: /*gfx::state::CullFace::Nothing*/match cull_face {
|
||||
cull_face, /*gfx::state::CullFace::Nothing*//*match cull_face {
|
||||
gfx::state::CullFace::Front => gfx::state::CullFace::Back,
|
||||
gfx::state::CullFace::Back => gfx::state::CullFace::Front,
|
||||
gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing,
|
||||
},
|
||||
}*/
|
||||
method: gfx::state::RasterMethod::Fill,
|
||||
offset: None,//Some(gfx::state::Offset(4, /*10*/-10)),
|
||||
samples:None,//Some(gfx::state::MultiSample),
|
||||
offset: None, //Some(gfx::state::Offset(2, 10)),
|
||||
samples: None, // Some(gfx::state::MultiSample),
|
||||
},
|
||||
pipe,
|
||||
)?,
|
||||
|
@ -43,8 +43,8 @@ const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not
|
||||
// const NEAR_PLANE: f32 = 0.5;
|
||||
// const FAR_PLANE: f32 = 100000.0;
|
||||
|
||||
const SHADOW_NEAR: f32 = 1.0; //1.0; //0.5;//1.0; // Near plane for shadow map rendering.
|
||||
const SHADOW_FAR: f32 = 128.0; //25.0; //100000.0;//25.0; // Far plane for shadow map rendering.
|
||||
const SHADOW_NEAR: f32 = 0.25; //1.0; //0.5;//1.0; // Near plane for shadow map rendering.
|
||||
const SHADOW_FAR: f32 = 128.0; //100000.0;//128.0; //25.0; //100000.0;//25.0; // Far plane for shadow map rendering.
|
||||
|
||||
/// Above this speed is considered running
|
||||
/// Used for first person camera effects
|
||||
|
@ -2,7 +2,8 @@ use crate::{
|
||||
mesh::Meshable,
|
||||
render::{
|
||||
Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model, Renderer, Shadow,
|
||||
ShadowLocals, SpriteInstance, SpritePipeline, TerrainLocals, TerrainPipeline, Texture,
|
||||
ShadowLocals, ShadowPipeline, SpriteInstance, SpritePipeline, TerrainLocals,
|
||||
TerrainPipeline, Texture,
|
||||
},
|
||||
};
|
||||
|
||||
@ -27,10 +28,12 @@ struct TerrainChunkData {
|
||||
load_time: f32,
|
||||
opaque_model: Model<TerrainPipeline>,
|
||||
fluid_model: Option<Model<FluidPipeline>>,
|
||||
shadow_model: Model<ShadowPipeline>,
|
||||
sprite_instances: HashMap<(BlockKind, usize), Instances<SpriteInstance>>,
|
||||
locals: Consts<TerrainLocals>,
|
||||
|
||||
visible: bool,
|
||||
can_shadow: bool,
|
||||
z_bounds: (f32, f32),
|
||||
frustum_last_plane_index: u8,
|
||||
}
|
||||
@ -48,6 +51,7 @@ struct MeshWorkerResponse {
|
||||
z_bounds: (f32, f32),
|
||||
opaque_mesh: Mesh<TerrainPipeline>,
|
||||
fluid_mesh: Mesh<FluidPipeline>,
|
||||
shadow_mesh: Mesh<ShadowPipeline>,
|
||||
sprite_instances: HashMap<(BlockKind, usize), Vec<SpriteInstance>>,
|
||||
started_tick: u64,
|
||||
}
|
||||
@ -254,12 +258,13 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
||||
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
|
||||
range: Aabb<i32>,
|
||||
) -> MeshWorkerResponse {
|
||||
let (opaque_mesh, fluid_mesh) = volume.generate_mesh(range);
|
||||
let (opaque_mesh, fluid_mesh, shadow_mesh) = volume.generate_mesh(range);
|
||||
MeshWorkerResponse {
|
||||
pos,
|
||||
z_bounds,
|
||||
opaque_mesh,
|
||||
fluid_mesh,
|
||||
shadow_mesh,
|
||||
// Extract sprite locations from volume
|
||||
sprite_instances: {
|
||||
let mut instances = HashMap::new();
|
||||
@ -2106,6 +2111,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
} else {
|
||||
None
|
||||
},
|
||||
shadow_model: renderer
|
||||
.create_model(&response.shadow_mesh)
|
||||
.expect("Failed to upload chunk mesh to the GPU!"),
|
||||
sprite_instances: response
|
||||
.sprite_instances
|
||||
.into_iter()
|
||||
@ -2130,6 +2138,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
}])
|
||||
.expect("Failed to upload chunk locals to the GPU!"),
|
||||
visible: false,
|
||||
can_shadow: false,
|
||||
z_bounds: response.z_bounds,
|
||||
frustum_last_plane_index: 0,
|
||||
});
|
||||
@ -2155,8 +2164,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// Limit focus_pos to chunk bounds and ensure the chunk is within the fog
|
||||
// boundary
|
||||
let nearest_in_chunk = Vec2::from(focus_pos).clamped(chunk_pos, chunk_pos + chunk_sz);
|
||||
let in_range = Vec2::<f32>::from(focus_pos).distance_squared(nearest_in_chunk)
|
||||
< loaded_distance.powf(2.0);
|
||||
let distance_2 = Vec2::<f32>::from(focus_pos).distance_squared(nearest_in_chunk);
|
||||
let in_range = distance_2 < loaded_distance.powf(2.0);
|
||||
|
||||
if !in_range {
|
||||
chunk.visible = in_range;
|
||||
@ -2176,6 +2185,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
|
||||
chunk.frustum_last_plane_index = last_plane_index;
|
||||
chunk.visible = in_frustum;
|
||||
// FIXME: Hack that only works when only the lantern casts point shadows
|
||||
// (and hardcodes the shadow distance). Should ideally exist per-light, too.
|
||||
chunk.can_shadow = distance_2 < (128.0 * 128.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2207,11 +2219,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
.take(self.chunks.len());
|
||||
|
||||
// Shadows
|
||||
// let mut shadow_vertex_count = 0;
|
||||
for (_, chunk) in chunk_iter.clone() {
|
||||
/* if chunk.visible */
|
||||
{
|
||||
if chunk.can_shadow {
|
||||
// shadow_vertex_count += chunk.shadow_model.vertex_range.len();
|
||||
renderer.render_shadow(
|
||||
&chunk.opaque_model,
|
||||
&chunk.shadow_model,
|
||||
globals,
|
||||
&chunk.locals,
|
||||
shadow_mats,
|
||||
@ -2227,10 +2240,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
renderer.flush_shadows();
|
||||
|
||||
// Terrain
|
||||
// let mut terrain_vertex_count = 0;
|
||||
for (_, chunk) in chunk_iter {
|
||||
// terrain_vertex_count += chunk.opaque_model.vertex_range.len();
|
||||
if chunk.visible {
|
||||
renderer.render_terrain_chunk(
|
||||
&chunk.opaque_model,
|
||||
// &chunk.shadow_model,
|
||||
globals,
|
||||
&chunk.locals,
|
||||
lights,
|
||||
@ -2240,6 +2256,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
);
|
||||
}
|
||||
}
|
||||
// println!("Vertex count (shadow / terrain / ratio): {:?} / {:?} / {:?}", shadow_vertex_count, terrain_vertex_count, shadow_vertex_count as f64 / terrain_vertex_count as f64);
|
||||
}
|
||||
|
||||
pub fn render_translucent(
|
||||
|
Loading…
Reference in New Issue
Block a user