unlinked gate fx
authorhgn <hgodden00@gmail.com>
Tue, 28 Nov 2023 00:59:18 +0000 (00:59 +0000)
committerhgn <hgodden00@gmail.com>
Tue, 28 Nov 2023 00:59:18 +0000 (00:59 +0000)
build.c
shaders/model_gate.h
shaders/model_gate_unlinked.fs [new file with mode: 0644]
shaders/model_gate_unlinked.h [new file with mode: 0644]
world_gate.c
world_gate.h
world_render.c

diff --git a/build.c b/build.c
index e769465c428149e70f9ec090e58f7f96eb8b78a7..addff9e7118bc00fb6ee9f74e108c53734467f01 100644 (file)
--- a/build.c
+++ b/build.c
@@ -265,7 +265,8 @@ void build_shaders(void){
    _S( "model_character_view", "model_skinned.vs", "model_character_view.fs" );
    _S( "model_board_view",     "model.vs",         "model_character_view.fs" );
    _S( "model_entity",         "model.vs",         "model_entity.fs" );
-   _S( "model_gate",           "model_gate.vs",    "model_gate_lq.fs" );
+   _S( "model_gate",           "model.vs",         "model_gate_lq.fs" );
+   _S( "model_gate_unlinked",  "model.vs",         "model_gate_unlinked.fs" );
    _S( "model_font",           "model_font.vs",    "model_font.fs" );
 
    /* Pointcloud */
index cd2c29b1832e962282c610737a33461b6413476a..31329abb360c00b1bc97621f47263aa79ace7606 100644 (file)
@@ -7,27 +7,59 @@ static struct vg_shader _shader_model_gate = {
    .link = shader_model_gate_link,
    .vs = 
 {
-.orig_file = "shaders/model_gate.vs",
+.orig_file = "shaders/model.vs",
 .static_src = 
 "layout (location=0) in vec3 a_co;\n"
 "layout (location=1) in vec3 a_norm;\n"
 "layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line       1        1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line      2        0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   // This magically solves some artifacting errors!\n"
+"   //\n"
+"   vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      9        0 \n"
 "\n"
-"uniform mat4 uPv;\n"
 "uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
-"out vec3 aNorm;\n"
+"out vec4 aColour;\n"
 "out vec2 aUv;\n"
+"out vec3 aNorm;\n"
 "out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4( a_co, 1.0 );\n"
-"   gl_Position = uPv * vec4(world_pos,1.0);\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
 "\n"
-"   aNorm = a_norm;\n"
-"   aCo = world_pos;\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
+"   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
+"   aNorm = mat3(uMdl) * a_norm;\n"
+"   aCo = a_co;\n"
 "}\n"
 ""},
    .fs = 
@@ -61,17 +93,21 @@ static struct vg_shader _shader_model_gate = {
 ""},
 };
 
-static GLuint _uniform_model_gate_uPv;
 static GLuint _uniform_model_gate_uMdl;
+static GLuint _uniform_model_gate_uPv;
+static GLuint _uniform_model_gate_uPvmPrev;
 static GLuint _uniform_model_gate_uTime;
 static GLuint _uniform_model_gate_uCam;
 static GLuint _uniform_model_gate_uInvRes;
 static GLuint _uniform_model_gate_uColour;
+static void shader_model_gate_uMdl(m4x3f m){
+   glUniformMatrix4x3fv(_uniform_model_gate_uMdl,1,GL_FALSE,(float*)m);
+}
 static void shader_model_gate_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_model_gate_uPv,1,GL_FALSE,(float*)m);
 }
-static void shader_model_gate_uMdl(m4x3f m){
-   glUniformMatrix4x3fv(_uniform_model_gate_uMdl,1,GL_FALSE,(float*)m);
+static void shader_model_gate_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_model_gate_uPvmPrev,1,GL_FALSE,(float*)m);
 }
 static void shader_model_gate_uTime(float f){
    glUniform1f(_uniform_model_gate_uTime,f);
@@ -90,8 +126,9 @@ static void shader_model_gate_register(void){
 }
 static void shader_model_gate_use(void){ glUseProgram(_shader_model_gate.id); }
 static void shader_model_gate_link(void){
-   _uniform_model_gate_uPv = glGetUniformLocation( _shader_model_gate.id, "uPv" );
    _uniform_model_gate_uMdl = glGetUniformLocation( _shader_model_gate.id, "uMdl" );
+   _uniform_model_gate_uPv = glGetUniformLocation( _shader_model_gate.id, "uPv" );
+   _uniform_model_gate_uPvmPrev = glGetUniformLocation( _shader_model_gate.id, "uPvmPrev" );
    _uniform_model_gate_uTime = glGetUniformLocation( _shader_model_gate.id, "uTime" );
    _uniform_model_gate_uCam = glGetUniformLocation( _shader_model_gate.id, "uCam" );
    _uniform_model_gate_uInvRes = glGetUniformLocation( _shader_model_gate.id, "uInvRes" );
diff --git a/shaders/model_gate_unlinked.fs b/shaders/model_gate_unlinked.fs
new file mode 100644 (file)
index 0000000..d5c0663
--- /dev/null
@@ -0,0 +1,41 @@
+out vec4 FragColor;
+
+uniform float uTime;
+uniform vec3 uCam;
+uniform vec4 uColour;
+
+in vec3 aNorm;
+in vec2 aUv;
+in vec3 aCo;
+
+#include "motion_vectors_fs.glsl"
+
+const int NOISE_LOOP = 3;
+vec3 digital_noise( uvec3 iuv ){
+   iuv *=uvec3(8,2524,7552);
+   for( int i=0; i<NOISE_LOOP; i++ )
+      iuv += (iuv.yzx<<2) ^ (iuv.yxz)+iuv.z;
+   return vec3(iuv)*(1.0/float(0xffffffffU));
+}
+
+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(){
+   compute_motion_vectors();
+
+   vec2 ssuv = gl_FragCoord.xy;
+   float grad = 1.0-aUv.y*0.1;
+   float opacity = rand_hash22( vec2(floor(aUv.y*100.0),floor(aCo.z*10.0+uTime*40.0)) ).r*grad;
+   
+   vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );
+   float dither = fract( vDither.g / 71.0 ) - 0.5;
+
+   if( opacity<0.9 )
+      discard;
+
+   FragColor = vec4(0.7,0.5,0.5,1.0);
+}
diff --git a/shaders/model_gate_unlinked.h b/shaders/model_gate_unlinked.h
new file mode 100644 (file)
index 0000000..b617ab5
--- /dev/null
@@ -0,0 +1,153 @@
+#ifndef SHADER_model_gate_unlinked_H
+#define SHADER_model_gate_unlinked_H
+static void shader_model_gate_unlinked_link(void);
+static void shader_model_gate_unlinked_register(void);
+static struct vg_shader _shader_model_gate_unlinked = {
+   .name = "model_gate_unlinked",
+   .link = shader_model_gate_unlinked_link,
+   .vs = 
+{
+.orig_file = "shaders/model.vs",
+.static_src = 
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line       1        1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line      2        0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   // This magically solves some artifacting errors!\n"
+"   //\n"
+"   vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      9        0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
+"   aColour = a_colour;\n"
+"   aUv = a_uv;\n"
+"   aNorm = mat3(uMdl) * a_norm;\n"
+"   aCo = a_co;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/model_gate_unlinked.fs",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform float uTime;\n"
+"uniform vec3 uCam;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec3 aNorm;\n"
+"in vec2 aUv;\n"
+"in vec3 aCo;\n"
+"\n"
+"#line       1        1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line      2        0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+"   oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line     12        0 \n"
+"\n"
+"void main(){\n"
+"   compute_motion_vectors();\n"
+"\n"
+"   vec2 ssuv = gl_FragCoord.xy;\n"
+"   float opacity = 1.0-smoothstep(0.0,1.0,aUv.y+uColour.a);\n"
+"   \n"
+"   vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+"   float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+"   if( opacity+dither<0.5 )\n"
+"      discard;\n"
+"\n"
+"   FragColor = uColour;\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_model_gate_unlinked_uMdl;
+static GLuint _uniform_model_gate_unlinked_uPv;
+static GLuint _uniform_model_gate_unlinked_uPvmPrev;
+static GLuint _uniform_model_gate_unlinked_uTime;
+static GLuint _uniform_model_gate_unlinked_uCam;
+static GLuint _uniform_model_gate_unlinked_uColour;
+static void shader_model_gate_unlinked_uMdl(m4x3f m){
+   glUniformMatrix4x3fv(_uniform_model_gate_unlinked_uMdl,1,GL_FALSE,(float*)m);
+}
+static void shader_model_gate_unlinked_uPv(m4x4f m){
+   glUniformMatrix4fv(_uniform_model_gate_unlinked_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_model_gate_unlinked_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_model_gate_unlinked_uPvmPrev,1,GL_FALSE,(float*)m);
+}
+static void shader_model_gate_unlinked_uTime(float f){
+   glUniform1f(_uniform_model_gate_unlinked_uTime,f);
+}
+static void shader_model_gate_unlinked_uCam(v3f v){
+   glUniform3fv(_uniform_model_gate_unlinked_uCam,1,v);
+}
+static void shader_model_gate_unlinked_uColour(v4f v){
+   glUniform4fv(_uniform_model_gate_unlinked_uColour,1,v);
+}
+static void shader_model_gate_unlinked_register(void){
+   vg_shader_register( &_shader_model_gate_unlinked );
+}
+static void shader_model_gate_unlinked_use(void){ glUseProgram(_shader_model_gate_unlinked.id); }
+static void shader_model_gate_unlinked_link(void){
+   _uniform_model_gate_unlinked_uMdl = glGetUniformLocation( _shader_model_gate_unlinked.id, "uMdl" );
+   _uniform_model_gate_unlinked_uPv = glGetUniformLocation( _shader_model_gate_unlinked.id, "uPv" );
+   _uniform_model_gate_unlinked_uPvmPrev = glGetUniformLocation( _shader_model_gate_unlinked.id, "uPvmPrev" );
+   _uniform_model_gate_unlinked_uTime = glGetUniformLocation( _shader_model_gate_unlinked.id, "uTime" );
+   _uniform_model_gate_unlinked_uCam = glGetUniformLocation( _shader_model_gate_unlinked.id, "uCam" );
+   _uniform_model_gate_unlinked_uColour = glGetUniformLocation( _shader_model_gate_unlinked.id, "uColour" );
+}
+#endif /* SHADER_model_gate_unlinked_H */
index 79ddbc9867a14adc77fbbac5987fcf26f633da39..ba4701c81a5097b4ebe81f48f9303ccc222752a2 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "world_water.h"
 #include "player_remote.h"
+#include "shaders/model_gate_unlinked.h"
 
 /*
  * Update the transform matrices for gate
@@ -45,6 +46,7 @@ static void world_gates_init(void)
    vg_info( "world_gates_init\n" );
 
    shader_model_gate_register();
+   shader_model_gate_unlinked_register();
 
    vg_linear_clear( vg_mem.scratch );
 
@@ -78,6 +80,21 @@ static void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl ){
    }
 }
 
+static void render_gate_mesh( world_instance *world, ent_gate *gate ){
+   if( gate->flags & k_ent_gate_custom_mesh ){
+      mesh_bind( &world->mesh_no_collide );
+      for( u32 i=0; i<gate->submesh_count; i++ ){
+         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                       gate->submesh_start+i );
+         mdl_draw_submesh( sm );
+      }
+   }
+   else {
+      mesh_bind( &world_gates.mesh );
+      mdl_draw_submesh( &world_gates.sm_surface );
+   }
+}
+
 /*
  * Render the view through a gate
  */
@@ -159,19 +176,7 @@ static int render_gate( world_instance *world, world_instance *world_inside,
    m4x3f mmdl;
    ent_gate_get_mdl_mtx( gate, mmdl );
    shader_model_gate_uMdl( mmdl );
-   
-   if( gate->flags & k_ent_gate_custom_mesh ){
-      mesh_bind( &world->mesh_no_collide );
-      for( u32 i=0; i<gate->submesh_count; i++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
-                                       gate->submesh_start+i );
-         mdl_draw_submesh( sm );
-      }
-   }
-   else {
-      mesh_bind( &world_gates.mesh );
-      mdl_draw_submesh( &world_gates.sm_surface );
-   }
+   render_gate_mesh( world, gate );
 
    render_world( world_inside, &world_gates.cam, 
                  1, !localplayer.gate_waiting, 1, 1 );
@@ -179,6 +184,26 @@ static int render_gate( world_instance *world, world_instance *world_inside,
    return 1;
 }
 
+static void render_gate_unlinked( world_instance *world,
+                                  ent_gate *gate, camera *cam ){
+   m4x3f mmdl; m4x4f m4mdl;
+   ent_gate_get_mdl_mtx( gate, mmdl );
+   m4x3_expand( mmdl, m4mdl );
+   m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl );
+
+   shader_model_gate_unlinked_use();
+   shader_model_gate_unlinked_uPv( cam->mtx.pv );
+   shader_model_gate_unlinked_uPvmPrev( m4mdl );
+   shader_model_gate_unlinked_uCam( cam->pos );
+   shader_model_gate_unlinked_uColour( (v4f){0.0f,1.0f,0.0f,0.0f} );
+   shader_model_gate_unlinked_uTime( vg.time*0.25f );
+   shader_model_gate_unlinked_uMdl( mmdl );
+
+   vg_line_point( gate->co[0], 0.1f, 0xffffff00 );
+
+   render_gate_mesh( world, gate );
+}
+
 /*
  * Intersect the plane of a gate with a line segment, plane coordinate result 
  * stored in 'where'
@@ -299,6 +324,7 @@ static void world_link_nonlocal_async( void *payload, u32 size ){
 
    for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, j );
+      gate_transform_update( gate );
 
       if( !(gate->flags & k_ent_gate_nonlocal) ) continue;
       if( gate->flags & k_ent_gate_linked ) continue;
index f1b4f027fd6a4e0632f1f2e3168452bd1361713d..151e428ff7be1172dd9d761572ac2cc097a91f33 100644 (file)
@@ -31,5 +31,7 @@ static void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl );
 
 static void world_link_nonlocal_async( void *payload, u32 size );
 static void world_unlink_nonlocal( world_instance *world );
+static void render_gate_unlinked( world_instance *world,
+                                  ent_gate *gate, camera *cam );
 
 #endif /* WORLD_GATE_H */
index 990a1abfcc3ed6e565e322f36d67307d6b87114e..8c346b677606b832313031a891f474bcfa2b20a8 100644 (file)
@@ -808,8 +808,10 @@ static void render_world_gates( world_instance *world, camera *cam ){
 
    for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
       ent_gate *gi = mdl_arritm( &world->ent_gate, i );
-      if( !(gi->flags & k_ent_gate_linked) )
-         continue;
+
+      if( !(gi->flags & k_ent_gate_nonlocal) )
+         if( !(gi->flags & k_ent_gate_linked) )
+            continue;
 
       float dist = v3_dist2( gi->co[0], cam->transform[3] );
 
@@ -830,8 +832,10 @@ static void render_world_gates( world_instance *world, camera *cam ){
       }
 
       if( gate->flags & k_ent_gate_nonlocal ){
-         if( world_static.load_state != k_world_loader_none ){
+         if( !(gate->flags & k_ent_gate_linked) ||
+             (world_static.load_state != k_world_loader_none) ){
             world->rendering_gate = NULL;
+            render_gate_unlinked( world, gate, cam );
             return;
          }