From ebb55da52cb79e40eed09aefe92af3e6c32bf00a Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Thu, 3 Oct 2019 16:25:28 +0200 Subject: [PATCH] Nice --- assets/shaders/default.frag | 50 ++++++++++++++++++++++++++++++++++--- assets/shaders/default.vert | 5 ++++ src/model/mod.rs | 35 ++++++++++++++++++-------- src/programs/viewer.rs | 1 + 4 files changed, 78 insertions(+), 13 deletions(-) diff --git a/assets/shaders/default.frag b/assets/shaders/default.frag index bdebc2f..ea753e5 100644 --- a/assets/shaders/default.frag +++ b/assets/shaders/default.frag @@ -1,31 +1,75 @@ #version 140 +#extension GL_OES_standard_derivatives : enable + + uniform sampler2D tex; uniform vec3 diffuse; in vec3 v_normal; in vec2 v_tex_coords; +in vec3 v_barycentric; +in vec4 v_position; out vec4 color; +vec4 wireframe_color; +vec4 render_color; + vec3 ambientLight = vec3(0.3,0.3,0.3); vec3 directionnalLight = normalize(vec3(10,5,7)); vec3 directionnalLightFactor = vec3(0.6,0.6,0.6); +// float edgeFactor(vec3 a){ +// vec3 d = fwidth(v_barycentric); +// vec3 a3 = smoothstep(vec3(0.0), d*1.5, v_barycentric); +// return min(min(a3.x, a3.y), a3.z); +// } + void main() { + + vec3 d = fwidth(v_barycentric); + vec3 a3 = smoothstep(vec3(0.0), 0.8 * d, v_barycentric); + float scale = (1 - min(min(a3.x, a3.y), a3.z)) / 2 + 0.5; + + wireframe_color = vec4(scale, scale, scale, 1.0); + + // float threshold = 0.1; + // vec3 d = fwidth(v_barycentric); + + // if (d.x < threshold || d.y < threshold || d.z < threshold) { + // wireframe_color = vec4(1.0, 1.0, 1.0, 1.0); + // } else { + // wireframe_color = vec4(0.5, 0.5, 0.5, 1.0); + // } + vec3 lambertComponent = dot(directionnalLight, v_normal) * directionnalLightFactor; lambertComponent = max(vec3(0.0, 0.0, 0.0), lambertComponent); vec4 factor = vec4(ambientLight + lambertComponent, 1.0); - color = factor * vec4(diffuse, 1.0) * texture(tex, v_tex_coords); + render_color = factor * vec4(diffuse, 1.0) * texture(tex, v_tex_coords); - if (color.a < 0.05) { + if (render_color.a < 0.05) { discard; } else { - color.a = 1.0; + render_color.a = 1.0; } + float z_min = 0.15; + float z_max = 0.25; + + float lambda = (v_position.z - z_min) / (z_max - z_min); + + if (lambda < 0) { + lambda = 0; + } + if (lambda > 1) { + lambda = 1; + } + + color = lambda * wireframe_color + (1 - lambda) * render_color; + } diff --git a/assets/shaders/default.vert b/assets/shaders/default.vert index b4bfb74..33e5efe 100644 --- a/assets/shaders/default.vert +++ b/assets/shaders/default.vert @@ -6,14 +6,19 @@ uniform vec3 texture_size; in vec3 vertex; in vec2 tex_coords; +in vec3 barycentric; in vec3 normal; out vec2 v_tex_coords; out vec3 v_normal; +out vec3 v_barycentric; +out vec4 v_position; void main() { v_normal = normal; + v_barycentric = barycentric; v_tex_coords = vec2(tex_coords.x * texture_size.x, tex_coords.y * texture_size.y); gl_Position = perspective * view * vec4(vertex, 1.0); + v_position = gl_Position; } diff --git a/src/model/mod.rs b/src/model/mod.rs index 15aafa4..5b4f1bb 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -23,13 +23,14 @@ use renderer::Renderer; #[derive(Copy, Clone, Debug, PartialEq)] /// A raw vertex, with its 3D coordinates, texture coordinates and normals. pub struct Vertex { - vertex: [f64; 3], - tex_coords: [f64; 2], - normal: [f64; 3], - face_color: [f64; 3], + vertex: [f64; 3], + tex_coords: [f64; 2], + normal: [f64; 3], + barycentric: [f64; 3], + face_color: [f64; 3], } -implement_vertex!(Vertex, vertex, tex_coords, normal, face_color); +implement_vertex!(Vertex, vertex, tex_coords, normal, barycentric, face_color); /// A part of a 3D model. /// @@ -534,7 +535,12 @@ impl Model { let mut vertex_buffer = vec![]; for face in part.faces() { - for &&v in &[&face.a, &face.b, &face.c] { + let v0 = vertices[face.a.vertex]; + let v1 = vertices[face.b.vertex]; + let v2 = vertices[face.c.vertex]; + let barycenter = (v0 + v1 + v2) / 3.0; + + for (index, &&v) in [&face.a, &face.b, &face.c].iter().enumerate() { let vertex = vertices[v.vertex].into(); let tex_coord = if let Some(tex_index) = v.texture_coordinate { texture_coordinates[tex_index].into() @@ -542,6 +548,14 @@ impl Model { [0.0, 0.0] }; + + let barycentric = match index { + 0 => [1.0, 0.0, 0.0], + 1 => [0.0, 1.0, 0.0], + 2 => [0.0, 0.0, 1.0], + _ => unreachable!(), + }; + let normal = if let Some(normal_index) = v.normal { normals[normal_index].into() } else { @@ -564,10 +578,11 @@ impl Model { ]; vertex_buffer.push(Vertex { - vertex: vertex, - tex_coords: tex_coord, - normal: normal, - face_color: [r, g, b], + vertex: vertex, + tex_coords: tex_coord, + normal: normal, + barycentric: barycentric, + face_color: [r, g, b], }); } } diff --git a/src/programs/viewer.rs b/src/programs/viewer.rs index 389075f..aad928e 100644 --- a/src/programs/viewer.rs +++ b/src/programs/viewer.rs @@ -131,6 +131,7 @@ fn main() { let context = glutin::ContextBuilder::new().with_depth_buffer(24); let display = Display::new(window, context, &events_loop).unwrap(); let mut renderer = Renderer::new(display); + renderer.set_clear_color(1.0, 1.0, 1.0, 1.0); let mut scene = Scene::new(); let mut before;