post_processing/
post_processing.rs1use macroquad::prelude::*;
2
3#[macroquad::main("Post processing")]
4async fn main() {
5 let render_target = render_target(320, 150);
6 render_target.texture.set_filter(FilterMode::Nearest);
7
8 let material = load_material(
9 ShaderSource::Glsl {
10 vertex: CRT_VERTEX_SHADER,
11 fragment: CRT_FRAGMENT_SHADER,
12 },
13 Default::default(),
14 )
15 .unwrap();
16
17 loop {
18 set_camera(&Camera2D {
22 zoom: vec2(0.01, 0.01),
23 target: vec2(0.0, 0.0),
24 render_target: Some(render_target.clone()),
25 ..Default::default()
26 });
27
28 clear_background(LIGHTGRAY);
29 draw_line(-30.0, 45.0, 30.0, 45.0, 3.0, BLUE);
30 draw_circle(-45.0, -35.0, 20.0, YELLOW);
31 draw_circle(45.0, -35.0, 20.0, GREEN);
32
33 set_default_camera();
36
37 clear_background(WHITE);
38 gl_use_material(&material);
39 draw_texture_ex(
40 &render_target.texture,
41 0.,
42 0.,
43 WHITE,
44 DrawTextureParams {
45 dest_size: Some(vec2(screen_width(), screen_height())),
46 ..Default::default()
47 },
48 );
49 gl_use_default_material();
50
51 next_frame().await;
52 }
53}
54
55const CRT_FRAGMENT_SHADER: &'static str = r#"#version 100
56precision lowp float;
57
58varying vec4 color;
59varying vec2 uv;
60
61uniform sampler2D Texture;
62
63// https://www.shadertoy.com/view/XtlSD7
64
65vec2 CRTCurveUV(vec2 uv)
66{
67 uv = uv * 2.0 - 1.0;
68 vec2 offset = abs( uv.yx ) / vec2( 6.0, 4.0 );
69 uv = uv + uv * offset * offset;
70 uv = uv * 0.5 + 0.5;
71 return uv;
72}
73
74void DrawVignette( inout vec3 color, vec2 uv )
75{
76 float vignette = uv.x * uv.y * ( 1.0 - uv.x ) * ( 1.0 - uv.y );
77 vignette = clamp( pow( 16.0 * vignette, 0.3 ), 0.0, 1.0 );
78 color *= vignette;
79}
80
81
82void DrawScanline( inout vec3 color, vec2 uv )
83{
84 float iTime = 0.1;
85 float scanline = clamp( 0.95 + 0.05 * cos( 3.14 * ( uv.y + 0.008 * iTime ) * 240.0 * 1.0 ), 0.0, 1.0 );
86 float grille = 0.85 + 0.15 * clamp( 1.5 * cos( 3.14 * uv.x * 640.0 * 1.0 ), 0.0, 1.0 );
87 color *= scanline * grille * 1.2;
88}
89
90void main() {
91 vec2 crtUV = CRTCurveUV(uv);
92 vec3 res = texture2D(Texture, uv).rgb * color.rgb;
93 if (crtUV.x < 0.0 || crtUV.x > 1.0 || crtUV.y < 0.0 || crtUV.y > 1.0)
94 {
95 res = vec3(0.0, 0.0, 0.0);
96 }
97 DrawVignette(res, crtUV);
98 DrawScanline(res, uv);
99 gl_FragColor = vec4(res, 1.0);
100
101}
102"#;
103
104const CRT_VERTEX_SHADER: &'static str = "#version 100
105attribute vec3 position;
106attribute vec2 texcoord;
107attribute vec4 color0;
108
109varying lowp vec2 uv;
110varying lowp vec4 color;
111
112uniform mat4 Model;
113uniform mat4 Projection;
114
115void main() {
116 gl_Position = Projection * Model * vec4(position, 1);
117 color = color0 / 255.0;
118 uv = texcoord;
119}
120";