Copying terrain pipeline and shaders for fluids

This commit is contained in:
Luc Fauvel 2019-08-05 22:50:49 -04:00 committed by Joshua Barretto
parent 910e0aed2a
commit 4a29900914
6 changed files with 169 additions and 1 deletions

View File

@ -0,0 +1,30 @@
#version 330 core
#include <globals.glsl>
in vec3 f_pos;
flat in vec3 f_norm;
in vec3 f_col;
in float f_light;
in float f_opac;
layout (std140)
uniform u_locals {
vec3 model_offs;
};
out vec4 tgt_color;
#include <sky.glsl>
#include <light.glsl>
void main() {
vec3 light = get_sun_diffuse(f_norm, time_of_day.x) * f_light + light_at(f_pos, f_norm);
vec3 surf_color = f_col * light;
float fog_level = fog(f_pos.xy, focus_pos.xy);
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x);
vec3 color = mix(surf_color, fog_color, fog_level);
tgt_color = vec4(color, f_opac);
}

View File

@ -0,0 +1,49 @@
#version 330 core
#include <globals.glsl>
in uint v_pos_norm;
in uint v_col_light;
layout (std140)
uniform u_locals {
vec3 model_offs;
};
out vec3 f_pos;
flat out vec3 f_norm;
out vec3 f_col;
out float f_light;
// First 3 normals are negative, next 3 are positive
vec3 normals[6] = vec3[]( vec3(-1,0,0), vec3(0,-1,0), vec3(0,0,-1), vec3(1,0,0), vec3(0,1,0), vec3(0,0,1) );
void main() {
f_pos = vec3(
float((v_pos_norm >> 0) & 0x00FFu),
float((v_pos_norm >> 8) & 0x00FFu),
float((v_pos_norm >> 16) & 0x1FFFu)
) + model_offs;
// TODO: last 3 bits in v_pos_norm should be a number between 0 and 5, rather than 0-2 and a direction.
uint norm_axis = (v_pos_norm >> 30) & 0x3u;
// Increase array access by 3 to access positive values
uint norm_dir = ((v_pos_norm >> 29) & 0x1u) * 3u;
// Use an array to avoid conditional branching
f_norm = normals[norm_axis + norm_dir];
f_col = vec3(
float((v_col_light >> 8) & 0xFFu),
float((v_col_light >> 16) & 0xFFu),
float((v_col_light >> 24) & 0xFFu)
) / 200.0;
f_light = float(v_col_light & 0xFFu) / 255.0;
gl_Position =
proj_mat *
view_mat *
vec4(f_pos, 1);
}

View File

@ -22,6 +22,7 @@ pub use self::{
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
Mode as UiMode, UiPipeline,
},
fluid::{Locals as FluidLocals, FluidPipeline},
Globals, Light,
},
renderer::{Renderer, TgtColorFmt, TgtDepthFmt, WinColorFmt, WinDepthFmt},

View File

@ -0,0 +1,78 @@
use super::{
super::{Pipeline, TgtColorFmt, TgtDepthFmt},
Globals, Light,
};
use gfx::{
self,
gfx_constant_struct_meta,
// Macros
gfx_defines,
gfx_impl_struct_meta,
gfx_pipeline,
gfx_pipeline_inner,
gfx_vertex_struct_meta,
};
use std::ops::Mul;
use vek::*;
gfx_defines! {
vertex Vertex {
pos_norm: u32 = "v_pos_norm",
col_light: u32 = "v_col_light",
}
constant Locals {
model_offs: [f32; 3] = "model_offs",
}
pipeline pipe {
vbuf: gfx::VertexBuffer<Vertex> = (),
locals: gfx::ConstantBuffer<Locals> = "u_locals",
globals: gfx::ConstantBuffer<Globals> = "u_globals",
lights: gfx::ConstantBuffer<Light> = "u_lights",
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
}
}
impl Vertex {
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>, light: f32, opac: f32) -> Self {
let (norm_axis, norm_dir) = norm
.as_slice()
.into_iter()
.enumerate()
.find(|(_i, e)| **e != 0.0)
.unwrap_or((0, &1.0));
let norm_bits = (norm_axis << 1) | if *norm_dir > 0.0 { 1 } else { 0 };
Self {
pos_norm: 0
| ((pos.x as u32) & 0x00FF) << 0
| ((pos.y as u32) & 0x00FF) << 8
| ((pos.z.max(0.0).min((1 << 13) as f32) as u32) & 0x1FFF) << 16
| ((norm_bits as u32) & 0x7) << 29,
col_light: 0
| ((col.r.mul(200.0) as u32) & 0xFF) << 8
| ((col.g.mul(200.0) as u32) & 0xFF) << 16
| ((col.b.mul(200.0) as u32) & 0xFF) << 24
| ((light.mul(255.0) as u32) & 0xFF) << 0
| ((opac.mul(0.4) as u32) & 0xFF) << 0,
}
}
}
impl Locals {
pub fn default() -> Self {
Self {
model_offs: [0.0; 3],
}
}
}
pub struct FluidPipeline;
impl Pipeline for FluidPipeline {
type Vertex = Vertex;
}

View File

@ -3,6 +3,7 @@ pub mod postprocess;
pub mod skybox;
pub mod terrain;
pub mod ui;
pub mod fluid;
use super::util::arr_to_mat;
use gfx::{

View File

@ -3,7 +3,7 @@ use super::{
gfx_backend,
mesh::Mesh,
model::{DynamicModel, Model},
pipelines::{figure, postprocess, skybox, terrain, ui, Globals, Light},
pipelines::{figure, postprocess, skybox, terrain, ui, Globals, Light, fluid},
texture::Texture,
Pipeline, RenderError,
};
@ -83,6 +83,15 @@ impl Renderer {
let (skybox_pipeline, figure_pipeline, terrain_pipeline, ui_pipeline, postprocess_pipeline) =
create_pipelines(&mut factory, &mut shader_reload_indicator)?;
// Construct a pipeline for rendering fluids
let fluid_pipeline = create_pipeline(
&mut factory,
fluid::pipe::new(),
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/shaders/fluid.vert")),
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/shaders/fluid.frag")),
&include_ctx,
)?;
let dims = win_color_view.get_dimensions();
let (tgt_color_view, tgt_depth_view, tgt_color_res) =
Self::create_rt_views(&mut factory, (dims.0, dims.1))?;