k_ragdoll_debug_constraints = 0;
VG_STATIC int k_debug_light_indices = 0,
- k_debug_light_complexity = 0;
+ k_debug_light_complexity = 0,
+ k_light_preview = 0;
VG_STATIC int freecam = 0;
VG_STATIC int walk_grid_iterations = 1;
VG_VAR_I32( cl_thirdperson );
VG_VAR_F32_PERSISTENT( fc_speed );
- /* TODO: NOT PERSISTENT */
VG_VAR_F32( k_ragdoll_limit_scale );
VG_VAR_I32( k_ragdoll_div );
VG_VAR_I32( k_ragdoll_debug_collider );
VG_VAR_I32( k_ragdoll_debug_constraints );
VG_VAR_I32( k_debug_light_indices );
VG_VAR_I32( k_debug_light_complexity );
+ VG_VAR_I32( k_light_preview );
VG_VAR_F32( k_friction_lat );
world_link_lighting_ub( world, _shader_model_character_view.id );
world_bind_position_texture( world, _shader_model_character_view.id,
_uniform_model_character_view_g_world_depth, 2 );
+ world_bind_light_array( world, _shader_model_character_view.id,
+ _uniform_model_character_view_uLightsArray, 3 );
+ world_bind_light_index( world, _shader_model_character_view.id,
+ _uniform_model_character_view_uLightsIndex, 4 );
glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms,
player->playeravatar->sk.bone_count,
v3f co; /* 3*32 */
v2f uv; /* 2*32 */
i8 norm[4]; /* 4*8 */
- u16 lights[4]; /* 4*16 */
+ u16 unused[4];
};
#pragma pack(pop)
stride, (void *)offsetof(scene_vert, uv) );
glEnableVertexAttribArray( 2 );
+#if 0
/* 3: light cluster */
glVertexAttribIPointer( 3, 4, GL_UNSIGNED_SHORT,
stride, (void *)offsetof(scene_vert, lights) );
glEnableVertexAttribArray( 3 );
+#endif
VG_CHECK_GL_ERR();
in vec4 aNorm;
in vec3 aCo;
in vec3 aWorldCo;
-flat in ivec4 light_indices;
-
-uniform samplerBuffer uLightsArray;
-uniform usampler3D uLightsIndex;
#include "common_world.glsl"
-#include "light_clearskies.glsl"
float sdLine( vec3 p, vec3 a, vec3 b )
{
return 1.0 - player_shadow*0.8;
}
-vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )
-{
- float dist = pow(fdist*0.0010,0.78);
- return mix( vfrag, colour, min( 1.0, dist ) );
-}
-
-vec3 rand33(vec3 p3)
-{
- p3 = fract(p3 * vec3(.1031, .1030, .0973));
- p3 += dot(p3, p3.yxz+33.33);
- return fract((p3.xxy + p3.yxx)*p3.zyx);
-}
-
-vec3 scene_calculate_light( int light_index,
- vec3 halfview, vec3 co, vec3 normal )
-{
- vec4 light_colour = texelFetch( uLightsArray, light_index+0 );
- vec4 light_co = texelFetch( uLightsArray, light_index+1 );
- vec4 light_dir = texelFetch( uLightsArray, light_index+2 );
-
- vec3 light_delta = light_co.xyz-co;
- float dist2 = dot(light_delta,light_delta);
-
- light_delta = normalize( light_delta );
-
- float quadratic = dist2*100.0;
- float attenuation = 1.0f/( 1.0f + quadratic );
- attenuation *= max( dot( light_delta, normal ), 0.0 );
-
- float falloff = max( 0.0, 1.0-(dist2*light_co.w) );
-
- if( light_dir.w < 0.999999 )
- {
- float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );
- falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );
- }
-
- return light_colour.rgb * attenuation * falloff;
-}
-
-vec3 scene_calculate_packed_light_patch( uint packed_index,
- vec3 halfview, vec3 co, vec3 normal )
+vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )
{
- uint light_count = packed_index & 0x3u;
-
- vec3 l = vec3(0.0);
-
- if( light_count >= 1u )
- {
- int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );
- int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );
- int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );
-
- l += scene_calculate_light( index_0, halfview, co, normal );
-
- if( light_count >= 2u )
- {
- l += scene_calculate_light( index_1, halfview, co, normal );
-
- if( light_count >= 3u )
- {
- l += scene_calculate_light( index_2, halfview, co, normal );
- }
- }
- }
-
- return l;
-}
-
-vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )
-{
- world_info world;
- scene_state( g_time, world );
-
- // Lighting
- vec3 halfview = uCamera - aWorldCo;
- float fdist = length(halfview);
- halfview /= fdist;
-
- vec3 total_light = vec3(0.0);
- float world_shadow = newlight_compute_sun_shadow( world.sun_dir
- * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );
- float board_shadow = compute_board_shadow();
-
- total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ),
- halfview, world );
-
- vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;
- cube_coord = floor( cube_coord );
-
- if( g_debug_indices == 1 )
- {
- return rand33(cube_coord);
- }
-
- if( g_debug_complexity == 1 )
- {
- ivec3 coord = ivec3( cube_coord );
- uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );
-
- uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);
- return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );
- }
-
- // FIXME: this should absolutely must be clamped!
-
- ivec3 coord = ivec3( cube_coord );
- uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );
-
- total_light +=
- scene_calculate_packed_light_patch( index_sample.x,
- halfview, aWorldCo, wnormal )
- * board_shadow;
- total_light +=
- scene_calculate_packed_light_patch( index_sample.y,
- halfview, aWorldCo, wnormal )
- * board_shadow;
-
- vec3 fog_colour = scene_sky( -halfview, world );
- return scene_apply_fog( diffuse * total_light, fog_colour, fdist );
+ return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );
}
layout (location = 0) out vec4 oColour;
+// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...
layout (std140) uniform ub_world_lighting
{
vec4 g_cube_min;
vec4 g_cube_inv_range;
- vec4 g_light_colours[3];
- vec4 g_light_directions[3];
- vec4 g_ambient_colour;
-
vec4 g_water_plane;
vec4 g_depth_bounds;
+
+ vec4 g_daysky_colour;
+ vec4 g_nightsky_colour;
+ vec4 g_sunset_colour;
+ vec4 g_ambient_colour;
+ vec4 g_sunset_ambient;
+ vec4 g_sun_colour;
+ vec4 g_sun_dir;
+
float g_water_fog;
float g_time;
- int g_light_count;
+ float g_shadow_length;
+ float g_shadow_spread;
+
+ float g_time_of_day;
+ float g_day_phase;
+ float g_sunset_phase;
+
int g_light_preview;
int g_shadow_samples;
int g_debug_indices;
int g_debug_complexity;
-
- // g_time ?
-
- //vec4 g_point_light_positions[32];
- //vec4 g_point_light_colours[32];
};
uniform sampler2D g_world_depth;
+uniform samplerBuffer uLightsArray;
+uniform usampler3D uLightsIndex;
+
+#include "light_clearskies.glsl"
float world_depth_sample( vec3 pos )
{
float height_sample = world_depth_sample( sample_pos );
float fdelta = height_sample - sample_pos.y;
- return clamp( fdelta, 0.1, 0.2 )-0.1;
-}
-
-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 ) );
-}
-
-
-// New lighting model
-
-vec3 newlight_compute_ambient()
-{
- return g_ambient_colour.rgb;
+ return clamp( fdelta, 0.2, 0.4 )-0.2;
}
float newlight_compute_sun_shadow( vec3 dir )
return 1.0;
}
- float fspread = g_light_colours[0].w;
- vec3 vdir = dir;
- float flength = g_light_directions[0].w;
+ float fspread = g_shadow_spread;
+ float flength = g_shadow_length;
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);
+ 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((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);
return 1.0 - famt;
}
-vec3 newlight_compute_world_diffuse( vec3 wnormal )
+float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )
{
- 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 vtotal;
+ vec3 specdir = reflect( -dir, wnormal );
+ return pow(max(dot( halfview, specdir ), 0.0), exponent);
}
-vec3 newlight_compute_sun_spec( vec3 wnormal, vec3 halfview, float fintensity )
+vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )
{
- 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 vcolour*spec*fintensity;
+ float dist = pow(fdist*0.0010,0.78);
+ return mix( vfrag, colour, min( 1.0, dist ) );
}
-float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )
+vec3 rand33(vec3 p3)
{
- vec3 specdir = reflect( -dir, wnormal );
- return pow(max(dot( halfview, specdir ), 0.0), exponent);
+ p3 = fract(p3 * vec3(.1031, .1030, .0973));
+ p3 += dot(p3, p3.yxz+33.33);
+ return fract((p3.xxy + p3.yxx)*p3.zyx);
}
-vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,
- vec3 light_colour, vec3 light_pos )
+vec3 scene_calculate_light( int light_index,
+ vec3 halfview, vec3 co, vec3 normal )
{
- vec3 light_delta = light_pos-aWorldCo;
+ vec4 light_colour = texelFetch( uLightsArray, light_index+0 );
+ vec4 light_co = texelFetch( uLightsArray, light_index+1 );
+ vec4 light_dir = texelFetch( uLightsArray, light_index+2 );
+ vec3 light_delta = light_co.xyz-co;
float dist2 = dot(light_delta,light_delta);
+ light_delta = normalize( light_delta );
+
float quadratic = dist2*100.0;
float attenuation = 1.0f/( 1.0f + quadratic );
- attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );
+ attenuation *= max( dot( light_delta, normal ), 0.0 );
+
+ float falloff = max( 0.0, 1.0-(dist2*light_co.w) );
+
+ if( light_dir.w < 0.999999 )
+ {
+ float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );
+ falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );
+ }
- float falloff = max( 0.0, 1.0-(dist2*max_dist) );
- return light_colour * attenuation * falloff;
+ return light_colour.rgb * attenuation * falloff;
}
-vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview,
- vec3 light_colour, vec3 light_pos,
- vec4 light_dir )
+vec3 scene_calculate_packed_light_patch( uint packed_index,
+ vec3 halfview, vec3 co, vec3 normal )
{
- vec3 light_delta = (light_pos-aWorldCo) * 10.0;
+ uint light_count = packed_index & 0x3u;
- float quadratic = dot(light_delta,light_delta);
- float attenuation = 1.0f/( 1.0f + quadratic );
+ vec3 l = vec3(0.0);
- light_delta = normalize( light_delta );
- attenuation *= max( 0.0, dot( light_delta, wnormal ) );
+ if( light_count >= 1u )
+ {
+ int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );
+ int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );
+ int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );
+
+ l += scene_calculate_light( index_0, halfview, co, normal );
+
+ if( light_count >= 2u )
+ {
+ l += scene_calculate_light( index_1, halfview, co, normal );
+
+ if( light_count >= 3u )
+ {
+ l += scene_calculate_light( index_2, halfview, co, normal );
+ }
+ }
+ }
- float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),
- falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );
+ return l;
+}
+
+vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,
+ float light_mask )
+{
+ if( g_light_preview == 1 )
+ diffuse = vec3(0.75);
+
+ // Lighting
+ vec3 halfview = uCamera - co;
+ 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)) );
+
+ vec3 total_light = clearskies_lighting(
+ normal, min( light_mask, world_shadow ), halfview );
+
+ vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;
+ cube_coord = floor( cube_coord );
+
+ if( g_debug_indices == 1 )
+ {
+ return rand33(cube_coord);
+ }
+
+ if( g_debug_complexity == 1 )
+ {
+ ivec3 coord = ivec3( cube_coord );
+ uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );
+
+ uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);
+ return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );
+ }
- return light_colour*attenuation*falloff;
+ // FIXME: this coord should absolutely must be clamped!
+
+ ivec3 coord = ivec3( cube_coord );
+ uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );
+
+ total_light +=
+ scene_calculate_packed_light_patch( index_sample.x,
+ halfview, co, normal )
+ * light_mask;
+ total_light +=
+ scene_calculate_packed_light_patch( index_sample.y,
+ halfview, co, normal )
+ * light_mask;
+
+ // Take a section of the sky function to give us a matching fog colour
+
+ vec3 fog_colour = clearskies_ambient( -halfview );
+ float sun_theta = dot( -halfview, g_sun_dir.xyz );
+ float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );
+ float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;
+
+ vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );
+ sun_colour *= sun_shape;
+
+ fog_colour += sun_colour;
+ return scene_apply_fog( diffuse * total_light, fog_colour, fdist );
}
-const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );
-const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );
-const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );
-const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );
-const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );
-const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;
+//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );
+//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );
+//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );
+//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );
+//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );
+//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );
const float SUN_ANGLE = 0.0001;
-const float TIME_RATE = 0.025;
-
const float PI = 3.14159265;
-struct world_info
-{
- float time,
- time_of_day,
- day_phase,
- sunset_phase;
-
- vec3 sun_dir;
-};
+//struct world_info
+//{
+// float time,
+// time_of_day,
+// day_phase,
+// sunset_phase;
+//
+// vec3 sun_dir;
+//};
float luminance( vec3 v )
{
return dot( v, vec3(0.2126, 0.7152, 0.0722) );
}
-vec3 scene_ambient( vec3 dir, const world_info w )
+vec3 clearskies_ambient( vec3 dir )
{
- float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;
+ float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);
float sky_gradient = dir.y;
/* Blend phase colours */
- vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);
- ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;
- ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);
+ vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);
+ ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;
+ ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);
/* Add gradient */
ambient -= sky_gradient * luminance(ambient);
return ambient;
}
-vec3 scene_sky( vec3 ray_dir, const world_info w )
+vec3 clearskies_sky( vec3 ray_dir )
{
ray_dir.y = abs( ray_dir.y );
- vec3 sky_colour = scene_ambient( ray_dir, w );
+ vec3 sky_colour = clearskies_ambient( ray_dir );
/* Sun */
- float sun_theta = dot( ray_dir, w.sun_dir );
+ float sun_theta = dot( ray_dir, g_sun_dir.xyz );
float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );
float sun_shape = pow( sun_size, 2000.0 );
- sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;
+ sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;
- vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );
+ vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );
sun_colour *= sun_shape;
vec3 composite = sky_colour + sun_colour;
return composite;
}
-vec3 scene_compute_ambient( vec3 normal, const world_info w )
-{
- return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );
-}
-
-vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )
-{
- vec3 dir3 = vec3
- (
- cos(dir.y) * cos(dir.x),
- sin(dir.x),
- sin(dir.y) * cos(dir.x)
- );
-
- float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );
-
- return flight * colour;
-}
-
-vec3 scene_lighting_old( vec3 normal, const world_info w )
-{
- vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );
- vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );
- vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );
-
- return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +
- SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) +
- SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;
-}
-
-vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )
+vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )
{
float fresnel = 1.0 - abs(dot(normal,halfview));
- vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );
- vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR
- * w.day_phase;
+ vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb,
+ g_sunset_phase );
- float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );
+ vec3 sky_reflection = 0.5 * fresnel * reflect_colour;
+ vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25)
+ * g_sun_colour.rgb * g_day_phase;
- vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );
+ float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );
+ vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb,
+ g_sunset_phase );
return ambient + (light_sun + sky_reflection) * shadow;
-
-
-
-
-
-
- float sun_theta = dot( normal, w.sun_dir );
-
- float softness_min = 0.5;
- float softness = softness_min + w.sunset_phase * (1.0-softness_min);
- float light_min = 0.0 * w.day_phase;
- float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);
- light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;
-
- float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );
- light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );
-
- vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);
- vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );
-
- float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 )
- * 0.2 * shadow * w.day_phase;
-
- return mix(dark_colour, light_colour, light_direct) +
- spec +
- dark_colour * light_bounce;
}
-
-void scene_state( float world_time, out world_info w )
-{
- w.time = world_time;
- w.time_of_day = fract( w.time );
- w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;
- w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;
- w.sunset_phase = pow( w.sunset_phase, 6.0 );
-
- float a = w.time_of_day * PI * 2.0;
- w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );
-}
-
{
compute_motion_vectors();
- vec3 vfrag = texture( uTexMain, aUv ).rgb;
+ vec3 qnorm = normalize(floor(aNorm*2.0)*0.5) + vec3(0.001,0.0,0.0);
+ vec3 diffuse = texture( uTexMain, aUv ).rgb;
+ vec3 composite = world_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );
- // Lighting
- vec3 halfview = uCamera - aWorldCo;
- float fdist = length( halfview );
- halfview /= fdist;
- fdist -= 0.08;
+ float dist = distance( aWorldCo, uCamera ) - 0.08;
+ float opacity = clamp( dist*dist, 0.0, 1.0 );
- vec3 qnorm = normalize(floor(aNorm*2.0)*0.5) + vec3(0.001,0.0,0.0);
-
- vec3 total_light = newlight_compute_ambient();
- vec3 world_light = newlight_compute_world_diffuse( qnorm );
-
- float world_shadow = newlight_compute_sun_shadow( vec3(1.0) );
- total_light += world_light * world_shadow;
-
- vfrag = apply_fog( vfrag * total_light, fdist );
-
- float opacity = clamp( fdist*fdist, 0.0, 1.0 );
- oColour = vec4(vfrag,opacity);
+ oColour = vec4( composite, opacity );
}
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 41 0 \n"
"\n"
"float world_depth_sample( vec3 pos )\n"
"{\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 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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
"float newlight_compute_sun_shadow( vec3 dir )\n"
" return 1.0;\n"
" }\n"
"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\n"
-" float flength = g_light_directions[0].w;\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\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"
+" 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"
+"\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"
"\n"
" return 1.0 - famt;\n"
"}\n"
"\n"
-"vec3 newlight_compute_world_diffuse( vec3 wnormal )\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\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 vtotal;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
-"vec3 newlight_compute_sun_spec( vec3 wnormal, vec3 halfview, float fintensity )\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\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 vcolour*spec*fintensity;\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
"}\n"
"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"vec3 rand33(vec3 p3)\n"
"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
"}\n"
"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
" float dist2 = dot(light_delta,light_delta);\n"
"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
" float quadratic = dist2*100.0;\n"
" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
+" if( light_dir.w < 0.999999 )\n"
+" {\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff;\n"
"}\n"
"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
+" uint light_count = packed_index & 0x3u;\n"
"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
+" vec3 l = vec3(0.0);\n"
"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
+" if( light_count >= 1u )\n"
+" {\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
+" if( light_count >= 2u )\n"
+" {\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
"\n"
-" return light_colour*attenuation*falloff;\n"
+" if( light_count >= 3u )\n"
+" {\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\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"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 11 0 \n"
"{\n"
" compute_motion_vectors();\n"
"\n"
-" vec3 vfrag = texture( uTexMain, aUv ).rgb;\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
-" float fdist = length( halfview );\n"
-" halfview /= fdist;\n"
-" fdist -= 0.08;\n"
-"\n"
-" vec3 qnorm = normalize(floor(aNorm*2.0)*0.5) + vec3(0.001,0.0,0.0);\n"
-"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" vec3 world_light = newlight_compute_world_diffuse( qnorm );\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( vec3(1.0) );\n"
-" total_light += world_light * world_shadow;\n"
+" vec3 qnorm = normalize(floor(aNorm*2.0)*0.5) + vec3(0.001,0.0,0.0);\n"
+" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
+" vec3 composite = world_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );\n"
"\n"
-" vfrag = apply_fog( vfrag * total_light, fdist );\n"
+" float dist = distance( aWorldCo, uCamera ) - 0.08;\n"
+" float opacity = clamp( dist*dist, 0.0, 1.0 );\n"
"\n"
-" float opacity = clamp( fdist*fdist, 0.0, 1.0 );\n"
-" oColour = vec4(vfrag,opacity);\n"
+" oColour = vec4( composite, opacity );\n"
"}\n"
""},
};
static GLuint _uniform_model_character_view_uTexMain;
static GLuint _uniform_model_character_view_uCamera;
static GLuint _uniform_model_character_view_g_world_depth;
+static GLuint _uniform_model_character_view_uLightsArray;
+static GLuint _uniform_model_character_view_uLightsIndex;
static void shader_model_character_view_uPv(m4x4f m){
glUniformMatrix4fv(_uniform_model_character_view_uPv,1,GL_FALSE,(float*)m);
}
_uniform_model_character_view_uTexMain = glGetUniformLocation( _shader_model_character_view.id, "uTexMain" );
_uniform_model_character_view_uCamera = glGetUniformLocation( _shader_model_character_view.id, "uCamera" );
_uniform_model_character_view_g_world_depth = glGetUniformLocation( _shader_model_character_view.id, "g_world_depth" );
+ _uniform_model_character_view_uLightsArray = glGetUniformLocation( _shader_model_character_view.id, "uLightsArray" );
+ _uniform_model_character_view_uLightsIndex = glGetUniformLocation( _shader_model_character_view.id, "uLightsIndex" );
}
#endif /* SHADER_model_character_view_H */
in vec3 aCo;
in vec3 aWorldCo;
+// Spooky!
+const vec3 uCamera = vec3(0.0);
+
#include "common_world.glsl"
#include "motion_vectors_fs.glsl"
-#include "light_clearskies.glsl"
void main()
{
compute_motion_vectors();
- world_info world;
- scene_state( g_time, world );
-
vec3 rd = normalize(aNorm);
- float fmove = g_time * 0.004;
+ float fmove = g_time * 5.0;
vec2 cloudplane = (rd.xz / (rd.y*sign(rd.y))) * 0.025;
vec4 clouds1 = texture( uTexGarbage, cloudplane + vec2(0.1,0.4)*fmove*2.0 );
vec4 clouds2 = texture( uTexGarbage, cloudplane*2.0 + vec2(0.3,0.1)*fmove );
float cloud_d = max(clouds1.b*clouds2.r -0.2 - clouds2.g*0.4,0.0);
float cloud_e = pow(cloud_d,1.5)*pow(abs(rd.y),0.3)*2.0;
- oColour = vec4( scene_sky( -rd, world ) ,1.0);
+ oColour = vec4( clearskies_sky( -rd ) ,1.0);
+
+ vec3 cloud_colour = mix( mix(g_nightsky_colour.rgb,vec3(1.0),g_day_phase),
+ g_sunset_colour.rgb, g_sunset_phase );
- vec3 cloud_colour = mix( mix(NIGHTSKY_COLOUR,vec3(1.0),world.day_phase),
- SUNSET_COLOUR, world.sunset_phase );
oColour.rgb = mix( oColour.rgb, cloud_colour, cloud_e );
}
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
"\n"
+"// Spooky!\n"
+"const vec3 uCamera = vec3(0.0);\n"
+"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 41 0 \n"
"\n"
"float world_depth_sample( vec3 pos )\n"
"{\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 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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
"float newlight_compute_sun_shadow( vec3 dir )\n"
" return 1.0;\n"
" }\n"
"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\n"
-" float flength = g_light_directions[0].w;\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\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"
+" 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"
+"\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"
"\n"
" return 1.0 - famt;\n"
"}\n"
"\n"
-"vec3 newlight_compute_world_diffuse( vec3 wnormal )\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\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 vtotal;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
-"vec3 newlight_compute_sun_spec( vec3 wnormal, vec3 halfview, float fintensity )\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\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 vcolour*spec*fintensity;\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
"}\n"
"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"vec3 rand33(vec3 p3)\n"
"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
"}\n"
"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
" float dist2 = dot(light_delta,light_delta);\n"
"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
" float quadratic = dist2*100.0;\n"
" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 )\n"
+" {\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
+" return light_colour.rgb * attenuation * falloff;\n"
"}\n"
"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
+" uint light_count = packed_index & 0x3u;\n"
"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
+" vec3 l = vec3(0.0);\n"
"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
+" if( light_count >= 1u )\n"
+" {\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
+" if( light_count >= 2u )\n"
+" {\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
"\n"
-"#line 10 0 \n"
-"#line 1 2 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
+" if( light_count >= 3u )\n"
+" {\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
+" return l;\n"
+"}\n"
"\n"
-"void compute_motion_vectors()\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
"\n"
-"#line 11 0 \n"
-"#line 1 3 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\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"
"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-"const float PI = 3.14159265;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
-"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
-"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"\n"
-"\n"
-"\n"
-"\n"
+"#line 13 0 \n"
+"#line 1 2 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
"\n"
+"#line 2 0 \n"
"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
-"}\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"void compute_motion_vectors()\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
"\n"
-"#line 12 0 \n"
+"#line 14 0 \n"
"\n"
"void main()\n"
"{\n"
" compute_motion_vectors();\n"
"\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
-"\n"
" vec3 rd = normalize(aNorm);\n"
"\n"
" float fmove = g_time * 0.004;\n"
" float cloud_d = max(clouds1.b*clouds2.r -0.2 - clouds2.g*0.4,0.0);\n"
" float cloud_e = pow(cloud_d,1.5)*pow(abs(rd.y),0.3)*2.0;\n"
"\n"
-" oColour = vec4( scene_sky( -rd, world ) ,1.0);\n"
+" oColour = vec4( clearskies_sky( -rd ) ,1.0);\n"
+"\n"
+" vec3 cloud_colour = mix( mix(g_nightsky_colour.rgb,vec3(1.0),g_day_phase), \n"
+" g_sunset_colour.rgb, g_sunset_phase );\n"
"\n"
-" vec3 cloud_colour = mix( mix(NIGHTSKY_COLOUR,vec3(1.0),world.day_phase), \n"
-" SUNSET_COLOUR, world.sunset_phase );\n"
" oColour.rgb = mix( oColour.rgb, cloud_colour, cloud_e );\n"
"}\n"
""},
static GLuint _uniform_model_sky_uPvmPrev;
static GLuint _uniform_model_sky_uTexGarbage;
static GLuint _uniform_model_sky_g_world_depth;
+static GLuint _uniform_model_sky_uLightsArray;
+static GLuint _uniform_model_sky_uLightsIndex;
static void shader_model_sky_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_model_sky_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_model_sky_uPvmPrev = glGetUniformLocation( _shader_model_sky.id, "uPvmPrev" );
_uniform_model_sky_uTexGarbage = glGetUniformLocation( _shader_model_sky.id, "uTexGarbage" );
_uniform_model_sky_g_world_depth = glGetUniformLocation( _shader_model_sky.id, "g_world_depth" );
+ _uniform_model_sky_uLightsArray = glGetUniformLocation( _shader_model_sky.id, "uLightsArray" );
+ _uniform_model_sky_uLightsIndex = glGetUniformLocation( _shader_model_sky.id, "uLightsIndex" );
}
#endif /* SHADER_model_sky_H */
layout (location=0) in vec3 a_co;
layout (location=1) in vec4 a_norm;
layout (location=2) in vec2 a_uv;
-layout (location=3) in ivec4 a_lights;
#include "motion_vectors_vs.glsl"
out vec3 aCo;
out vec3 aWorldCo;
-flat out ivec4 light_indices;
-
void main()
{
vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );
aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );
aCo = a_co;
aWorldCo = world_pos0;
-
- light_indices = a_lights;
}
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
"#line 8 0 \n"
"\n"
"// Water blending\n"
static GLuint _uniform_scene_depth_uCamera;
static GLuint _uniform_scene_depth_uBoard0;
static GLuint _uniform_scene_depth_uBoard1;
+static GLuint _uniform_scene_depth_g_world_depth;
static GLuint _uniform_scene_depth_uLightsArray;
static GLuint _uniform_scene_depth_uLightsIndex;
-static GLuint _uniform_scene_depth_g_world_depth;
static void shader_scene_depth_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_depth_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_depth_uCamera = glGetUniformLocation( _shader_scene_depth.id, "uCamera" );
_uniform_scene_depth_uBoard0 = glGetUniformLocation( _shader_scene_depth.id, "uBoard0" );
_uniform_scene_depth_uBoard1 = glGetUniformLocation( _shader_scene_depth.id, "uBoard1" );
+ _uniform_scene_depth_g_world_depth = glGetUniformLocation( _shader_scene_depth.id, "g_world_depth" );
_uniform_scene_depth_uLightsArray = glGetUniformLocation( _shader_scene_depth.id, "uLightsArray" );
_uniform_scene_depth_uLightsIndex = glGetUniformLocation( _shader_scene_depth.id, "uLightsIndex" );
- _uniform_scene_depth_g_world_depth = glGetUniformLocation( _shader_scene_depth.id, "g_world_depth" );
}
#endif /* SHADER_scene_depth_H */
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
"#line 8 0 \n"
"\n"
"void main()\n"
static GLuint _uniform_scene_position_uCamera;
static GLuint _uniform_scene_position_uBoard0;
static GLuint _uniform_scene_position_uBoard1;
+static GLuint _uniform_scene_position_g_world_depth;
static GLuint _uniform_scene_position_uLightsArray;
static GLuint _uniform_scene_position_uLightsIndex;
-static GLuint _uniform_scene_position_g_world_depth;
static void shader_scene_position_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_position_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_position_uCamera = glGetUniformLocation( _shader_scene_position.id, "uCamera" );
_uniform_scene_position_uBoard0 = glGetUniformLocation( _shader_scene_position.id, "uBoard0" );
_uniform_scene_position_uBoard1 = glGetUniformLocation( _shader_scene_position.id, "uBoard1" );
+ _uniform_scene_position_g_world_depth = glGetUniformLocation( _shader_scene_position.id, "g_world_depth" );
_uniform_scene_position_uLightsArray = glGetUniformLocation( _shader_scene_position.id, "uLightsArray" );
_uniform_scene_position_uLightsIndex = glGetUniformLocation( _shader_scene_position.id, "uLightsIndex" );
- _uniform_scene_position_g_world_depth = glGetUniformLocation( _shader_scene_position.id, "g_world_depth" );
}
#endif /* SHADER_scene_position_H */
}
// Lighting
-
- vfrag = scene_do_lighting( vfrag, qnorm );
+ vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );
oColour = vec4(vfrag, 1.0);
}
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
"\n"
" }\n"
"\n"
" // Lighting\n"
-"\n"
-" vfrag = scene_do_lighting( vfrag, qnorm );\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
" oColour = vec4(vfrag, 1.0);\n"
"}\n"
""},
static GLuint _uniform_scene_route_uColour;
static GLuint _uniform_scene_route_uBoard0;
static GLuint _uniform_scene_route_uBoard1;
+static GLuint _uniform_scene_route_g_world_depth;
static GLuint _uniform_scene_route_uLightsArray;
static GLuint _uniform_scene_route_uLightsIndex;
-static GLuint _uniform_scene_route_g_world_depth;
static void shader_scene_route_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_route_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_route_uColour = glGetUniformLocation( _shader_scene_route.id, "uColour" );
_uniform_scene_route_uBoard0 = glGetUniformLocation( _shader_scene_route.id, "uBoard0" );
_uniform_scene_route_uBoard1 = glGetUniformLocation( _shader_scene_route.id, "uBoard1" );
+ _uniform_scene_route_g_world_depth = glGetUniformLocation( _shader_scene_route.id, "g_world_depth" );
_uniform_scene_route_uLightsArray = glGetUniformLocation( _shader_scene_route.id, "uLightsArray" );
_uniform_scene_route_uLightsIndex = glGetUniformLocation( _shader_scene_route.id, "uLightsIndex" );
- _uniform_scene_route_g_world_depth = glGetUniformLocation( _shader_scene_route.id, "g_world_depth" );
}
#endif /* SHADER_scene_route_H */
vfrag = vec3(0.5);
}
- vfrag = scene_do_lighting( vfrag, qnorm );
+ vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );
oColour = vec4( vfrag, 1.0 );
}
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
"\n"
" vfrag = vec3(0.5);\n"
" }\n"
"\n"
-" vfrag = scene_do_lighting( vfrag, qnorm );\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
" oColour = vec4( vfrag, 1.0 );\n"
"}\n"
""},
static GLuint _uniform_scene_standard_uPlane;
static GLuint _uniform_scene_standard_uBoard0;
static GLuint _uniform_scene_standard_uBoard1;
+static GLuint _uniform_scene_standard_g_world_depth;
static GLuint _uniform_scene_standard_uLightsArray;
static GLuint _uniform_scene_standard_uLightsIndex;
-static GLuint _uniform_scene_standard_g_world_depth;
static void shader_scene_standard_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_standard_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_standard_uPlane = glGetUniformLocation( _shader_scene_standard.id, "uPlane" );
_uniform_scene_standard_uBoard0 = glGetUniformLocation( _shader_scene_standard.id, "uBoard0" );
_uniform_scene_standard_uBoard1 = glGetUniformLocation( _shader_scene_standard.id, "uBoard1" );
+ _uniform_scene_standard_g_world_depth = glGetUniformLocation( _shader_scene_standard.id, "g_world_depth" );
_uniform_scene_standard_uLightsArray = glGetUniformLocation( _shader_scene_standard.id, "uLightsArray" );
_uniform_scene_standard_uLightsIndex = glGetUniformLocation( _shader_scene_standard.id, "uLightsIndex" );
- _uniform_scene_standard_g_world_depth = glGetUniformLocation( _shader_scene_standard.id, "g_world_depth" );
}
#endif /* SHADER_scene_standard_H */
vfrag = vec3(0.5);
}
- vfrag = scene_do_lighting( vfrag, qnorm );
+ vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );
oColour = vec4(vfrag, 1.0);
}
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
"\n"
" vfrag = vec3(0.5);\n"
" }\n"
"\n"
-" vfrag = scene_do_lighting( vfrag, qnorm );\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
" oColour = vec4(vfrag, 1.0);\n"
"}\n"
""},
static GLuint _uniform_scene_standard_alphatest_uBoard1;
static GLuint _uniform_scene_standard_alphatest_uCamera;
static GLuint _uniform_scene_standard_alphatest_uPlane;
+static GLuint _uniform_scene_standard_alphatest_g_world_depth;
static GLuint _uniform_scene_standard_alphatest_uLightsArray;
static GLuint _uniform_scene_standard_alphatest_uLightsIndex;
-static GLuint _uniform_scene_standard_alphatest_g_world_depth;
static void shader_scene_standard_alphatest_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_standard_alphatest_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_standard_alphatest_uBoard1 = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uBoard1" );
_uniform_scene_standard_alphatest_uCamera = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uCamera" );
_uniform_scene_standard_alphatest_uPlane = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPlane" );
+ _uniform_scene_standard_alphatest_g_world_depth = glGetUniformLocation( _shader_scene_standard_alphatest.id, "g_world_depth" );
_uniform_scene_standard_alphatest_uLightsArray = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsArray" );
_uniform_scene_standard_alphatest_uLightsIndex = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsIndex" );
- _uniform_scene_standard_alphatest_g_world_depth = glGetUniformLocation( _shader_scene_standard_alphatest.id, "g_world_depth" );
}
#endif /* SHADER_scene_standard_alphatest_H */
vfrag = vec3(0.5);
}
- vfrag = scene_do_lighting( vfrag, qnorm );
+ vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );
oColour = vec4(vfrag, 1.0);
}
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
"#line 10 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" vfrag = vec3(0.5);\n"
" }\n"
"\n"
-" vfrag = scene_do_lighting( vfrag, qnorm );\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
" oColour = vec4(vfrag, 1.0);\n"
"}\n"
""},
static GLuint _uniform_scene_terrain_uBlendOffset;
static GLuint _uniform_scene_terrain_uBoard0;
static GLuint _uniform_scene_terrain_uBoard1;
+static GLuint _uniform_scene_terrain_g_world_depth;
static GLuint _uniform_scene_terrain_uLightsArray;
static GLuint _uniform_scene_terrain_uLightsIndex;
-static GLuint _uniform_scene_terrain_g_world_depth;
static void shader_scene_terrain_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_terrain_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_terrain_uBlendOffset = glGetUniformLocation( _shader_scene_terrain.id, "uBlendOffset" );
_uniform_scene_terrain_uBoard0 = glGetUniformLocation( _shader_scene_terrain.id, "uBoard0" );
_uniform_scene_terrain_uBoard1 = glGetUniformLocation( _shader_scene_terrain.id, "uBoard1" );
+ _uniform_scene_terrain_g_world_depth = glGetUniformLocation( _shader_scene_terrain.id, "g_world_depth" );
_uniform_scene_terrain_uLightsArray = glGetUniformLocation( _shader_scene_terrain.id, "uLightsArray" );
_uniform_scene_terrain_uLightsIndex = glGetUniformLocation( _shader_scene_terrain.id, "uLightsIndex" );
- _uniform_scene_terrain_g_world_depth = glGetUniformLocation( _shader_scene_terrain.id, "g_world_depth" );
}
#endif /* SHADER_scene_terrain_H */
vfrag = vec3(0.5);
}
- vfrag = scene_do_lighting( vfrag, qnorm );
+ vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );
oColour = vec4(vfrag, 1.0);
}
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
"#line 8 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" vfrag = vec3(0.5);\n"
" }\n"
"\n"
-" vfrag = scene_do_lighting( vfrag, qnorm );\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
" oColour = vec4(vfrag, 1.0);\n"
"}\n"
""},
static GLuint _uniform_scene_vertex_blend_uCamera;
static GLuint _uniform_scene_vertex_blend_uBoard0;
static GLuint _uniform_scene_vertex_blend_uBoard1;
+static GLuint _uniform_scene_vertex_blend_g_world_depth;
static GLuint _uniform_scene_vertex_blend_uLightsArray;
static GLuint _uniform_scene_vertex_blend_uLightsIndex;
-static GLuint _uniform_scene_vertex_blend_g_world_depth;
static void shader_scene_vertex_blend_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_vertex_blend_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_vertex_blend_uCamera = glGetUniformLocation( _shader_scene_vertex_blend.id, "uCamera" );
_uniform_scene_vertex_blend_uBoard0 = glGetUniformLocation( _shader_scene_vertex_blend.id, "uBoard0" );
_uniform_scene_vertex_blend_uBoard1 = glGetUniformLocation( _shader_scene_vertex_blend.id, "uBoard1" );
+ _uniform_scene_vertex_blend_g_world_depth = glGetUniformLocation( _shader_scene_vertex_blend.id, "g_world_depth" );
_uniform_scene_vertex_blend_uLightsArray = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsArray" );
_uniform_scene_vertex_blend_uLightsIndex = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsIndex" );
- _uniform_scene_vertex_blend_g_world_depth = glGetUniformLocation( _shader_scene_vertex_blend.id, "g_world_depth" );
}
#endif /* SHADER_scene_vertex_blend_H */
vec4 vsurface = water_surf( halfview, surfnorm, depthvalue, beneath, above );
vsurface.a -= fdist;
oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );
- oColour.rgb = scene_do_lighting( oColour.rgb, aNorm.xyz );
+ oColour.rgb = scene_compute_lighting( oColour.rgb, aNorm.xyz, aWorldCo );
}
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
"#line 16 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" vec4 vsurface = water_surf( halfview, surfnorm, depthvalue, beneath, above );\n"
" vsurface.a -= fdist;\n"
" oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
-" oColour.rgb = scene_do_lighting( oColour.rgb, aNorm.xyz );\n"
+" oColour.rgb = scene_compute_lighting( oColour.rgb, aNorm.xyz, aWorldCo );\n"
"}\n"
""},
};
static GLuint _uniform_scene_water_uBoard1;
static GLuint _uniform_scene_water_uShoreColour;
static GLuint _uniform_scene_water_uOceanColour;
+static GLuint _uniform_scene_water_g_world_depth;
static GLuint _uniform_scene_water_uLightsArray;
static GLuint _uniform_scene_water_uLightsIndex;
-static GLuint _uniform_scene_water_g_world_depth;
static void shader_scene_water_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_water_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_water_uBoard1 = glGetUniformLocation( _shader_scene_water.id, "uBoard1" );
_uniform_scene_water_uShoreColour = glGetUniformLocation( _shader_scene_water.id, "uShoreColour" );
_uniform_scene_water_uOceanColour = glGetUniformLocation( _shader_scene_water.id, "uOceanColour" );
+ _uniform_scene_water_g_world_depth = glGetUniformLocation( _shader_scene_water.id, "g_world_depth" );
_uniform_scene_water_uLightsArray = glGetUniformLocation( _shader_scene_water.id, "uLightsArray" );
_uniform_scene_water_uLightsIndex = glGetUniformLocation( _shader_scene_water.id, "uLightsIndex" );
- _uniform_scene_water_g_world_depth = glGetUniformLocation( _shader_scene_water.id, "g_world_depth" );
}
#endif /* SHADER_scene_water_H */
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in ivec4 a_lights;\n"
"\n"
"#line 1 1 \n"
"const float k_motion_lerp_amount = 0.01;\n"
" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
"}\n"
"\n"
-"#line 7 0 \n"
+"#line 6 0 \n"
"\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
"\n"
-"flat out ivec4 light_indices;\n"
-"\n"
"void main()\n"
"{\n"
" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
-"\n"
-" light_indices = a_lights;\n"
"}\n"
""},
.fs =
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in ivec4 light_indices;\n"
-"\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
"layout (std140) uniform ub_world_lighting\n"
"{\n"
" vec4 g_cube_min;\n"
" vec4 g_cube_inv_range;\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"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+"\n"
" float g_water_fog;\n"
" float g_time;\n"
-" int g_light_count;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
"\n"
" int g_debug_indices;\n"
" int g_debug_complexity;\n"
-"\n"
-" // g_time ?\n"
-"\n"
-" //vec4 g_point_light_positions[32];\n"
-" //vec4 g_point_light_colours[32];\n"
"};\n"
"\n"
"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\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 world_water_depth( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return texture( g_world_depth, depth_coord ).g - 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"
-"\n"
-" float fdelta = height_sample - sample_pos.y;\n"
-" return clamp( fdelta, 0.1, 0.2 )-0.1;\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"
-"\n"
-"// New lighting model\n"
-"\n"
-"vec3 newlight_compute_ambient()\n"
-"{\n"
-" return g_ambient_colour.rgb;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 dir )\n"
-"{\n"
-" if( g_shadow_samples == 0 )\n"
-" {\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = dir;\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"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_world_diffuse( 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 vtotal;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_sun_spec( 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 vcolour*spec*fintensity;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_quadratic( vec3 wnormal, float max_dist,\n"
-" vec3 light_colour, vec3 light_pos )\n"
-"{\n"
-" vec3 light_delta = light_pos-aWorldCo;\n"
-"\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-" attenuation *= max( dot( normalize(light_delta), wnormal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*max_dist) );\n"
-" return light_colour * attenuation * falloff;\n"
-"}\n"
-"\n"
-"vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview, \n"
-" vec3 light_colour, vec3 light_pos,\n"
-" vec4 light_dir )\n"
-"{\n"
-" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
-"\n"
-" float quadratic = dot(light_delta,light_delta);\n"
-" float attenuation = 1.0f/( 1.0f + quadratic );\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-" attenuation *= max( 0.0, dot( light_delta, wnormal ) );\n"
-"\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) ),\n"
-" falloff = max( 0.0,( spot_theta - light_dir.w ) / (1.0-light_dir.w) );\n"
-"\n"
-" return light_colour*attenuation*falloff;\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 ) * 1.125;\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
"\n"
"const float SUN_ANGLE = 0.0001;\n"
-"const float TIME_RATE = 0.025;\n"
-"\n"
"const float PI = 3.14159265;\n"
"\n"
-"struct world_info\n"
-"{\n"
-" float time,\n"
-" time_of_day,\n"
-" day_phase,\n"
-" sunset_phase;\n"
-" \n"
-" vec3 sun_dir;\n"
-"};\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
"\n"
"float luminance( vec3 v )\n"
"{\n"
" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
"}\n"
"\n"
-"vec3 scene_ambient( vec3 dir, const world_info w )\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
"{\n"
-" float sun_azimuth = dot( dir.xz, w.sun_dir.xz ) * 0.4 + 0.6;\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
" float sky_gradient = dir.y;\n"
" \n"
" /* Blend phase colours */\n"
-" vec3 ambient = DAYSKY_COLOUR * (w.day_phase-w.sunset_phase*0.1);\n"
-" ambient += SUNSET_COLOUR * (1.0-dir.y*0.5) * w.sunset_phase * sun_azimuth;\n"
-" ambient += NIGHTSKY_COLOUR * (1.0-w.day_phase);\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
" \n"
" /* Add gradient */\n"
" ambient -= sky_gradient * luminance(ambient);\n"
" return ambient;\n"
"}\n"
"\n"
-"vec3 scene_sky( vec3 ray_dir, const world_info w )\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
"{\n"
" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = scene_ambient( ray_dir, w );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
" \n"
" /* Sun */\n"
-" float sun_theta = dot( ray_dir, w.sun_dir );\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(w.sun_dir.y,0.0) * 0.5;\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
" \n"
-" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.sunset_phase*0.5 );\n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
" sun_colour *= sun_shape;\n"
" \n"
" vec3 composite = sky_colour + sun_colour;\n"
" return composite;\n"
"}\n"
"\n"
-"vec3 scene_compute_ambient( vec3 normal, const world_info w )\n"
-"{\n"
-" return scene_ambient( (normal * vec3(1.0,-1.0,1.0)) * 0.5 + 0.5, w );\n"
-"}\n"
-"\n"
-"vec3 SR_LIGHT( vec3 normal, vec2 dir, vec3 colour )\n"
-"{\n"
-" vec3 dir3 = vec3\n"
-" (\n"
-" cos(dir.y) * cos(dir.x),\n"
-" sin(dir.x),\n"
-" sin(dir.y) * cos(dir.x)\n"
-" );\n"
-"\n"
-" float flight = max( dot( normal, dir3 ) * 0.75 + 0.25, 0.0 );\n"
-" \n"
-" return flight * colour;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting_old( vec3 normal, const world_info w )\n"
-"{\n"
-" vec3 SR_COLOUR_SUN = vec3( 1.36, 1.35, 1.01 );\n"
-" vec3 SR_COLOUR_FILL = vec3( 0.33, 0.56, 0.64 );\n"
-" vec3 SR_COLOUR_RIM = vec3( 0.05, 0.05, 0.23 );\n"
-" \n"
-" return SR_LIGHT( normal, vec2( 0.63, -0.08 ), SR_COLOUR_SUN ) +\n"
-" SR_LIGHT( normal, vec2( -2.60, -0.13 ), SR_COLOUR_FILL ) + \n"
-" SR_LIGHT( normal, vec2( 2.60, -0.84 ), SR_COLOUR_RIM ) ;\n"
-"}\n"
-"\n"
-"vec3 scene_lighting( vec3 normal, float shadow, vec3 halfview, const world_info w )\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
"{\n"
" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
"\n"
-" vec3 sky_reflection = 0.5 * fresnel * mix( DAYSKY_COLOUR, SUNSET_COLOUR, w.sunset_phase );\n"
-" vec3 light_sun = max(0.0,dot(normal,w.sun_dir)*0.75+0.25) * SUN_COLOUR \n"
-" * w.day_phase;\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0,dot(normal,g_sun_dir.xyz)*0.75+0.25) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
"\n"
-" vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
"\n"
" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
"\n"
+"#line 41 0 \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 world_water_depth( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return texture( g_world_depth, depth_coord ).g - 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"
"\n"
-"\n"
-" float sun_theta = dot( normal, w.sun_dir );\n"
-"\n"
-" float softness_min = 0.5;\n"
-" float softness = softness_min + w.sunset_phase * (1.0-softness_min);\n"
-" float light_min = 0.0 * w.day_phase;\n"
-" float light_direct = light_min + smoothstep( -softness, softness, sun_theta ) * (1.0-light_min);\n"
-" light_direct *= clamp(w.sun_dir.y * 4.0 + 1.0,0.0,1.0) * shadow;\n"
-" \n"
-" float light_bounce = 0.5 + 0.5 * dot( -normal, w.sun_dir );\n"
-" light_bounce *= light_bounce * max( w.sun_dir.y, 0.0 );\n"
-" \n"
-" vec3 light_colour = SUN_COLOUR*w.day_phase + (SUNSET_COLOUR*w.sunset_phase + 0.1);\n"
-" vec3 dark_colour = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.sunset_phase );\n"
-" \n"
-" float spec = newlight_specular( normal, w.sun_dir, halfview, 2.0 ) \n"
-" * 0.2 * shadow * w.day_phase;\n"
-" \n"
-" return mix(dark_colour, light_colour, light_direct) + \n"
-" spec +\n"
-" dark_colour * light_bounce;\n"
+" float fdelta = height_sample - sample_pos.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
"}\n"
"\n"
-"void scene_state( float world_time, out world_info w )\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
-" w.time = world_time;\n"
-" w.time_of_day = fract( w.time );\n"
-" w.day_phase = cos( w.time_of_day * PI * 2.0 ) * 0.5 + 0.5;\n"
-" w.sunset_phase = cos( w.time_of_day * PI * 4.0 + PI ) * 0.5 + 0.5;\n"
-" w.sunset_phase = pow( w.sunset_phase, 6.0 );\n"
-" \n"
-" float a = w.time_of_day * PI * 2.0;\n"
-" w.sun_dir = normalize( vec3( sin( a ), cos( a ), 0.2) );\n"
-"}\n"
+" if( g_shadow_samples == 0 )\n"
+" {\n"
+" return 1.0;\n"
+" }\n"
"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
"\n"
-"#line 14 0 \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"
"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\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"
"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
+" return 1.0 - famt;\n"
"}\n"
"\n"
-"float compute_board_shadow()\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
"}\n"
"\n"
"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
" return l;\n"
"}\n"
"\n"
-"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
"{\n"
-" world_info world;\n"
-" scene_state( g_time, world );\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
"\n"
" // Lighting\n"
-" vec3 halfview = uCamera - aWorldCo;\n"
+" vec3 halfview = uCamera - co;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = vec3(0.0);\n"
-" float world_shadow = newlight_compute_sun_shadow( world.sun_dir \n"
-" * (1.0/(max(world.sun_dir.y,0.0)+0.2)) );\n"
-" float board_shadow = compute_board_shadow();\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"
"\n"
-" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
-" halfview, world );\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
"\n"
-" vec3 cube_coord = (aWorldCo - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
" cube_coord = floor( cube_coord );\n"
"\n"
" if( g_debug_indices == 1 )\n"
" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
" }\n"
"\n"
-" // FIXME: this should absolutely must be clamped!\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
" \n"
" ivec3 coord = ivec3( cube_coord );\n"
" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
"\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, aWorldCo, wnormal ) \n"
-" * board_shadow;\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
" total_light += \n"
" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, aWorldCo, wnormal )\n"
-" * board_shadow;\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
"\n"
-" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" fog_colour += sun_colour;\n"
" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, uBoard0, uBoard1 )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
"#line 13 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
static GLuint _uniform_scene_water_fast_uBoard1;
static GLuint _uniform_scene_water_fast_uShoreColour;
static GLuint _uniform_scene_water_fast_uOceanColour;
+static GLuint _uniform_scene_water_fast_g_world_depth;
static GLuint _uniform_scene_water_fast_uLightsArray;
static GLuint _uniform_scene_water_fast_uLightsIndex;
-static GLuint _uniform_scene_water_fast_g_world_depth;
static void shader_scene_water_fast_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_scene_water_fast_uMdl,1,GL_FALSE,(float*)m);
}
_uniform_scene_water_fast_uBoard1 = glGetUniformLocation( _shader_scene_water_fast.id, "uBoard1" );
_uniform_scene_water_fast_uShoreColour = glGetUniformLocation( _shader_scene_water_fast.id, "uShoreColour" );
_uniform_scene_water_fast_uOceanColour = glGetUniformLocation( _shader_scene_water_fast.id, "uOceanColour" );
+ _uniform_scene_water_fast_g_world_depth = glGetUniformLocation( _shader_scene_water_fast.id, "g_world_depth" );
_uniform_scene_water_fast_uLightsArray = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsArray" );
_uniform_scene_water_fast_uLightsIndex = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsIndex" );
- _uniform_scene_water_fast_g_world_depth = glGetUniformLocation( _shader_scene_water_fast.id, "g_world_depth" );
}
#endif /* SHADER_scene_water_fast_H */
v4f g_cube_min,
g_cube_inv_range;
- /* v3f (padded) */
- v4f g_light_colours[3],
- g_light_directions[3],
- g_ambient_colour;
-
v4f g_water_plane,
g_depth_bounds;
+ v4f g_daysky_colour;
+ v4f g_nightsky_colour;
+ v4f g_sunset_colour;
+ v4f g_ambient_colour;
+ v4f g_sunset_ambient;
+ v4f g_sun_colour;
+ v4f g_sun_dir;
+
float g_water_fog;
float g_time;
- int g_light_count;
+ float g_shadow_length;
+ float g_shadow_spread;
+
+ float g_time_of_day;
+ float g_day_phase;
+ float g_sunset_phase;
+
int g_light_preview;
int g_shadow_samples;
int g_debug_indices;
int g_debug_complexity;
-
-#if 0
- v4f g_point_light_positions[32];
- v4f g_point_light_colours[32];
-#endif
}
ub_lighting;
GLuint ubo_lighting;
static double g_time = 0.0;
g_time += vg.time_delta * (1.0/(k_day_length*60.0));
- world->ub_lighting.g_time = g_time;
- world->ub_lighting.g_debug_indices = k_debug_light_indices;
- world->ub_lighting.g_debug_complexity = k_debug_light_complexity;
+
+ struct ub_world_lighting *state = &world->ub_lighting;
+
+ state->g_time = g_time;
+ state->g_debug_indices = k_debug_light_indices;
+ state->g_light_preview = k_light_preview;
+ state->g_debug_complexity = k_debug_light_complexity;
+
+ state->g_time_of_day = vg_fractf( g_time );
+ state->g_day_phase = cosf( state->g_time_of_day * VG_PIf * 2.0f );
+ state->g_sunset_phase= cosf( state->g_time_of_day * VG_PIf * 4.0f + VG_PIf );
+
+ state->g_day_phase = state->g_day_phase * 0.5f + 0.5f;
+ state->g_sunset_phase = powf( state->g_sunset_phase * 0.5f + 0.5f, 6.0f );
+
+ float a = state->g_time_of_day * VG_PIf * 2.0f;
+ state->g_sun_dir[0] = sinf( a );
+ state->g_sun_dir[1] = cosf( a );
+ state->g_sun_dir[2] = 0.2f;
+ v3_normalize( state->g_sun_dir );
+
+
glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
glBufferSubData( GL_UNIFORM_BUFFER, 0,
return 0.0f;
}
-VG_STATIC void world_scene_compute_light_clusters( world_instance *world,
- scene *sc )
-{
- for( int i=0; i<sc->vertex_count; i++ )
- {
- scene_vert *vert = &sc->arrvertices[i];
- vert->lights[0] = 0;
- vert->lights[1] = 1;
- vert->lights[2] = 2;
- vert->lights[3] = 0;
-
- float influences[3] = { 0.0f, 0.0f, 0.0f };
- const int N = vg_list_size( influences );
-
- for( int j=0; j<world->light_count; j ++ )
- {
- float influence = calc_light_influence( world, vert->co, j );
-
- int best_pos = N;
- for( int k=best_pos-1; k>=0; k -- )
- if( influence > influences[k] )
- best_pos = k;
-
- if( best_pos < N )
- {
- for( int k=N-1; k>best_pos; k -- )
- {
- influences[k] = influences[k-1];
- vert->lights[k] = vert->lights[k-1];
- }
-
- influences[best_pos] = influence;
- vert->lights[best_pos] = j;
- }
- }
-
- for( int j=0; j<N; j++ )
- {
- if( influences[j] > 0.00000125f )
- vert->lights[3] ++ ;
- }
- }
-}
-
VG_STATIC void world_generate( world_instance *world )
{
/*
scene_copy_slice( world->scene_geo, &mat->sm_geo );
}
- world_scene_compute_light_clusters( world, world->scene_geo );
/* compress that bad boy */
world->scene_geo = scene_fix( world_global.generic_heap, world->scene_geo );
scene_copy_slice( world->scene_no_collide, &mat->sm_no_collide );
}
- world_scene_compute_light_clusters( world, world->scene_no_collide );
/* upload and free that */
vg_acquire_thread_sync();
return d * ((q[0]*c[1]-q[1]*c[0]<0.0f)?-1.0f:1.0f);
}
+VG_STATIC void world_compute_light_indices( world_instance *world )
+{
+ /* light cubes */
+ v3f cubes_min, cubes_max;
+ v3_muls( world->scene_geo->bbx[0], 1.0f/k_light_cube_size, cubes_min );
+ v3_muls( world->scene_geo->bbx[1], 1.0f/k_light_cube_size, cubes_max );
+
+ v3_sub( cubes_min, (v3f){ 0.5f, 0.5f, 0.5f }, cubes_min );
+ v3_add( cubes_max, (v3f){ 0.5f, 0.5f, 0.5f }, cubes_max );
+
+ v3_floor( cubes_min, cubes_min );
+ v3_floor( cubes_max, cubes_max );
+
+ v3i icubes_min, icubes_max;
+
+ for( int i=0; i<3; i++ )
+ {
+ icubes_min[i] = cubes_min[i];
+ icubes_max[i] = cubes_max[i];
+ }
+
+ v3i icubes_count;
+ v3i_sub( icubes_max, icubes_min, icubes_count );
+
+ for( int i=0; i<3; i++ )
+ {
+ icubes_count[i] = VG_MIN( 128, icubes_count[i]+1 );
+ cubes_max[i] = icubes_min[i] + icubes_count[i];
+ }
+
+ v3_muls( cubes_min, k_light_cube_size, cubes_min );
+ v3_muls( cubes_max, k_light_cube_size, cubes_max );
+
+ for( int i=0; i<3; i++ )
+ {
+ float range = cubes_max[i]-cubes_min[i];
+ world->ub_lighting.g_cube_inv_range[i] = 1.0f / range;
+ world->ub_lighting.g_cube_inv_range[i] *= (float)icubes_count[i];
+
+ vg_info( "cubes[%d]: %d\n", i, icubes_count[i] );
+ }
+
+ int total_cubes = icubes_count[0]*icubes_count[1]*icubes_count[2];
+
+ u32 *cubes_index = vg_linear_alloc( world_global.generic_heap,
+ total_cubes * sizeof(u32) * 2.0f );
+
+ vg_info( "Computing light cubes (%d) [%f %f %f] -> [%f %f %f]\n",
+ total_cubes, cubes_min[0], -cubes_min[2], cubes_min[1],
+ cubes_max[0], -cubes_max[2], cubes_max[1] );
+
+ v3_copy( cubes_min, world->ub_lighting.g_cube_min );
+
+ v3f cube_size;
+ v3_div( (v3f){1.0f,1.0f,1.0f}, world->ub_lighting.g_cube_inv_range,
+ cube_size );
+ float bound_radius = v3_length( cube_size );
+
+ for( int iz = 0; iz<icubes_count[2]; iz ++ )
+ {
+ for( int iy = 0; iy<icubes_count[1]; iy++ )
+ {
+ for( int ix = 0; ix<icubes_count[0]; ix++ )
+ {
+ boxf bbx;
+ v3_div( (v3f){ ix, iy, iz }, world->ub_lighting.g_cube_inv_range,
+ bbx[0] );
+ v3_div( (v3f){ ix+1, iy+1, iz+1 },
+ world->ub_lighting.g_cube_inv_range,
+ bbx[1] );
+
+ v3_add( bbx[0], world->ub_lighting.g_cube_min, bbx[0] );
+ v3_add( bbx[1], world->ub_lighting.g_cube_min, bbx[1] );
+
+ v3f center;
+ v3_add( bbx[0], bbx[1], center );
+ v3_muls( center, 0.5f, center );
+
+ u32 indices[6] = { 0, 0, 0, 0, 0, 0 };
+ u32 count = 0;
+
+ float influences[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
+ const int N = vg_list_size( influences );
+
+ for( int j=0; j<world->light_count; j ++ )
+ {
+ struct world_light *light = &world->lights[j];
+ v3f closest;
+ closest_point_aabb( light->node->co, bbx, closest );
+
+ float dist = v3_dist( closest, light->node->co ),
+ influence = 1.0f/(dist+1.0f);
+
+ if( dist > light->inf->range )
+ continue;
+
+ if( (light->inf->type == k_light_type_spot) ||
+ (light->inf->type == k_light_type_spot_nighttime_only) )
+ {
+ v3f local;
+ m4x3_mulv( light->inverse_world, center, local );
+
+ float r = fsd_cone_infinite( local, light->angle_sin_cos );
+
+ if( r > bound_radius )
+ continue;
+ }
+
+ int best_pos = N;
+ for( int k=best_pos-1; k>=0; k -- )
+ if( influence > influences[k] )
+ best_pos = k;
+
+ if( best_pos < N )
+ {
+ for( int k=N-1; k>best_pos; k -- )
+ {
+ influences[k] = influences[k-1];
+ indices[k] = indices[k-1];
+ }
+
+ influences[best_pos] = influence;
+ indices[best_pos] = j;
+ }
+ }
+
+ for( int j=0; j<N; j++ )
+ if( influences[j] > 0.0f )
+ count ++;
+
+ int base_index = iz * (icubes_count[0]*icubes_count[1]) +
+ iy * (icubes_count[0]) +
+ ix;
+
+ int lower_count = VG_MIN( 3, count );
+ u32 packed_index_lower = lower_count;
+ packed_index_lower |= indices[0]<<2;
+ packed_index_lower |= indices[1]<<12;
+ packed_index_lower |= indices[2]<<22;
+
+ int upper_count = VG_MAX( 0, count - lower_count );
+ u32 packed_index_upper = upper_count;
+ packed_index_upper |= indices[3]<<2;
+ packed_index_upper |= indices[4]<<12;
+ packed_index_upper |= indices[5]<<22;
+
+ cubes_index[ base_index*2 + 0 ] = packed_index_lower;
+ cubes_index[ base_index*2 + 1 ] = packed_index_upper;
+ }
+ }
+ }
+
+ vg_acquire_thread_sync();
+
+ glGenTextures( 1, &world->tex_light_cubes );
+ glBindTexture( GL_TEXTURE_3D, world->tex_light_cubes );
+ glTexImage3D( GL_TEXTURE_3D, 0, GL_RG32UI,
+ icubes_count[0], icubes_count[1], icubes_count[2],
+ 0, GL_RG_INTEGER, GL_UNSIGNED_INT, cubes_index );
+ glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+
+ vg_linear_del( world_global.generic_heap, cubes_index );
+
+ vg_release_thread_sync();
+}
+
VG_STATIC int reset_player( int argc, char const *argv[] );
VG_STATIC void world_post_process( world_instance *world )
{
}
audio_unlock();
+ world_compute_light_indices( world );
+
vg_acquire_thread_sync();
{
/* create scene lighting buffer */
shader_blitcolour_uColour( (v4f){-9999.0f,-9999.0f,-9999.0f,-9999.0f} );
render_fsquad();
- /* todo: hmm?? */
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_MAX);
glEnable(GL_DEPTH_TEST);
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-
-
-
- /* light cubes */
-
- v3f cubes_min, cubes_max;
- v3_muls( world->scene_geo->bbx[0], 1.0f/k_light_cube_size, cubes_min );
- v3_muls( world->scene_geo->bbx[1], 1.0f/k_light_cube_size, cubes_max );
-
- v3_sub( cubes_min, (v3f){ 0.5f, 0.5f, 0.5f }, cubes_min );
- v3_add( cubes_max, (v3f){ 0.5f, 0.5f, 0.5f }, cubes_max );
-
- v3_floor( cubes_min, cubes_min );
- v3_floor( cubes_max, cubes_max );
-
- v3i icubes_min, icubes_max;
-
- for( int i=0; i<3; i++ )
- {
- icubes_min[i] = cubes_min[i];
- icubes_max[i] = cubes_max[i];
- }
-
- v3i icubes_count;
- v3i_sub( icubes_max, icubes_min, icubes_count );
-
- for( int i=0; i<3; i++ )
- {
- icubes_count[i] = VG_MIN( 128, icubes_count[i]+1 );
- cubes_max[i] = icubes_min[i] + icubes_count[i];
- }
-
- v3_muls( cubes_min, k_light_cube_size, cubes_min );
- v3_muls( cubes_max, k_light_cube_size, cubes_max );
-
- for( int i=0; i<3; i++ )
- {
- float range = cubes_max[i]-cubes_min[i];
- world->ub_lighting.g_cube_inv_range[i] = 1.0f / range;
- world->ub_lighting.g_cube_inv_range[i] *= (float)icubes_count[i];
-
- vg_info( "cubes[%d]: %d\n", i, icubes_count[i] );
- }
-
- int total_cubes = icubes_count[0]*icubes_count[1]*icubes_count[2];
-
- u32 *cubes_index = vg_linear_alloc( world_global.generic_heap,
- total_cubes * sizeof(u32) * 2.0f );
-
- vg_info( "Computing light cubes (%d) [%f %f %f] -> [%f %f %f]\n",
- total_cubes, cubes_min[0], -cubes_min[2], cubes_min[1],
- cubes_max[0], -cubes_max[2], cubes_max[1] );
-
- v3_copy( cubes_min, world->ub_lighting.g_cube_min );
-
- vg_info( "g_cube_min[%f %f %f]\n",
- world->ub_lighting.g_cube_min[0],
- world->ub_lighting.g_cube_min[1],
- world->ub_lighting.g_cube_min[2] );
- vg_info( "g_cube_inv_range[%f %f %f]\n",
- world->ub_lighting.g_cube_inv_range[0],
- world->ub_lighting.g_cube_inv_range[1],
- world->ub_lighting.g_cube_inv_range[2] );
-
- v3f cube_size;
- v3_div( (v3f){1.0f,1.0f,1.0f}, world->ub_lighting.g_cube_inv_range,
- cube_size );
- float bound_radius = v3_length( cube_size );
-
- for( int iz = 0; iz<icubes_count[2]; iz ++ )
- {
- for( int iy = 0; iy<icubes_count[1]; iy++ )
- {
- for( int ix = 0; ix<icubes_count[0]; ix++ )
- {
- boxf bbx;
- v3_div( (v3f){ ix, iy, iz }, world->ub_lighting.g_cube_inv_range,
- bbx[0] );
- v3_div( (v3f){ ix+1, iy+1, iz+1 },
- world->ub_lighting.g_cube_inv_range,
- bbx[1] );
-
- v3_add( bbx[0], world->ub_lighting.g_cube_min, bbx[0] );
- v3_add( bbx[1], world->ub_lighting.g_cube_min, bbx[1] );
-
- v3f center;
- v3_add( bbx[0], bbx[1], center );
- v3_muls( center, 0.5f, center );
-
- u32 indices[6] = { 0, 0, 0, 0, 0, 0 };
- u32 count = 0;
-
- float influences[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
- const int N = vg_list_size( influences );
-
- for( int j=0; j<world->light_count; j ++ )
- {
- struct world_light *light = &world->lights[j];
- v3f closest;
- closest_point_aabb( light->node->co, bbx, closest );
-
- float dist = v3_dist( closest, light->node->co ),
- influence = 1.0f/(dist+1.0f);
-
- if( dist > light->inf->range )
- continue;
-
- if( (light->inf->type == k_light_type_spot) ||
- (light->inf->type == k_light_type_spot_nighttime_only) )
- {
- v3f local;
- m4x3_mulv( light->inverse_world, center, local );
-
- float r = fsd_cone_infinite( local, light->angle_sin_cos );
-
- if( r > bound_radius )
- continue;
- }
-
- int best_pos = N;
- for( int k=best_pos-1; k>=0; k -- )
- if( influence > influences[k] )
- best_pos = k;
-
- if( best_pos < N )
- {
- for( int k=N-1; k>best_pos; k -- )
- {
- influences[k] = influences[k-1];
- indices[k] = indices[k-1];
- }
-
- influences[best_pos] = influence;
- indices[best_pos] = j;
- }
- }
-
- for( int j=0; j<N; j++ )
- if( influences[j] > 0.0f )
- count ++;
-
- int base_index = iz * (icubes_count[0]*icubes_count[1]) +
- iy * (icubes_count[0]) +
- ix;
-
- int lower_count = VG_MIN( 3, count );
- u32 packed_index_lower = lower_count;
- packed_index_lower |= indices[0]<<2;
- packed_index_lower |= indices[1]<<12;
- packed_index_lower |= indices[2]<<22;
-
- int upper_count = VG_MAX( 0, count - lower_count );
- u32 packed_index_upper = upper_count;
- packed_index_upper |= indices[3]<<2;
- packed_index_upper |= indices[4]<<12;
- packed_index_upper |= indices[5]<<22;
-
- cubes_index[ base_index * 2 + 0 ] = packed_index_lower;
- cubes_index[ base_index * 2 + 1 ] = packed_index_upper;
- }
- }
- }
-
- glGenTextures( 1, &world->tex_light_cubes ); /* FIXME: glDeleteTextures */
- glBindTexture( GL_TEXTURE_3D, world->tex_light_cubes );
- glTexImage3D( GL_TEXTURE_3D, 0, GL_RG32UI,
- icubes_count[0], icubes_count[1], icubes_count[2],
- 0, GL_RG_INTEGER, GL_UNSIGNED_INT, cubes_index );
- glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-
- vg_linear_del( world_global.generic_heap, cubes_index );
-
-
-
-
-
/* upload full buffer */
glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
glBufferSubData( GL_UNIFORM_BUFFER, 0,
glDeleteBuffers( 1, &world->tbo_light_entities );
glDeleteTextures( 1, &world->tex_light_entities );
+ glDeleteTextures( 1, &world->tex_light_cubes );
/* FIXME: CANT DO THIS HERE */
world_global.time = 0.0;
vg_release_thread_sync();
}
-VG_STATIC void world_add_global_light( world_instance *world,
- v2f dir, v3f colour )
-{
- int id = world->ub_lighting.g_light_count;
-
- v3_copy( colour, world->ub_lighting.g_light_colours[id] );
- v3_copy( (v3f){ cosf(dir[1]) * cosf(dir[0]),
- sinf(dir[0]),
- sinf(dir[1]) * cosf(dir[0]) },
- world->ub_lighting.g_light_directions[id] );
-
- world->ub_lighting.g_light_count ++;
-}
-
VG_STATIC void world_clean( world_instance *world )
{
/* clean dangling pointers */
/* default lighting conditions
* -------------------------------------------------------------*/
- world->ub_lighting.g_light_count = 0;
- world->ub_lighting.g_light_preview = 0;
- world->ub_lighting.g_shadow_samples = 8;
- world->ub_lighting.g_water_fog = 0.04f;
-
- v4_zero( world->ub_lighting.g_water_plane );
- v4_zero( world->ub_lighting.g_depth_bounds );
- v4_zero( world->ub_lighting.g_ambient_colour );
-
- v3_copy( (v3f){ 0.09f, 0.03f, 0.07f }, world->ub_lighting.g_ambient_colour );
+ struct ub_world_lighting *state = &world->ub_lighting;
- world_add_global_light( world, (v2f){ 0.63f, -0.08f },
- (v3f){ 1.36f, 1.35f, 1.01f } );
+ state->g_light_preview = 0;
+ state->g_shadow_samples = 8;
+ state->g_water_fog = 0.04f;
- world_add_global_light( world, (v2f){ -2.60f, -0.13f },
- (v3f){ 0.33f, 0.56f, 0.64f } );
+ v4_zero( state->g_water_plane );
+ v4_zero( state->g_depth_bounds );
- world_add_global_light( world, (v2f){ 2.60f, -0.84f },
- (v3f){ 0.05f, 0.05f, 0.23f } );
+ state->g_shadow_length = 9.50f;
+ state->g_shadow_spread = 0.65f;
- world->ub_lighting.g_light_directions[0][3] = 9.50f;
- world->ub_lighting.g_light_colours[0][3] = 0.65f;
+ v3_copy( (v3f){0.37f, 0.54f, 0.97f}, state->g_daysky_colour );
+ v3_copy( (v3f){0.03f, 0.05f, 0.20f}, state->g_nightsky_colour );
+ v3_copy( (v3f){1.00f, 0.32f, 0.01f}, state->g_sunset_colour );
+ v3_copy( (v3f){0.13f, 0.17f, 0.35f}, state->g_ambient_colour );
+ v3_copy( (v3f){0.25f, 0.17f, 0.51f}, state->g_sunset_ambient );
+ v3_copy( (v3f){1.10f, 0.89f, 0.35f}, state->g_sun_colour );
}
VG_STATIC void world_load( world_instance *world, const char *path )
scene_copy_slice( world->scene_lines, &route->sm );
}
-VG_STATIC void world_scene_compute_light_clusters( world_instance *world,
- scene *sc );
/*
* Create the strips of colour that run through the world along course paths
*/
for( u32 i=0; i<world->route_count; i++ )
world_routes_create_mesh( world, i );
- world_scene_compute_light_clusters( world, world->scene_lines );
-
vg_acquire_thread_sync();
{
scene_upload( world->scene_lines, &world->mesh_route_lines );