Made some awful shadows

main
_ 2020-03-07 03:36:05 +00:00
parent e5b6d7839a
commit 18da547bc5
9 changed files with 196 additions and 44 deletions

1
Cargo.lock generated
View File

@ -201,6 +201,7 @@ dependencies = [
"iota 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@ -19,4 +19,5 @@ iota = "0.2.1"
nom = "5.1.0"
png = "0.15.3"
rand = "0.6.5"
sdl2 = "0.32.2"

View File

@ -3,24 +3,26 @@
#define highp
#line 0
uniform lowp sampler2D uni_texture;
uniform lowp vec3 uni_albedo;
uniform lowp vec3 uni_object_space_light;
uniform lowp vec3 uni_min_bright;
uniform lowp vec3 uni_min_albedo;
//varying lowp vec4 vary_color;
varying lowp vec3 vary_color;
varying lowp vec3 vary_normal;
varying mediump vec2 vary_uv;
void main (void) {
lowp vec3 normal = normalize (vary_normal);
lowp vec3 albedo = uni_albedo * max (uni_min_albedo, texture2D (uni_texture, vary_uv).rgb);
//lowp vec3 albedo = vec3 (vary_uv, 0.0);
lowp vec3 albedo = vary_color * max (uni_min_albedo, texture2D (uni_texture, vary_uv).rgb);
lowp float diffuse_factor = dot (normal, uni_object_space_light);
lowp vec3 sun = max (diffuse_factor, 0.0) * vec3 (0.95, 0.9, 0.85);
lowp vec3 sky = (diffuse_factor * 0.45 + 0.55) * vec3 (0.05, 0.1, 0.15);
lowp vec3 sky_color = pow (vec3 (42.0, 52.0, 109.0) / vec3 (255.0), vec3 (2.0));
lowp float sun_factor = dot (normal, uni_object_space_light);
lowp float sky_factor = normal.z;
lowp vec3 sun = max (sun_factor, 0.0) * (vec3 (1.0) - sky_color);
lowp vec3 sky = (sky_factor * 0.5 + 0.5) * sky_color;
lowp vec3 diffuse_color = albedo * max (uni_min_bright, (sun + sky));
gl_FragColor = vec4 (sqrt (diffuse_color), 1.0);

View File

@ -3,20 +3,21 @@
#define highp
#line 0
uniform highp mat4 uni_mvp;
uniform lowp vec3 uni_albedo;
attribute highp vec4 attr_pos;
attribute mediump vec2 attr_uv;
attribute lowp vec3 attr_normal;
varying mediump vec2 vary_uv;
varying lowp vec3 vary_color;
varying lowp vec3 vary_normal;
varying mediump vec2 vary_uv;
void main (void) {
vary_uv = attr_uv;
lowp vec4 light_color = vec4 (1.0);
vary_normal = attr_normal;
vary_color = uni_albedo * uni_albedo;
gl_Position = uni_mvp * attr_pos;
}

20
shaders/shadow-frag.glsl Normal file
View File

@ -0,0 +1,20 @@
#define lowp
#define mediump
#define highp
#line 0
uniform lowp float uni_dither_phase;
void main (void) {
lowp float dither_phase = uni_dither_phase;
dither_phase += 4.0 * mod (gl_FragCoord.y + 0.5, 4.0);
dither_phase += mod (gl_FragCoord.x + 0.5, 4.0);
dither_phase = mod (dither_phase, 16.0);
lowp float dither = 1.0;
if (dither_phase == 0.0) {
dither = 0.0;
}
gl_FragColor = vec4 (vec3 (20.0, 12.0, 28.0) / vec3 (255.0), dither);
}

13
shaders/shadow-vert.glsl Normal file
View File

@ -0,0 +1,13 @@
#define lowp
#define mediump
#define highp
#line 0
uniform highp mat4 uni_mvp;
attribute highp vec4 attr_pos;
void main (void) {
highp float depth_adjust = -1.0 / 512.0;
gl_Position = uni_mvp * attr_pos + vec4 (0.0, 0.0, depth_adjust, 0.0);
}

View File

@ -1,4 +1,5 @@
use glam::{Mat4, Vec3, Vec4};
use rand::Rng;
use sdl2::event::Event;
use sdl2::keyboard::{Keycode, Scancode};
@ -107,6 +108,7 @@ iota! {
, MIN_ALBEDO
, MIN_BRIGHT
, TEXTURE
, DITHER_PHASE
}
}
@ -138,10 +140,19 @@ fn main () {
// And I'm still not actually checking errors - Just checkmarking
// that I know where they are.
let vert_shader = ShaderObject::from_file (gl::VERTEX_SHADER, "shaders/pumpkin-vert.glsl").unwrap ();
let frag_shader = ShaderObject::from_file (gl::FRAGMENT_SHADER, "shaders/pumpkin-frag.glsl").unwrap ();
let shader_program = {
let vert_shader = ShaderObject::from_file (gl::VERTEX_SHADER, "shaders/pumpkin-vert.glsl").unwrap ();
let frag_shader = ShaderObject::from_file (gl::FRAGMENT_SHADER, "shaders/pumpkin-frag.glsl").unwrap ();
ShaderProgram::new (&vert_shader, &frag_shader).unwrap ()
};
let shader_program = ShaderProgram::new (&vert_shader, &frag_shader).unwrap ();
let shadow_shader = {
let vert_shader = ShaderObject::from_file (gl::VERTEX_SHADER, "shaders/shadow-vert.glsl").unwrap ();
let frag_shader = ShaderObject::from_file (gl::FRAGMENT_SHADER, "shaders/shadow-frag.glsl").unwrap ();
ShaderProgram::new (&vert_shader, &frag_shader).unwrap ()
};
let uni_lookup: HashMap <_, &str> = HashMap::from_iter ({
use uniforms::*;
@ -152,15 +163,29 @@ fn main () {
(MIN_ALBEDO, "min_albedo"),
(MIN_BRIGHT, "min_bright"),
(TEXTURE, "texture"),
(DITHER_PHASE, "dither_phase"),
].into_iter ()
});
let unis = shader_program.get_uniform_locations (uni_lookup.values ().copied ());
let unis = {
let unis = shader_program.get_uniform_locations (uni_lookup.values ().copied ());
let unis: HashMap <u32, i32> = HashMap::from_iter (
uni_lookup.iter ()
.map (|(key, name)| (*key, *unis.get (*name).unwrap ()))
);
unis
};
let unis: HashMap <u32, i32> = HashMap::from_iter (
uni_lookup.iter ()
.map (|(key, name)| (*key, *unis.get (*name).unwrap ()))
);
let shadow_unis = {
let unis = shadow_shader.get_uniform_locations (uni_lookup.values ().copied ());
let unis: HashMap <u32, i32> = HashMap::from_iter (
uni_lookup.iter ()
.map (|(key, name)| (*key, *unis.get (*name).unwrap ()))
);
unis
};
let attrs = shader_program.get_attribute_locations (vec! [
"pos",
@ -168,6 +193,12 @@ fn main () {
"normal",
].into_iter ());
let shadow_attrs = shadow_shader.get_attribute_locations (vec! [
"pos",
"uv",
"normal",
].into_iter ());
let texture = Texture::from_file ("sky.png");
texture.bind ();
@ -181,17 +212,42 @@ fn main () {
let renderable_sky = RenderableModel::from_iqm (&sky_model);
let renderable_pitch = {
let (renderable_pitch, pitch_colors) = {
let data = load_small_file ("pitch.iqm", 1024 * 1024);
let model = Model::from_slice (&data);
for i in 0..model.meshes.len () {
let silver = (255.0, 255.0, 255.0);
let wood = (133.0, 76.0, 48.0);
let color_lookup: HashMap <&str, _> = HashMap::from_iter (vec! [
("GoalN1", silver),
("GoalN2", silver),
("GoalN3", silver),
("GoalS1", silver),
("GoalS2", silver),
("GoalS3", silver),
("TowerNW", wood),
("TowerNE", wood),
("TowerSW", wood),
("TowerSE", wood),
("Wall", wood),
("Grass", (52.0, 101.0, 36.0)),
].into_iter ());
let colors: Vec <_> = (0..model.meshes.len ()).map (|i| {
let name = str::from_utf8 (model.get_mesh_name (i)).unwrap ();
println! ("{} {}", i, name);
}
match color_lookup.get (name) {
Some (t) => color_from_255 (*t),
_ => (0.0, 0.0, 0.0).into (),
}
}).collect ();
RenderableModel::from_iqm (&model)
(RenderableModel::from_iqm (&model), colors)
};
glezz::enable_vertex_attrib_array (attrs ["pos"]);
@ -227,45 +283,57 @@ fn main () {
}
window.gl_make_current (&gl_ctx).unwrap ();
let dither_phase = rand::thread_rng ().gen_range (0, 16);
let longitude = state.azimuth.to_radians ();
let latitude = (state.altitude - 90.0).to_radians ();
let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), 1280.0 / 720.0, 0.5, 500.0);
let model_mat =
Mat4::from_translation (Vec3::from ((0.0, 0.0, -2.7 * 0.5)))
let model_mat = Mat4::identity ();
Mat4::from_translation ((0.0, 0.0, 0.0).into ())
;
let shadow_model = {
let mut mat = Mat4::identity ();
mat.set_z_axis ((0.25, 0.125, 0.0, 0.0).into ());
mat * model_mat
};
let view_mat = proj_mat *
Mat4::from_translation (Vec3::from ((0.0, 0.0, -8.0))) *
Mat4::from_rotation_x (latitude) *
Mat4::from_rotation_z (longitude)
Mat4::from_rotation_z (longitude) *
Mat4::from_translation ((0.0, 0.0, -2.7 * 0.5).into ())
;
let mvp_mat = view_mat * model_mat;
let shadow_mvp = view_mat * shadow_model;
let sky_mvp_mat = view_mat * Mat4::from_scale (Vec3::from ((16.0, 16.0, 16.0)));
let sky_mvp_mat = view_mat * Mat4::from_scale ((16.0, 16.0, 16.0).into ());
let light = Vec3::from ((2.0, 0.0, 5.0)).normalize ();
let object_space_light = model_mat.inverse () * Vec4::from ((light.x (), light.y (), light.z (), 0.0));
let object_space_light = Vec3::from ((object_space_light.x (), object_space_light.y (), object_space_light.z ()));
let orange = color_from_255 ((255.0, 154.0, 0.0));
let green = color_from_255 ((14.0, 127.0, 24.0));
let white = Vec3::from ((1.0, 1.0, 1.0));
let black = Vec3::from ((0.0, 0.0, 0.0));
let orange = orange * orange;
let green = green * green;
let orange = color_from_255 ((210.0, 125.0, 44.0));
let green = color_from_255 ((52.0, 101.0, 36.0));
let white = color_from_255 ((222.0, 238.0, 214.0));
let black = color_from_255 ((0.0, 0.0, 0.0));
let off_black = color_from_255 ((20.0, 12.0, 28.0));
glezz::clear_color (1.0f32, 1.0f32, 1.0f32, 1.0f32);
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
glezz::disable (gl::CULL_FACE);
glezz::enable (gl::CULL_FACE);
{
use uniforms::*;
shader_program.use_program ();
glezz::front_face (gl::CW);
glezz::disable (gl::BLEND);
glezz::uniform_3fv (unis [&MIN_BRIGHT], &black);
glezz::uniform_3fv (unis [&MIN_ALBEDO], &white);
@ -282,7 +350,7 @@ fn main () {
{
for i in 0..renderable_pitch.num_meshes () {
glezz::uniform_3fv (unis [&ALBEDO], &green);
glezz::uniform_3fv (unis [&ALBEDO], &pitch_colors [i]);
renderable_pitch.draw (&attrs, i);
}
}
@ -297,6 +365,30 @@ fn main () {
renderable_sky.draw (&attrs, 0);
}
shadow_shader.use_program ();
glezz::front_face (gl::CCW);
glezz::enable (gl::BLEND);
glezz::blend_func (gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
glezz::uniform_1f (shadow_unis [&DITHER_PHASE], dither_phase as f32);
glezz::uniform_3fv (shadow_unis [&MIN_BRIGHT], &black);
glezz::uniform_3fv (shadow_unis [&MIN_ALBEDO], &white);
glezz::uniform_matrix_4fv (shadow_unis [&MVP], &shadow_mvp);
glezz::uniform_3fv (shadow_unis [&OBJECT_SPACE_LIGHT], &object_space_light);
{
renderable_model.draw (&shadow_attrs, 0);
renderable_model.draw (&shadow_attrs, 1);
}
{
for i in 0..renderable_pitch.num_meshes () {
renderable_pitch.draw (&shadow_attrs, i);
}
}
}
window.gl_swap_window ();

View File

@ -26,6 +26,18 @@ pub fn enable (constant: u32) {
}
}
pub fn front_face (constant: u32) {
unsafe {
gl::FrontFace (constant);
}
}
pub fn blend_func (src: u32, dst: u32) {
unsafe {
gl::BlendFunc (src, dst);
}
}
pub fn enable_vertex_attrib_array (id: Option <u32>) {
if let Some (id) = id {
// Are safety checks really needed here?
@ -41,6 +53,12 @@ pub fn uniform_1i (uni: i32, x: i32) {
}
}
pub fn uniform_1f (uni: i32, x: f32) {
unsafe {
gl::Uniform1f (uni, x);
}
}
pub fn uniform_3fv (uni: i32, v: &Vec3) {
unsafe {
gl::Uniform3fv (uni, 1, v as *const Vec3 as *const f32);

View File

@ -119,9 +119,16 @@ impl ShaderProgram {
}
}
pub fn get_uniform_location (&self, name: &CStr) -> i32 {
pub fn use_program (&self) {
unsafe {
gl::UseProgram (self.id);
}
}
pub fn get_uniform_location (&self, name: &CStr) -> i32 {
self.use_program ();
unsafe {
gl::GetUniformLocation (self.id, name.as_ptr ())
}
}
@ -130,9 +137,7 @@ impl ShaderProgram {
-> HashMap <String, i32>
where I: Iterator <Item = &'a str>
{
unsafe {
gl::UseProgram (self.id);
}
self.use_program ();
names
.map (|name| {
@ -150,8 +155,9 @@ impl ShaderProgram {
}
pub fn get_attribute_location (&self, name: &CStr) -> i32 {
self.use_program ();
unsafe {
gl::UseProgram (self.id);
gl::GetAttribLocation (self.id, name.as_ptr ())
}
}
@ -160,9 +166,7 @@ impl ShaderProgram {
-> HashMap <String, Option <u32>>
where I: Iterator <Item = &'a str>
{
unsafe {
gl::UseProgram (self.id);
}
self.use_program ();
names
.map (|name| {