m4x3_mulv( mats[k_chpart_body1], offs[k_chpart_neck],
mats[k_chpart_neck][3] );
+#if 1
v4f qhead;
q_axis_angle( qhead, (v3f){ 0.0f,1.0f,0.0f }, ch->rhead );
q_m3x3( qhead, mats[k_chpart_head] );
- //m3x3_mul( mats[k_chpart_neck], mats[k_chpart_head], mats[k_chpart_head] );
m4x3_mulv( mats[k_chpart_neck], offs[k_chpart_head], mats[k_chpart_head][3]);
+ m3x3_mul( mats[k_chpart_neck], mats[k_chpart_head], mats[k_chpart_head] );
+#else
+ m4x3_mulv( mats[k_chpart_neck], offs[k_chpart_head], mats[k_chpart_head][3]);
+ m3x3_copy( mats[k_chpart_neck], mats[k_chpart_head] );
+#endif
/* Feet */
m3x3_copy( mats[k_chpart_leg_l1], mats[k_chpart_foot_l] );
m4x3_identity( ch->matrices[k_chpart_wf] );
}
+static float *player_cam_pos(void);
static void character_draw( struct character *ch, float temp )
{
shader_character_use();
vg_tex2d_bind( &tex_pallet, 0 );
shader_character_uTexMain( 0 );
shader_character_uOpacity( temp );
+ shader_character_uCamera( player_cam_pos() );
+ shader_link_standard_ub( _shader_character.id, 2 );
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );
for( int i=4; i<PART_COUNT; i++ )
{
+#if 0
+ if( i == k_chpart_head || i == k_chpart_neck )
+ continue;
+#endif
+
shader_character_uMdl( ch->matrices[i] );
submodel_draw( &ch->parts[i] );
}
/* Convars */
static int debugview = 0;
static int sv_debugcam = 0;
+static int lightedit = 0;
/* Components */
#include "road.h"
.persistent = 1
});
+ vg_convar_push( (struct vg_convar){
+ .name = "ledit",
+ .data = &lightedit,
+ .data_type = k_convar_dtype_i32,
+ .opt_i32 = { .min=0, .max=1, .clamp=1 },
+ .persistent = 1
+ });
+
vg_convar_push( (struct vg_convar){
.name = "walk_speed",
.data = &k_walkspeed,
init_other();
- character_load( &player.mdl, "ch_default" );
+ character_load( &player.mdl, "ch_mike" );
character_init_ragdoll( &player.mdl );
world_load();
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
else
glClear( GL_COLOR_BUFFER_BIT );
-
+
+ if( !player.is_dead )
+ {
+ m4x4_projection( vg_pv, gpipeline.fov,
+ (float)vg_window_x / (float)vg_window_y,
+ 0.01f, 100.0f );
+ m4x4_mul( vg_pv, world_4x4, vg_pv );
+ }
draw_player();
/* Draw back in the background
glViewport( 0,0, vg_window_x, vg_window_y );
}
+static void run_light_widget( struct light_widget *lw )
+{
+ struct ui_checkbox c1 = { .data=&lw->enabled };
+
+ ui_checkbox( &ui_global_ctx, &c1 );
+
+ if( lw->enabled )
+ {
+ struct ui_slider_vector
+ colour = { .min=0.0f, .max=2.0f, .len=3, .data=lw->colour },
+ dir = { .min=-VG_PIf, .max=VG_PIf, .len=2, .data=lw->dir };
+
+ ui_slider_vector( &ui_global_ctx, &colour );
+ ui_global_ctx.cursor[1] += 4;
+ ui_slider_vector( &ui_global_ctx, &dir );
+ }
+}
+
void vg_ui(void)
{
char buf[20];
+#if 0
snprintf( buf, 20, "%.2fm/s", v3_length( player.v ) );
gui_text( (ui_px [2]){ 0, 0 }, buf, 1, k_text_align_left );
gui_text( (ui_px [2]){ 0, 60 },
"Gamepad not ready", 1, k_text_align_left );
}
+#endif
+
+ if( lightedit )
+ {
+ ui_global_ctx.cursor[0] = 10;
+ ui_global_ctx.cursor[1] = 10;
+ ui_global_ctx.cursor[2] = 200;
+ ui_global_ctx.cursor[3] = 20;
+
+ struct ub_world_lighting *wl = &gpipeline.ub_world_lighting;
+ struct ui_slider_vector
+ s5 = { .min=0.0f, .max=2.0f, .len=3, .data=wl->g_ambient_colour };
+
+ struct ui_slider
+ s8 = { .min=0.0f, .max=2.0f, .data = &gpipeline.shadow_spread },
+ s9 = { .min=0.0f, .max=25.0f, .data = &gpipeline.shadow_length };
+
+ for( int i=0; i<3; i++ )
+ run_light_widget( &gpipeline.widgets[i] );
+
+ gui_text( ui_global_ctx.cursor, "Ambient", 1, 0 );
+ ui_global_ctx.cursor[1] += 16;
+ ui_slider_vector( &ui_global_ctx, &s5 );
+
+ gui_text( ui_global_ctx.cursor, "Shadows", 1, 0 );
+ ui_global_ctx.cursor[1] += 16;
+ ui_slider( &ui_global_ctx, &s8 );
+ ui_slider( &ui_global_ctx, &s9 );
+
+ gui_text( ui_global_ctx.cursor, "Misc", 1, 0 );
+ ui_global_ctx.cursor[1] += 16;
+ struct ui_checkbox c1 = {.data = &wl->g_light_preview};
+ ui_checkbox( &ui_global_ctx, &c1 );
+
+ render_update_lighting_ub();
+ }
}
float iY; /* Yaw inertia */
int in_air, is_dead, on_board;
- /* Input */
- v2f joy_l;
-
v2f board_xy;
float grab;
float pitch;
.on_board = 1
};
+static float *player_cam_pos(void)
+{
+ return player.camera_pos;
+}
+
static void player_transform_update(void)
{
q_normalize( player.rot );
static void player_mouseview(void)
{
+ if( gui_want_mouse() )
+ return;
+
static v2f mouse_last,
view_vel = { 0.0f, 0.0f };
{
vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * fwd_resistance );
- /* This used to be -7.0 */
- vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -10.0f *substep );
+ /* This used to be -7.0, then -10.0 */
+ vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -8.5f *substep );
}
static double start_push = 0.0;
player.iY -= 3.6f * ktimestep;
float steer = vg_get_axis( "horizontal" );
- player.iY -= vg_signf(steer)*powf(steer,2.0f) * 1.5f * ktimestep;
+ player.iY -= vg_signf(steer)*powf(steer,2.0f) * 2.5f * ktimestep;
/* Too much lean and it starts to look like a snowboard here */
v2_lerp( player.board_xy, (v2f){ slip*0.25f, 0.0f },
float horizontal = vg_get_axis("horizontal"),
vertical = vg_get_axis("vertical");
- player.joy_l[0] = vg_signf(horizontal) * powf( horizontal, 2.0f );
- player.joy_l[1] = vg_signf(vertical) * powf( vertical, 2.0f );
-
if( player.in_air )
player_physics_air();
player.angles[0] = atan2f( player.vl[0], -player.vl[2] );
player.angles[1] = atan2f( -player.vl[1], sqrtf(player.vl[0]*player.vl[0]+
- player.vl[2]*player.vl[2]) ) * 0.3f;
+ player.vl[2]*player.vl[2]) ) * 0.7f;
}
static int player_walkgrid_tri_walkable( u32 tri[3] )
character_pose_reset( &player.mdl );
+ /* TODO */
+ fstand = 1.0f;
+
float amt_air = ffly*ffly,
amt_ground = 1.0f-amt_air,
amt_std = (1.0f-fslide) * amt_ground,
character_final_pose( &player.mdl, (v3f){0.0f,0.0f,0.0f},
&pose_fly, amt_air );
+#if 0
static float fupper = 0.0f;
fupper = vg_lerpf( fupper, -vg_get_axis("horizontal")*0.2f, 0.1f );
character_yaw_upper( &player.mdl, fupper );
+#endif
/* Camera position */
v3_lerp( player.smooth_localcam, player.mdl.cam_pos, 0.08f,
v3f localv;
m3x3_mulv( player.to_local, player.v, localv );
+
+#if 0
v3_muladds( arm_l->end, localv, -0.01f, arm_l->end );
v3_muladds( arm_r->end, localv, -0.01f, arm_r->end );
+#endif
/* New board transformation */
v4f board_rotation; v3f board_location;
/* Head rotation */
static float rhead = 0.0f;
+ static const float klook_max = 0.8f;
rhead = vg_lerpf( rhead,
- vg_clampf(atan2f( localv[2], -localv[0] ),-1.0f,1.0f), 0.04f );
+ vg_clampf( atan2f(localv[2],-localv[0]),-klook_max,klook_max), 0.04f );
player.mdl.rhead = rhead;
}
player_do_motion();
player_animate();
- v3f offs = { -0.35f, 0.0f, 0.0f };
- m3x3_mulv( player.to_world, offs, offs );
+ v3f offs = { -0.29f, 0.08f, 0.0f };
+ m3x3_mulv( player.to_world, offs, offs );
m4x3_mulv( player.to_world, player.mdl.ik_body.end, player.camera_pos );
- v3_add( offs, player.camera_pos, player.camera_pos );
+ //m4x3_mulv( player.mdl.matrices[k_chpart_head], offs, player.camera_pos );
+ // v3_copy( player.mdl.matrices[k_chpart_head][3], player.camera_pos );
+ v3_add( offs, player.camera_pos, player.camera_pos );
}
else
{
/* Update camera matrices */
m4x3_identity( player.camera );
m4x3_rotate_y( player.camera, -player.angles[0] );
- m4x3_rotate_x( player.camera, -0.33f -player.angles[1] );
+ m4x3_rotate_x( player.camera, -0.30f -player.angles[1] );
v3_copy( player.camera_pos, player.camera[3] );
m4x3_invert_affine( player.camera, player.camera_inverse );
}
struct ub_world_lighting
{
/* v3f (padded) */
- v4f g_directional,
- g_sun_colour,
- g_shadow_colour;
+ v4f g_light_colours[3],
+ g_light_directions[3],
+ g_ambient_colour;
v4f g_water_plane,
g_depth_bounds;
+
float g_water_fog;
+ int g_light_count;
+ int g_light_preview;
}
ub_world_lighting;
+ struct light_widget
+ {
+ int enabled;
+ v2f dir;
+ v3f colour;
+ }
+ widgets[3];
+
+ float shadow_spread, shadow_length;
+
GLuint fb_depthmap, rgb_depthmap;
GLuint ubo_world_lighting,
ubo_world;
}
-gpipeline;
+gpipeline =
+{
+ .widgets =
+ {
+ {
+ .enabled = 1,
+ .colour = { 1.36f, 1.35f, 1.01f },
+ .dir = { 0.63f, -0.08f }
+ },
+ {
+ .enabled = 1,
+ .colour = { 0.33f, 0.56f, 0.64f },
+ .dir = { -2.60f, -0.13f }
+ },
+ {
+ .enabled = 1,
+ .colour = { 0.05f, 0.05f, 0.23f },
+ .dir = { 2.60f, -0.84f }
+ }
+ },
+ .shadow_spread = 0.65f,
+ .shadow_length = 9.50f,
+
+ .ub_world_lighting =
+ {
+ .g_ambient_colour = { 0.09f, 0.03f, 0.07f }
+ }
+};
static void render_water_texture( m4x3f camera );
static void render_water_surface( m4x4f pv, m4x3f camera );
static void render_update_lighting_ub(void)
{
- glBindBuffer( GL_UNIFORM_BUFFER, gpipeline.ubo_world_lighting );
+ struct ub_world_lighting *winf = &gpipeline.ub_world_lighting;
+ int c = 0;
+ for( int i=0; i<3; i++ )
+ {
+ struct light_widget *lw = &gpipeline.widgets[i];
+
+ if( lw->enabled )
+ {
+ float pitch = lw->dir[0],
+ yaw = lw->dir[1],
+ xz = cosf( pitch );
+
+ v3_copy( (v3f){ xz*cosf(yaw), sinf(pitch), xz*sinf(yaw) },
+ winf->g_light_directions[c] );
+ v3_copy( lw->colour, winf->g_light_colours[c] );
+
+ c ++;
+ }
+ }
+
+ winf->g_light_count = c;
+ winf->g_light_directions[0][3] = gpipeline.shadow_length;
+ winf->g_light_colours[0][3] = gpipeline.shadow_spread;
+
+ glBindBuffer( GL_UNIFORM_BUFFER, gpipeline.ubo_world_lighting );
glBufferSubData( GL_UNIFORM_BUFFER, 0, sizeof(struct ub_world_lighting),
&gpipeline.ub_world_lighting );
}
in vec2 aUv;
+float kPi = 3.14159265358979;
+
+vec2 fisheye_distort(vec2 xy)
+{
+ float aperture = 1350.0;
+ float apertureHalf = 0.5 * aperture * (kPi / 180.0);
+ float maxFactor = sin(apertureHalf);
+
+ vec2 uv;
+ float d = length(xy);
+ if(d < (2.0-maxFactor))
+ {
+ d = length(xy * maxFactor);
+ float z = sqrt(1.0 - d * d);
+ float r = atan(d, z) / kPi;
+ float phi = atan(xy.y, xy.x);
+
+ uv.x = r * cos(phi) + 0.5;
+ uv.y = r * sin(phi) + 0.5;
+ }
+ else
+ {
+ uv = 0.5*xy + 0.5;
+ }
+
+ return uv;
+}
+
+
void main()
{
+ vec2 vwarp = 2.0*aUv - 1.0;
+ vwarp = fisheye_distort( vwarp );
+
FragColor = texture( uTexMain, aUv );
}
"\n"
"in vec2 aUv;\n"
"\n"
+"float kPi = 3.14159265358979;\n"
+"\n"
+"vec2 fisheye_distort(vec2 xy)\n"
+"{\n"
+" float aperture = 1350.0;\n"
+" float apertureHalf = 0.5 * aperture * (kPi / 180.0);\n"
+" float maxFactor = sin(apertureHalf);\n"
+"\n"
+" vec2 uv;\n"
+" float d = length(xy);\n"
+" if(d < (2.0-maxFactor))\n"
+" {\n"
+" d = length(xy * maxFactor);\n"
+" float z = sqrt(1.0 - d * d);\n"
+" float r = atan(d, z) / kPi;\n"
+" float phi = atan(xy.y, xy.x);\n"
+"\n"
+" uv.x = r * cos(phi) + 0.5;\n"
+" uv.y = r * sin(phi) + 0.5;\n"
+" }\n"
+" else\n"
+" {\n"
+" uv = 0.5*xy + 0.5;\n"
+" }\n"
+" \n"
+" return uv;\n"
+"}\n"
+"\n"
+"\n"
"void main()\n"
"{\n"
+" vec2 vwarp = 2.0*aUv - 1.0;\n"
+" vwarp = fisheye_distort( vwarp );\n"
+"\n"
" FragColor = texture( uTexMain, aUv );\n"
"}\n"
""},
uniform sampler2D uTexMain;
uniform vec4 uColour;
+uniform vec3 uCamera;
in vec4 aColour;
in vec2 aUv;
in vec3 aCo;
in float aOpacity;
+#include "common_world.glsl"
+
void main()
{
- vec3 diffuse = texture( uTexMain, aUv ).rgb;
- FragColor = vec4(pow(diffuse,vec3(1.0)),aOpacity);
+ vec3 vfrag = texture( uTexMain, aUv ).rgb;
+
+ // Lighting
+ vec3 halfview = uCamera - aCo;
+ float fdist = length( halfview );
+ halfview /= fdist;
+
+ //vfrag = do_light_diffuse( vfrag, aNorm );
+ vfrag = do_light_spec( vfrag, aNorm, halfview, 0.1 );
+ vfrag = do_light_shadowing( vfrag );
+ //vfrag = apply_fog( vfrag, fdist );
+
+ FragColor = vec4(vfrag,aOpacity);
}
"void main()\n"
"{\n"
" vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-" gl_Position = uPv * vec4(world_pos,1.0);\n"
+" vec4 clip_pos = uPv * vec4(world_pos,1.0);\n"
+" gl_Position = clip_pos;\n"
"\n"
" aColour = a_colour;\n"
" aUv = a_uv;\n"
" aNorm = mat3(uMdl) * a_norm;\n"
-" aCo = a_co;\n"
-" aOpacity = 1.0-(gl_Position.y+0.5)*uOpacity;\n"
+" aCo = world_pos;\n"
+" aOpacity = max(clip_pos.w*3.0,0.1);// 1.0-(gl_Position.y+0.5)*uOpacity;\n"
"}\n"
""},
.fs =
"\n"
"uniform sampler2D uTexMain;\n"
"uniform vec4 uColour;\n"
+"uniform vec3 uCamera;\n"
"\n"
"in vec4 aColour;\n"
"in vec2 aUv;\n"
"in vec3 aCo;\n"
"in float aOpacity;\n"
"\n"
+"#line 1 1 \n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_light_colours[3];\n"
+" vec4 g_light_directions[3];\n"
+" vec4 g_ambient_colour;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+" float g_water_fog;\n"
+" int g_light_count;\n"
+" int g_light_preview;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"\n"
+"// Standard diffuse + spec models\n"
+"// ==============================\n"
+"\n"
+"vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )\n"
+"{\n"
+" vec3 vtotal = g_ambient_colour.rgb;\n"
+"\n"
+" for( int i=0; i<g_light_count; i++ )\n"
+" {\n"
+" vec3 vcolour = g_light_colours[i].rgb;\n"
+" vec3 vdir = g_light_directions[i].xyz;\n"
+"\n"
+" float flight = max(dot( vdir, wnormal )*0.75+0.25,0.0);\n"
+" vtotal += vcolour*flight;\n"
+" }\n"
+"\n"
+" return vfrag * vtotal;\n"
+"}\n"
+"\n"
+"vec3 do_light_spec( vec3 vfrag, vec3 wnormal, vec3 halfview, float fintensity )\n"
+"{\n"
+" vec3 vcolour = g_light_colours[0].rgb;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+"\n"
+" vec3 specdir = reflect( -vdir, wnormal );\n"
+" float spec = pow(max(dot( halfview, specdir ), 0.0), 10.0);\n"
+" return vfrag + vcolour*spec*fintensity;\n"
+"}\n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 vdir )\n"
+"{\n"
+" vec3 sample_pos = aCo + vdir;\n"
+" float height_sample = world_depth_sample( sample_pos );\n"
+"\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.1, 0.2 )-0.1;\n"
+"}\n"
+"\n"
+"vec3 do_light_shadowing_old( vec3 vfrag )\n"
+"{\n"
+" float faccum = 0.0;\n"
+" faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 )*1.5);\n"
+" faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 )*1.5);\n"
+" faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 )*1.5);\n"
+" faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 )*1.5);\n"
+" return mix( vfrag, g_ambient_colour.rgb, faccum );\n"
+"}\n"
+"\n"
+"vec3 do_light_shadowing( vec3 vfrag )\n"
+"{\n"
+" float fspread = g_light_colours[0].w;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+" float flength = g_light_directions[0].w;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt+=shadow_sample((vdir+vec3(-0.563, 0.550, 0.307)*fspread)*flength*0.1);\n"
+" famt+=shadow_sample((vdir+vec3( 0.808, 0.686, 0.346)*fspread)*flength*0.2);\n"
+" famt+=shadow_sample((vdir+vec3( 0.787, 0.074,-0.065)*fspread)*flength*0.3);\n"
+" famt+=shadow_sample((vdir+vec3(-0.593, 0.071,-0.425)*fspread)*flength*0.4);\n"
+" famt+=shadow_sample((vdir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" famt+=shadow_sample((vdir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" famt+=shadow_sample((vdir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" famt+=shadow_sample((vdir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" return mix( vfrag, g_ambient_colour.rgb, famt );\n"
+"}\n"
+"\n"
+"vec3 apply_fog( vec3 vfrag, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0008,1.2);\n"
+" return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"#line 14 0 \n"
+"\n"
"void main()\n"
"{\n"
-" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
-" FragColor = vec4(pow(diffuse,vec3(1.0)),aOpacity);\n"
+" vec3 vfrag = texture( uTexMain, aUv ).rgb;\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - aCo;\n"
+" float fdist = length( halfview );\n"
+" halfview /= fdist;\n"
+"\n"
+" //vfrag = do_light_diffuse( vfrag, aNorm );\n"
+" vfrag = do_light_spec( vfrag, aNorm, halfview, 0.1 );\n"
+" vfrag = do_light_shadowing( vfrag );\n"
+" //vfrag = apply_fog( vfrag, fdist );\n"
+"\n"
+" FragColor = vec4(vfrag,aOpacity);\n"
"}\n"
""},
};
static GLuint _uniform_character_uOpacity;
static GLuint _uniform_character_uTexMain;
static GLuint _uniform_character_uColour;
+static GLuint _uniform_character_uCamera;
+static GLuint _uniform_character_g_world_depth;
static void shader_character_uPv(m4x4f m){
glUniformMatrix4fv( _uniform_character_uPv, 1, GL_FALSE, (float *)m );
}
static void shader_character_uColour(v4f v){
glUniform4fv( _uniform_character_uColour, 1, v );
}
+static void shader_character_uCamera(v3f v){
+ glUniform3fv( _uniform_character_uCamera, 1, v );
+}
+static void shader_character_g_world_depth(int i){
+ glUniform1i( _uniform_character_g_world_depth, i );
+}
static void shader_character_register(void){
vg_shader_register( &_shader_character );
}
_uniform_character_uOpacity = glGetUniformLocation( _shader_character.id, "uOpacity" );
_uniform_character_uTexMain = glGetUniformLocation( _shader_character.id, "uTexMain" );
_uniform_character_uColour = glGetUniformLocation( _shader_character.id, "uColour" );
+ _uniform_character_uCamera = glGetUniformLocation( _shader_character.id, "uCamera" );
+ _uniform_character_g_world_depth = glGetUniformLocation( _shader_character.id, "g_world_depth" );
}
#endif /* SHADER_character_H */
void main()
{
vec3 world_pos = uMdl * vec4(a_co,1.0);
- gl_Position = uPv * vec4(world_pos,1.0);
+ vec4 clip_pos = uPv * vec4(world_pos,1.0);
+ gl_Position = clip_pos;
aColour = a_colour;
aUv = a_uv;
aNorm = mat3(uMdl) * a_norm;
- aCo = a_co;
- aOpacity = 1.0-(gl_Position.y+0.5)*uOpacity;
+ aCo = world_pos;
+ aOpacity = max(clip_pos.w*3.0,0.1);// 1.0-(gl_Position.y+0.5)*uOpacity;
}
layout (std140) uniform ub_world_lighting
{
- vec3 g_directional;
- vec3 g_sun_colour;
- vec3 g_shadow_colour;
+ vec4 g_light_colours[3];
+ vec4 g_light_directions[3];
+ vec4 g_ambient_colour;
+
vec4 g_water_plane;
vec4 g_depth_bounds;
float g_water_fog;
+ int g_light_count;
+ int g_light_preview;
};
uniform sampler2D g_world_depth;
vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )
{
- float flight = dot( g_directional, wnormal )*0.5+0.5;
- return vfrag * mix( g_shadow_colour, g_sun_colour, flight );
+ vec3 vtotal = g_ambient_colour.rgb;
+
+ for( int i=0; i<g_light_count; i++ )
+ {
+ vec3 vcolour = g_light_colours[i].rgb;
+ vec3 vdir = g_light_directions[i].xyz;
+
+ float flight = max(dot( vdir, wnormal )*0.75+0.25,0.0);
+ vtotal += vcolour*flight;
+ }
+
+ return vfrag * vtotal;
}
vec3 do_light_spec( vec3 vfrag, vec3 wnormal, vec3 halfview, float fintensity )
{
- vec3 specdir = reflect( -g_directional, wnormal );
+ vec3 vcolour = g_light_colours[0].rgb;
+ vec3 vdir = g_light_directions[0].xyz;
+
+ vec3 specdir = reflect( -vdir, wnormal );
float spec = pow(max(dot( halfview, specdir ), 0.0), 10.0);
- return vfrag + g_sun_colour*spec*fintensity;
+ return vfrag + vcolour*spec*fintensity;
}
float world_depth_sample( vec3 pos )
return clamp( fdelta, 0.1, 0.2 )-0.1;
}
-vec3 do_light_shadowing( vec3 vfrag )
+vec3 do_light_shadowing_old( vec3 vfrag )
{
float faccum = 0.0;
faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 ));
faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 )*1.5);
faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 )*1.5);
faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 )*1.5);
- return mix( vfrag, g_shadow_colour, faccum );
+ return mix( vfrag, g_ambient_colour.rgb, faccum );
}
+vec3 do_light_shadowing( vec3 vfrag )
+{
+ float fspread = g_light_colours[0].w;
+ vec3 vdir = g_light_directions[0].xyz;
+ float flength = g_light_directions[0].w;
+
+ float famt = 0.0;
+ famt+=shadow_sample((vdir+vec3(-0.563, 0.550, 0.307)*fspread)*flength*0.1);
+ famt+=shadow_sample((vdir+vec3( 0.808, 0.686, 0.346)*fspread)*flength*0.2);
+ famt+=shadow_sample((vdir+vec3( 0.787, 0.074,-0.065)*fspread)*flength*0.3);
+ famt+=shadow_sample((vdir+vec3(-0.593, 0.071,-0.425)*fspread)*flength*0.4);
+ famt+=shadow_sample((vdir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);
+ famt+=shadow_sample((vdir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);
+ famt+=shadow_sample((vdir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);
+ famt+=shadow_sample((vdir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);
+ return mix( vfrag, g_ambient_colour.rgb, famt );
+}
+
+vec3 apply_fog( vec3 vfrag, float fdist )
+{
+ float dist = pow(fdist*0.0008,1.2);
+ return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );
+}
"#line 1 1 \n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
-" vec3 g_directional;\n"
-" vec3 g_sun_colour;\n"
-" vec3 g_shadow_colour;\n"
+" vec4 g_light_colours[3];\n"
+" vec4 g_light_directions[3];\n"
+" vec4 g_ambient_colour;\n"
+"\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" int g_light_count;\n"
+" int g_light_preview;\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
"\n"
"vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )\n"
"{\n"
-" float flight = dot( g_directional, wnormal )*0.5+0.5;\n"
-" return vfrag * mix( g_shadow_colour, g_sun_colour, flight );\n"
+" vec3 vtotal = g_ambient_colour.rgb;\n"
+"\n"
+" for( int i=0; i<g_light_count; i++ )\n"
+" {\n"
+" vec3 vcolour = g_light_colours[i].rgb;\n"
+" vec3 vdir = g_light_directions[i].xyz;\n"
+"\n"
+" float flight = max(dot( vdir, wnormal )*0.75+0.25,0.0);\n"
+" vtotal += vcolour*flight;\n"
+" }\n"
+"\n"
+" return vfrag * vtotal;\n"
"}\n"
"\n"
"vec3 do_light_spec( vec3 vfrag, vec3 wnormal, vec3 halfview, float fintensity )\n"
"{\n"
-" vec3 specdir = reflect( -g_directional, wnormal );\n"
+" vec3 vcolour = g_light_colours[0].rgb;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+"\n"
+" vec3 specdir = reflect( -vdir, wnormal );\n"
" float spec = pow(max(dot( halfview, specdir ), 0.0), 10.0);\n"
-" return vfrag + g_sun_colour*spec*fintensity;\n"
+" return vfrag + vcolour*spec*fintensity;\n"
"}\n"
"\n"
"float world_depth_sample( vec3 pos )\n"
" return clamp( fdelta, 0.1, 0.2 )-0.1;\n"
"}\n"
"\n"
-"vec3 do_light_shadowing( vec3 vfrag )\n"
+"vec3 do_light_shadowing_old( vec3 vfrag )\n"
"{\n"
" float faccum = 0.0;\n"
" faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 ));\n"
" faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 )*1.5);\n"
" faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 )*1.5);\n"
" faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 )*1.5);\n"
-" return mix( vfrag, g_shadow_colour, faccum );\n"
+" return mix( vfrag, g_ambient_colour.rgb, faccum );\n"
"}\n"
"\n"
+"vec3 do_light_shadowing( vec3 vfrag )\n"
+"{\n"
+" float fspread = g_light_colours[0].w;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+" float flength = g_light_directions[0].w;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt+=shadow_sample((vdir+vec3(-0.563, 0.550, 0.307)*fspread)*flength*0.1);\n"
+" famt+=shadow_sample((vdir+vec3( 0.808, 0.686, 0.346)*fspread)*flength*0.2);\n"
+" famt+=shadow_sample((vdir+vec3( 0.787, 0.074,-0.065)*fspread)*flength*0.3);\n"
+" famt+=shadow_sample((vdir+vec3(-0.593, 0.071,-0.425)*fspread)*flength*0.4);\n"
+" famt+=shadow_sample((vdir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" famt+=shadow_sample((vdir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" famt+=shadow_sample((vdir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" famt+=shadow_sample((vdir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" return mix( vfrag, g_ambient_colour.rgb, famt );\n"
+"}\n"
+"\n"
+"vec3 apply_fog( vec3 vfrag, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0008,1.2);\n"
+" return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
+"}\n"
"\n"
"#line 11 0 \n"
"\n"
void main()
{
float fintensity = 1.0-(abs(aNorm.y)*0.7);
- float fblend = pow(fintensity,8.0);
+ float fblend = pow(fintensity,4.0);
vec3 horizon = vec3( 0.8, 0.9, 0.9 );
vec3 skycolour = vec3( 0.5, 0.6, 0.9 );
vec3 diffuse = mix( skycolour, horizon, fblend );
float fhorizon = step( aNorm.y * 0.5 + 0.5, 0.5 );
vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);
- FragColor = vec4(skycomp,1.0);
+ FragColor = vec4(pow(skycomp, vec3(1.5)),1.0);
}
"void main()\n"
"{\n"
" float fintensity = 1.0-(abs(aNorm.y)*0.7);\n"
-" float fblend = pow(fintensity,8.0);\n"
+" float fblend = pow(fintensity,4.0);\n"
" vec3 horizon = vec3( 0.8, 0.9, 0.9 );\n"
" vec3 skycolour = vec3( 0.5, 0.6, 0.9 );\n"
" vec3 diffuse = mix( skycolour, horizon, fblend );\n"
" float fhorizon = step( aNorm.y * 0.5 + 0.5, 0.5 );\n"
"\n"
" vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);\n"
-" FragColor = vec4(skycomp,1.0);\n"
+" FragColor = vec4(pow(skycomp, vec3(1.5)),1.0);\n"
"}\n"
""},
};
float amtsand = min(max((aCo.y - 10.0) * -0.1,0.0)*qnorm.y,1.0);
vec2 uvgradients = aUv + vec2( amtgrass*0.5 + rgarbage.a*0.4, 0.0 );
vfrag = texture( uTexGradients, uvgradients ).rgb;
- vfrag = mix( vfrag, vec3(1.0,0.9,0.8), amtsand );
+ vfrag = mix( vfrag, vec3(1.0,0.9,0.8)*0.9, amtsand );
+
+ qnorm = mix( qnorm, aNorm, amtsand );
+
+ if( g_light_preview == 1 )
+ {
+ vfrag = vec3(0.5);
+ }
// Lighting
- vec3 halfview = normalize( uCamera - aCo );
+ vec3 halfview = uCamera - aCo;
+ float fdist = length( halfview );
+ halfview /= fdist;
+
vfrag = do_light_diffuse( vfrag, qnorm );
- vfrag = do_light_spec( vfrag, qnorm, halfview, 0.2 * rgarbage.a );
+ vfrag = do_light_spec( vfrag, qnorm, halfview, 0.1 );
vfrag = do_light_shadowing( vfrag );
+ vfrag = apply_fog( vfrag, fdist );
- FragColor = vec4( vfrag, 1.0 );
+ FragColor = vec4(vfrag, 1.0 );
}
.link = shader_terrain_link,
.vs =
{
-.orig_file = "../shaders/terrain.vs",
+.orig_file = "../shaders/standard.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec3 a_norm;\n"
"#line 1 1 \n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
-" vec3 g_directional;\n"
-" vec3 g_sun_colour;\n"
-" vec3 g_shadow_colour;\n"
+" vec4 g_light_colours[3];\n"
+" vec4 g_light_directions[3];\n"
+" vec4 g_ambient_colour;\n"
+"\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" int g_light_count;\n"
+" int g_light_preview;\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
"\n"
"vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )\n"
"{\n"
-" float flight = dot( g_directional, wnormal )*0.5+0.5;\n"
-" return vfrag * mix( g_shadow_colour, g_sun_colour, flight );\n"
+" vec3 vtotal = g_ambient_colour.rgb;\n"
+"\n"
+" for( int i=0; i<g_light_count; i++ )\n"
+" {\n"
+" vec3 vcolour = g_light_colours[i].rgb;\n"
+" vec3 vdir = g_light_directions[i].xyz;\n"
+"\n"
+" float flight = max(dot( vdir, wnormal )*0.75+0.25,0.0);\n"
+" vtotal += vcolour*flight;\n"
+" }\n"
+"\n"
+" return vfrag * vtotal;\n"
"}\n"
"\n"
"vec3 do_light_spec( vec3 vfrag, vec3 wnormal, vec3 halfview, float fintensity )\n"
"{\n"
-" vec3 specdir = reflect( -g_directional, wnormal );\n"
+" vec3 vcolour = g_light_colours[0].rgb;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+"\n"
+" vec3 specdir = reflect( -vdir, wnormal );\n"
" float spec = pow(max(dot( halfview, specdir ), 0.0), 10.0);\n"
-" return vfrag + g_sun_colour*spec*fintensity;\n"
+" return vfrag + vcolour*spec*fintensity;\n"
"}\n"
"\n"
"float world_depth_sample( vec3 pos )\n"
" return clamp( fdelta, 0.1, 0.2 )-0.1;\n"
"}\n"
"\n"
-"vec3 do_light_shadowing( vec3 vfrag )\n"
+"vec3 do_light_shadowing_old( vec3 vfrag )\n"
"{\n"
" float faccum = 0.0;\n"
" faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 ));\n"
" faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 )*1.5);\n"
" faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 )*1.5);\n"
" faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 )*1.5);\n"
-" return mix( vfrag, g_shadow_colour, faccum );\n"
+" return mix( vfrag, g_ambient_colour.rgb, faccum );\n"
"}\n"
"\n"
+"vec3 do_light_shadowing( vec3 vfrag )\n"
+"{\n"
+" float fspread = g_light_colours[0].w;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+" float flength = g_light_directions[0].w;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt+=shadow_sample((vdir+vec3(-0.563, 0.550, 0.307)*fspread)*flength*0.1);\n"
+" famt+=shadow_sample((vdir+vec3( 0.808, 0.686, 0.346)*fspread)*flength*0.2);\n"
+" famt+=shadow_sample((vdir+vec3( 0.787, 0.074,-0.065)*fspread)*flength*0.3);\n"
+" famt+=shadow_sample((vdir+vec3(-0.593, 0.071,-0.425)*fspread)*flength*0.4);\n"
+" famt+=shadow_sample((vdir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" famt+=shadow_sample((vdir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" famt+=shadow_sample((vdir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" famt+=shadow_sample((vdir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" return mix( vfrag, g_ambient_colour.rgb, famt );\n"
+"}\n"
+"\n"
+"vec3 apply_fog( vec3 vfrag, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0008,1.2);\n"
+" return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
+"}\n"
"\n"
"#line 13 0 \n"
"\n"
" float amtsand = min(max((aCo.y - 10.0) * -0.1,0.0)*qnorm.y,1.0);\n"
" vec2 uvgradients = aUv + vec2( amtgrass*0.5 + rgarbage.a*0.4, 0.0 );\n"
" vfrag = texture( uTexGradients, uvgradients ).rgb;\n"
-" vfrag = mix( vfrag, vec3(1.0,0.9,0.8), amtsand );\n"
+" vfrag = mix( vfrag, vec3(1.0,0.9,0.8)*0.9, amtsand );\n"
+"\n"
+" qnorm = mix( qnorm, aNorm, amtsand );\n"
+" \n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
"\n"
" // Lighting\n"
-" vec3 halfview = normalize( uCamera - aCo );\n"
+" vec3 halfview = uCamera - aCo;\n"
+" float fdist = length( halfview );\n"
+" halfview /= fdist;\n"
+"\n"
" vfrag = do_light_diffuse( vfrag, qnorm );\n"
-" vfrag = do_light_spec( vfrag, qnorm, halfview, 0.2 * rgarbage.a );\n"
+" vfrag = do_light_spec( vfrag, qnorm, halfview, 0.1 );\n"
" vfrag = do_light_shadowing( vfrag );\n"
+" vfrag = apply_fog( vfrag, fdist );\n"
"\n"
-" FragColor = vec4( vfrag, 1.0 );\n"
+" FragColor = vec4(vfrag, 1.0 );\n"
"}\n"
""},
};
uniform sampler2D uTexGarbage;
uniform sampler2D uTexGradients;
-uniform sampler2D uTexDepth;
-uniform vec4 uDepthBounds;
uniform vec3 uCamera;
uniform vec4 uPlane;
in vec3 aNorm;
in vec3 aCo;
-float water_depth( vec3 pos, vec3 dir, vec4 plane )
-{
- float d = dot( plane.xyz, dir );
- float t = dot((plane.xyz*plane.w - pos),plane.xyz) / d;
- return t*0.04;
-}
-
-float sample_height( vec3 pos )
-{
- vec2 depth_coords = (pos.xz-uDepthBounds.xy)*uDepthBounds.zw;
- return texture( uTexDepth, depth_coords ).r;
-}
-
-float create_shadowing( vec3 vdir )
-{
- return clamp( sample_height( aCo+vdir ) - (aCo.y+vdir.y), 0.1, 0.2 )-0.1;
-}
+#include "common_world.glsl"
void main()
{
+ vec3 vfrag = vec3(0.5,0.5,0.5);
+
+ // ws modulation
vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.160 );
// Creating normal patches
float fblendclip = step(0.380,aColour.r + (rgarbage.r-0.5)*-1.740)*0.320;
vec2 uvgradients = aUv + vec2( fblendclip, 0.0 );
- vec3 diffuse = texture( uTexGradients, uvgradients ).rgb;
- diffuse -= rgarbage.a*0.04;
+ vfrag = texture( uTexGradients, uvgradients ).rgb;
+ vfrag -= rgarbage.a*0.04;
+
+ if( g_light_preview == 1 )
+ {
+ vfrag = vec3(0.5);
+ }
// Lighting
- vec3 lightdir = normalize(vec3(0.5,0.5,-0.1));
- vec3 shadow = vec3(0.27,0.25,0.34);
- float light1 = dot( lightdir, aNorm )*0.5+0.5;
- diffuse = diffuse * (light1*vec3(1.0,0.96,0.9)*1.2 + shadow*(1.0-light1));
-
- // Specular lighting
- vec3 halfview = normalize( uCamera - aCo );
- vec3 specdir = reflect( -lightdir, qnorm );
- float spec = pow(max(dot(halfview,specdir),0.0),10.0) * 0.3*rgarbage.r;
- //diffuse += spec * vec3(1.0,0.8,0.8);
+ vec3 halfview = uCamera - aCo;
+ float fdist = length( halfview );
+ halfview /= fdist;
- float faccum = 0.0;
- vec3 offs = vec3(rgarbage.x, 0.0, rgarbage.z)*4.0;
- faccum += create_shadowing( vec3( 0.0, 0.5, 0.0 )*0.6);
- faccum += create_shadowing( vec3( 2.0, 0.3, 0.0 )*0.6);
- faccum += create_shadowing( vec3( 3.0, 1.0, 0.0 )*0.6);
- faccum += create_shadowing( vec3( 5.0, 1.0, 0.0 )*0.6);
- faccum += create_shadowing( vec3( 0.0, 0.5, 0.0 )*0.6*1.5+offs);
- faccum += create_shadowing( vec3( 2.0, 0.3, 0.0 )*0.6*1.5);
- faccum += create_shadowing( vec3( 3.0, 1.0, 0.0 )*0.6*1.5-offs);
- faccum += create_shadowing( vec3( 5.0, 1.0, 0.0 )*0.6*1.5);
- diffuse = mix( diffuse, vec3(0.15,0.1,0.2), min(faccum*1.0,1.0));
+ vfrag = do_light_diffuse( vfrag, qnorm );
+ vfrag = do_light_spec( vfrag, qnorm, halfview, 0.1 );
+ vfrag = do_light_shadowing( vfrag );
+ vfrag = apply_fog( vfrag, fdist );
- FragColor = vec4(diffuse, water_depth(aCo,halfview,uPlane));
+ FragColor = vec4(vfrag, 1.0 );
}
.link = shader_vblend_link,
.vs =
{
-.orig_file = "../shaders/terrain.vs",
+.orig_file = "../shaders/standard.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec3 a_norm;\n"
"\n"
"uniform sampler2D uTexGarbage;\n"
"uniform sampler2D uTexGradients;\n"
-"uniform sampler2D uTexDepth;\n"
-"uniform vec4 uDepthBounds;\n"
"uniform vec3 uCamera;\n"
"uniform vec4 uPlane;\n"
"\n"
"in vec3 aNorm;\n"
"in vec3 aCo;\n"
"\n"
-"float water_depth( vec3 pos, vec3 dir, vec4 plane )\n"
+"#line 1 1 \n"
+"layout (std140) uniform ub_world_lighting\n"
"{\n"
-" float d = dot( plane.xyz, dir );\n"
-" float t = dot((plane.xyz*plane.w - pos),plane.xyz) / d;\n"
-" return t*0.04;\n"
+" vec4 g_light_colours[3];\n"
+" vec4 g_light_directions[3];\n"
+" vec4 g_ambient_colour;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+" float g_water_fog;\n"
+" int g_light_count;\n"
+" int g_light_preview;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"\n"
+"// Standard diffuse + spec models\n"
+"// ==============================\n"
+"\n"
+"vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )\n"
+"{\n"
+" vec3 vtotal = g_ambient_colour.rgb;\n"
+"\n"
+" for( int i=0; i<g_light_count; i++ )\n"
+" {\n"
+" vec3 vcolour = g_light_colours[i].rgb;\n"
+" vec3 vdir = g_light_directions[i].xyz;\n"
+"\n"
+" float flight = max(dot( vdir, wnormal )*0.75+0.25,0.0);\n"
+" vtotal += vcolour*flight;\n"
+" }\n"
+"\n"
+" return vfrag * vtotal;\n"
+"}\n"
+"\n"
+"vec3 do_light_spec( vec3 vfrag, vec3 wnormal, vec3 halfview, float fintensity )\n"
+"{\n"
+" vec3 vcolour = g_light_colours[0].rgb;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+"\n"
+" vec3 specdir = reflect( -vdir, wnormal );\n"
+" float spec = pow(max(dot( halfview, specdir ), 0.0), 10.0);\n"
+" return vfrag + vcolour*spec*fintensity;\n"
+"}\n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 vdir )\n"
+"{\n"
+" vec3 sample_pos = aCo + vdir;\n"
+" float height_sample = world_depth_sample( sample_pos );\n"
+"\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.1, 0.2 )-0.1;\n"
+"}\n"
+"\n"
+"vec3 do_light_shadowing_old( vec3 vfrag )\n"
+"{\n"
+" float faccum = 0.0;\n"
+" faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 ));\n"
+" faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 )*1.5);\n"
+" faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 )*1.5);\n"
+" faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 )*1.5);\n"
+" faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 )*1.5);\n"
+" return mix( vfrag, g_ambient_colour.rgb, faccum );\n"
"}\n"
"\n"
-"float sample_height( vec3 pos )\n"
+"vec3 do_light_shadowing( vec3 vfrag )\n"
"{\n"
-" vec2 depth_coords = (pos.xz-uDepthBounds.xy)*uDepthBounds.zw;\n"
-" return texture( uTexDepth, depth_coords ).r;\n"
+" float fspread = g_light_colours[0].w;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+" float flength = g_light_directions[0].w;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt+=shadow_sample((vdir+vec3(-0.563, 0.550, 0.307)*fspread)*flength*0.1);\n"
+" famt+=shadow_sample((vdir+vec3( 0.808, 0.686, 0.346)*fspread)*flength*0.2);\n"
+" famt+=shadow_sample((vdir+vec3( 0.787, 0.074,-0.065)*fspread)*flength*0.3);\n"
+" famt+=shadow_sample((vdir+vec3(-0.593, 0.071,-0.425)*fspread)*flength*0.4);\n"
+" famt+=shadow_sample((vdir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" famt+=shadow_sample((vdir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" famt+=shadow_sample((vdir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" famt+=shadow_sample((vdir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" return mix( vfrag, g_ambient_colour.rgb, famt );\n"
"}\n"
"\n"
-"float create_shadowing( vec3 vdir )\n"
+"vec3 apply_fog( vec3 vfrag, float fdist )\n"
"{\n"
-" return clamp( sample_height( aCo+vdir ) - (aCo.y+vdir.y), 0.1, 0.2 )-0.1;\n"
+" float dist = pow(fdist*0.0008,1.2);\n"
+" return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
"}\n"
"\n"
+"#line 14 0 \n"
+"\n"
"void main()\n"
"{\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+"\n"
+" // ws modulation\n"
" vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.160 );\n"
" \n"
" // Creating normal patches\n"
" float fblendclip = step(0.380,aColour.r + (rgarbage.r-0.5)*-1.740)*0.320;\n"
" vec2 uvgradients = aUv + vec2( fblendclip, 0.0 );\n"
"\n"
-" vec3 diffuse = texture( uTexGradients, uvgradients ).rgb;\n"
-" diffuse -= rgarbage.a*0.04;\n"
+" vfrag = texture( uTexGradients, uvgradients ).rgb;\n"
+" vfrag -= rgarbage.a*0.04;\n"
+"\n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
"\n"
" // Lighting\n"
-" vec3 lightdir = normalize(vec3(0.5,0.5,-0.1));\n"
-" vec3 shadow = vec3(0.27,0.25,0.34);\n"
-" float light1 = dot( lightdir, aNorm )*0.5+0.5;\n"
-" diffuse = diffuse * (light1*vec3(1.0,0.96,0.9)*1.2 + shadow*(1.0-light1));\n"
-" \n"
-" // Specular lighting\n"
-" vec3 halfview = normalize( uCamera - aCo );\n"
-" vec3 specdir = reflect( -lightdir, qnorm );\n"
-" float spec = pow(max(dot(halfview,specdir),0.0),10.0) * 0.3*rgarbage.r;\n"
-" //diffuse += spec * vec3(1.0,0.8,0.8);\n"
+" vec3 halfview = uCamera - aCo;\n"
+" float fdist = length( halfview );\n"
+" halfview /= fdist;\n"
"\n"
-" float faccum = 0.0;\n"
-" vec3 offs = vec3(rgarbage.x, 0.0, rgarbage.z)*4.0;\n"
-" faccum += create_shadowing( vec3( 0.0, 0.5, 0.0 )*0.6);\n"
-" faccum += create_shadowing( vec3( 2.0, 0.3, 0.0 )*0.6);\n"
-" faccum += create_shadowing( vec3( 3.0, 1.0, 0.0 )*0.6);\n"
-" faccum += create_shadowing( vec3( 5.0, 1.0, 0.0 )*0.6);\n"
-" faccum += create_shadowing( vec3( 0.0, 0.5, 0.0 )*0.6*1.5+offs);\n"
-" faccum += create_shadowing( vec3( 2.0, 0.3, 0.0 )*0.6*1.5);\n"
-" faccum += create_shadowing( vec3( 3.0, 1.0, 0.0 )*0.6*1.5-offs);\n"
-" faccum += create_shadowing( vec3( 5.0, 1.0, 0.0 )*0.6*1.5);\n"
-" diffuse = mix( diffuse, vec3(0.15,0.1,0.2), min(faccum*1.0,1.0));\n"
-"\n"
-" FragColor = vec4(diffuse, water_depth(aCo,halfview,uPlane));\n"
+" vfrag = do_light_diffuse( vfrag, qnorm );\n"
+" vfrag = do_light_spec( vfrag, qnorm, halfview, 0.1 );\n"
+" vfrag = do_light_shadowing( vfrag );\n"
+" vfrag = apply_fog( vfrag, fdist );\n"
+"\n"
+" FragColor = vec4(vfrag, 1.0 );\n"
"}\n"
""},
};
static GLuint _uniform_vblend_uMdl;
static GLuint _uniform_vblend_uTexGarbage;
static GLuint _uniform_vblend_uTexGradients;
-static GLuint _uniform_vblend_uTexDepth;
-static GLuint _uniform_vblend_uDepthBounds;
static GLuint _uniform_vblend_uCamera;
static GLuint _uniform_vblend_uPlane;
+static GLuint _uniform_vblend_g_world_depth;
static void shader_vblend_uPv(m4x4f m){
glUniformMatrix4fv( _uniform_vblend_uPv, 1, GL_FALSE, (float *)m );
}
static void shader_vblend_uTexGradients(int i){
glUniform1i( _uniform_vblend_uTexGradients, i );
}
-static void shader_vblend_uTexDepth(int i){
- glUniform1i( _uniform_vblend_uTexDepth, i );
-}
-static void shader_vblend_uDepthBounds(v4f v){
- glUniform4fv( _uniform_vblend_uDepthBounds, 1, v );
-}
static void shader_vblend_uCamera(v3f v){
glUniform3fv( _uniform_vblend_uCamera, 1, v );
}
static void shader_vblend_uPlane(v4f v){
glUniform4fv( _uniform_vblend_uPlane, 1, v );
}
+static void shader_vblend_g_world_depth(int i){
+ glUniform1i( _uniform_vblend_g_world_depth, i );
+}
static void shader_vblend_register(void){
vg_shader_register( &_shader_vblend );
}
_uniform_vblend_uMdl = glGetUniformLocation( _shader_vblend.id, "uMdl" );
_uniform_vblend_uTexGarbage = glGetUniformLocation( _shader_vblend.id, "uTexGarbage" );
_uniform_vblend_uTexGradients = glGetUniformLocation( _shader_vblend.id, "uTexGradients" );
- _uniform_vblend_uTexDepth = glGetUniformLocation( _shader_vblend.id, "uTexDepth" );
- _uniform_vblend_uDepthBounds = glGetUniformLocation( _shader_vblend.id, "uDepthBounds" );
_uniform_vblend_uCamera = glGetUniformLocation( _shader_vblend.id, "uCamera" );
_uniform_vblend_uPlane = glGetUniformLocation( _shader_vblend.id, "uPlane" );
+ _uniform_vblend_g_world_depth = glGetUniformLocation( _shader_vblend.id, "g_world_depth" );
}
#endif /* SHADER_vblend_H */
"#line 1 1 \n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
-" vec3 g_directional;\n"
-" vec3 g_sun_colour;\n"
-" vec3 g_shadow_colour;\n"
+" vec4 g_light_colours[3];\n"
+" vec4 g_light_directions[3];\n"
+" vec4 g_ambient_colour;\n"
+"\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" int g_light_count;\n"
+" int g_light_preview;\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
"\n"
"vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )\n"
"{\n"
-" float flight = dot( g_directional, wnormal )*0.5+0.5;\n"
-" return vfrag * mix( g_shadow_colour, g_sun_colour, flight );\n"
+" vec3 vtotal = g_ambient_colour.rgb;\n"
+"\n"
+" for( int i=0; i<g_light_count; i++ )\n"
+" {\n"
+" vec3 vcolour = g_light_colours[i].rgb;\n"
+" vec3 vdir = g_light_directions[i].xyz;\n"
+"\n"
+" float flight = max(dot( vdir, wnormal )*0.75+0.25,0.0);\n"
+" vtotal += vcolour*flight;\n"
+" }\n"
+"\n"
+" return vfrag * vtotal;\n"
"}\n"
"\n"
"vec3 do_light_spec( vec3 vfrag, vec3 wnormal, vec3 halfview, float fintensity )\n"
"{\n"
-" vec3 specdir = reflect( -g_directional, wnormal );\n"
+" vec3 vcolour = g_light_colours[0].rgb;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+"\n"
+" vec3 specdir = reflect( -vdir, wnormal );\n"
" float spec = pow(max(dot( halfview, specdir ), 0.0), 10.0);\n"
-" return vfrag + g_sun_colour*spec*fintensity;\n"
+" return vfrag + vcolour*spec*fintensity;\n"
"}\n"
"\n"
"float world_depth_sample( vec3 pos )\n"
" return clamp( fdelta, 0.1, 0.2 )-0.1;\n"
"}\n"
"\n"
-"vec3 do_light_shadowing( vec3 vfrag )\n"
+"vec3 do_light_shadowing_old( vec3 vfrag )\n"
"{\n"
" float faccum = 0.0;\n"
" faccum += shadow_sample( vec3( 0.0, 0.5, 0.0 ));\n"
" faccum += shadow_sample( vec3( 2.0, 0.3, 0.0 )*1.5);\n"
" faccum += shadow_sample( vec3( 3.0, 1.0, 0.0 )*1.5);\n"
" faccum += shadow_sample( vec3( 5.0, 1.0, 0.0 )*1.5);\n"
-" return mix( vfrag, g_shadow_colour, faccum );\n"
+" return mix( vfrag, g_ambient_colour.rgb, faccum );\n"
"}\n"
"\n"
+"vec3 do_light_shadowing( vec3 vfrag )\n"
+"{\n"
+" float fspread = g_light_colours[0].w;\n"
+" vec3 vdir = g_light_directions[0].xyz;\n"
+" float flength = g_light_directions[0].w;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt+=shadow_sample((vdir+vec3(-0.563, 0.550, 0.307)*fspread)*flength*0.1);\n"
+" famt+=shadow_sample((vdir+vec3( 0.808, 0.686, 0.346)*fspread)*flength*0.2);\n"
+" famt+=shadow_sample((vdir+vec3( 0.787, 0.074,-0.065)*fspread)*flength*0.3);\n"
+" famt+=shadow_sample((vdir+vec3(-0.593, 0.071,-0.425)*fspread)*flength*0.4);\n"
+" famt+=shadow_sample((vdir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" famt+=shadow_sample((vdir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" famt+=shadow_sample((vdir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" famt+=shadow_sample((vdir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+" return mix( vfrag, g_ambient_colour.rgb, famt );\n"
+"}\n"
+"\n"
+"vec3 apply_fog( vec3 vfrag, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0008,1.2);\n"
+" return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
+"}\n"
"\n"
"#line 18 0 \n"
"\n"
shader blit blit.vs blit.fs
shader fscolour blit.vs colour.fs
-shader terrain terrain.vs terrain.fs
-shader vblend terrain.vs vblend.fs
+shader terrain standard.vs terrain.fs
+shader vblend standard.vs vblend.fs
shader standard standard.vs standard.fs
shader unlit standard.vs unlit.fs
shader character character.vs character.fs
* TODO: World settings entity
*/
struct ub_world_lighting *winfo = &gpipeline.ub_world_lighting;
-
- v3f sundir = { 0.5f, 0.8f, 0.2f };
- v3_normalize( sundir );
- v3_copy( sundir, winfo->g_directional );
- v3_copy( (v3f){ 1.2f,1.152f,1.08f }, winfo->g_sun_colour );
- v3_copy( (v3f){ 0.15f,0.1f,0.2f }, winfo->g_shadow_colour );
v4_copy( wrender.plane, winfo->g_water_plane );
v4f bounds;
static void render_world( m4x4f projection, m4x3f camera )
{
render_sky( camera );
+ render_props( projection, camera[3] );
render_terrain( projection, camera[3] );
- /* render props... */
}
static void render_world_depth( m4x4f projection, m4x3f camera )
scene_bind( &world.geo );
scene_draw( &world.geo );
+#if 0
glDisable(GL_CULL_FACE);
scene_bind( &world.foliage );
scene_draw( &world.foliage );
glEnable(GL_CULL_FACE);
+#endif
scene_bind( &world.props );
scene_draw( &world.props );