transfer code from skate rift
authorhgn <hgodden00@gmail.com>
Fri, 14 Jun 2024 12:55:24 +0000 (13:55 +0100)
committerhgn <hgodden00@gmail.com>
Fri, 14 Jun 2024 12:55:24 +0000 (13:55 +0100)
shaders/blit.vs [new file with mode: 0644]
shaders/blit_blur.fs [new file with mode: 0644]
shaders/blit_colour.fs [new file with mode: 0644]
shaders/blit_tex.fs [new file with mode: 0644]
shaders/motion_vectors_common.glsl [new file with mode: 0644]
shaders/motion_vectors_fs.glsl [new file with mode: 0644]
shaders/motion_vectors_vs.glsl [new file with mode: 0644]
vg_build_utils_shader.h
vg_engine.c
vg_render.c [new file with mode: 0644]
vg_render.h [new file with mode: 0644]

diff --git a/shaders/blit.vs b/shaders/blit.vs
new file mode 100644 (file)
index 0000000..06ffba6
--- /dev/null
@@ -0,0 +1,10 @@
+layout (location=0) in vec2 a_co;
+out vec2 aUv;
+
+uniform vec2 uInverseRatio;
+
+void main()
+{
+   gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);
+   aUv = a_co * uInverseRatio;
+}
diff --git a/shaders/blit_blur.fs b/shaders/blit_blur.fs
new file mode 100644 (file)
index 0000000..592c83f
--- /dev/null
@@ -0,0 +1,32 @@
+out vec4 FragColor;
+uniform sampler2D uTexMain;
+uniform sampler2D uTexMotion;
+uniform float uBlurStrength;
+uniform vec2 uOverrideDir;
+uniform vec2 uClampUv;
+
+in vec2 aUv;
+
+vec2 rand_hash22( vec2 p )
+{
+   vec3 p3 = fract(vec3(p.xyx) * 213.8976123);
+   p3 += dot(p3, p3.yzx+19.19);
+   return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
+}
+
+void main()
+{
+   vec2 vuv = aUv; 
+
+   vec2 vrand = rand_hash22( vuv ) * 2.0 - vec2(1.0);
+   vec2 vrand1 = rand_hash22( vrand ) * 2.0 - vec2(1.0);
+   
+   vec2 vdir = texture( uTexMotion, vuv ).xy * uBlurStrength + uOverrideDir;
+
+   vec4 vcolour0 = texture( uTexMain, min(vuv + vdir*vrand.x,uClampUv) );
+   vec4 vcolour1 = texture( uTexMain, min(vuv + vdir*vrand.y,uClampUv) );
+   vec4 vcolour2 = texture( uTexMain, min(vuv + vdir*vrand1.x,uClampUv) );
+   vec4 vcolour3 = texture( uTexMain, min(vuv + vdir*vrand1.y,uClampUv) );
+
+   FragColor = ( vcolour0 + vcolour1 + vcolour2 + vcolour3 ) * 0.25;
+}
diff --git a/shaders/blit_colour.fs b/shaders/blit_colour.fs
new file mode 100644 (file)
index 0000000..7eb290e
--- /dev/null
@@ -0,0 +1,9 @@
+out vec4 FragColor;
+uniform vec4 uColour;
+
+in vec2 aUv;
+
+void main()
+{
+   FragColor = uColour;
+}
diff --git a/shaders/blit_tex.fs b/shaders/blit_tex.fs
new file mode 100644 (file)
index 0000000..634e84f
--- /dev/null
@@ -0,0 +1,41 @@
+out vec4 FragColor;
+uniform sampler2D uTexMain;
+
+in vec2 aUv;
+
+float kPi = 3.14159265358979;
+
+vec2 fisheye_distort(vec2 xy)
+{
+   float aperture = 1350.0;
+   float apertureHalf = 0.5 * aperture * (kPi / 180.0);
+   float maxFactor = sin(apertureHalf);
+
+   vec2 uv;
+   float d = length(xy);
+   if(d < (2.0-maxFactor))
+   {
+      d = length(xy * maxFactor);
+      float z = sqrt(1.0 - d * d);
+      float r = atan(d, z) / kPi;
+      float phi = atan(xy.y, xy.x);
+
+      uv.x = r * cos(phi) + 0.5;
+      uv.y = r * sin(phi) + 0.5;
+   }
+   else
+   {
+      uv = 0.5*xy + 0.5;
+   }
+   
+   return uv;
+}
+
+
+void main()
+{
+   vec2 vwarp = 2.0*aUv - 1.0;
+   vwarp = fisheye_distort( vwarp );
+
+   FragColor = texture( uTexMain, aUv );
+}
diff --git a/shaders/motion_vectors_common.glsl b/shaders/motion_vectors_common.glsl
new file mode 100644 (file)
index 0000000..7e6c114
--- /dev/null
@@ -0,0 +1 @@
+const float k_motion_lerp_amount = 0.01;
diff --git a/shaders/motion_vectors_fs.glsl b/shaders/motion_vectors_fs.glsl
new file mode 100644 (file)
index 0000000..b92ae2d
--- /dev/null
@@ -0,0 +1,16 @@
+#include "../vg/shaders/motion_vectors_common.glsl"
+
+layout (location = 1) out vec4 oMotionVec;
+
+in vec3 aMotionVec0;
+in vec3 aMotionVec1;
+
+void compute_motion_vectors()
+{
+   // Write motion vectors
+   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;
+   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;
+   vec2 vmotion  = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);
+
+   oMotionVec = vec4( vmotion, 0.0, 1.0 );
+}
diff --git a/shaders/motion_vectors_vs.glsl b/shaders/motion_vectors_vs.glsl
new file mode 100644 (file)
index 0000000..4eee0a6
--- /dev/null
@@ -0,0 +1,14 @@
+#include "../vg/shaders/motion_vectors_common.glsl"
+
+out vec3 aMotionVec0;
+out vec3 aMotionVec1;
+
+void vs_motion_out( vec4 vproj0, vec4 vproj1 )
+{
+   // This magically solves some artifacting errors!
+   //
+   vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;
+
+   aMotionVec0 = vec3( vproj0.xy, vproj0.w );
+   aMotionVec1 = vec3( vproj1.xy, vproj1.w );
+}
index a9d885b04f23fde38cac5c26340e82d86c5b37ca..f83e20c297df1ce180ae7037b351b65eb9ce94c6 100644 (file)
@@ -154,6 +154,9 @@ void vg_build_shader_impl( char *path )
    fclose( fp );
 }
 
+#define _S( NAME, VS, FS ) \
+   vg_build_shader( "shaders/" VS, "shaders/" FS, NULL, "shaders", NAME )
+
 int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
                      char *src_frag, /* path/to/frag.fs    */
                      char *src_geo,  /* unused currently   */
@@ -201,6 +204,7 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
    if( !compile_subshader( c_body, src_vert ) )
    {
       fclose( header );
+      vg_fatal_error( "Failed to assemble vertex source code" );
       return 0;
    }
 
@@ -208,6 +212,7 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
    if( !compile_subshader( c_body, src_frag ) )
    {
       fclose( header );
+      vg_fatal_error( "Failed to assemble fragment source code" );
       return 0;
    }
 
@@ -281,3 +286,10 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
    fclose( header );
    return 1;
 }
+
+void vg_build_postprocess_shaders(void)
+{
+   _S( "blit",      "../vg/shaders/blit.vs", "../vg/shaders/blit_tex.fs" );
+   _S( "blitblur",  "../vg/shaders/blit.vs", "../vg/shaders/blit_blur.fs" );
+   _S( "blitcolour","../vg/shaders/blit.vs", "../vg/shaders/blit_colour.fs" );
+}
index 86b44c4397604c820f6d3d9b87de9babf609c30d..a7e8a686c02ff768451940cfedb614425a5df0fe 100644 (file)
@@ -1,7 +1,8 @@
 #include "vg_engine.h"
 #include "vg_async.h"
 
-struct vg_engine vg = { 
+struct vg_engine vg = 
+{ 
    .time_rate = 1.0, 
    .time_fixed_delta = VG_TIMESTEP_FIXED,
 };
@@ -64,6 +65,7 @@ static void _vg_opengl_sync_init(void)
 #include "vg_tex.h"
 #include "vg_input.h"
 #include "vg_framebuffer.h"
+#include "vg_render.h"
 #include "vg_lines.h"
 #include "vg_rigidbody_view.h"
 #include "vg_loader.h"
@@ -132,6 +134,7 @@ static void _vg_load_full( void *data )
 
    /* internal */
    vg_loader_step( vg_framebuffer_init, NULL );
+   vg_loader_step( vg_render_init, NULL );
    vg_loader_step( vg_input_init, vg_input_free );
    vg_loader_step( vg_lines_init, NULL );
    vg_loader_step( vg_rb_view_init, NULL );
@@ -744,6 +747,7 @@ void vg_enter( int argc, char *argv[], const char *window_name )
                         k_var_dtype_i32, VG_VAR_PERSISTENT );
    vg_console_reg_var( "vg_screen_mode", &vg.screen_mode,
                         k_var_dtype_i32, VG_VAR_PERSISTENT );
+
    vg_audio_register();
    vg_console_load_autos();
 
@@ -1304,6 +1308,7 @@ int AmdPowerXpressRequestHighPerformance = 1;
 #include "vg_rigidbody_view.c"
 #include "vg_shader.c"
 #include "vg_framebuffer.c"
+#include "vg_render.c"
 
 #ifdef VG_CUSTOM_SHADERS
  #include "shaders/impl.c"
diff --git a/vg_render.c b/vg_render.c
new file mode 100644 (file)
index 0000000..3274721
--- /dev/null
@@ -0,0 +1,183 @@
+#include "vg_render.h"
+#include "shaders/blit.h"
+#include "shaders/blitblur.h"
+
+struct vg_postprocess vg_postprocess = 
+{
+   .blur_effect = 1,
+   .blur_strength = 0.3f,
+};
+
+struct vg_render _vg_render = 
+{
+   .scale = 1.0f
+};
+
+static void vg_async_postprocess_init( void *payload, u32 size )
+{
+   f32 quad[] = 
+   { 
+      0.00f,0.00f, 1.00f,1.00f, 0.00f,1.00f,
+      0.00f,0.00f, 1.00f,0.00f, 1.00f,1.00f,    
+   };
+
+   glGenVertexArrays( 1, &vg_postprocess.quad_vao );
+   glGenBuffers( 1, &vg_postprocess.quad_vbo );
+   glBindVertexArray( vg_postprocess.quad_vao );
+   glBindBuffer( GL_ARRAY_BUFFER, vg_postprocess.quad_vbo );
+   glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW );
+   glBindVertexArray( vg_postprocess.quad_vao );
+   glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(f32)*2, (void*)0 );
+   glEnableVertexAttribArray( 0 );
+}
+
+void vg_render_init(void)
+{
+   vg_async_call( vg_async_postprocess_init, NULL, 0 );
+
+   vg_console_reg_var( "render_scale", &_vg_render.scale,
+                       k_var_dtype_f32, VG_VAR_PERSISTENT );
+
+#ifdef VG_3D
+   vg_console_reg_var( "blur_strength", &vg_postprocess.blur_strength, 
+                        k_var_dtype_f32, 0 );
+   vg_console_reg_var( "blur_effect", &vg_postprocess.blur_effect,
+                        k_var_dtype_i32, VG_VAR_PERSISTENT );
+
+   void *alloc = vg_mem.rtmemory;
+   
+   /* 
+    * Main framebuffer
+    */
+   _vg_render.fb_main = vg_framebuffer_allocate( alloc, 3, 1 );
+   _vg_render.fb_main->display_name = "main";
+   _vg_render.fb_main->resolution_div = 1;
+   _vg_render.fb_main->attachments[0] = (vg_framebuffer_attachment)
+   {
+      "colour", k_framebuffer_attachment_type_texture,
+
+      .internalformat = GL_RGB,
+      .format         = GL_RGB,
+      .type           = GL_UNSIGNED_BYTE,
+      .attachment     = GL_COLOR_ATTACHMENT0
+   };
+   _vg_render.fb_main->attachments[1] = (vg_framebuffer_attachment)
+   {
+      "motion", k_framebuffer_attachment_type_texture,
+
+      .quality        = k_framebuffer_quality_high_only,
+      .internalformat = GL_RG16F,
+      .format         = GL_RG,
+      .type           = GL_FLOAT,
+      .attachment     = GL_COLOR_ATTACHMENT1
+   };
+   _vg_render.fb_main->attachments[2] = (vg_framebuffer_attachment)
+   {
+      "depth_stencil", k_framebuffer_attachment_type_texture_depth,
+      .internalformat = GL_DEPTH24_STENCIL8,
+      .format         = GL_DEPTH_STENCIL,
+      .type           = GL_UNSIGNED_INT_24_8,
+      .attachment     = GL_DEPTH_STENCIL_ATTACHMENT
+   };
+   vg_framebuffer_create( _vg_render.fb_main );
+   
+   /* 
+    * Water reflection
+    */
+   _vg_render.fb_water_reflection = vg_framebuffer_allocate( alloc, 2, 1 );
+   _vg_render.fb_water_reflection->display_name = "water_reflection";
+   _vg_render.fb_water_reflection->resolution_div = 2;
+   _vg_render.fb_water_reflection->attachments[0] = (vg_framebuffer_attachment) 
+   {
+      "colour", k_framebuffer_attachment_type_texture,
+      .internalformat = GL_RGB,
+      .format         = GL_RGB,
+      .type           = GL_UNSIGNED_BYTE,
+      .attachment     = GL_COLOR_ATTACHMENT0
+   };
+   _vg_render.fb_water_reflection->attachments[1] = (vg_framebuffer_attachment) 
+   {
+      "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
+      .internalformat = GL_DEPTH24_STENCIL8,
+      .attachment     = GL_DEPTH_STENCIL_ATTACHMENT
+   };
+   vg_framebuffer_create( _vg_render.fb_water_reflection );
+
+   /*
+    * Thid rendered view from the perspective of the camera, but just 
+    * captures stuff thats under the water
+    */
+   _vg_render.fb_water_beneath = vg_framebuffer_allocate( alloc, 2, 1 );
+   _vg_render.fb_water_beneath->display_name = "water_beneath";
+   _vg_render.fb_water_beneath->resolution_div = 2;
+   _vg_render.fb_water_beneath->attachments[0] = (vg_framebuffer_attachment) 
+   {
+      "colour", k_framebuffer_attachment_type_texture,
+      .internalformat = GL_RED,
+      .format         = GL_RED,
+      .type           = GL_UNSIGNED_BYTE,
+      .attachment     = GL_COLOR_ATTACHMENT0
+   };
+   _vg_render.fb_water_beneath->attachments[1] = (vg_framebuffer_attachment) 
+   {
+      "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
+      .internalformat = GL_DEPTH24_STENCIL8,
+      .attachment     = GL_DEPTH_STENCIL_ATTACHMENT
+   };
+   vg_framebuffer_create( _vg_render.fb_water_beneath );
+#endif
+}
+
+void vg_render_fullscreen_quad(void)
+{
+   glBindVertexArray( vg_postprocess.quad_vao );
+   glDrawArrays( GL_TRIANGLES, 0, 6 );
+}
+
+/*
+ * Utility
+ */
+
+void vg_postprocess_to_screen( vg_framebuffer *fb )
+{
+   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+   glViewport( 0,0, vg.window_x, vg.window_y );
+
+   glEnable(GL_BLEND);
+   glDisable(GL_DEPTH_TEST);
+   glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
+   glBlendEquation(GL_FUNC_ADD);
+
+   v2f inverse;
+   vg_framebuffer_inverse_ratio( fb, inverse );
+
+#ifdef VG_3D
+   if( vg_postprocess.blur_effect )
+   {
+      shader_blitblur_use();
+      shader_blitblur_uTexMain( 0 );
+      shader_blitblur_uTexMotion( 1 );
+
+      f32 s = vg.time_frame_delta*60.0;
+      shader_blitblur_uBlurStrength( vg_postprocess.blur_strength / s );
+      shader_blitblur_uInverseRatio( inverse );
+
+      inverse[0] -= 0.0001f;
+      inverse[1] -= 0.0001f;
+      shader_blitblur_uClampUv( inverse );
+      shader_blitblur_uOverrideDir( vg_postprocess.motion_blur_override );
+
+      vg_framebuffer_bind_texture( fb, 0, 0 );
+      vg_framebuffer_bind_texture( fb, 1, 1 );
+   }
+   else
+#endif
+   {
+      shader_blit_use();
+      shader_blit_uTexMain( 0 );
+      shader_blit_uInverseRatio( inverse );
+      vg_framebuffer_bind_texture( fb, 0, 0 );
+   }
+
+   vg_render_fullscreen_quad();
+}
diff --git a/vg_render.h b/vg_render.h
new file mode 100644 (file)
index 0000000..15ff12e
--- /dev/null
@@ -0,0 +1,31 @@
+#pragma once
+#include "vg_engine.h"
+
+struct vg_postprocess
+{
+   GLuint quad_vao, 
+          quad_vbo;
+
+#ifdef VG_3D
+   i32 blur_effect;
+   f32 blur_strength;
+   v2f motion_blur_override;
+#endif
+}
+extern vg_postprocess;
+
+struct vg_render
+{
+   f32 scale;
+
+#ifdef VG_3D
+   vg_framebuffer *fb_main,
+                  *fb_water_reflection,
+                  *fb_water_beneath;
+#endif
+}
+extern _vg_render;
+
+void vg_render_init(void);
+void vg_render_fullscreen_quad(void);
+void vg_postprocess_to_screen( vg_framebuffer *fb );