implemented post-process shaders

Commit 12fd5e5df509 · silentevermore · 2026-10-08 17:49 +0300

Changeset
12fd5e5df509dffc1f52251d4e7c68ff268ae57b

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/shaders/frag.glsl b/shaders/frag.glsl
--- a/shaders/frag.glsl
+++ b/shaders/frag.glsl
@@ -4,19 +4,63 @@
 in vec3 fragNormal;
 in vec2 fragTexCoord;
 
-out vec4 finalColor;
-
 uniform sampler2D texture0;
 
 uniform float ambient;
-uniform vec3 lightPosition;
+uniform vec3 lightDir;
 uniform vec3 lightColor;
 
+out vec4 finalColor;
+
+const mat4 bayerMatrix = mat4(
+		0.0/16.0, 12.0/16.0,  3.0/16.0, 15.0/16.0,
+		8.0/16.0,  4.0/16.0, 11.0/16.0,  7.0/16.0,
+		2.0/16.0, 14.0/16.0,  1.0/16.0, 13.0/16.0,
+		10.0/16.0,  6.0/16.0,  9.0/16.0,  5.0/16.0
+);
+
+float pixel_size = 1.0;
+float contrast = 1.5;
+float levels = 32.0;
+vec2 gamma = vec2(0.5, 1.5);
+
 void main() {
-    vec3 baseColor = texture(texture0, fragTexCoord).rgb;
-    vec3 lightDir = normalize(lightPosition - fragPosition);
-    float diffuse = max(dot(fragNormal, lightDir), 0.0);
-    vec3 color = baseColor * (ambient + diffuse * lightColor);
+	// pixelization
+	vec2 texsize = textureSize(texture0, 0);
+	vec2 pixel_c = texsize / (pixel_size * 2.0);
+	vec2 pixel_uv = floor(fragTexCoord * pixel_c) / pixel_c;
+
+	vec2 p = pixel_uv - vec2(0.5);
+	float r = length(p);
+	vec2 dist = p / (1.0 + 0.25 * r);
+	pixel_uv = dist * 0.5 + vec2(0.5);
+
+	vec4 color = texture(texture0, pixel_uv);
 
-    finalColor = vec4(color, 1.0);
+	// dither
+	{
+		float lum = dot(color.rgb, vec3(0.299, 0.587, 0.114));
+		int x = int(mod(gl_FragCoord.x, 4.0));
+		int y = int(mod(gl_FragCoord.y, 4.0));
+		float thres = bayerMatrix[x][y];
+		color.rgb = (lum > thres) ? color.rgb * 2.0 : vec3(0.0);
+	}
+
+	// gamma + posterization
+	color.rgb = pow(color.rgb, vec3(gamma.x));
+	{
+		float gray = max(color.r, max(color.g, color.b));
+		float low = floor(gray * levels) / levels;
+		float high = ceil(gray * levels) / levels;
+		float level = abs(low - gray) < abs(high - gray) ? low : high;
+		float adj = level / gray;
+		color.rgb *= adj;
+	}
+	color.rgb = pow(color.rgb, vec3(gamma.y));
+
+	// vignette
+	float diff = length(fragTexCoord - vec2(0.5));
+	color.rgb *= 1.0 - diff;
+
+	finalColor = color;
 }
diff --git a/src/main.rs b/src/main.rs
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,4 @@
-use sola_raylib as rlb;
+use sola_raylib::{self as rlb, ffi::Rectangle};
 use rlb::{
     prelude::*,
     core::*,
@@ -26,7 +26,7 @@
     );
 
     // shader stuff
-    let mut shader = rl.load_shader(&rl_thd, Some("shaders/vert.glsl"), Some("shaders/frag.glsl")).unwrap();
+    let mut shader = rl.load_shader(&rl_thd, None, Some("shaders/frag.glsl")).unwrap();
 
     let ambient_pos = shader.get_shader_location("ambient");
     let light_pos = shader.get_shader_location("lightPosition");
@@ -40,19 +40,14 @@
 
     let suzanne = rl.load_model(&rl_thd, "res/obj/suzanne.obj").unwrap();
 
-    // i was forced to do this...
-    for i in 0..suzanne.materialCount {
-        unsafe {
-            (*suzanne.materials.add(i as usize)).shader = shader.clone();
-        }
-    }
-
     rl.hide_cursor();
     rl.disable_cursor();
 
     while !rl.window_should_close() {
+        let mut rend_tex = rl.load_render_texture(&rl_thd, rl.get_render_width() as u32, rl.get_render_height() as u32).unwrap();
+
         // update shader data
-        lighting_data.light_dir = Vector3::new(0.6, 1.0, 0.6);
+        lighting_data.light_dir = Vector3::new(1.0, 1.0, 1.0);
         shader.set_shader_value(
             ambient_pos,
             lighting_data.ambient
@@ -68,16 +63,21 @@
 
         rl.update_camera(&mut cam, CameraMode::CAMERA_FREE);
         rl.draw(&rl_thd, |mut d| {
-            d.clear_background(Color::BLACK);
-            d.draw_mode3D(cam, |mut d3, _| {
-                // main rendering pipeline
-                d3.draw_grid(100, 1.0);
-
-                // shaded pipeline
-                d3.draw_shader_mode(&mut shader, |mut shd| {
-                    shd.draw_model(&suzanne, Vector3::zero(), 1.0, Color::WHITE);
+            d.draw_texture_mode(&rl_thd, &mut rend_tex, |mut tx| {
+                tx.clear_background(Color::new(30, 30, 30, 255));
+                tx.draw_mode3D(cam, |mut d3, _| {
+                    d3.draw_grid(100, 1.0);
+                    d3.draw_model(&suzanne, Vector3::zero(), 1.0, Color::BLUEVIOLET);
                 });
             });
+            d.draw_shader_mode(&mut shader, |mut shd| {
+                shd.draw_texture_rec(&rend_tex, Rectangle{
+                    x: 0.0,
+                    y: 0.0,
+                    width: rend_tex.texture().width as f32,
+                    height: -rend_tex.texture().height as f32
+                }, Vector2::zero(), Color::WHITE);
+            });
         });
     }
 }