1
0
Fork 0
* fix the 'slanting shadow > 75 meters' problem
* lay down the shadow flat on the ground

wlbragg:
* add fading effect based o altitude
This commit is contained in:
Erik Hofman 2017-03-25 09:57:36 +01:00
parent b923ccbd47
commit 44cabc2eec
2 changed files with 83 additions and 21 deletions

View file

@ -2,6 +2,7 @@
uniform sampler2D texture; uniform sampler2D texture;
uniform float scattering; uniform float scattering;
varying float alpha_correction;
void main() void main()
{ {
@ -15,5 +16,5 @@ void main()
texel.a = min(0.8, texel.a); texel.a = min(0.8, texel.a);
vec4 fragColor = texel; vec4 fragColor = texel;
gl_FragColor = fragColor; gl_FragColor = fragColor * alpha_correction;;
} }

View file

@ -5,14 +5,14 @@
uniform float hazeLayerAltitude; uniform float hazeLayerAltitude;
uniform float terminator; uniform float terminator;
uniform float terrain_alt; uniform float terrain_alt;
uniform float overcast; uniform float overcast;
uniform float ground_scattering; uniform float ground_scattering;
uniform float eye_alt; uniform float eye_alt;
uniform float moonlight; uniform float moonlight;
uniform float alt_agl; uniform float alt_agl;
uniform float pitch; uniform float pitch;
uniform float roll; uniform float roll;
uniform float gear_clearance; uniform float gear_clearance;
@ -22,12 +22,24 @@ const float terminator_width = 200000.0;
void rotationMatrixPR(in float sinRx, in float cosRx, in float sinRy, in float cosRy, out mat4 rotmat) void rotationMatrixPR(in float sinRx, in float cosRx, in float sinRy, in float cosRy, out mat4 rotmat)
{ {
rotmat = mat4( cosRy , sinRx * sinRy , cosRx * sinRy, 0.0, rotmat = mat4( cosRy , sinRx * sinRy , cosRx * sinRy, 0.0,
0.0 , cosRx , -sinRx * cosRx, 0.0, 0.0 , cosRx , -sinRx , 0.0,
-sinRy, sinRx * cosRy, cosRx * cosRy , 0.0, -sinRy, sinRx * cosRy, cosRx * cosRy , 0.0,
0.0 , 0.0 , 0.0 , 1.0 ); 0.0 , 0.0 , 0.0 , 1.0 );
} }
/*
//Experimental - not used for now. Seems to work functionally the same as rotationMatrixPR
void rotationMatrixRP(in float sinRx, in float cosRx, in float sinRy, in float cosRy, out mat4 rotmat)
{
rotmat = mat4( cosRy , sinRx * sinRy , -cosRx * sinRy, 0.0,
0.0 , cosRx , sinRx , 0.0,
sinRy, -sinRx * cosRy, cosRx * cosRy , 0.0,
0.0 , 0.0 , 0.0 , 1.0 );
}
*/
float light_func (in float x, in float a, in float b, in float c, in float d, in float e) float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
{ {
@ -36,10 +48,15 @@ if (x < -15.0) {return 0.0;}
return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d)); return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d));
} }
varying float alpha_correction;
void main() void main()
{ {
float start_fade = 0;
float end_fade = 100;
float diff = end_fade - start_fade;
alpha_correction = 1.0 - smoothstep(start_fade, end_fade, alt_agl);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0); vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
@ -48,7 +65,7 @@ void main()
// compute the strength of light // compute the strength of light
float vertex_alt = max(gl_Vertex.z,100.0); float vertex_alt = max(gl_Vertex.z,100.0);
float scattering = ground_scattering + (1.0 - ground_scattering) * smoothstep(hazeLayerAltitude -100.0, hazeLayerAltitude + 100.0, vertex_alt); float scattering = ground_scattering + (1.0 - ground_scattering) * smoothstep(hazeLayerAltitude -100.0, hazeLayerAltitude + 100.0, vertex_alt);
vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz; vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz;
vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0)); vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0));
float yprime = -dot(relPos, lightHorizon); float yprime = -dot(relPos, lightHorizon);
@ -65,36 +82,80 @@ void main()
light_diffuse.rgb = light_diffuse.rgb * (1.0 + 1.2 * shade_depth); light_diffuse.rgb = light_diffuse.rgb * (1.0 + 1.2 * shade_depth);
//experiment
light_diffuse.b = 1.0;
light_diffuse.g = 1.0;
light_diffuse.r = 1.0;
light_diffuse.a = 1.0;
//prepare rotation matrix //prepare rotation matrix
mat4 RotMatPR; mat4 RotMatPR;
mat4 RotMatPR_tr;
float _roll = roll; float _roll = roll;
if (_roll>90.0 || _roll < -90.0) //if (_roll>90.0 || _roll < -90.0) //making roll=-roll when >90 is no longer necessary thanks to fix with transpose of rotation matrix.
{_roll = -_roll;} //{_roll = -_roll;}
float cosRx = cos(radians(_roll)); float cosRx = cos(radians(-_roll));
float sinRx = sin(radians(_roll)); float sinRx = sin(radians(-_roll));
float cosRy = cos(radians(-pitch)); float cosRy = cos(radians(pitch));
float sinRy = sin(radians(-pitch)); float sinRy = sin(radians(pitch));
rotationMatrixPR(sinRx, cosRx, sinRy, cosRy, RotMatPR); rotationMatrixPR(sinRx, cosRx, sinRy, cosRy, RotMatPR);
//rotationMatrixRP(sinRx, cosRx, sinRy, cosRy, RotMatPR);
RotMatPR_tr=transpose(RotMatPR); //RotMatPR works fine if pitch =0 or roll=0 but if say pitch=35 and roll=60 the rotation is all wrong. transpose(RotMatPR) however works perfectly.
// project the shadow onto the ground // project the shadow onto the ground
vec4 vertex = RotMatPR * gl_Vertex; //vec4 vertex = RotMatPR * gl_Vertex;
vec4 vertex = RotMatPR_tr * gl_Vertex;
vec4 pos = vertex; vec4 pos = vertex;
pos.z = -0.9* alt_agl + 0.05 * vertex.z;
//pos.z = 0.05 * (vertex.z + gear_clearance); vec2 deltaxy = lightFull.xy * 0.95* (alt_agl + vertex.z + gear_clearance)/lightFull.z; //This is the 'actual' location, taking into a account the full 3-D structure of the aircraft
vec2 deltazeroxy = lightFull.xy * 0.95* (alt_agl + gear_clearance)/lightFull.z; //Instead of using the exact z value of this particularly point to determine the distance of the shadow & reposition & shrink it appropriately, we'll just use the origin (0,0,0) of the model instead. This avoids a problem below, where varying vertex.z in deltaxy and then using deltaxy to calculate dist caused the shadow to sort of slant upwards, thanks to the varying z values used
float dist = sqrt(deltazeroxy.x * deltazeroxy.x + deltazeroxy.y * deltazeroxy.y + alt_agl * alt_agl); //could use function 'distance' instead, might be better?
if (dist < 75)
{
pos.z = -0.9 * alt_agl + 0.05 * vertex.z;
//pos.z = 0.05 * (vertex.z + gear_clearance);
pos.xy -= deltaxy;
}
else
{
//The code below to shrink the shadow while keeping it 75 m. away has some issues that need to be fixed. Making the shadow shrink at x^2 rate partly to cover up this problem until it can be solved . . .
//The problem is that the aircraft isn't flat/parallel to the ground any more, but it appears to be at an angle to the ground.
//The various shrinkages perhaps mess with the angles somehow, meaning that when the animations apply the roll & pitch corrections they just don't quite work as they should
pos.z = (-0.9*75)*alt_agl/dist + 0.05 * vertex.z ; //if the shadow is more than about 75 meters from the aircraft it disappears so we are going to just keep it right at 75 m. & make it smaller to simulate greater distance.
//(-0.9*75) is the same factor for altitude we were using above when dist=75. *alt_agl/dist keeps it at the right height proportionally to simulate the location at a further distance, while actually just keeping it at 75 m. distance.
//pos.z = 0.05 * vertex.z ; //if the shadow is more than about 75 meters from the aircraft it disappears so we are going to just keep it right at 75 m. & make it smaller to simulate greater distance.
//shrink the size FIRST, THEN move where it needs to be. If you shrink later you're also shrinking the deltaxy distance moved, which doesn't work well
pos.xy = 75 / dist * pos.xy; //shrinking the size of the shadow to simulate further distance. Should be linear shrinkage but doing it ^2 for now to help ucover up the issues in code above.
pos.xy -= 75 * deltaxy/dist; // Similarly to above, * deltaxy/dist; keeps it at the right XY position proportionally to simulate the location at a further distance, while actually just keeping it at 75 m. distance.
}
// pos.z = pos.z - offset; // pos.z = pos.z - offset;
pos.xy -= lightFull.xy * 0.95* (alt_agl + vertex.z + gear_clearance)/lightFull.z;
//if (dist>=75) pos = pos * 30/dist; //not sure why this doesn't work/ perhaps an overflow of some kind?
gl_Position = gl_ModelViewProjectionMatrix * pos; gl_Position = gl_ModelViewProjectionMatrix * pos;
gl_FrontColor = light_diffuse; gl_FrontColor = light_diffuse;
//light_diffuse.a=0;
gl_BackColor = gl_FrontColor; gl_BackColor = gl_FrontColor;
//gl_BackColor = light_diffuse;
} }