# Classtype 200
#
-# Purpose: point light
+# Purpose: world light
#
-class classtype_point_light(Structure):
+class classtype_world_light( Structure ):
#{
_pack_ = 1
- _fields_ = [("colour",c_float*4)]
+ _fields_ = [("type",c_uint32),
+ ("colour",c_float*4),
+ ("angle",c_float)]
def encode_obj(_, node, node_def):
#{
node.classtype = 200
- data = node_def['obj'].data
+ obj = node_def['obj']
+ data = obj.data
_.colour[0] = data.color[0]
_.colour[1] = data.color[1]
_.colour[2] = data.color[2]
_.colour[3] = data.energy
+
+ if obj.data.type == 'POINT':
+ #{
+ _.type = 0
+ _.angle = 0.0
+ #}
+ elif obj.data.type == 'SPOT':
+ #{
+ _.type = 1
+ _.angle = math.cos(data.spot_size*0.5)
+ #}
#}
@staticmethod
obj_classtype = 'classtype_skeleton'
elif obj_type == 'LIGHT':
#{
- if obj.data.type == 'POINT':
- obj_classtype = 'classtype_point_light'
+ obj_classtype = 'classtype_world_light'
#}
else:
#{
k_cam_spring = 20.0f,
k_cam_damp = 6.7f;
+VG_STATIC float
+ k_day_length = 30.0f; /* minutes */
+
VG_STATIC float k_ragdoll_floatyiness = 20.0f,
k_ragdoll_floatydrag = 1.0f,
k_ragdoll_limit_scale = 1.0f;
k_ragdoll_debug_collider = 1,
k_ragdoll_debug_constraints = 0;
+VG_STATIC int k_debug_light_index = 1;
VG_STATIC int freecam = 0;
VG_STATIC int walk_grid_iterations = 1;
VG_STATIC void common_var_temp(void)
{
+ VG_VAR_F32( k_day_length );
+
VG_VAR_F32( k_cam_punch );
VG_VAR_F32( k_cam_damp );
VG_VAR_F32( k_cam_spring );
k_classtype_trigger = 100,
k_classtype_logic_achievement = 101,
k_classtype_logic_relay = 102,
- k_classtype_point_light = 200,
+ k_classtype_world_light = 200,
k_classtype_nonlocal_gate = 300
};
float volume;
};
-struct classtype_point_light
+struct classtype_world_light
{
+ enum light_type
+ {
+ k_light_type_point,
+ k_light_type_spot
+ }
+ type;
+
v4f colour; /* RGB, Energy */
+ float angle;
};
#pragma pack(pop)
.link = shader_blit_link,
.vs =
{
+.orig_file = "shaders/blit.vs",
.static_src =
"layout (location=0) in vec2 a_co;\n"
"out vec2 aUv;\n"
""},
.fs =
{
+.orig_file = "shaders/blit.fs",
.static_src =
"out vec4 FragColor;\n"
"uniform sampler2D uTexMain;\n"
.link = shader_blitblur_link,
.vs =
{
+.orig_file = "shaders/blit.vs",
.static_src =
"layout (location=0) in vec2 a_co;\n"
"out vec2 aUv;\n"
""},
.fs =
{
+.orig_file = "shaders/blitblur.fs",
.static_src =
"out vec4 FragColor;\n"
"uniform sampler2D uTexMain;\n"
.link = shader_blitcolour_link,
.vs =
{
+.orig_file = "shaders/blit.vs",
.static_src =
"layout (location=0) in vec2 a_co;\n"
"out vec2 aUv;\n"
""},
.fs =
{
+.orig_file = "shaders/colour.fs",
.static_src =
"out vec4 FragColor;\n"
"uniform vec4 uColour;\n"
in vec4 aNorm;
in vec3 aCo;
in vec3 aWorldCo;
-flat in vec4 light_colours[3];
-flat in vec4 light_positions[3];
+flat in ivec4 light_indices;
+
+uniform samplerBuffer uLightsArray;
#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 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 = newlight_compute_ambient();
-
- // Compute world lighting contribution and apply it according to the
- // shadow map
- //
- vec3 world_light = newlight_compute_world_diffuse( wnormal );
- world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );
+ vec3 total_light = vec3(0.0);
+
- float world_shadow = newlight_compute_sun_shadow();
+ 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 += world_light * min( board_shadow, world_shadow );
+ total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ),
+ halfview, world );
+
+ //total_light += scene_lighting_old( wnormal, world );
// Compute the other lights that exist in the map, not effected by the sun
// shadow
- total_light += newlight_compute_quadratic
+ // read lights
+ vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );
+ vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );
+ vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );
+ vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );
+ vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );
+ vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );
+ vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );
+ vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );
+ vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );
+
+ //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),
+ // fract(distance(light_co_1.xyz,aWorldCo)),
+ // fract(distance(light_co_2.xyz,aWorldCo)));
+
+ // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),
+ // fract(light_indices.z * 0.125 ));
+
+ total_light += newlight_compute_spot
(
wnormal, halfview,
- light_positions[0].xyz,
- light_colours[0].rgb
+ light_colour_0.rgb,
+ light_co_0.xyz,
+ light_dir_0
) * board_shadow;
- total_light += newlight_compute_quadratic
+
+ total_light += newlight_compute_spot
(
wnormal, halfview,
- light_positions[1].xyz,
- light_colours[1].rgb
+ light_colour_1.rgb,
+ light_co_1.xyz,
+ light_dir_1
) * board_shadow;
- total_light += newlight_compute_quadratic
+ total_light += newlight_compute_spot
(
wnormal, halfview,
- light_positions[2].xyz,
- light_colours[2].rgb
+ light_colour_2.rgb,
+ light_co_2.xyz,
+ light_dir_2
) * board_shadow;
- return apply_fog( diffuse * total_light, fdist );
+ vec3 fog_colour = scene_sky( -halfview, world );
+
+ return scene_apply_fog( diffuse * total_light, fog_colour, fdist );
}
vec4 g_water_plane;
vec4 g_depth_bounds;
float g_water_fog;
+ float g_time;
int g_light_count;
int g_light_preview;
int g_shadow_samples;
return g_ambient_colour.rgb;
}
-float newlight_compute_sun_shadow()
+float newlight_compute_sun_shadow( vec3 dir )
{
if( g_shadow_samples == 0 )
{
}
float fspread = g_light_colours[0].w;
- vec3 vdir = g_light_directions[0].xyz;
+ vec3 vdir = dir;
float flength = g_light_directions[0].w;
float famt = 0.0;
return vcolour*spec*fintensity;
}
+float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )
+{
+ vec3 specdir = reflect( -dir, wnormal );
+ return pow(max(dot( halfview, specdir ), 0.0), exponent);
+}
+
vec3 newlight_compute_quadratic( vec3 wnormal, vec3 halfview,
- vec3 light_pos, vec3 light_colour )
+ vec3 light_colour, vec3 light_pos )
{
vec3 light_delta = (light_pos-aWorldCo) * 10.0;
return light_colour*attenuation;
}
+
+vec3 newlight_compute_spot( vec3 wnormal, vec3 halfview,
+ vec3 light_colour, vec3 light_pos,
+ vec4 light_dir )
+{
+ vec3 light_delta = (light_pos-aWorldCo) * 10.0;
+
+ float quadratic = dot(light_delta,light_delta);
+ float attenuation = 1.0f/( 1.0f + quadratic );
+
+ light_delta = normalize( light_delta );
+ attenuation *= max( 0.0, dot( light_delta, wnormal ) );
+
+ 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*attenuation*falloff;
+}
--- /dev/null
+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 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;
+};
+
+float luminance( vec3 v )
+{
+ return dot( v, vec3(0.2126, 0.7152, 0.0722) );
+}
+
+vec3 scene_ambient( vec3 dir, const world_info w )
+{
+ float sun_azimuth = dot( dir.xz, w.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);
+
+ /* Add gradient */
+ ambient -= sky_gradient * luminance(ambient);
+
+ return ambient;
+}
+
+vec3 scene_sky( vec3 ray_dir, const world_info w )
+{
+ ray_dir.y = abs( ray_dir.y );
+ vec3 sky_colour = scene_ambient( ray_dir, w );
+
+ /* Sun */
+ float sun_theta = dot( ray_dir, w.sun_dir );
+ 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;
+
+ vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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 )
+{
+ 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;
+
+ float scaled_shadow = max( shadow, 1.0 - max(w.sun_dir.y,0.0) );
+
+ vec3 ambient = mix( AMBIENT_COLOUR, SUNSET_AMBIENT, w.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) );
+}
+
vec3 total_light = newlight_compute_ambient();
vec3 world_light = newlight_compute_world_diffuse( qnorm );
- float world_shadow = newlight_compute_sun_shadow();
+ float world_shadow = newlight_compute_sun_shadow( vec3(1.0) );
total_light += world_light * world_shadow;
vfrag = apply_fog( vfrag * total_light, fdist );
.link = shader_model_character_view_link,
.vs =
{
+.orig_file = "shaders/model_skinned.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec3 a_norm;\n"
""},
.fs =
{
+.orig_file = "shaders/model_character_view.fs",
.static_src =
"uniform sampler2D uTexMain;\n"
"uniform vec3 uCamera;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\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 11 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\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();\n"
+" float world_shadow = newlight_compute_sun_shadow( vec3(1.0) );\n"
" total_light += world_light * world_shadow;\n"
"\n"
" vfrag = apply_fog( vfrag * total_light, fdist );\n"
.link = shader_model_gate_link,
.vs =
{
+.orig_file = "shaders/model_gate.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec3 a_norm;\n"
""},
.fs =
{
+.orig_file = "shaders/model_gate_lq.fs",
.static_src =
"out vec4 FragColor;\n"
"\n"
.link = shader_model_menu_link,
.vs =
{
+.orig_file = "shaders/model.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec3 a_norm;\n"
""},
.fs =
{
+.orig_file = "shaders/model_menu.fs",
.static_src =
"out vec4 FragColor;\n"
"\n"
uniform sampler2D uTexGarbage;
-uniform float uTime;
in vec4 aColour;
in vec2 aUv;
#include "common_world.glsl"
#include "motion_vectors_fs.glsl"
+#include "light_clearskies.glsl"
void main()
{
compute_motion_vectors();
- vec3 rd = normalize(aNorm);
+ world_info world;
+ scene_state( g_time, world );
- float fintensity = 1.0-(abs(rd.y)*0.7);
- float fblend = pow(fintensity,4.0);
- vec3 horizon = vec3( 0.87, 0.93, 0.98 );
- vec3 skycolour = vec3( 0.16, 0.58, 0.95 ) - rd.y*rd.y*0.5;
- vec3 diffuse = mix( skycolour, horizon, fblend );
+ vec3 rd = normalize(aNorm);
- float fmove = uTime * 0.004;
- vec2 cloudplane = (rd.xz / (rd.y*sign(rd.y))) * 0.05;
+ float fmove = g_time * 0.004;
+ 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;
- vec3 colour_ocean = vec3( 0.61, 0.84, 0.9 );
- float fhorizon = step( rd.y * 0.5 + 0.5, 0.5 );
-
- vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);
-
-
- float sundot = clamp(dot(rd, -g_light_directions[0].xyz), 0.0, 1.0);
- vec3 sun = 0.25 * vec3(1.0,0.7,0.4) * pow( sundot,5.0 );
- sun += 0.25 * vec3(1.0,0.8,0.6) * pow( sundot,64.0 );
- sun += 0.2 * vec3(1.0,0.8,0.6) * pow( sundot,512.0 );
- skycomp += sun * g_light_colours[0].rgb;
+ oColour = vec4( scene_sky( -rd, world ) ,1.0);
- oColour = vec4(skycomp,1.0);
+ 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 );
}
.link = shader_model_sky_link,
.vs =
{
+.orig_file = "shaders/model.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec3 a_norm;\n"
""},
.fs =
{
+.orig_file = "shaders/model_sky.fs",
.static_src =
"uniform sampler2D uTexGarbage;\n"
-"uniform float uTime;\n"
"\n"
"in vec4 aColour;\n"
"in vec2 aUv;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 10 0 \n"
"#line 1 2 \n"
"const float k_motion_lerp_amount = 0.01;\n"
"\n"
" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
"}\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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
"#line 12 0 \n"
"\n"
"void main()\n"
"{\n"
" compute_motion_vectors();\n"
"\n"
-" vec3 rd = normalize(aNorm);\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
"\n"
-" float fintensity = 1.0-(abs(rd.y)*0.7);\n"
-" float fblend = pow(fintensity,4.0);\n"
-" vec3 horizon = vec3( 0.87, 0.93, 0.98 );\n"
-" vec3 skycolour = vec3( 0.16, 0.58, 0.95 ) - rd.y*rd.y*0.5;\n"
-" vec3 diffuse = mix( skycolour, horizon, fblend );\n"
+" vec3 rd = normalize(aNorm);\n"
"\n"
-" float fmove = uTime * 0.004;\n"
-" vec2 cloudplane = (rd.xz / (rd.y*sign(rd.y))) * 0.05;\n"
+" float fmove = g_time * 0.004;\n"
+" vec2 cloudplane = (rd.xz / (rd.y*sign(rd.y))) * 0.025;\n"
" vec4 clouds1 = texture( uTexGarbage, cloudplane + vec2(0.1,0.4)*fmove*2.0 );\n"
" vec4 clouds2 = texture( uTexGarbage, cloudplane*2.0 + vec2(0.3,0.1)*fmove );\n"
"\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"
-" vec3 colour_ocean = vec3( 0.61, 0.84, 0.9 );\n"
-" float fhorizon = step( rd.y * 0.5 + 0.5, 0.5 );\n"
-"\n"
-" vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);\n"
+" oColour = vec4( scene_sky( -rd, world ) ,1.0);\n"
"\n"
-"\n"
-" float sundot = clamp(dot(rd, -g_light_directions[0].xyz), 0.0, 1.0);\n"
-" vec3 sun = 0.25 * vec3(1.0,0.7,0.4) * pow( sundot,5.0 );\n"
-" sun += 0.25 * vec3(1.0,0.8,0.6) * pow( sundot,64.0 );\n"
-" sun += 0.2 * vec3(1.0,0.8,0.6) * pow( sundot,512.0 );\n"
-" skycomp += sun * g_light_colours[0].rgb;\n"
-"\n"
-" oColour = vec4(skycomp,1.0);\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_uPv;
static GLuint _uniform_model_sky_uPvmPrev;
static GLuint _uniform_model_sky_uTexGarbage;
-static GLuint _uniform_model_sky_uTime;
static GLuint _uniform_model_sky_g_world_depth;
static void shader_model_sky_uMdl(m4x3f m){
glUniformMatrix4x3fv(_uniform_model_sky_uMdl,1,GL_FALSE,(float*)m);
static void shader_model_sky_uTexGarbage(int i){
glUniform1i(_uniform_model_sky_uTexGarbage,i);
}
-static void shader_model_sky_uTime(float f){
- glUniform1f(_uniform_model_sky_uTime,f);
-}
static void shader_model_sky_g_world_depth(int i){
glUniform1i(_uniform_model_sky_g_world_depth,i);
}
_uniform_model_sky_uPv = glGetUniformLocation( _shader_model_sky.id, "uPv" );
_uniform_model_sky_uPvmPrev = glGetUniformLocation( _shader_model_sky.id, "uPvmPrev" );
_uniform_model_sky_uTexGarbage = glGetUniformLocation( _shader_model_sky.id, "uTexGarbage" );
- _uniform_model_sky_uTime = glGetUniformLocation( _shader_model_sky.id, "uTime" );
_uniform_model_sky_g_world_depth = glGetUniformLocation( _shader_model_sky.id, "g_world_depth" );
}
#endif /* SHADER_model_sky_H */
--- /dev/null
+uniform sampler2D uTexGarbage;
+uniform float uTime;
+
+in vec4 aColour;
+in vec2 aUv;
+in vec3 aNorm;
+in vec3 aCo;
+in vec3 aWorldCo;
+
+#include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
+
+void main()
+{
+ compute_motion_vectors();
+
+ vec3 rd = normalize(aNorm);
+
+ float fintensity = 1.0-(abs(rd.y)*0.7);
+ float fblend = pow(fintensity,4.0);
+ vec3 horizon = vec3( 0.87, 0.93, 0.98 );
+ vec3 skycolour = vec3( 0.16, 0.58, 0.95 ) - rd.y*rd.y*0.5;
+ vec3 diffuse = mix( skycolour, horizon, fblend );
+
+ float fmove = uTime * 0.004;
+ vec2 cloudplane = (rd.xz / (rd.y*sign(rd.y))) * 0.05;
+ 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;
+
+ vec3 colour_ocean = vec3( 0.61, 0.84, 0.9 );
+ float fhorizon = step( rd.y * 0.5 + 0.5, 0.5 );
+
+ vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);
+
+
+ float sundot = clamp(dot(rd, -g_light_directions[0].xyz), 0.0, 1.0);
+ vec3 sun = 0.25 * vec3(1.0,0.7,0.4) * pow( sundot,5.0 );
+ sun += 0.25 * vec3(1.0,0.8,0.6) * pow( sundot,64.0 );
+ sun += 0.2 * vec3(1.0,0.8,0.6) * pow( sundot,512.0 );
+ skycomp += sun * g_light_colours[0].rgb;
+
+ oColour = vec4(skycomp,1.0);
+}
.link = shader_routeui_link,
.vs =
{
+.orig_file = "shaders/routeui.vs",
.static_src =
"layout (location=0) in vec2 a_co;\n"
"\n"
""},
.fs =
{
+.orig_file = "shaders/routeui.fs",
.static_src =
"out vec4 FragColor;\n"
"\n"
uniform mat4x3 uMdl;
uniform mat4 uPv;
uniform mat4 uPvmPrev;
-uniform samplerBuffer uLightsArray;
out vec2 aUv;
out vec4 aNorm;
out vec3 aCo;
out vec3 aWorldCo;
-flat out vec4 light_colours[3];
-flat out vec4 light_positions[3];
+
+flat out ivec4 light_indices;
void main()
{
aCo = a_co;
aWorldCo = world_pos0;
- // read lights
- light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );
- light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );
- light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );
- light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );
- light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );
- light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );
+ light_indices = a_lights;
}
.link = shader_scene_depth_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_depth.fs",
.static_src =
"out vec4 FragColor;\n"
"\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 8 0 \n"
static GLuint _uniform_scene_depth_uMdl;
static GLuint _uniform_scene_depth_uPv;
static GLuint _uniform_scene_depth_uPvmPrev;
-static GLuint _uniform_scene_depth_uLightsArray;
static GLuint _uniform_scene_depth_uCamera;
static GLuint _uniform_scene_depth_uBoard0;
static GLuint _uniform_scene_depth_uBoard1;
+static GLuint _uniform_scene_depth_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_depth.id, "uMdl" );
_uniform_scene_depth_uPv = glGetUniformLocation( _shader_scene_depth.id, "uPv" );
_uniform_scene_depth_uPvmPrev = glGetUniformLocation( _shader_scene_depth.id, "uPvmPrev" );
- _uniform_scene_depth_uLightsArray = glGetUniformLocation( _shader_scene_depth.id, "uLightsArray" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_depth.id, "uLightsArray" );
_uniform_scene_depth_g_world_depth = glGetUniformLocation( _shader_scene_depth.id, "g_world_depth" );
}
#endif /* SHADER_scene_depth_H */
.link = shader_scene_position_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_position.fs",
.static_src =
"out vec4 FragColor;\n"
"\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 8 0 \n"
static GLuint _uniform_scene_position_uMdl;
static GLuint _uniform_scene_position_uPv;
static GLuint _uniform_scene_position_uPvmPrev;
-static GLuint _uniform_scene_position_uLightsArray;
static GLuint _uniform_scene_position_uCamera;
static GLuint _uniform_scene_position_uBoard0;
static GLuint _uniform_scene_position_uBoard1;
+static GLuint _uniform_scene_position_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_position.id, "uMdl" );
_uniform_scene_position_uPv = glGetUniformLocation( _shader_scene_position.id, "uPv" );
_uniform_scene_position_uPvmPrev = glGetUniformLocation( _shader_scene_position.id, "uPvmPrev" );
- _uniform_scene_position_uLightsArray = glGetUniformLocation( _shader_scene_position.id, "uLightsArray" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_position.id, "uLightsArray" );
_uniform_scene_position_g_world_depth = glGetUniformLocation( _shader_scene_position.id, "g_world_depth" );
}
#endif /* SHADER_scene_position_H */
.link = shader_scene_route_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_route.fs",
.static_src =
"uniform sampler2D uTexGarbage;\n"
"uniform sampler2D uTexGradients;\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 9 0 \n"
static GLuint _uniform_scene_route_uMdl;
static GLuint _uniform_scene_route_uPv;
static GLuint _uniform_scene_route_uPvmPrev;
-static GLuint _uniform_scene_route_uLightsArray;
static GLuint _uniform_scene_route_uTexGarbage;
static GLuint _uniform_scene_route_uTexGradients;
static GLuint _uniform_scene_route_uCamera;
static GLuint _uniform_scene_route_uColour;
static GLuint _uniform_scene_route_uBoard0;
static GLuint _uniform_scene_route_uBoard1;
+static GLuint _uniform_scene_route_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_route.id, "uMdl" );
_uniform_scene_route_uPv = glGetUniformLocation( _shader_scene_route.id, "uPv" );
_uniform_scene_route_uPvmPrev = glGetUniformLocation( _shader_scene_route.id, "uPvmPrev" );
- _uniform_scene_route_uLightsArray = glGetUniformLocation( _shader_scene_route.id, "uLightsArray" );
_uniform_scene_route_uTexGarbage = glGetUniformLocation( _shader_scene_route.id, "uTexGarbage" );
_uniform_scene_route_uTexGradients = glGetUniformLocation( _shader_scene_route.id, "uTexGradients" );
_uniform_scene_route_uCamera = glGetUniformLocation( _shader_scene_route.id, "uCamera" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_route.id, "uLightsArray" );
_uniform_scene_route_g_world_depth = glGetUniformLocation( _shader_scene_route.id, "g_world_depth" );
}
#endif /* SHADER_scene_route_H */
.link = shader_scene_standard_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_standard.fs",
.static_src =
"uniform sampler2D uTexGarbage;\n"
"uniform sampler2D uTexMain;\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 9 0 \n"
static GLuint _uniform_scene_standard_uMdl;
static GLuint _uniform_scene_standard_uPv;
static GLuint _uniform_scene_standard_uPvmPrev;
-static GLuint _uniform_scene_standard_uLightsArray;
static GLuint _uniform_scene_standard_uTexGarbage;
static GLuint _uniform_scene_standard_uTexMain;
static GLuint _uniform_scene_standard_uCamera;
static GLuint _uniform_scene_standard_uPlane;
static GLuint _uniform_scene_standard_uBoard0;
static GLuint _uniform_scene_standard_uBoard1;
+static GLuint _uniform_scene_standard_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_standard.id, "uMdl" );
_uniform_scene_standard_uPv = glGetUniformLocation( _shader_scene_standard.id, "uPv" );
_uniform_scene_standard_uPvmPrev = glGetUniformLocation( _shader_scene_standard.id, "uPvmPrev" );
- _uniform_scene_standard_uLightsArray = glGetUniformLocation( _shader_scene_standard.id, "uLightsArray" );
_uniform_scene_standard_uTexGarbage = glGetUniformLocation( _shader_scene_standard.id, "uTexGarbage" );
_uniform_scene_standard_uTexMain = glGetUniformLocation( _shader_scene_standard.id, "uTexMain" );
_uniform_scene_standard_uCamera = glGetUniformLocation( _shader_scene_standard.id, "uCamera" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_standard.id, "uLightsArray" );
_uniform_scene_standard_g_world_depth = glGetUniformLocation( _shader_scene_standard.id, "g_world_depth" );
}
#endif /* SHADER_scene_standard_H */
.link = shader_scene_standard_alphatest_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_standard_alphatest.fs",
.static_src =
"uniform sampler2D uTexGarbage;\n"
"uniform sampler2D uTexMain;\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 9 0 \n"
static GLuint _uniform_scene_standard_alphatest_uMdl;
static GLuint _uniform_scene_standard_alphatest_uPv;
static GLuint _uniform_scene_standard_alphatest_uPvmPrev;
-static GLuint _uniform_scene_standard_alphatest_uLightsArray;
static GLuint _uniform_scene_standard_alphatest_uTexGarbage;
static GLuint _uniform_scene_standard_alphatest_uTexMain;
static GLuint _uniform_scene_standard_alphatest_uBoard0;
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_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uMdl" );
_uniform_scene_standard_alphatest_uPv = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPv" );
_uniform_scene_standard_alphatest_uPvmPrev = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPvmPrev" );
- _uniform_scene_standard_alphatest_uLightsArray = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsArray" );
_uniform_scene_standard_alphatest_uTexGarbage = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uTexGarbage" );
_uniform_scene_standard_alphatest_uTexMain = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uTexMain" );
_uniform_scene_standard_alphatest_uBoard0 = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uBoard0" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsArray" );
_uniform_scene_standard_alphatest_g_world_depth = glGetUniformLocation( _shader_scene_standard_alphatest.id, "g_world_depth" );
}
#endif /* SHADER_scene_standard_alphatest_H */
.link = shader_scene_terrain_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_terrain.fs",
.static_src =
"uniform sampler2D uTexGarbage;\n"
"uniform sampler2D uTexGradients;\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 10 0 \n"
static GLuint _uniform_scene_terrain_uMdl;
static GLuint _uniform_scene_terrain_uPv;
static GLuint _uniform_scene_terrain_uPvmPrev;
-static GLuint _uniform_scene_terrain_uLightsArray;
static GLuint _uniform_scene_terrain_uTexGarbage;
static GLuint _uniform_scene_terrain_uTexGradients;
static GLuint _uniform_scene_terrain_uCamera;
static GLuint _uniform_scene_terrain_uBlendOffset;
static GLuint _uniform_scene_terrain_uBoard0;
static GLuint _uniform_scene_terrain_uBoard1;
+static GLuint _uniform_scene_terrain_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_terrain.id, "uMdl" );
_uniform_scene_terrain_uPv = glGetUniformLocation( _shader_scene_terrain.id, "uPv" );
_uniform_scene_terrain_uPvmPrev = glGetUniformLocation( _shader_scene_terrain.id, "uPvmPrev" );
- _uniform_scene_terrain_uLightsArray = glGetUniformLocation( _shader_scene_terrain.id, "uLightsArray" );
_uniform_scene_terrain_uTexGarbage = glGetUniformLocation( _shader_scene_terrain.id, "uTexGarbage" );
_uniform_scene_terrain_uTexGradients = glGetUniformLocation( _shader_scene_terrain.id, "uTexGradients" );
_uniform_scene_terrain_uCamera = glGetUniformLocation( _shader_scene_terrain.id, "uCamera" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_terrain.id, "uLightsArray" );
_uniform_scene_terrain_g_world_depth = glGetUniformLocation( _shader_scene_terrain.id, "g_world_depth" );
}
#endif /* SHADER_scene_terrain_H */
.link = shader_scene_vertex_blend_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_vertex_blend.fs",
.static_src =
"uniform sampler2D uTexGarbage;\n"
"uniform sampler2D uTexGradients;\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 8 0 \n"
static GLuint _uniform_scene_vertex_blend_uMdl;
static GLuint _uniform_scene_vertex_blend_uPv;
static GLuint _uniform_scene_vertex_blend_uPvmPrev;
-static GLuint _uniform_scene_vertex_blend_uLightsArray;
static GLuint _uniform_scene_vertex_blend_uTexGarbage;
static GLuint _uniform_scene_vertex_blend_uTexGradients;
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_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_vertex_blend.id, "uMdl" );
_uniform_scene_vertex_blend_uPv = glGetUniformLocation( _shader_scene_vertex_blend.id, "uPv" );
_uniform_scene_vertex_blend_uPvmPrev = glGetUniformLocation( _shader_scene_vertex_blend.id, "uPvmPrev" );
- _uniform_scene_vertex_blend_uLightsArray = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsArray" );
_uniform_scene_vertex_blend_uTexGarbage = glGetUniformLocation( _shader_scene_vertex_blend.id, "uTexGarbage" );
_uniform_scene_vertex_blend_uTexGradients = glGetUniformLocation( _shader_scene_vertex_blend.id, "uTexGradients" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsArray" );
_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 );
}
.link = shader_scene_water_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_water.fs",
.static_src =
"uniform sampler2D uTexMain;\n"
"uniform sampler2D uTexDudv;\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 16 0 \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"
"}\n"
""},
};
static GLuint _uniform_scene_water_uMdl;
static GLuint _uniform_scene_water_uPv;
static GLuint _uniform_scene_water_uPvmPrev;
-static GLuint _uniform_scene_water_uLightsArray;
static GLuint _uniform_scene_water_uTexMain;
static GLuint _uniform_scene_water_uTexDudv;
static GLuint _uniform_scene_water_uTexBack;
static GLuint _uniform_scene_water_uBoard1;
static GLuint _uniform_scene_water_uShoreColour;
static GLuint _uniform_scene_water_uOceanColour;
+static GLuint _uniform_scene_water_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_water.id, "uMdl" );
_uniform_scene_water_uPv = glGetUniformLocation( _shader_scene_water.id, "uPv" );
_uniform_scene_water_uPvmPrev = glGetUniformLocation( _shader_scene_water.id, "uPvmPrev" );
- _uniform_scene_water_uLightsArray = glGetUniformLocation( _shader_scene_water.id, "uLightsArray" );
_uniform_scene_water_uTexMain = glGetUniformLocation( _shader_scene_water.id, "uTexMain" );
_uniform_scene_water_uTexDudv = glGetUniformLocation( _shader_scene_water.id, "uTexDudv" );
_uniform_scene_water_uTexBack = glGetUniformLocation( _shader_scene_water.id, "uTexBack" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_water.id, "uLightsArray" );
_uniform_scene_water_g_world_depth = glGetUniformLocation( _shader_scene_water.id, "g_world_depth" );
}
#endif /* SHADER_scene_water_H */
.link = shader_scene_water_fast_link,
.vs =
{
+.orig_file = "shaders/scene.vs",
.static_src =
"layout (location=0) in vec3 a_co;\n"
"layout (location=1) in vec4 a_norm;\n"
"uniform mat4x3 uMdl;\n"
"uniform mat4 uPv;\n"
"uniform mat4 uPvmPrev;\n"
-"uniform samplerBuffer uLightsArray;\n"
"\n"
"out vec2 aUv;\n"
"out vec4 aNorm;\n"
"out vec3 aCo;\n"
"out vec3 aWorldCo;\n"
-"flat out vec4 light_colours[3];\n"
-"flat out vec4 light_positions[3];\n"
+"\n"
+"flat out ivec4 light_indices;\n"
"\n"
"void main()\n"
"{\n"
" aCo = a_co;\n"
" aWorldCo = world_pos0;\n"
"\n"
-" // read lights\n"
-" light_colours[0] = texelFetch( uLightsArray, a_lights.x*2+0 );\n"
-" light_colours[1] = texelFetch( uLightsArray, a_lights.y*2+0 );\n"
-" light_colours[2] = texelFetch( uLightsArray, a_lights.z*2+0 );\n"
-" light_positions[0] = texelFetch( uLightsArray, a_lights.x*2+1 );\n"
-" light_positions[1] = texelFetch( uLightsArray, a_lights.y*2+1 );\n"
-" light_positions[2] = texelFetch( uLightsArray, a_lights.z*2+1 );\n"
+" light_indices = a_lights;\n"
"}\n"
""},
.fs =
{
+.orig_file = "shaders/scene_water_fast.fs",
.static_src =
"uniform sampler2D uTexDudv;\n"
"\n"
"in vec4 aNorm;\n"
"in vec3 aCo;\n"
"in vec3 aWorldCo;\n"
-"flat in vec4 light_colours[3];\n"
-"flat in vec4 light_positions[3];\n"
+"flat in ivec4 light_indices;\n"
+"\n"
+"uniform samplerBuffer uLightsArray;\n"
"\n"
"#line 1 1 \n"
"layout (location = 0) out vec4 oColour;\n"
" vec4 g_water_plane;\n"
" vec4 g_depth_bounds;\n"
" float g_water_fog;\n"
+" float g_time;\n"
" int g_light_count;\n"
" int g_light_preview;\n"
" int g_shadow_samples;\n"
" return g_ambient_colour.rgb;\n"
"}\n"
"\n"
-"float newlight_compute_sun_shadow()\n"
+"float newlight_compute_sun_shadow( vec3 dir )\n"
"{\n"
" if( g_shadow_samples == 0 )\n"
" {\n"
" }\n"
"\n"
" float fspread = g_light_colours[0].w;\n"
-" vec3 vdir = g_light_directions[0].xyz;\n"
+" vec3 vdir = dir;\n"
" float flength = g_light_directions[0].w;\n"
"\n"
" float famt = 0.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, vec3 halfview, \n"
-" vec3 light_pos, vec3 light_colour )\n"
+" vec3 light_colour, vec3 light_pos )\n"
"{\n"
" vec3 light_delta = (light_pos-aWorldCo) * 10.0;\n"
"\n"
" return light_colour*attenuation;\n"
"}\n"
"\n"
-"#line 11 0 \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 12 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"
+"\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"
+"\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"
+"{\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"
+"\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"
+" \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"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), SUNSET_COLOUR, w.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"
+"{\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"
+"\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"
+"}\n"
+"\n"
+"void scene_state( float world_time, out world_info w )\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"
+"\n"
+"\n"
+"#line 13 0 \n"
"\n"
"float sdLine( vec3 p, vec3 a, vec3 b )\n"
"{\n"
" return 1.0 - player_shadow*0.8;\n"
"}\n"
"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist )\n"
+"{\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
"vec3 scene_do_lighting( vec3 diffuse, vec3 wnormal )\n"
"{\n"
+" world_info world;\n"
+" scene_state( g_time, world );\n"
+"\n"
" // Lighting\n"
" vec3 halfview = uCamera - aWorldCo;\n"
" float fdist = length(halfview);\n"
" halfview /= fdist;\n"
"\n"
-" vec3 total_light = newlight_compute_ambient();\n"
-" \n"
-" // Compute world lighting contribution and apply it according to the\n"
-" // shadow map\n"
-" //\n"
-" vec3 world_light = newlight_compute_world_diffuse( wnormal );\n"
-" world_light += newlight_compute_sun_spec( wnormal, halfview, 0.1 );\n"
+" vec3 total_light = vec3(0.0);\n"
+"\n"
"\n"
-" float world_shadow = newlight_compute_sun_shadow();\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"
"\n"
-" total_light += world_light * min( board_shadow, world_shadow );\n"
+" total_light += scene_lighting( wnormal, min( board_shadow, world_shadow ), \n"
+" halfview, world );\n"
+"\n"
+" //total_light += scene_lighting_old( wnormal, world );\n"
"\n"
" // Compute the other lights that exist in the map, not effected by the sun\n"
" // shadow\n"
"\n"
-" total_light += newlight_compute_quadratic\n"
+" // read lights\n"
+" vec4 light_colour_0 = texelFetch( uLightsArray, light_indices.x*3+0 );\n"
+" vec4 light_colour_1 = texelFetch( uLightsArray, light_indices.y*3+0 );\n"
+" vec4 light_colour_2 = texelFetch( uLightsArray, light_indices.z*3+0 );\n"
+" vec4 light_co_0 = texelFetch( uLightsArray, light_indices.x*3+1 );\n"
+" vec4 light_co_1 = texelFetch( uLightsArray, light_indices.y*3+1 );\n"
+" vec4 light_co_2 = texelFetch( uLightsArray, light_indices.z*3+1 );\n"
+" vec4 light_dir_0 = texelFetch( uLightsArray, light_indices.x*3+2 );\n"
+" vec4 light_dir_1 = texelFetch( uLightsArray, light_indices.y*3+2 );\n"
+" vec4 light_dir_2 = texelFetch( uLightsArray, light_indices.z*3+2 );\n"
+"\n"
+" //return vec3(fract(distance(light_co_0.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_1.xyz,aWorldCo)),\n"
+" // fract(distance(light_co_2.xyz,aWorldCo)));\n"
+"\n"
+" // return vec3(fract(light_indices.x * 0.125), fract(light_indices.y*0.125),\n"
+" // fract(light_indices.z * 0.125 ));\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[0].xyz,\n"
-" light_colours[0].rgb \n"
+" light_colour_0.rgb,\n"
+" light_co_0.xyz,\n"
+" light_dir_0\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+"\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[1].xyz,\n"
-" light_colours[1].rgb \n"
+" light_colour_1.rgb,\n"
+" light_co_1.xyz,\n"
+" light_dir_1\n"
" ) * board_shadow;\n"
-" total_light += newlight_compute_quadratic\n"
+" total_light += newlight_compute_spot\n"
" ( \n"
" wnormal, halfview,\n"
-" light_positions[2].xyz,\n"
-" light_colours[2].rgb \n"
+" light_colour_2.rgb,\n"
+" light_co_2.xyz,\n"
+" light_dir_2\n"
" ) * board_shadow;\n"
"\n"
-" return apply_fog( diffuse * total_light, fdist );\n"
+" vec3 fog_colour = scene_sky( -halfview, world );\n"
+" \n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
"}\n"
"\n"
"#line 13 0 \n"
static GLuint _uniform_scene_water_fast_uMdl;
static GLuint _uniform_scene_water_fast_uPv;
static GLuint _uniform_scene_water_fast_uPvmPrev;
-static GLuint _uniform_scene_water_fast_uLightsArray;
static GLuint _uniform_scene_water_fast_uTexDudv;
static GLuint _uniform_scene_water_fast_uTime;
static GLuint _uniform_scene_water_fast_uCamera;
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_uLightsArray;
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_uMdl = glGetUniformLocation( _shader_scene_water_fast.id, "uMdl" );
_uniform_scene_water_fast_uPv = glGetUniformLocation( _shader_scene_water_fast.id, "uPv" );
_uniform_scene_water_fast_uPvmPrev = glGetUniformLocation( _shader_scene_water_fast.id, "uPvmPrev" );
- _uniform_scene_water_fast_uLightsArray = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsArray" );
_uniform_scene_water_fast_uTexDudv = glGetUniformLocation( _shader_scene_water_fast.id, "uTexDudv" );
_uniform_scene_water_fast_uTime = glGetUniformLocation( _shader_scene_water_fast.id, "uTime" );
_uniform_scene_water_fast_uCamera = glGetUniformLocation( _shader_scene_water_fast.id, "uCamera" );
_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_uLightsArray = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsArray" );
_uniform_scene_water_fast_g_world_depth = glGetUniformLocation( _shader_scene_water_fast.id, "g_world_depth" );
}
#endif /* SHADER_scene_water_fast_H */
g_depth_bounds;
float g_water_fog;
+ float g_time;
int g_light_count;
int g_light_preview;
int g_shadow_samples;
*/
struct world_light
{
- v3f co;
- v4f colour;
+ mdl_node *node;
+ struct classtype_world_light *inf;
+
+ /* enabled.. etc?
+ * TODO: we should order entities in the binary by their type */
}
* lights;
u32 light_count;
VG_STATIC void world_update( world_instance *world, v3f pos )
{
+ /* TEMP!!!!!! */
+ 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;
+
+ glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
+ glBufferSubData( GL_UNIFORM_BUFFER, 0,
+ sizeof(struct ub_world_lighting), &world->ub_lighting );
+ /* TEMP!!!!!! */
+
+
#if 0
if( world.switching_to_new_world )
{
0xff00ff00 );
}
- if( 0 )
+ if( k_debug_light_index )
{
for( int i=0; i<world->light_count; i++ )
{
struct world_light *light = &world->lights[i];
+ struct classtype_world_light *inf = light->inf;
u32 colour = 0xff000000;
- u8 r = light->colour[0] * 255.0f,
- g = light->colour[1] * 255.0f,
- b = light->colour[2] * 255.0f;
+ u8 r = inf->colour[0] * 255.0f,
+ g = inf->colour[1] * 255.0f,
+ b = inf->colour[2] * 255.0f;
colour |= r;
colour |= g << 8;
colour |= b << 16;
- vg_line_pt3( light->co, 0.25f, colour );
+ vg_line_pt3( light->node->co, 0.25f, colour );
}
}
sizeof(struct logic_achievement)
},
{
- k_classtype_point_light,
+ k_classtype_world_light,
(void*)&world->lights,
sizeof(struct world_light)
},
world->achievement_count ++;
}
-VG_STATIC void world_pct_point_light( world_instance *world, mdl_node *pnode )
+VG_STATIC void world_pct_world_light( world_instance *world, mdl_node *pnode )
{
- struct world_light *light = &world->lights[ world->light_count ];
- v3_copy( pnode->co, light->co );
-
- struct classtype_point_light *inf = mdl_get_entdata( world->meta, pnode );
- v4_copy( inf->colour, light->colour );
-
- world->light_count ++;
+ struct world_light *light = &world->lights[ world->light_count ++ ];
+ light->node = pnode;
+ light->inf = mdl_get_entdata( world->meta, pnode );
}
VG_STATIC void world_pct_nonlocal_gate( world_instance *world, mdl_node *pnode )
{ k_classtype_trigger, world_pct_trigger },
{ k_classtype_logic_relay, world_pct_relay },
{ k_classtype_logic_achievement, world_pct_achievement },
- { k_classtype_point_light, world_pct_point_light },
+ { k_classtype_world_light, world_pct_world_light },
{ k_classtype_nonlocal_gate, world_pct_nonlocal_gate }
};
}
}
+VG_STATIC float colour_luminance( v3f v )
+{
+ return v3_dot( v, (v3f){0.2126f, 0.7152f, 0.0722f} );
+}
+
+VG_STATIC float calc_light_influence( world_instance *world, v3f position,
+ v3f normal, int light )
+{
+ struct world_light *world_light = &world->lights[ light ];
+ struct classtype_world_light *inf = world_light->inf;
+
+ v3f light_delta;
+ v3_sub( world_light->node->co, position, light_delta );
+ v3_muls( light_delta, 10.0f, light_delta );
+
+ float quadratic = v3_dot( light_delta, light_delta ),
+ attenuation = 1.0f/( 1.0f + quadratic );
+
+ v3_normalize( light_delta );
+ //attenuation *= vg_maxf( 0.0, v3_dot( light_delta, normal ) );
+
+ float quadratic_light = attenuation * colour_luminance( inf->colour );
+
+ if( inf->type == k_light_type_point )
+ {
+ return quadratic_light;
+ }
+ else if( inf->type == k_light_type_spot )
+ {
+ v3f dir;
+ q_mulv( world_light->node->q, (v3f){0.0f,1.0f,0.0f}, dir );
+
+ float spot_theta = vg_maxf( 0.0f, v3_dot( light_delta, dir ) ),
+ falloff = spot_theta >= 0.0f? 1.0f: 0.0f;
+
+ return quadratic_light * falloff;
+ }
+ else
+ 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] = 255;
- vert->lights[1] = 255;
- vert->lights[2] = 255;
- vert->lights[3] = 255;
+ vert->lights[0] = 0;
+ vert->lights[1] = 1;
+ vert->lights[2] = 2;
+ vert->lights[3] = 3;
- float distances[4] = { INFINITY, INFINITY, INFINITY, INFINITY };
+ float influences[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+
+ v3f co, norm;
+ v3_copy( vert->co, co );
+
+ norm[0] = vert->norm[0];
+ norm[1] = vert->norm[1];
+ norm[2] = vert->norm[2];
+
+ v3_muls( norm, 1.0f/127.0f, norm );
for( int j=0; j<world->light_count; j ++ )
{
- float dist = v3_dist2( world->lights[j].co, vert->co );
+ float influence = calc_light_influence( world, co, norm, j );
int best_pos = 4;
for( int k=best_pos-1; k>=0; k -- )
- if( dist < distances[k] )
+ if( influence > influences[k] )
best_pos = k;
if( best_pos < 4 )
{
for( int k=3; k>best_pos; k -- )
{
- distances[k] = distances[k-1];
+ influences[k] = influences[k-1];
vert->lights[k] = vert->lights[k-1];
}
- distances[best_pos] = dist;
+ influences[best_pos] = influence;
vert->lights[best_pos] = j;
}
}
vg_acquire_thread_sync();
{
/* create scene lighting buffer */
+
+ u32 size = VG_MAX(world->light_count,1) * sizeof(float)*12;
+
+ vg_info( "Upload %ubytes (lighting)\n", size );
+
glGenBuffers( 1, &world->tbo_light_entities );
glBindBuffer( GL_TEXTURE_BUFFER, world->tbo_light_entities );
- glBufferData( GL_TEXTURE_BUFFER, world->light_count*sizeof(float)*8,
- NULL, GL_DYNAMIC_DRAW );
+ glBufferData( GL_TEXTURE_BUFFER, size, NULL, GL_DYNAMIC_DRAW );
+
+ /* buffer layout
+ *
+ * colour position direction (spots)
+ * | . . . . | . . . . | . . . . |
+ * | Re Ge Be Night | Xco Yco Zco | Dx Dy Dz Da |
+ *
+ */
v4f *light_dst = glMapBuffer( GL_TEXTURE_BUFFER, GL_WRITE_ONLY );
for( int i=0; i<world->light_count; i++ )
{
struct world_light *light = &world->lights[i];
+ struct classtype_world_light *inf = light->inf;
- v3_muls( light->colour, light->colour[3] * 2.0f, light_dst[i*2+0] );
- v3_copy( light->co, light_dst[i*2+1] );
+ /* colour + night */
+ v3_muls( inf->colour, inf->colour[3] * 2.0f, light_dst[i*3+0] );
+ light_dst[i*3+0][3] = 1.0f;
+
+ /* position + nothing */
+ v3_copy( light->node->co, light_dst[i*3+1] );
+
+ /* direction + angle */
+ q_mulv( light->node->q, (v3f){0.0f,-1.0f,0.0f}, light_dst[i*3+2]);
+ light_dst[i*3+2][3] = inf->angle;
}
glUnmapBuffer( GL_TEXTURE_BUFFER );
mesh_free( &world->mesh_geo );
mesh_free( &world->mesh_no_collide );
+ glDeleteBuffers( 1, &world->tbo_light_entities );
+ glDeleteTextures( 1, &world->tex_light_entities );
+
/* FIXME: CANT DO THIS HERE */
world_global.time = 0.0;
world_global.rewind_from = 0.0;
world_render_both_stages( world, k_shader_terrain_blend, bindpoint_terrain );
}
-VG_STATIC void render_sky( camera *cam )
+VG_STATIC void render_sky( world_instance *world, camera *cam )
{
/*
* Modify matrix to remove clipping and view translation
shader_model_sky_uPv( pv );
shader_model_sky_uPvmPrev( pv_prev );
shader_model_sky_uTexGarbage(0);
- shader_model_sky_uTime( world_global.sky_time );
+ world_link_lighting_ub( world, _shader_model_sky.id );
vg_tex2d_bind( &tex_terrain_noise, 0 );
VG_STATIC void render_world( world_instance *world, camera *cam )
{
- render_sky( cam );
+ render_sky( world, cam );
render_world_routes( world, cam );
render_world_standard( world, cam );
VG_STATIC void world_bind_position_texture( world_instance *world,
GLuint shader, GLuint location,
int slot );
+VG_STATIC void world_bind_light_array( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
/*
* Does not write motion vectors
world_link_lighting_ub( world, _shader_scene_water.id );
world_bind_position_texture( world, _shader_scene_water.id,
_uniform_scene_water_g_world_depth, 2 );
+ world_bind_light_array( world, _shader_scene_water.id,
+ _uniform_scene_water_uLightsArray, 4 );
render_fb_bind_texture( gpipeline.fb_water_beneath, 0, 3 );
shader_scene_water_uTexBack( 3 );
world_link_lighting_ub( world, _shader_scene_water_fast.id );
world_bind_position_texture( world, _shader_scene_water_fast.id,
_uniform_scene_water_fast_g_world_depth, 2 );
+ world_bind_light_array( world, _shader_scene_water_fast.id,
+ _uniform_scene_water_fast_uLightsArray, 4 );
m4x3f full;
m4x3_identity( full );