_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 */
.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 =
""},
};
-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);
}
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" );
--- /dev/null
+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);
+}
--- /dev/null
+#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 */
#include "world_water.h"
#include "player_remote.h"
+#include "shaders/model_gate_unlinked.h"
/*
* Update the transform matrices for gate
vg_info( "world_gates_init\n" );
shader_model_gate_register();
+ shader_model_gate_unlinked_register();
vg_linear_clear( vg_mem.scratch );
}
}
+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
*/
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 );
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'
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;
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 */
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] );
}
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;
}