diff --git a/shaders/pumpkin-frag.glsl b/shaders/pumpkin-frag.glsl index bb9f203..bc381b3 100644 --- a/shaders/pumpkin-frag.glsl +++ b/shaders/pumpkin-frag.glsl @@ -10,16 +10,17 @@ varying lowp vec3 vary_color; varying lowp vec3 vary_normal; varying mediump vec2 vary_uv; varying lowp vec3 vary_object_space_light; +varying lowp vec3 vary_object_space_sky; void main (void) { lowp vec3 normal = normalize (vary_normal); lowp vec3 albedo = vary_color * max (uni_min_albedo, texture2D (uni_texture, vary_uv).rgb); - lowp vec3 sky_color = pow (vec3 (42.0, 52.0, 109.0) / vec3 (255.0), vec3 (2.0)); + lowp vec3 sky_color = pow (vec3 (89.0, 125.0, 206.0) / vec3 (255.0), vec3 (2.0)); lowp float sun_factor = dot (normal, vary_object_space_light); - lowp float sky_factor = normal.z; + lowp float sky_factor = dot (normal, vary_object_space_sky); lowp vec3 sun = max (sun_factor, 0.0) * (vec3 (1.0) - sky_color); lowp vec3 sky = (sky_factor * 0.5 + 0.5) * sky_color; diff --git a/shaders/pumpkin-vert.glsl b/shaders/pumpkin-vert.glsl index 6d99e4d..5b2abb2 100644 --- a/shaders/pumpkin-vert.glsl +++ b/shaders/pumpkin-vert.glsl @@ -4,6 +4,7 @@ #line 0 uniform highp mat4 uni_mvp; uniform lowp vec3 uni_albedo; +uniform lowp vec3 uni_object_space_sky; uniform lowp vec3 uni_object_space_light; attribute highp vec4 attr_pos; @@ -14,6 +15,7 @@ varying lowp vec3 vary_color; varying lowp vec3 vary_normal; varying mediump vec2 vary_uv; varying lowp vec3 vary_object_space_light; +varying lowp vec3 vary_object_space_sky; void main (void) { vary_uv = attr_uv; @@ -21,6 +23,7 @@ void main (void) { vary_normal = attr_normal; vary_color = uni_albedo * uni_albedo; vary_object_space_light = normalize (uni_object_space_light); + vary_object_space_sky = normalize (uni_object_space_sky); gl_Position = uni_mvp * attr_pos; } diff --git a/shaders/shadow-frag.glsl b/shaders/shadow-frag.glsl index 8b80183..25c0684 100644 --- a/shaders/shadow-frag.glsl +++ b/shaders/shadow-frag.glsl @@ -3,18 +3,6 @@ #define highp #line 0 -uniform lowp float uni_dither_phase; - void main (void) { - lowp float dither_phase = 0.0; - 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_phase == 10.0) { - dither = 0.0; - } - - gl_FragColor = vec4 (vec3 (20.0, 12.0, 28.0) / vec3 (255.0), dither); + gl_FragColor = vec4 (0.0, 0.0, 0.0, 1.0); } diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index e7a1c42..ce52924 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -104,6 +104,7 @@ use iota::iota; iota! { pub const MVP: u32 = iota; , OBJECT_SPACE_LIGHT + , OBJECT_SPACE_SKY , ALBEDO , MIN_ALBEDO , MIN_BRIGHT @@ -112,6 +113,14 @@ iota! { } } +fn make_object_space_vec (inverse_model_mat: &Mat4, world_space_vec: &Vec3) +-> Vec3 +{ + let v = world_space_vec; + let v4 = *inverse_model_mat * Vec4::from ((v.x (), v.y (), v.z (), 0.0)); + Vec3::from ((v4.x (), v4.y (), v4.z ())) +} + fn main () { let sdl_context = sdl2::init ().unwrap (); let video_subsystem = sdl_context.video ().unwrap (); @@ -159,6 +168,7 @@ fn main () { vec! [ (MVP, "mvp"), (OBJECT_SPACE_LIGHT, "object_space_light"), + (OBJECT_SPACE_SKY, "object_space_sky"), (ALBEDO, "albedo"), (MIN_ALBEDO, "min_albedo"), (MIN_BRIGHT, "min_bright"), @@ -212,7 +222,7 @@ fn main () { let renderable_sky = RenderableModel::from_iqm (&sky_model); - let (renderable_pitch, pitch_colors) = { + let (renderable_pitch, pitch_colors, grass_index) = { let data = load_small_file ("pitch.iqm", 1024 * 1024); let model = Model::from_slice (&data); @@ -238,8 +248,12 @@ fn main () { ("Grass", (52.0, 101.0, 36.0)), ].into_iter ()); + let mut grass_index = None; let colors: Vec <_> = (0..model.meshes.len ()).map (|i| { let name = str::from_utf8 (model.get_mesh_name (i)).unwrap (); + if name == "Grass" { + grass_index = Some (i); + } match color_lookup.get (name) { Some (t) => color_from_255 (*t), @@ -247,7 +261,7 @@ fn main () { } }).collect (); - (RenderableModel::from_iqm (&model), colors) + (RenderableModel::from_iqm (&model), colors, grass_index.unwrap ()) }; glezz::enable_vertex_attrib_array (attrs ["pos"]); @@ -306,16 +320,17 @@ fn main () { 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 light = Vec3::from ((0.0, 0.0, 0.0)).normalize (); 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 ((255.0, 255.0, 255.0)); - let off_white = color_from_255 ((222.0, 238.0, 214.0)); + let _off_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)); + let _off_black = color_from_255 ((20.0, 12.0, 28.0)); glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32); - glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); + glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT); glezz::enable (gl::CULL_FACE); let pumpkin_model_mat = @@ -330,18 +345,22 @@ fn main () { use uniforms::*; shader_program.use_program (); + glezz::disable (gl::STENCIL_TEST); glezz::front_face (gl::CW); - glezz::disable (gl::BLEND); - - glezz::uniform_3fv (unis [&MIN_BRIGHT], &black); - glezz::uniform_3fv (unis [&MIN_ALBEDO], &white); let mvp = view_mat * pumpkin_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); - let object_space_light = pumpkin_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 inverse_pumpkin = pumpkin_model_mat.inverse (); + + let object_space_light = make_object_space_vec (&inverse_pumpkin, &light); + + let object_space_sky = make_object_space_vec (&inverse_pumpkin, &Vec3::from ((0.0, 0.0, 1.0))); + + glezz::uniform_3fv (unis [&MIN_BRIGHT], &black); + glezz::uniform_3fv (unis [&MIN_ALBEDO], &white); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); + glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky); { glezz::uniform_3fv (unis [&ALBEDO], &orange); @@ -354,9 +373,10 @@ fn main () { let mvp = view_mat * world_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); + for (i, color) in pitch_colors.iter ().enumerate ().take (renderable_pitch.num_meshes ()) { - for i in 0..renderable_pitch.num_meshes () { - glezz::uniform_3fv (unis [&ALBEDO], &pitch_colors [i]); + glezz::uniform_3fv (unis [&ALBEDO], color); + if i != grass_index { renderable_pitch.draw (&attrs, i); } } @@ -373,17 +393,16 @@ fn main () { renderable_sky.draw (&attrs, 0); } + glezz::enable (gl::STENCIL_TEST); + unsafe { + gl::StencilFunc (gl::ALWAYS, 1, 1); + gl::StencilOp (gl::KEEP, gl::KEEP, gl::REPLACE); + + gl::ColorMask (0, 0, 0, 0); + gl::DepthMask (0); + gl::StencilMask (1); + } 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_3fv (shadow_unis [&OBJECT_SPACE_LIGHT], &object_space_light); let view_mat = view_mat * shadow_mat; @@ -398,11 +417,47 @@ fn main () { let mvp = view_mat * world_model_mat; glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp); - { - for i in 0..renderable_pitch.num_meshes () { + for i in 0..renderable_pitch.num_meshes () { + if i != grass_index { renderable_pitch.draw (&shadow_attrs, i); } } + + unsafe { + gl::ColorMask (255, 255, 255, 255); + gl::DepthMask (1); + } + shader_program.use_program (); + glezz::front_face (gl::CW); + + let inverse_pumpkin = pumpkin_model_mat.inverse (); + + let object_space_light = make_object_space_vec (&inverse_pumpkin, &light); + + let object_space_sky = make_object_space_vec (&inverse_pumpkin, &Vec3::from ((0.0, 0.0, 1.0))); + + glezz::uniform_3fv (unis [&MIN_BRIGHT], &black); + glezz::uniform_3fv (unis [&MIN_ALBEDO], &white); + glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky); + + let mvp = view_mat * world_model_mat; + glezz::uniform_matrix_4fv (unis [&MVP], &mvp); + + glezz::uniform_3fv (unis [&ALBEDO], &pitch_colors [grass_index]); + + unsafe { + gl::StencilFunc (gl::NOTEQUAL, 0, 1); + gl::StencilOp (gl::KEEP, gl::KEEP, gl::KEEP); + } + glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &Vec3::from ((0.0, 0.0, 0.0))); + renderable_pitch.draw (&attrs, grass_index); + + unsafe { + gl::StencilFunc (gl::EQUAL, 0, 1); + gl::StencilOp (gl::KEEP, gl::KEEP, gl::KEEP); + } + glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); + renderable_pitch.draw (&attrs, grass_index); } window.gl_swap_window ();