/*
* parse uid to alias. returns 1 if successful
*/
-static int addon_uid_to_alias( char uid[ADDON_UID_MAX], addon_alias *alias ){
+static int addon_uid_to_alias( const char *uid, addon_alias *alias ){
/* 1
* 01234567890123
* sr&&&-@@@@@-#*
static u32 addon_match( addon_alias *alias );
static int addon_alias_eq( addon_alias *a, addon_alias *b );
static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] );
-static int addon_uid_to_alias( char uid[ADDON_UID_MAX], addon_alias *alias );
+static int addon_uid_to_alias( const char *uid, addon_alias *alias );
static void invalidate_addon_alias( addon_alias *alias );
static void addon_mount_content_folder( enum addon_type type,
const char *base_folder,
('ent_ccmd', 'CCmd', '', 17 ),
('ent_objective', 'Objective', '', 18 ),
('ent_challenge', 'Challenge', '', 19 ),
- ('ent_relay', 'Relay', '', 20 )
+ ('ent_relay', 'Relay', '', 20 ),
+ ('ent_miniworld', 'Mini World', '', 22 )
]
MDL_VERSION_NR = 103
SR_TRIGGERABLE = [ 'ent_audio', 'ent_ccmd', 'ent_gate', 'ent_challenge', \
- 'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route' ]
+ 'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route',\
+ 'ent_miniworld' ]
def get_entity_enum_id( alias ):
#{
("placeholder",c_uint32*2)]
#}
+class ent_miniworld(Structure):#{
+ _fields_ = [("transform",mdl_transform),
+ ("pstr_world",c_uint32),
+ ("purpose",c_int32)]
+
+ sr_functions = { 0: 'zone' }
+#}
+
def obj_ent_type( obj ):
#{
if obj.type == 'ARMATURE': return 'mdl_armature'
cubemap.live = 60
sr_ent_push( cubemap )
#}
+ elif ent_type == 'ent_miniworld':#{
+ miniworld = ent_miniworld()
+ obj_data = obj.SR_data.ent_miniworld[0]
+
+ compile_obj_transform( obj, miniworld.transform )
+ miniworld.pstr_world = sr_compile_string( obj_data.world )
+ sr_ent_push( miniworld )
+ #}
#}
#}
poll=lambda self,obj: sr_filter_ent_type(obj,['ent_gate']))
#}
+class SR_OBJECT_ENT_MINIWORLD(bpy.types.PropertyGroup):
+#{
+ world: bpy.props.StringProperty( name='world UID' )
+#}
+
class SR_UL_ROUTE_NODE_LIST(bpy.types.UIList):
#{
bl_idname = 'SR_UL_ROUTE_NODE_LIST'
ent_objective: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_OBJECTIVE)
ent_challenge: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CHALLENGE)
ent_relay: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_RELAY)
+ ent_miniworld: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_MINIWORLD)
ent_type: bpy.props.EnumProperty(
name="Type",
SR_OBJECT_ENT_WORKSHOP_PREVIEW,SR_OBJECT_ENT_MENU_ITEM,\
SR_OBJECT_ENT_WORLD_INFO,SR_OBJECT_ENT_CCMD,\
SR_OBJECT_ENT_OBJECTIVE,SR_OBJECT_ENT_CHALLENGE,\
- SR_OBJECT_ENT_RELAY,\
+ SR_OBJECT_ENT_RELAY,SR_OBJECT_ENT_MINIWORLD,\
\
SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES,
SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \
/* Scene */
_S( "scene_standard", "scene.vs", "scene_standard.fs" );
_S( "scene_standard_alphatest", "scene.vs", "scene_standard_alphatest.fs" );
- _S( "scene_override", "scene.vs", "scene_override.fs" );
+ _S( "scene_override", "scene_override.vs", "scene_override.fs" );
_S( "scene_fxglow", "scene_fxglow.vs", "scene_fxglow.fs" );
_S( "scene_vertex_blend", "scene.vs", "scene_vertex_blend.fs" );
_S( "scene_terrain", "scene.vs", "scene_terrain.fs" );
--- /dev/null
+#include "entity.h"
+#include "ent_miniworld.h"
+#include "world_render.h"
+
+static void ent_miniworld_call( world_instance *world, ent_call *call ){
+ ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld,
+ mdl_entity_id_id(call->id) );
+
+ int world_id = world - world_static.instances;
+
+ if( call->function == 0 ){ /* zone() */
+ const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world );
+ skaterift_load_world_command( 1, (const char *[]){ uid } );
+
+ global_miniworld.active_id = call->id;
+ }
+}
+
+static void ent_miniworld_render( world_instance *host_world ){
+ u32 entity_id = global_miniworld.active_id;
+
+ if( !entity_id )
+ return;
+
+ ent_miniworld *miniworld = mdl_arritm( &host_world->ent_miniworld,
+ mdl_entity_id_id(entity_id) );
+
+ if( miniworld->purpose == k_world_purpose_invalid )
+ return;
+
+ m4x3f mmdl;
+ mdl_transform_m4x3( &miniworld->transform, mmdl );
+ render_world_override( &world_static.instances[miniworld->purpose], mmdl );
+
+ //render_world_routes( , &skaterift.cam, 1 );
+}
--- /dev/null
+#ifndef ENT_MINIWORLD_H
+#define ENT_MINIWORLD_H
+
+#include "entity.h"
+
+struct {
+ u32 active_id; /* TODO: world references in entity ID */
+}
+static global_miniworld;
+
+static void ent_miniworld_call( world_instance *world, ent_call *call );
+
+#endif /* ENT_MINIWORLD_H */
--- /dev/null
+#if 0
+#include "ent_portal.h"
+#include "addon.h"
+#include "pointcloud.h"
+
+static void ent_portal_pointcloud_load_thread(void *_){
+ char path_buf[4096];
+ vg_str path;
+ vg_strnull( &path, path_buf, 4096 );
+ addon_get_content_folder( global_portal.display_world, &path );
+ vg_strcat( &path, "/preview.bin" );
+
+ vg_linear_clear(vg_mem.scratch);
+ u32 size;
+
+ void *data = vg_file_read( vg_mem.scratch, path_buf, &size );
+ if( data ){
+ if( size < sizeof(pointcloud_buffer) ){
+ vg_async_call( pointcloud_clear_async, NULL, 0 );
+ return;
+ }
+
+ vg_async_item *call = vg_async_alloc(size);
+ pointcloud_buffer *pcbuf = call->payload;
+ memcpy( pcbuf, data, size );
+
+ u32 point_count = (size-sizeof(pointcloud_buffer)) /
+ sizeof(struct pointcloud_vert);
+ pcbuf->max = point_count;
+ pcbuf->count = point_count;
+ pcbuf->op = k_pointcloud_op_clear;
+
+ vg_async_dispatch( call, async_pointcloud_sub );
+ vg_async_call( pointcloud_async_end, NULL, 0 );
+ }
+ else{
+ vg_async_call( pointcloud_clear_async, NULL, 0 );
+ }
+}
+
+/*
+ * Set new world to be loaded into portal
+ */
+static void ent_portal_set_world( addon_reg *reg ){
+ global_portal.display_world = reg;
+ global_portal.dirty = 1;
+}
+
+/* VG Events */
+
+static void ent_portal_preupdate(void){
+ if( global_portal.dirty && vg_loader_availible() ){
+ global_portal.dirty = 0;
+ vg_loader_start( ent_portal_pointcloud_load_thread, NULL );
+ }
+}
+
+static void ent_portal_render(void){
+ if( !global_portal.active )
+ return;
+
+ m4x3f mmdl;
+#if 0
+ mdl_transform_m4x3( &mark_display->transform, mmdl );
+ m4x3_rotate_y( mmdl, vg.time * 0.2 );
+#endif
+ m3x3_identity( mmdl );
+ m3x3_diagonal( mmdl, 20.0f );
+ v3_copy( global_portal.display_co, mmdl[3] );
+ mmdl[3][1] += 2.0f;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ glDisable(GL_DEPTH_TEST);
+ pointcloud_render( &skaterift.cam, mmdl );
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+}
+
+#endif
--- /dev/null
+#ifndef ENT_PORTAL_H
+#define ENT_PORTAL_H
+
+#include "addon.h"
+
+/* world portals */
+
+struct {
+ addon_reg *display_world;
+ int dirty, active;
+
+ v3f display_co;
+}
+static global_portal = { .display_co = { 12,1,0 }, .active = 1 };
+
+#endif /* ENT_PORTAL_H */
#include "player.h"
#include "gui.h"
#include "menu.h"
-#include "pointcloud.h"
#include "highscores.h"
#include "steam.h"
#include "addon.h"
else return 0;
}
-static void pointcloud_async_end(void *_, u32 __)
-{
- pointcloud_animate( k_pointcloud_anim_opening );
-}
-
-static void pointcloud_clear_async(void *_, u32 __)
-{
- pointcloud.count = 0;
- pointcloud_animate( k_pointcloud_anim_opening );
-}
-
-static void skateshop_world_preview_loader_thread( void *_data )
-{
- addon_reg *reg = _data;
-
- char path_buf[4096];
- vg_str path;
- vg_strnull( &path, path_buf, 4096 );
- addon_get_content_folder( reg, &path );
- vg_strcat( &path, "/preview.bin" );
-
- vg_linear_clear(vg_mem.scratch);
- u32 size;
-
- void *data = vg_file_read( vg_mem.scratch, path_buf, &size );
- if( data ){
- if( size < sizeof(pointcloud_buffer) ){
- vg_async_call( pointcloud_clear_async, NULL, 0 );
- return;
- }
-
- vg_async_item *call = vg_async_alloc(size);
- pointcloud_buffer *pcbuf = call->payload;
- memcpy( pcbuf, data, size );
-
- u32 point_count = (size-sizeof(pointcloud_buffer)) /
- sizeof(struct pointcloud_vert);
- pcbuf->max = point_count;
- pcbuf->count = point_count;
- pcbuf->op = k_pointcloud_op_clear;
-
- vg_async_dispatch( call, async_pointcloud_sub );
- vg_async_call( pointcloud_async_end, NULL, 0 );
- }
- else{
- vg_async_call( pointcloud_clear_async, NULL, 0 );
- }
-}
-
-static void skateshop_world_preview_loader_thread_and_end( void *_data ){
- skateshop_world_preview_loader_thread( _data );
-}
-
-static void skateshop_load_world_preview( addon_reg *reg ){
- vg_loader_start( skateshop_world_preview_loader_thread_and_end, reg );
-}
-
/*
* VG event preupdate
*/
}
}
+#if 0
if( change && pointcloud_idle() ){
pointcloud_animate( k_pointcloud_anim_hiding );
}
}
}
}
+#endif
}
else{
vg_fatal_error( "Unknown store (%u)\n", shop->type );
m4x3_mul( mtext, mlocal, mtextmdl );
font3d_simple_draw( 0, bufsubtext, &skaterift.cam, mtextmdl );
+#if 0
/* pointcloud */
m4x3f mmdl;
mdl_transform_m4x3( &mark_display->transform, mmdl );
pointcloud_render( world, &skaterift.cam, mmdl );
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
+#endif
}
/*
}
else if( shop->type == k_skateshop_type_worldshop ){
ent_skateshop_helpers_pickable( "open rift" );
- pointcloud_animate( k_pointcloud_anim_opening );
skateshop_op_world_scan();
}
}
#include "ent_challenge.c"
#include "ent_relay.c"
#include "ent_route.c"
+#include "ent_portal.c"
+#include "ent_miniworld.c"
typedef void (*fn_entity_call_handler)( world_instance *, ent_call *);
[k_ent_gate] = ent_gate_call,
[k_ent_relay] = ent_relay_call,
[k_ent_challenge] = ent_challenge_call,
- [k_ent_route] = ent_route_call
+ [k_ent_route] = ent_route_call,
+ [k_ent_miniworld] = ent_miniworld_call
};
if( type >= vg_list_size(table) ){
typedef struct ent_challenge ent_challenge;
typedef struct ent_relay ent_relay;
typedef struct ent_cubemap ent_cubemap;
+typedef struct ent_miniworld ent_miniworld;
enum entity_alias{
k_ent_none = 0,
k_ent_objective = 18,
k_ent_challenge = 19,
k_ent_relay = 20,
- k_ent_cubemap = 21
+ k_ent_cubemap = 21,
+ k_ent_miniworld = 22
};
static u32 mdl_entity_id_type( u32 entity_id ){
/* v102+ */
enum ent_gate_flag{
k_ent_gate_linked = 0x1, /* this is a working portal */
- k_ent_gate_nonlocal = 0x2, /* use the key string to link this portal.
+ k_ent_gate_nonlocal_DELETED = 0x2, /* use the key string to link this portal.
NOTE: if set, it adds the flip flag. */
k_ent_gate_flip = 0x4, /* flip direction 180* for exiting portal */
k_ent_gate_custom_mesh = 0x8, /* use a custom submesh instead of default */
void *data;
};
+struct ent_miniworld {
+ mdl_transform transform;
+ u32 pstr_world;
+
+ i32 purpose;
+};
+
#include "world.h"
static void entity_call( world_instance *world, ent_call *call );
vg.window_should_close = 1;
}
- /* DEPRECATED? */
- else if( MDL_CONST_PSTREQ( &menu.model, q, "reset_nearest" ) ){
- localplayer_cmd_respawn( 0, NULL );
- menu_close();
- }
- /* DEPRECATED? */
- else if( MDL_CONST_PSTREQ( &menu.model, q, "reset_home" ) ){
- world_set_active_instance( 0 );
- localplayer.viewable_world = world_current_instance();
- localplayer_cmd_respawn( 1, (const char *[]){"start"} );
- menu_close();
- }
-
else if( MDL_CONST_PSTREQ( &menu.model, q, "reset" ) ){
menu_close();
respawn_begin_chooser();
m4x3_mulv( gate->transport, localplayer.cam.pos, localplayer.cam.pos );
- if( gate->flags & k_ent_gate_nonlocal )
- world_set_active_instance( gate->target );
-
audio_lock();
audio_oneshot( &audio_gate_pass, 1.0f, 0.0f );
audio_unlock();
skaterift_replay_debug_info();
}
-
static void player__setpos( v3f pos ){
v3_copy( pos, localplayer.rb.co );
v3_zero( localplayer.rb.v );
rb_update_transform( &localplayer.rb );
}
-static void player__spawn( ent_spawn *rp ){
+static void player__reset(void){
replay_clear( &skaterift.replay );
- player__setpos( rp->transform.co );
+
+ v3_zero( localplayer.rb.v );
v3_zero( localplayer.rb.w );
- q_identity( localplayer.rb.q );
+
+ f32 l = v4_length( localplayer.rb.q );
+ if( (l < 0.9f) || (l > 1.1f) )
+ q_identity( localplayer.rb.q );
+
rb_update_transform( &localplayer.rb );
q_identity( localplayer.qbasis );
m3x3_identity( localplayer.invbasis );
localplayer.subsystem = k_player_subsystem_walk;
+ player__walk_reset();
+
localplayer.immobile = 0;
localplayer.gate_waiting = NULL;
- world_static.last_use = 0.0;
- world_static.focused_entity = 0;
+ localplayer.viewable_world = world_current_instance();
+
world_static.challenge_target = NULL;
world_static.challenge_timer = 0.0f;
+ world_static.focused_entity = 0;
+ world_static.active_trigger_volume_count = 0;
+ world_static.last_use = 0.0;
world_entity_unfocus();
- if( player_subsystems[ localplayer.subsystem ]->reset )
- player_subsystems[ localplayer.subsystem ]->reset( rp );
-
localplayer.boundary_hash ^= NETMSG_BOUNDARY_BIT;
for( u32 i=0; i<vg_list_size(world_static.instances); i++ ){
}
}
+static void player__spawn( ent_spawn *rp ){
+ player__setpos( rp->transform.co );
+ player__reset();
+}
+
static void player__kill(void){
}
struct player_subsystem_interface{
void(*system_register)(void);
void(*bind)(void);
- void(*reset)( ent_spawn *rp );
void(*pre_update)(void);
void(*update)(void);
void(*post_update)(void);
static void player__im_gui(void);
static void player__setpos( v3f pos );
static void player__spawn( ent_spawn *rp );
+static void player__reset(void);
static void player__kill(void);
static void player__begin_holdout( v3f offset );
player_drive.anim_drive = skeleton_get_anim( sk, "idle_cycle+y" );
}
-static void player__drive_reset( ent_spawn *rp ){
-}
-
#endif /* PLAYER_DRIVE_C */
static void player__drive_post_animate(void);
static void player__drive_im_gui(void);
static void player__drive_bind(void);
-static void player__drive_reset( ent_spawn *rp );
struct player_subsystem_interface static player_subsystem_drive = {
.pre_update = player__drive_pre_update,
.post_animate = player__drive_post_animate,
.im_gui = player__drive_im_gui,
.bind = player__drive_bind,
- .reset = player__drive_reset,
.animator_data = NULL,
.animator_size = 0,
m3x3_mulv( gate->transport, launch_v, launch_v);
m4x3_mulv( gate->transport, launch_co, launch_co );
m3x3_mul( gate->transport, basis, basis );
-
- if( gate->flags & k_ent_gate_nonlocal ){
- trace_world = &world_static.instances[ gate->target ];
- }
}
}
v3_zero( player_skate.weight_distribution );
}
-static void player__skate_reset( ent_spawn *rp ){
- struct player_skate_state *state = &player_skate.state;
- v3_zero( localplayer.rb.v );
- v4_copy( rp->transform.q, localplayer.rb.q );
-
- state->activity = k_skate_activity_air;
- state->activity_prev = k_skate_activity_air;
-
- player__skate_clear_mechanics();
- player__skate_reset_animator();
-
- v3_zero( state->head_position );
- state->head_position[1] = 1.8f;
-}
-
#include "network_compression.h"
static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ){
static void player__skate_animate (void);
static void player__skate_pose (void *animator, player_pose *pose);
static void player__skate_post_animate (void);
-static void player__skate_reset (ent_spawn *rp);
static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data );
static void player__skate_sfx_oneshot ( u8 id, v3f pos, f32 volume );
struct player_subsystem_interface static player_subsystem_skate = {
.system_register = player__skate_register,
.bind = player__skate_bind,
- .reset = player__skate_reset,
.pre_update = player__skate_pre_update,
.update = player__skate_update,
.post_update = player__skate_post_update,
}
}
else if( button_down( k_srbind_use ) && !localplayer.immobile ){
- if( v3_dist2( localplayer.rb.co, gzoomer.obj.rb.co ) <= 4.0f*4.0f ){
+ if( 0 && (v3_dist2(localplayer.rb.co,gzoomer.obj.rb.co) <= 4.0f*4.0f) ){
localplayer.subsystem = k_player_subsystem_drive;
}
else{
rb_update_transform( &localplayer.rb );
}
-static void player__walk_reset( ent_spawn *rp ){
+static void player__walk_reset(void){
struct player_walk *w = &player_walk;
w->state.activity = k_walk_activity_air;
w->state.outro_type = k_walk_outro_none;
static void player__walk_im_gui (void);
static void player__walk_bind (void);
static void player__walk_transition (void);
-static void player__walk_reset (ent_spawn *rp );
+static void player__walk_reset (void);
static void player__walk_restore (void);
static void player__walk_animator_exchange( bitpack_ctx *ctx, void *data );
struct player_subsystem_interface static player_subsystem_walk = {
.system_register = player__walk_register,
.bind = player__walk_bind,
- .reset = player__walk_reset,
.pre_update = player__walk_pre_update,
.update = player__walk_update,
.post_update = player__walk_post_update,
-#ifndef POINTCLOUD_H
+#if 0
+//#ifndef POINTCLOUD_H
#define POINTCLOUD_H
#include "common.h"
else return 0;
}
-static
-void pointcloud_render( world_instance *world, camera *cam, m4x3f model ){
+static void pointcloud_render( camera *cam, m4x3f model ){
if( pointcloud.anim < k_pointcloud_anim_idle_any ){
f32 const k_transition = 0.6f;
f32 t = (vg.time - pointcloud.anim_start) / k_transition;
vert->colour[i] = colour[i] * 255.0f;
}
+static void pointcloud_async_end(void *_, u32 __){
+ pointcloud_animate( k_pointcloud_anim_opening );
+}
+
+static void pointcloud_clear_async(void *_, u32 __){
+ pointcloud.count = 0;
+ pointcloud_animate( k_pointcloud_anim_opening );
+}
+
#endif /* POINTCLOUD_H */
}
}
- for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
- ent_gate *gate = mdl_arritm( &world->ent_gate, i );
- if( gate->flags & k_ent_gate_nonlocal ){
- respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0] );
- }
- }
-
for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
ent_route *route = mdl_arritm( &world->ent_route, i );
vs_motion_out( vproj0, vproj1 );
gl_Position = vproj0;
- gl_PointSize = (9.0*scaler) / (gl_Position.z + 0.01);
+ gl_PointSize = (9.0*scaler) / (max( gl_Position.z, 2.0 ));
aWorldCo = world_pos0;
aColour = a_colour*scaler*(1.0-uAnim.y*uAnim.y);
aCo = co;
return world_depth_sample( pos ) - ref_depth;
}
-float shadow_sample( vec3 vdir )
-{
- vec3 sample_pos = aWorldCo + vdir;
- float height_sample = world_depth_sample( sample_pos );
+float shadow_sample( vec3 co ){
+ float height_sample = world_depth_sample( co );
- float fdelta = height_sample - sample_pos.y;
+ float fdelta = height_sample - co.y;
return clamp( fdelta, 0.2, 0.4 )-0.2;
}
-float newlight_compute_sun_shadow( vec3 dir )
-{
- if( g_shadow_samples == 0 )
- {
+float newlight_compute_sun_shadow( vec3 co, vec3 dir ){
+ if( g_shadow_samples == 0 ){
return 1.0;
}
float flength = g_shadow_length;
float famt = 0.0;
- famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);
- famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);
- famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);
- famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);
+ famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);
+ famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);
+ famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);
+ famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);
- //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);
- //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);
- //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);
- //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);
+ //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);
+ //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);
+ //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);
+ //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);
return 1.0 - famt;
}
float fdist = length(halfview);
halfview /= fdist;
- float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz
- * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );
+ float world_shadow = newlight_compute_sun_shadow(
+ co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );
vec3 total_light = clearskies_lighting(
normal, min( light_mask, world_shadow ), halfview );
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" vs_motion_out( vproj0, vproj1 );\n"
"\n"
" gl_Position = vproj0;\n"
-" gl_PointSize = (9.0*scaler) / (gl_Position.z + 0.01);\n"
+" gl_PointSize = (9.0*scaler) / (max( gl_Position.z, 2.0 ));\n"
" aWorldCo = world_pos0;\n"
" aColour = a_colour*scaler*(1.0-uAnim.y*uAnim.y);\n"
" aCo = co;\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );
float dither = fract( vDither.g / 71.0 ) - 0.5;
- if( (aWorldCo.y*0.1 + dither) > ((uPlayerPos.y+40.0)*0.1) )
- discard;
+ float dcam = (-8.0+distance( aCo, uCamera ))/4.0;
+ if( min(aCo.y*0.5 + dither, dcam + dither) < 0.51 ) discard;
compute_motion_vectors();
- vec3 vfrag = vec3(0.5,0.5,0.5);
+ vec3 vfrag = vec3(0.6);
vec3 qnorm = aNorm.xyz;
+ qnorm = normalize(floor(aNorm.xyz*4.0)*0.25);
+ qnorm += vec3(0.001,0.0,0.0);
+
if( uAlphatest ){
vec4 vSample = texture( uTexMain, aUv );
if( vSample.a < 0.5 )
}
}
- vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );
+ vfrag = scene_compute_lighting( vfrag, qnorm, aCo );
// dots
float d0 = distance( aWorldCo, uPlayerPos.xyz )*2.0;
emit += vec3(fract(t*0.2-g_realtime+d3*0.2)*max(0.0,1.0-d3*0.2));
oColour = vec4( vfrag+emit, 1.0 );
+ oColour = vec4( vfrag, 1.0 );
}
.link = shader_scene_override_link,
.vs =
{
-.orig_file = "shaders/scene.vs",
+.orig_file = "shaders/scene_override.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
+"uniform mat3 uNormalMtx;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
" gl_Position = vproj0;\n"
"\n"
" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aNorm = vec4( a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"}\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
"\n"
-" if( (aWorldCo.y*0.1 + dither) > ((uPlayerPos.y+40.0)*0.1) )\n"
-" discard;\n"
+" float dcam = (-8.0+distance( aCo, uCamera ))/4.0;\n"
+" if( min(aCo.y*0.5 + dither, dcam + dither) < 0.51 ) discard;\n"
"\n"
" compute_motion_vectors();\n"
"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+" vec3 vfrag = vec3(0.6);\n"
" vec3 qnorm = aNorm.xyz;\n"
"\n"
+" qnorm = normalize(floor(aNorm.xyz*4.0)*0.25);\n"
+" qnorm += vec3(0.001,0.0,0.0);\n"
+"\n"
" if( uAlphatest ){\n"
" vec4 vSample = texture( uTexMain, aUv );\n"
" if( vSample.a < 0.5 )\n"
" }\n"
" }\n"
"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aCo );\n"
" \n"
" // dots\n"
" float d0 = distance( aWorldCo, uPlayerPos.xyz )*2.0;\n"
" emit += vec3(fract(t*0.2-g_realtime+d3*0.2)*max(0.0,1.0-d3*0.2));\n"
"\n"
" oColour = vec4( vfrag+emit, 1.0 );\n"
+" oColour = vec4( vfrag, 1.0 );\n"
"}\n"
""},
};
static GLuint _uniform_scene_override_uMdl;
static GLuint _uniform_scene_override_uPv;
static GLuint _uniform_scene_override_uPvmPrev;
+static GLuint _uniform_scene_override_uNormalMtx;
static GLuint _uniform_scene_override_uTexGarbage;
static GLuint _uniform_scene_override_uTexMain;
static GLuint _uniform_scene_override_uCamera;
static void shader_scene_override_uPvmPrev(m4x4f m){
glUniformMatrix4fv(_uniform_scene_override_uPvmPrev,1,GL_FALSE,(float*)m);
}
+static void shader_scene_override_uNormalMtx(m3x3f m){
+ glUniformMatrix3fv(_uniform_scene_override_uNormalMtx,1,GL_FALSE,(float*)m);
+}
static void shader_scene_override_uTexGarbage(int i){
glUniform1i(_uniform_scene_override_uTexGarbage,i);
}
_uniform_scene_override_uMdl = glGetUniformLocation( _shader_scene_override.id, "uMdl" );
_uniform_scene_override_uPv = glGetUniformLocation( _shader_scene_override.id, "uPv" );
_uniform_scene_override_uPvmPrev = glGetUniformLocation( _shader_scene_override.id, "uPvmPrev" );
+ _uniform_scene_override_uNormalMtx = glGetUniformLocation( _shader_scene_override.id, "uNormalMtx" );
_uniform_scene_override_uTexGarbage = glGetUniformLocation( _shader_scene_override.id, "uTexGarbage" );
_uniform_scene_override_uTexMain = glGetUniformLocation( _shader_scene_override.id, "uTexMain" );
_uniform_scene_override_uCamera = glGetUniformLocation( _shader_scene_override.id, "uCamera" );
--- /dev/null
+layout (location=0) in vec3 a_co;
+layout (location=1) in vec4 a_norm;
+layout (location=2) in vec2 a_uv;
+
+#include "motion_vectors_vs.glsl"
+
+uniform mat4x3 uMdl;
+uniform mat4 uPv;
+uniform mat4 uPvmPrev;
+uniform mat3 uNormalMtx;
+
+out vec2 aUv;
+out vec4 aNorm;
+out vec3 aCo;
+out vec3 aWorldCo;
+
+void main()
+{
+ vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );
+ vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );
+ vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );
+
+ vs_motion_out( vproj0, vproj1 );
+
+ gl_Position = vproj0;
+
+ aUv = a_uv;
+ aNorm = vec4( a_norm.xyz, a_norm.w );
+ aCo = a_co;
+ aWorldCo = world_pos0;
+}
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
" return world_depth_sample( pos ) - ref_depth;\n"
"}\n"
"\n"
-"float shadow_sample( vec3 vdir )\n"
-"{\n"
-" vec3 sample_pos = aWorldCo + vdir;\n"
-" float height_sample = world_depth_sample( sample_pos );\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
+" float fdelta = height_sample - co.y;\n"
" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
" return 1.0;\n"
" }\n"
"\n"
" float flength = g_shadow_length;\n"
"\n"
" float famt = 0.0;\n"
-" famt += shadow_sample((dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample((dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample((dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample((dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
"\n"
-" //famt+=shadow_sample((dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample((dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample((dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample((dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
"\n"
" return 1.0 - famt;\n"
"}\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow( g_sun_dir.xyz \n"
-" * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
"\n"
" vec3 total_light = clearskies_lighting( \n"
" normal, min( light_mask, world_shadow ), halfview );\n"
#include "network.h"
#include "menu.h"
#include "vehicle.h"
-#include "pointcloud.h"
#include "save.h"
#include "player_remote.h"
}
static void async_skaterift_player_start( void *payload, u32 size ){
- localplayer.viewable_world = world_current_instance();
- localplayer_cmd_respawn( 1, (const char *[]){ "start" } );
+ world_switch_instance(0);
}
static void async_call_ready( void *payload, u32 size ){
addon_cache_create_viewer( k_addon_type_player, player_reg_id );
kvsav.cur = orig;
+
+#if 0
if( vg_msg_seekframe( &kvsav, "world" ) ){
addon_alias q;
if( v3_length2(pos) > 1.0f )
player__setpos( pos );
}
+#endif
}
static void vg_load(void){
return;
}
- vg_console_reg_cmd( "changeworld", skaterift_change_world_command, NULL );
+ vg_console_reg_cmd( "load_world", skaterift_load_world_command, NULL );
+ vg_console_reg_cmd( "switch_active_instance",
+ skaterift_switch_instance_cmd, NULL );
vg_loader_step( render_init, NULL );
vg_loader_step( menu_init, NULL );
- vg_loader_step( pointcloud_init, NULL );
vg_loader_step( world_init, NULL );
vg_loader_step( vehicle_init, NULL );
vg_loader_step( font3d_init, NULL );
* -------------------------------------
*/
+ /* hub world */
+ addon_reg *hub =
+ addon_mount_local_addon( "maps/dev_hub", k_addon_type_world, ".mdl" );
+ hub->metadata_len = 0;
+
/* understate diy. */
addon_reg *spawn = addon_mount_local_addon( "maps/mp_spawn",
k_addon_type_world,
/* load home/permanent world manually */
world_static.load_state = k_world_loader_load;
+
struct world_load_args args = {
.purpose = k_world_purpose_hub,
- .reg = spawn
+ .reg = hub
};
skaterift_world_load_thread( &args );
vg_async_call( async_skaterift_player_start, NULL, 0 );
vg_async_stall();
-
- global_skateshop.selected_world_id=1;
- global_skateshop.pointcloud_world_id=1;
- skateshop_world_preview_loader_thread( mtzero ); /* HACK */
-
vg_console_load_autos();
menu_link();
vg_slewf( &skaterift.time_rate, target, vg.time_frame_delta * (1.0f/0.3f) );
vg.time_rate = vg_smoothstepf( skaterift.time_rate );
+ /* TODO: how can we compress this? */
player__pre_update();
world_entity_focus_preupdate();
skaterift_replay_pre_update();
if( skaterift.activity == k_skaterift_respawning ){
glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } );
glClearColor( 0.624f, 0.659f, 0.769f, 0.0f );
+ glClearColor( 0.824f, 0.0f, 0.1f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT );
glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1 } );
+#if 0
view_world = &world_static.instances[respawn_chooser.world_id];
render_world_override( view_world );
render_world_routes( view_world, &skaterift.cam, 1 );
+#endif
}
else{
render_world( view_world, &skaterift.cam, 0 );
render_fb_bind( gpipeline.fb_main, 1 );
render_water_surface( view_world, &skaterift.cam );
render_remote_players( view_world, &skaterift.cam );
+ ent_miniworld_render( view_world );
}
+
}
static void render_scene_gate_subview(void){
world_instance *view_world = localplayer.viewable_world;
if( (view_world != NULL) && (skaterift.activity != k_skaterift_respawning) ){
render_world_cubemaps( view_world );
-
- ent_gate *gate = view_world->rendering_gate;
- if( gate ){
- if( gate->flags & k_ent_gate_nonlocal ){
- world_instance *dest = &world_static.instances[ gate->target ];
- render_world_cubemaps( dest );
- }
- }
}
/* variable res target */
}
static gzoomer =
{
- .obj = { .type = k_rb_shape_sphere, .inf.sphere.radius = 1.0f }
+ .obj = { .type = k_rb_shape_sphere, .inf.sphere.radius = 1.0f,
+ .rb.co = {-2000,-2000,-2000}}
};
static int spawn_car( int argc, const char *argv[] );
VG_MEMORY_SYSTEM );
}
-static void world_set_active_instance( u32 index ){
- world_static.challenge_target = NULL;
- world_static.challenge_timer = 0.0f;
- world_static.focused_entity = 0;
- world_static.focus_strength = 0.0f;
- world_static.active_trigger_volume_count = 0;
+static void world_switch_instance( u32 index ){
+ assert( localplayer.subsystem == k_player_subsystem_walk );
+
+ if( index >= vg_list_size(world_static.instances) ){
+ vg_error( "Instance ID out of range (%u)\n", index );
+ return;
+ }
+
+ world_instance *new = &world_static.instances[ index ];
+
+ if( new->status != k_world_status_loaded ){
+ vg_error( "Instance is not loaded (%u)\n", index );
+ return;
+ }
+
+ if( index != world_static.active_instance ){
+ world_instance *current =
+ &world_static.instances[ world_static.active_instance ];
+ v3_copy( localplayer.rb.co, current->player_co );
+ v3_copy( localplayer.angles, current->player_angles );
+ current->player_angles[3] = player_get_heading_yaw();
+ }
+
+ v3_copy( new->player_co, localplayer.rb.co );
+ v3_copy( new->player_angles, localplayer.angles );
+ q_axis_angle( localplayer.rb.q, (v3f){0,1,0}, new->player_angles[3] );
+
world_static.active_instance = index;
+
+ player__reset();
+}
+
+static int skaterift_switch_instance_cmd( int argc, const char *argv[] ){
+ if( argc )
+ world_switch_instance( atoi(argv[0]) );
+ else
+ vg_info( "switch_active_instance <id>\n" );
+ return 0;
}
static void skaterift_world_get_save_path( enum world_purpose which,
};
enum world_purpose{
+ k_world_purpose_invalid = -1,
k_world_purpose_hub = 0,
k_world_purpose_client = 1,
k_world_max
* -------------------------------------------------------
*/
+ v4f player_co, player_angles;
+
void *heap;
enum world_status{
k_world_status_unloaded = 0,
ent_objective,
ent_challenge,
ent_relay,
- ent_cubemap;
+ ent_cubemap,
+ ent_miniworld;
ent_gate *rendering_gate;
static void world_init(void);
static world_instance *world_current_instance(void);
-static void world_set_active_instance( u32 index );
+static void world_switch_instance( u32 index );
#endif /* WORLD_H */
for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
ent_gate *gate = mdl_arritm( &world->ent_gate, j );
- if( !(gate->flags & k_ent_gate_nonlocal) ) {
+ if( !(gate->flags & k_ent_gate_nonlocal_DELETED) ) {
gate_transform_update( gate );
}
}
- vg_async_call( world_link_nonlocal_async, world, 0 );
/* water */
for( u32 j=0; j<mdl_arrcount(&world->ent_water); j++ ){
}
}
+/*
+ * used for relinking multi-world data. ran anytime the world setup changes
+ */
+static void world_entity_relink( world_instance *world ){
+ vg_info( "entity_relink(%d)\n", world - world_static.instances );
+ for( u32 i=0; i<mdl_arrcount(&world->ent_miniworld); i++ ){
+ ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld, i );
+ miniworld->purpose = k_world_purpose_invalid;
+
+ const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world );
+ addon_alias q;
+ addon_uid_to_alias( uid, &q );
+
+ u32 addon_id = addon_match( &q );
+ if( addon_id != 0xffffffff ){
+ addon_reg *reg = get_addon_from_index( k_addon_type_world, addon_id );
+
+ for( int j=0; j<k_world_max; j ++ ){
+ world_instance *other = &world_static.instances[j];
+ if( other == world ) continue;
+ if( (other->status == k_world_status_loaded) &&
+ (world_static.instance_addons[j] == reg) ){
+ miniworld->purpose = j;
+ break;
+ }
+ }
+ }
+ }
+}
+
static void world_entity_serialize( world_instance *world, vg_msg *sav ){
for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
ent_challenge *challenge = mdl_arritm(&world->ent_challenge,i);
static ent_spawn *world_find_closest_spawn( world_instance *world,
v3f position );
static void world_entity_start( world_instance *world, vg_msg *sav );
+static void world_entity_relink( world_instance *world );
static void world_entity_serialize( world_instance *world, vg_msg *sav );
static void ent_volume_call( world_instance *world, ent_call *call );
world_gates.sm_marker[i] = *sm;
}
+ mdl_mesh *icosphere = mdl_find_mesh( &mgate, "rs_icosphere" );
+ world_gates.sm_icosphere =
+ *((mdl_submesh *)mdl_arritm( &mgate.submeshs, icosphere->submesh_start ));
+
mdl_async_load_glmesh( &mgate, &world_gates.mesh );
mdl_close( &mgate );
}
if( !(gate->flags & k_ent_gate_linked) ) continue;
if( gate->flags & k_ent_gate_locked ) continue;
- if( gate->flags & k_ent_gate_nonlocal )
- if( world_static.load_state != k_world_loader_none )
- continue;
+ if( gate->flags & k_ent_gate_nonlocal_DELETED )
+ continue;
if( gate_intersect( gate, pos, last ) )
return mdl_entity_id( k_ent_gate, i );
return 0;
}
-/*
- * detatches any nonlocal gates
- */
-static void world_unlink_nonlocal( world_instance *world ){
- for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
- ent_gate *gate = mdl_arritm( &world->ent_gate, j );
-
- if( gate->flags & k_ent_gate_nonlocal ){
- gate->flags &= ~k_ent_gate_linked;
- }
- }
-}
-
-/*
- * attatches nonlocal gates, to be called from main thread ONLY!
- */
-static void world_link_nonlocal_async( void *payload, u32 size ){
- world_instance *world = payload;
- u32 world_id = world - world_static.instances;
-
- for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
- ent_gate *gate = mdl_arritm( &world->ent_gate, j );
-
- if( !(gate->flags & k_ent_gate_nonlocal) ) continue;
- if( gate->flags & k_ent_gate_linked ) continue;
-
- const char *key = mdl_pstr( &world->meta, gate->key );
- vg_info( "key: %s\n", key );
-
- for( u32 i=0; i<vg_list_size(world_static.instances); i++ ){
- world_instance *other = &world_static.instances[i];
- if( other == world ) continue;
- if( other->status != k_world_status_loaded ) continue;
- vg_info( "Checking world %u for key matches\n", i );
-
- for( u32 k=0; k<mdl_arrcount( &other->ent_gate ); k++ ){
- ent_gate *gate2 = mdl_arritm( &other->ent_gate, k );
-
- if( !(gate2->flags & k_ent_gate_nonlocal) ) continue;
- if( gate2->flags & k_ent_gate_linked ) continue;
-
- const char *key2 = mdl_pstr( &other->meta, gate2->key );
- vg_info( " key2: %s\n", key2 );
-
- if( strcmp( key, key2 ) ) continue;
-
- vg_success( "Non-local matching pair '%s' found. (%u:%u)\n",
- key, world_id, i );
-
- gate->flags |= k_ent_gate_linked;
- gate2->flags |= k_ent_gate_linked;
- gate->target = i;
- gate2->target = world_id;
-
- v3_copy( gate->co[0], gate2->co[1] );
- v3_copy( gate2->co[0], gate->co[1] );
- v4_copy( gate->q[0], gate2->q[1] );
- v4_copy( gate2->q[0], gate->q[1] );
-
- if( world->meta.info.version < 102 ){
- /* LEGACY BEHAVIOUR: v101
- * this would flip both the client worlds portal's entrance and
- * exit. effectively the clients portal would be the opposite
- * to the hub worlds one. new behaviour is to just flip the
- * destinations so the rules are consistent in each world.
- */
- v4f qflip;
- q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf );
- q_mul( gate->q[0], qflip, gate->q[0] );
- q_mul( gate->q[1], qflip, gate->q[1] );
- q_mul( gate2->q[1], qflip, gate2->q[1] );
- }
-
- gate_transform_update( gate );
- gate_transform_update( gate2 );
-
- goto matched;
- }
- } matched:;
- }
-}
-
static void ent_gate_call( world_instance *world, ent_call *call ){
u32 index = mdl_entity_id_id( call->id );
ent_gate *gate = mdl_arritm( &world->ent_gate, index );
struct world_gates{
glmesh mesh;
- mdl_submesh sm_surface, sm_marker[4];
+ mdl_submesh sm_surface, sm_marker[4], sm_icosphere;
camera cam;
+
+ v3f userportal_co;
}
static world_gates;
static void world_gates_init(void);
static void gate_transform_update( ent_gate *gate );
-static void world_link_nonlocal_async( void *payload, u32 size );
-static void world_unlink_nonlocal( world_instance *world );
static int render_gate( world_instance *world, world_instance *world_inside,
ent_gate *gate, camera *cam, int layer_depth );
}
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- world->status = k_world_status_loaded;
}
/* Loads textures from the pack file */
mdl_load_animation_block( meta, world->heap );
mdl_load_mesh_block( meta, world->heap );
+ /* TODO: Make this a table? */
mdl_load_array( meta, &world->ent_gate, "ent_gate", heap );
mdl_load_array( meta, &world->ent_camera, "ent_camera", heap );
mdl_load_array( meta, &world->ent_spawn, "ent_spawn", heap );
mdl_load_array( meta, &world->ent_challenge, "ent_challenge", heap );
mdl_load_array( meta, &world->ent_relay, "ent_relay", heap );
mdl_load_array( meta, &world->ent_cubemap, "ent_cubemap", heap );
+ mdl_load_array( meta, &world->ent_miniworld, "ent_miniworld", heap );
mdl_array_ptr infos;
mdl_load_array( meta, &infos, "ent_worldinfo", vg_mem.scratch );
world_gen_compute_light_indices( world );
mdl_close( meta );
+ /* init player position.
+ * - this is overriden by the save state when(if) it loads */
+ v3_zero( world->player_angles );
+ ent_spawn *rp = world_find_spawn_by_name( world, "start" );
+ if( !rp ) rp = world_find_closest_spawn( world, (v3f){0.0f,0.0f,0.0f} );
+
+ /* TODO: fallback to searching for a safe location using raycasts */
+ assert(rp);
+ v3_copy( rp->transform.co, world->player_co );
+
/* allocate leaderboard buffers */
u32 bs = mdl_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache);
world->leaderboard_cache = vg_linear_alloc( heap, bs );
struct world_load_complete_data{
savedata_file save;
- u32 instance_start, instance_count;
+ enum world_purpose purpose;
};
static void skaterift_world_load_done( void *payload, u32 size ){
struct world_load_complete_data *data = payload;
+ /* TODO(W2): Load player position from this save file */
vg_msg sav;
vg_msg_init( &sav, data->save.buf, data->save.len );
- for( u32 i=0; i<data->instance_count; i++ ){
- world_instance *world = &world_static.instances[ data->instance_start+i ];
- world_entity_start( world, &sav );
- }
-
+ world_instance *world = &world_static.instances[ data->purpose ];
+ world_entity_start( world, &sav );
+ world->status = k_world_status_loaded;
world_static.load_state = k_world_loader_none;
+
+ for( int i=0; i<k_world_max; i ++ ){
+ world_instance *wi = &world_static.instances[i];
+
+ if( wi->status == k_world_status_loaded )
+ world_entity_relink( wi );
+ }
}
struct world_load_args {
* Does a complete world switch using the remaining free slots
*/
static void skaterift_world_load_thread( void *_args ){
- struct world_load_args *args = _args;
+ /* FIXME: we need to check all threads that take args. args can dissapear! */
+ struct world_load_args args = *((struct world_load_args *)_args);
+
+ addon_reg *reg = args.reg;
+ world_static.instance_addons[ args.purpose ] = reg;
- addon_reg *reg = args->reg;
- world_static.instance_addons[ args->purpose ] = reg;
+ char uid[ADDON_UID_MAX];
+ addon_alias_uid( ®->alias, uid );
+ vg_info( "LOAD WORLD %s @%d\n", uid, args.purpose );
char path_buf[4096];
vg_str path;
}
}
- u32 instance_start = 0, instance_count = 1;
- if( args->purpose == k_world_purpose_client ) instance_start = 1;
-
- world_instance_load_mdl( instance_start, worlds[first_index] );
-
- /* TODO: Support multiply packed worlds */
-#if 0
- world_loader.generate_point_cloud = 0;
- for( u32 j=0; j<i; j++ ){
- if( j != first_index ){
- world_loader.world_index = j+1;
- world_load_mdl( worlds[j] );
- }
- }
-#endif
+ world_instance_load_mdl( args.purpose, worlds[first_index] );
vg_async_item *final_call =
vg_async_alloc( sizeof(struct world_load_complete_data) );
struct world_load_complete_data *data = final_call->payload;
- data->instance_start = instance_start;
- data->instance_count = instance_count;
+ data->purpose = args.purpose;
- skaterift_world_get_save_path( args->purpose, data->save.path );
+ skaterift_world_get_save_path( args.purpose, data->save.path );
savedata_file_read( &data->save );
vg_async_dispatch( final_call, skaterift_world_load_done );
vg_linear_clear( vg_mem.scratch ); /* ?? */
vg_info( "unloading old worlds\n" );
- world_unlink_nonlocal( &world_static.instances[0] );
for( u32 i=1; i<vg_list_size(world_static.instances); i++ ){
world_instance *inst = &world_static.instances[i];
}
}
+ world_entity_relink( &world_static.instances[k_world_purpose_hub] );
+
world_static.instance_addons[ k_world_purpose_client ] = reg;
network_send_item( k_netmsg_playeritem_world1 );
relink_all_remote_player_worlds();
}
/* console command for the above function */
-static int skaterift_change_world_command( int argc, const char *argv[] ){
- if( !vg_loader_availible() ) return 0;
+static int skaterift_load_world_command( int argc, const char *argv[] ){
+ if( !vg_loader_availible() ) return 0; /* FIXME */
if( argc == 1 ){
addon_alias q;
- q.type = k_addon_type_world;
- q.workshop_id = 0;
- vg_strncpy( argv[0], q.foldername, 64, k_strncpy_always_add_null );
+ addon_uid_to_alias( argv[0], &q );
u32 reg_id = addon_match( &q );
if( reg_id != 0xffffffff ){
skaterift_change_world_start( reg );
}
else {
- char buf[76];
- addon_alias_uid( &q, buf );
- vg_error( "Addon '%s' is not installed or not found.\n", buf );
+ vg_error( "Addon '%s' is not installed or not found.\n", argv[0] );
+ }
+ }
+ else {
+ vg_info( "worlds availible to load:\n" );
+
+ for( int i=0; i<addon_count(k_addon_type_world); i ++ ){
+ addon_reg *w = get_addon_from_index( k_addon_type_world, i );
+
+ char buf[ADDON_UID_MAX];
+ addon_alias_uid( &w->alias, buf );
+ vg_info( " %s\n", buf );
}
}
static void world_free( world_instance *world );
static int world_freeable( world_instance *world );
+static int skaterift_load_world_command( int argc, const char *argv[] );
#endif /* WORLD_LOAD_H */
struct world_surface *mat );
void (*fn_set_mdl)( m4x3f mdl );
void (*fn_set_uPvmPrev)( m4x4f pvm );
+ void (*fn_set_uNormalMtx)( m3x3f mnorm );
};
static
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) )
+ if( !(gi->flags & (k_ent_gate_linked|k_ent_gate_nonlocal_DELETED|
+ k_ent_gate_locked)) )
continue;
float dist = v3_dist2( gi->co[0], cam->transform[3] );
}
world->rendering_gate = gate;
- if( gate ){
- if( gate->flags & k_ent_gate_locked ) return;
-
- if( gate->flags & k_ent_gate_nonlocal ){
- if( world_static.load_state != k_world_loader_none ){
- world->rendering_gate = NULL;
- return;
- }
-
- world_instance *dest_world = &world_static.instances[ gate->target ];
- render_gate( world, dest_world, gate, cam, layer_depth );
- }
- else{
- render_gate( world, world, gate, cam, layer_depth );
- }
- }
+ if( gate )
+ render_gate( world, world, gate, cam, layer_depth );
}
static void world_prerender( world_instance *world ){
}
-static
-void render_world_override_pass( world_instance *world,
- struct world_pass *pass ){
+static void render_world_override_pass( world_instance *world,
+ struct world_pass *pass,
+ m4x3f mmdl, m3x3f mnormal,
+ m4x4f mpvm_prev ){
for( int i=0; i<world->surface_count; i++ ){
struct world_surface *mat = &world->surfaces[i];
if( !sm->indice_count )
continue;
- m4x3f mmdl;
- m4x3_identity( mmdl );
pass->fn_set_mdl( mmdl );
- pass->fn_set_uPvmPrev( pass->cam->mtx_prev.pv );
+ pass->fn_set_uNormalMtx( mnormal );
+ pass->fn_set_uPvmPrev( mpvm_prev );
pass->fn_bind_textures( world, mat );
mdl_draw_submesh( sm );
}
}
-static void render_world_override( world_instance *world ){
+static void render_world_override( world_instance *world, m4x3f mmdl ){
struct world_pass pass = {
.cam = &skaterift.cam,
.fn_bind_textures = bindpoint_override,
.fn_set_mdl = shader_scene_override_uMdl,
.fn_set_uPvmPrev = shader_scene_override_uPvmPrev,
+ .fn_set_uNormalMtx = shader_scene_override_uNormalMtx,
.shader = k_shader_override
};
WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_override );
bind_terrain_noise();
- shader_scene_override_uCamera( pass.cam->transform[3] );
+
+ m4x3f mmdl_inv;
+ m4x3_invert_full( mmdl, mmdl_inv );
+
+ v3f cam_pos;
+ m4x3_mulv( mmdl_inv, pass.cam->transform[3], cam_pos );
+ shader_scene_override_uCamera( cam_pos );
+
+ m4x4f mpvm_prev;
+ m4x3_expand( mmdl, mpvm_prev );
+ m4x4_mul( skaterift.cam.mtx_prev.pv, mpvm_prev, mpvm_prev );
+
+ m3x3f mnormal;
+ m3x3_inv( mmdl_inv, mnormal );
+ m3x3_transpose( mnormal, mnormal );
+ v3_normalize( mnormal[0] );
+ v3_normalize( mnormal[1] );
+ v3_normalize( mnormal[2] );
glDisable( GL_CULL_FACE );
mesh_bind( &world->mesh_geo );
pass.geo_type = k_world_geo_type_solid;
- render_world_override_pass( world, &pass );
+ render_world_override_pass( world, &pass, mmdl, mnormal, mpvm_prev );
mesh_bind( &world->mesh_no_collide );
pass.geo_type = k_world_geo_type_nonsolid;
- render_world_override_pass( world, &pass );
+ render_world_override_pass( world, &pass, mmdl, mnormal, mpvm_prev );
glEnable( GL_CULL_FACE );
}
int layer_depth );
static void render_world_cubemaps( world_instance *world );
static void bind_terrain_noise(void);
+static void render_world_override( world_instance *world, m4x3f mmdl );
#define WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( WORLD, SHADER ) \
world_link_lighting_ub( WORLD, _shader_##SHADER.id ); \
#include "network.h"
#include "font.h"
-#include "pointcloud.h"
#include "gui.h"
#include "steam.h"
#include "network_msg.h"
ent_gate *rg )
{
world_static.last_use = world_static.time;
-
- /* disable all routes and leave the world */
- if( rg->flags & k_ent_gate_nonlocal ){
- for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
- ent_route *route = mdl_arritm( &world->ent_route, i );
- route->active_checkpoint = 0xffff;
- }
- return;
- }
-
ent_gate *dest = mdl_arritm( &world->ent_gate, rg->target );
for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
}
}
-static
-void world_routes_pointcloud_spot( world_instance *world,
- pointcloud_buffer *pcbuf,
- v3f co, f32 radius, u32 samples, v4f colour )
-{
- v3f inv_ext;
- v3_sub( pcbuf->boundary[1], pcbuf->boundary[0], inv_ext );
- v3_div( (v3f){1.0f,1.0f,1.0f}, inv_ext, inv_ext );
-
- for( u32 j=0; j<samples; j++ ){
- if( pcbuf->count >= pcbuf->max )
- return;
-
- pointcloud_vert *vert = &pcbuf->buf[ pcbuf->count ++ ];
-
- v3f sample, jitter, point;
- vg_rand_sphere( jitter );
- v3_muladds( co, jitter, radius, sample );
-
- if( bh_closest_point( world->geo_bh, sample, point, radius*1.5f ) == -1 ){
- v3_copy( sample, point );
- }
-
- v3f pos;
- v3_sub( point, pcbuf->boundary[0], pos );
- v3_mul( pos, inv_ext, pos );
-
- float dist = 1.0f-(v3_length(jitter));
-
- v4f final_colour;
- v4_muls( colour, dist*dist, final_colour );
-
- pointcloud_packvert( vert, pos, final_colour );
- }
-}
-
-/*
- * '
- * .
- * |
- * |
- * /#\
- * -'###`-
- */
-static
-void world_routes_pointcloud_tower( world_instance *world,
- pointcloud_buffer *pcbuf,
- v3f co, f32 radius, f32 height,
- u32 samples, v4f colour )
-{
- v3f inv_ext;
- v3_sub( pcbuf->boundary[1], pcbuf->boundary[0], inv_ext );
- v3_div( (v3f){1.0f,1.0f,1.0f}, inv_ext, inv_ext );
-
- for( u32 j=0; j<samples; j++ ){
- if( pcbuf->count >= pcbuf->max )
- return;
-
- pointcloud_vert *vert = &pcbuf->buf[ pcbuf->count ++ ];
-
- v3f point;
- point[0] = vg_randf64()*2.0f-1.0f;
- point[1] = 0.0f;
- point[2] = vg_randf64()*2.0f-1.0f;
- v3_normalize( point );
- v3_muls( point, sqrtf(vg_randf64()), point );
-
- f32 h = vg_randf64();
- point[1] = h*h*h*height;
- point[0] *= radius;
- point[2] *= radius;
-
- v3_add( point, co, point );
- v3_sub( point, pcbuf->boundary[0], point );
- v3_mul( point, inv_ext, point );
-
- pointcloud_packvert( vert, point, colour );
- }
-}
static
void world_routes_place_curve( world_instance *world, ent_route *route,
- v4f h[3], v3f n0, v3f n2, scene_context *scene,
- pointcloud_buffer *pcbuf )
+ v4f h[3], v3f n0, v3f n2, scene_context *scene )
{
float t;
v3f p, pd;
int resa = ray_world( world, sa, down, &ha, k_material_flag_ghosts ),
resb = ray_world( world, sb, down, &hb, k_material_flag_ghosts );
-
- if( pcbuf && resa ){
- world_routes_pointcloud_spot( world, pcbuf, ha.pos,
- 12.0f, 10, route->colour );
- }
if( resa && resb ){
struct world_surface *surfa = ray_hit_surface( world, &ha ),
}
static void world_routes_gen_meshes( world_instance *world, u32 route_id,
- scene_context *sc,
- pointcloud_buffer *pcbuf )
+ scene_context *sc )
{
ent_route *route = mdl_arritm( &world->ent_route, route_id );
u8 colour[4];
v3_normalize( n0 );
v3_normalize( n2 );
- world_routes_place_curve( world, route, p, n0, n2, sc, pcbuf );
+ world_routes_place_curve( world, route, p, n0, n2, sc );
/* --- */
v4_copy( p[2], p[0] );
struct world_surface *world_tri_index_surface( world_instance *world,
u32 index );
-static f64 world_routes_scatter_surface_points( world_instance *world,
- pointcloud_buffer *pcbuf,
- f32 rate )
-{
- static f32 densities[] = {
- [k_surface_prop_concrete] = 2.0f,
- [k_surface_prop_grass] = 0.8f,
- [k_surface_prop_metal] = 1.0f,
- [k_surface_prop_wood] = 2.5f,
- [k_surface_prop_tiles] = 4.0f
- };
-
- /* calculate total area */
- f64 total_area = 0.0f;
- for( u32 i=0; i<world->scene_geo.indice_count/3; i++ ){
- u32 *tri = &world->scene_geo.arrindices[i*3];
- struct world_surface *surf = world_tri_index_surface( world, tri[0] );
-
- if( surf->info.shader == k_shader_boundary ||
- surf->info.shader == k_shader_invisible ) continue;
-
- if( !(surf->info.flags & k_material_flag_preview_visibile) ) continue;
-
- scene_vert *va = &world->scene_geo.arrvertices[tri[0]],
- *vb = &world->scene_geo.arrvertices[tri[1]],
- *vc = &world->scene_geo.arrvertices[tri[2]];
-
- v3f v0, v1, vn;
- v3_sub( vb->co, va->co, v0 );
- v3_sub( vc->co, va->co, v1 );
- v3_cross( v0, v1, vn );
- if( vn[1] < 0.0f ) continue;
-
- f32 density = 1.0f;
- if( surf->info.surface_prop < vg_list_size(densities) )
- density = densities[surf->info.surface_prop];
- total_area += v3_length(vn)*0.5f*density;
- }
-
- f32 accum = 0.0f;
-
- u8 colour[] = { 80,80,80,255 };
- v3f light_dir = {0.3f,0.8f,0.1f};
- v3_normalize( light_dir );
-
- v3f inv_ext;
- v3_sub( pcbuf->boundary[1], pcbuf->boundary[0], inv_ext );
- v3_div( (v3f){1.0f,1.0f,1.0f}, inv_ext, inv_ext );
-
- for( u32 i=0; i<world->scene_geo.indice_count/3; i++ ){
- u32 *tri = &world->scene_geo.arrindices[i*3];
- struct world_surface *surf = world_tri_index_surface( world, tri[0] );
-
- if( surf->info.shader == k_shader_boundary ||
- surf->info.shader == k_shader_invisible ) continue;
-
- if( !(surf->info.flags & k_material_flag_preview_visibile) ) continue;
-
- scene_vert *va = &world->scene_geo.arrvertices[tri[0]],
- *vb = &world->scene_geo.arrvertices[tri[1]],
- *vc = &world->scene_geo.arrvertices[tri[2]];
-
- v3f v0, v1, vn;
- v3_sub( vb->co, va->co, v0 );
- v3_sub( vc->co, va->co, v1 );
- v3_cross( v0, v1, vn );
- if( vn[1] < 0.0f ) continue;
-
- f32 density = 1.0f;
- if( surf->info.surface_prop < vg_list_size(densities) )
- density = densities[surf->info.surface_prop];
-
- f32 area = v3_length(vn)*0.5f*density;
- accum += area;
-
- v3_normalize( vn );
-
- while( accum > rate ){
- accum -= rate;
-
- if( pcbuf->count >= pcbuf->max ) return total_area;
-
- v2f co = { vg_randf64(), vg_randf64() };
- if( v2_length2(co) > 0.5f ){
- co[0] = 1.0f-co[0];
- co[1] = 1.0f-co[1];
- }
-
- v3f pt;
- v3_muls( v0, co[0], pt );
- v3_muladds( pt, v1, co[1], pt );
- v3_add( va->co, pt, pt );
-
- if( pt[1] < world->water.height ) continue;
- pointcloud_vert *vert = &pcbuf->buf[ pcbuf->count ++ ];
-
- v3f pos;
- v3_sub( pt, pcbuf->boundary[0], pos );
- v3_mul( pos, inv_ext, pos );
-
- static v4f colours[] = {
- [k_surface_prop_concrete] = { 0.13, 0.15, 0.17, 1.0 },
- [k_surface_prop_grass] = { 0.07, 0.1, 0.14, 1.0 },
- [k_surface_prop_metal] = { 0.15, 0.19, 0.22, 1.0 },
- [k_surface_prop_wood] = { 0.1, 0.13, 0.17, 1.0 },
- [k_surface_prop_tiles] = { 0.05, 0.06, 0.07, 1.0 },
- };
-
- v4f col = {0.0f,0.0f,0.0f,0.0f};
- if( surf->info.surface_prop < vg_list_size(colours) )
- v4_copy( colours[surf->info.surface_prop], col );
-
- f32 brightness = v3_dot(vn,light_dir)*0.5f+0.5f;
- v3_muls( col, brightness, col );
-
- pointcloud_packvert( vert, pos, col );
- }
- }
-
- return total_area;
-}
-
-static void world_routes_surface_grid( world_instance *world,
- pointcloud_buffer *pcbuf )
-{
- i32 const k_gridlines = 32,
- k_gridres = 255;
-
- v3f inv_ext;
- v3_sub( pcbuf->boundary[1], pcbuf->boundary[0], inv_ext );
- v3_div( (v3f){1.0f,1.0f,1.0f}, inv_ext, inv_ext );
- v4f colour = {0.2f,0.2f,0.2f,1.0f};
- v3f dir = {0.0f,-1.0f,0.0f};
-
- for( u32 k=0; k<2; k++ ){
- u32 a = k*2,
- b = (k^0x1)*2;
-
- for( i32 x=0; x<=k_gridlines; x++ ){
- f32 t = (float)x / (float)k_gridlines,
- px = vg_lerpf( pcbuf->boundary[0][a], pcbuf->boundary[1][a], t );
-
- for( i32 z=0; z<=k_gridres; z++ ){
- f32 tz = (float)z / (float)k_gridres,
- pz = vg_lerpf(pcbuf->boundary[0][b],pcbuf->boundary[1][b], tz);
-
- v3f ro, hit;
- ro[a] = px;
- ro[1] = 1000.0f;
- ro[b] = pz;
-
- bh_iter it;
- bh_iter_init_ray( 0, &it, ro, dir, INFINITY );
- i32 idx;
-
- while( bh_next( world->geo_bh, &it, &idx ) ){
- u32 *tri = &world->scene_geo.arrindices[ idx*3 ];
- v3f vs[3];
-
- u16 mask = k_material_flag_preview_visibile;
- if( !(world->scene_geo.arrvertices[tri[0]].flags & mask) )
- continue;
-
- for( u32 i=0; i<3; i++ ){
- v3_copy( world->scene_geo.arrvertices[tri[i]].co, vs[i] );
- }
-
- f32 t;
- if( ray_tri( vs, ro, dir, &t ) ){
- v3_muladds( ro, dir, t, hit );
-
- if( world->water.enabled )
- if( hit[1] < world->water.height )
- continue;
-
- if( pcbuf->count >= pcbuf->max ) return;
-
- pointcloud_vert *vert = &pcbuf->buf[ pcbuf->count ++ ];
-
- v3f co;
- v3_sub( hit, pcbuf->boundary[0], co );
- v3_mul( co, inv_ext, co );
-
- pointcloud_packvert( vert, co, colour );
- }
- }
- }
- }
- }
-}
-
-static void world_write_preview( addon_reg *reg, pointcloud_buffer *pcbuf ){
- if( reg->alias.workshop_id ) return;
-
- /*
- * FIXME: BUG: cannot correctly handle workshop because there is a stalling
- * call below, which deadlocks the scene upload. TODO: improve the async
- * stack to handle out of order execution. MAYBE
- */
-
- char path_buf[4096];
- vg_str path;
- vg_strnull( &path, path_buf, 4096 );
-
- addon_get_content_folder( reg, &path );
- vg_strcat( &path, "/preview.bin" );
-
- if( !vg_strgood( &path ) ) vg_fatal_error( "Path too long\n" );
- FILE *fp = fopen( path_buf, "wb" );
- if( !fp ) vg_fatal_error( "Cannot open '%s' for writing\n", path_buf );
-
- fwrite( pcbuf, sizeof(struct pointcloud_buffer) +
- sizeof(struct pointcloud_vert)*pcbuf->count, 1, fp );
- fclose( fp );
- vg_info( "written %s\n", path_buf );
-}
-
/*
* Create the strips of colour that run through the world along course paths
*/
&world->mesh_route_lines,
200000, 300000 );
- vg_async_item *call_pointcloud = NULL;
- pointcloud_buffer *pcbuf = NULL;
-
- if( instance_id <= 1 /*world_loader.generate_point_cloud*/ ){
- call_pointcloud = vg_async_alloc(
- sizeof(pointcloud_buffer) +
- sizeof(pointcloud_vert)*POINTCLOUD_POINTS );
- pcbuf = call_pointcloud->payload;
- pcbuf->count = 0;
- pcbuf->max = POINTCLOUD_POINTS;
- pcbuf->op = k_pointcloud_op_clear;
-
- v3f ext, mid, v0;
- v3_sub( world->scene_geo.bbx[1], world->scene_geo.bbx[0], ext );
- f32 maxe = v3_maxf( ext );
- v3_fill( v0, maxe * 0.5f );
- v3_muladds( world->scene_geo.bbx[0], ext, 0.5f, mid );
- v3_add( mid, v0, pcbuf->boundary[1] );
- v3_sub( mid, v0, pcbuf->boundary[0] );
- }
-
for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
ent_gate *gate = mdl_arritm( &world->ent_gate, i );
gate->ref_count = 0;
}
for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
- world_routes_gen_meshes( world, i, &world->scene_lines, pcbuf );
- }
-
- if( instance_id <= 1 /*world_loader.generate_point_cloud*/ ){
- f64 area = 0.0;
-
- area = world_routes_scatter_surface_points( world, pcbuf, 16.0f );
- world_routes_surface_grid( world, pcbuf );
-
- for( u32 i=0; i<mdl_arrcount( &world->ent_gate ); i++ ){
- ent_gate *gate = mdl_arritm( &world->ent_gate, i );
-
- world_routes_pointcloud_tower( world, pcbuf, gate->co[0],
- 2.0f, 50.0f, 128,
- (v4f){0.2f,0.2f,0.2f,1.0f} );
- }
-
- vg_info( "Distributed %u points over %fkm^2!\n",
- pcbuf->count, area/1e6f );
-
- world_write_preview( world_static.instance_addons[ instance_id ], pcbuf );
- vg_async_dispatch( call_pointcloud, async_pointcloud_sub );
+ world_routes_gen_meshes( world, i, &world->scene_lines );
}
vg_async_dispatch( call_scene, async_scene_upload );
}
if( (gate->flags & k_ent_gate_linked) &
- !(gate->flags & k_ent_gate_nonlocal) ){
+ !(gate->flags & k_ent_gate_nonlocal_DELETED) ){
gate = mdl_arritm(&world->ent_gate, gate->target );
for( u32 k=0; k<4; k++ ){
for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
ent_gate *gate = mdl_arritm( &world->ent_gate, j );
- if( !(gate->flags & k_ent_gate_nonlocal) )
+ if( !(gate->flags & k_ent_gate_nonlocal_DELETED) )
render_gate_markers( i, gate );
}
}