From 97cc53d7b362da167233e67f49704c0e2e41872d Mon Sep 17 00:00:00 2001 From: Thorsten Renk Date: Wed, 3 Feb 2016 09:13:30 +0200 Subject: [PATCH] Procedural aircraft lights for ALS - WIP --- Effects/procedural-light.eff | 213 ++++++++++++++++++++++++++ Models/Effects/procedural_light.ac | 22 +++ Models/Effects/procedural_light.xml | 15 ++ Shaders/light-ALS.frag | 230 ++++++++++++++++++++++++++++ Shaders/light-ALS.vert | 87 +++++++++++ 5 files changed, 567 insertions(+) create mode 100644 Effects/procedural-light.eff create mode 100644 Models/Effects/procedural_light.ac create mode 100644 Models/Effects/procedural_light.xml create mode 100644 Shaders/light-ALS.frag create mode 100644 Shaders/light-ALS.vert diff --git a/Effects/procedural-light.eff b/Effects/procedural-light.eff new file mode 100644 index 000000000..ff28ed1ad --- /dev/null +++ b/Effects/procedural-light.eff @@ -0,0 +1,213 @@ + + + + Effects/procedural-light + + + + white + + + 1.0 + 0.0 + 0.0 + 1.0 + 1.0 + 1.0 + 1.0 + -1.0 + 0.0 + 0.0 + false + false + 0.2 + 0.4 + 0.7 + 0.5 + /environment/ground-visibility-m + /environment/visibility-m + /environment/ground-haze-thickness-m + /environment/mean-terrain-elevation-m + /sim/rendering/eye-altitude-m + /environment/terminator-relative-position-m + + + + + + /sim/rendering/shaders/skydome + + + 2.0 + + + + GL_ARB_shader_objects + GL_ARB_shading_language_100 + GL_ARB_vertex_shader + GL_ARB_fragment_shader + + + + + + true + + material/active + material/ambient + material/diffuse + material/specular + material/emissive + material/shininess + material/color-mode + + + blend/active + blend/source + blend/destination + + shade-model + cull-face + rendering-hint + + 111 + DepthSortedBin + + + + 0 + texture[0]/active + texture[0]/type + texture[0]/image + texture[0]/filter + texture[0]/wrap-s + texture[0]/wrap-t + texture[0]/internal-format + + + false + + false + + Shaders/light-ALS.vert + Shaders/light-ALS.frag + Shaders/noise.frag + Shaders/hazes.frag + + + + + light_color_base_r + float + light_color_base_r + + + light_color_base_g + float + light_color_base_g + + + light_color_base_b + float + light_color_base_b + + + light_color_center_r + float + light_color_center_r + + + light_color_center_g + float + light_color_center_g + + + light_color_center_b + float + light_color_center_b + + + intensity_scale + float + intensity_scale + + + pointing_x + float + pointing_x + + + pointing_y + float + pointing_y + + + pointing_z + float + pointing_z + + + inner_angle + float + inner_angle + + + outer_angle + float + outer_angle + + + zero_angle + float + zero_angle + + + outer_gain + float + outer_gain + + + visibility + float + visibility + + + avisibility + float + avisibility + + + hazeLayerAltitude + float + lthickness + + + eye_alt + float + eye_alt + + + terminator + float + terminator + + + texture + sampler-2d + 0 + + + is_directional + bool + is_directional + + + is_strobe + bool + is_strobe + + + + + diff --git a/Models/Effects/procedural_light.ac b/Models/Effects/procedural_light.ac new file mode 100644 index 000000000..f5a8b00aa --- /dev/null +++ b/Models/Effects/procedural_light.ac @@ -0,0 +1,22 @@ +AC3Db +MATERIAL "DefaultWhite" rgb 1.0000 1.0000 1.0000 amb 0.2000 0.2000 0.2000 emis 0.0000 0.0000 0.0000 spec 0.5000 0.5000 0.5000 shi 10 trans 0.0000 +MATERIAL "DefaultWhite" rgb 1.0000 1.0000 1.0000 amb 0.2000 0.2000 0.2000 emis 0.0000 0.0000 0.0000 spec 0.0250 0.0250 0.0250 shi 50 trans 0.1000 +OBJECT world +name "Blender_export__procedural_light.ac" +kids 1 +OBJECT poly +name "procedural_light" +numvert 4 +-0.0000019 -1.0000000 -1.0000000 +-0.0000005 1.0000000 -1.0000000 +0.0000005 -1.0000000 1.0000000 +0.0000019 1.0000000 1.0000000 +numsurf 1 +SURF 0X20 +mat 1 +refs 4 +1 0 0 +0 0 0 +2 0 0 +3 0 0 +kids 0 diff --git a/Models/Effects/procedural_light.xml b/Models/Effects/procedural_light.xml new file mode 100644 index 000000000..7a0b13f12 --- /dev/null +++ b/Models/Effects/procedural_light.xml @@ -0,0 +1,15 @@ + + + + procedural_light.ac + + + + + + Effects/procedural-light + procedural_light + + + + diff --git a/Shaders/light-ALS.frag b/Shaders/light-ALS.frag new file mode 100644 index 000000000..e52250bdf --- /dev/null +++ b/Shaders/light-ALS.frag @@ -0,0 +1,230 @@ +// -*-C++-*- + +uniform sampler2D texture; + +uniform float light_color_base_r; +uniform float light_color_base_g; +uniform float light_color_base_b; + +uniform float light_color_center_r; +uniform float light_color_center_g; +uniform float light_color_center_b; + +uniform float intensity_scale; + +uniform float pointing_x; +uniform float pointing_y; +uniform float pointing_z; + +uniform float outer_angle; +uniform float inner_angle; +uniform float zero_angle; +uniform float outer_gain; + +uniform float visibility; +uniform float avisibility; +uniform float hazeLayerAltitude; +uniform float eye_alt; +uniform float terminator; + +uniform float osg_SimulationTime; + +uniform bool is_directional; +uniform bool is_strobe; + +varying vec3 vertex; +varying vec3 relPos; +varying vec3 normal; + +float Noise2D(in vec2 coord, in float wavelength); +float fog_func (in float targ, in float alt); + +float shape (in vec3 coord, in float noise, in float fade, in float transmission, in float glare, in float lightArg) +{ + float r = length (coord) / max(fade, 0.2); + + float angle = noise * 6.2832; + + float sinphi = dot(vec2 (sin(angle),cos(angle)), normalize(coord.yz)); + float sinterm = sin(mod((sinphi-3.0) * (sinphi-3.0),6.2832)); + float ray = 0.0; + if (sinterm == 0.0) + {ray = 0.0;} + else + {ray = clamp(pow(sinterm,10.0),0.0,1.0); + ray *= exp(-40.0 * r * r) * smoothstep(0.8, 1.0,fade) * smoothstep(0.7, 1.0, glare); + } + + + + float base = exp(-80.0*r*r ); + float halo = 0.2 * exp(-10.0 * r * r) * (1.0 - smoothstep(-5.0, 0.0, lightArg)); + float fogEffect = (1.0-smoothstep(0.4,0.8,transmission)); + //fogEffect = 1.0; + + //float offset = 0.0; + //offset *=0.3; + //vec2 offset_vec = vec2 (1.0, 0.0); + //offset_vec *= offset; + + // vec2 coord_reduced1 = vec2(coord.y- 1.2* offset_vec.x, coord.z - 1.2 * offset_vec.y); + //vec2 coord_reduced2 = vec2(coord.y- 2.0 * offset_vec.x, coord.z - 2.0 * offset_vec.y); + //vec3 coord_reduced = coord; + //r = min(length (coord_reduced1), 0.8* length(coord_reduced2)); + //r /= 1.0 - 0.3 * smoothstep(0.0, 0.3, offset); + + float intensity = clamp(base + halo + ray,0.0,1.0) + 0.2 * fogEffect * (1.0-smoothstep(0.3, 0.6,r)); + + intensity *=fade; + +return intensity; +} + + +float directional_fade (in float direction) +{ + +float arg = clamp(direction, 0.0, 1.0); +float ia = (1.0 - inner_angle); +float oa = (1.0 - outer_angle); +float za = (1.0 - zero_angle); + +if (direction > ia) {return 1.0;} +else if (direction > oa) + {return outer_gain + (1.0-outer_gain) * (direction - oa) / (ia - oa);} +else if (direction > za) + {return outer_gain * (direction - za) / (oa - za);} +else {return 0.0;} + +} + +float strobe_fade (in float fade) +{ + +float time_arg1 = sin(4.0 * osg_SimulationTime); +float time_arg2 = sin(4.0 * osg_SimulationTime - 0.4); + +return fade * 0.825 * (pow(time_arg1, 40.0) + pow(time_arg2, 8.0)); + +} + + +void main() +{ + +float noise = 0.0; + +vec3 light_color_base = vec3 (light_color_base_r, light_color_base_g, light_color_base_b); +vec3 light_color_center = vec3 (light_color_center_r, light_color_center_g, light_color_center_b); + +vec3 pointing_vec = vec3 (pointing_x, pointing_y, pointing_z); +vec3 viewDir = normalize(relPos); + +// fogging + +float dist = length(relPos); +float delta_z = hazeLayerAltitude - eye_alt; +float transmission; +float vAltitude; +float delta_zv; +float H; +float distance_in_layer; +float transmission_arg; + + // angle with horizon + float ct = dot(vec3(0.0, 0.0, 1.0), relPos)/dist; + + + if (delta_z > 0.0) // we're inside the layer + { + if (ct < 0.0) // we look down + { + distance_in_layer = dist; + vAltitude = min(distance_in_layer,min(visibility, avisibility)) * ct; + delta_zv = delta_z - vAltitude; + } + else // we may look through upper layer edge + { + H = dist * ct; + if (H > delta_z) {distance_in_layer = dist/H * delta_z;} + else {distance_in_layer = dist;} + vAltitude = min(distance_in_layer,visibility) * ct; + delta_zv = delta_z - vAltitude; + } + } + else // we see the layer from above, delta_z < 0.0 + { + H = dist * -ct; + if (H < (-delta_z)) + { + distance_in_layer = 0.0; + delta_zv = 0.0; + } + else + { + vAltitude = H + delta_z; + distance_in_layer = vAltitude/H * dist; + vAltitude = min(distance_in_layer,visibility) * (-ct); + delta_zv = vAltitude; + } + } + + + + transmission_arg = (dist-distance_in_layer)/avisibility; + if (visibility < avisibility) + { + transmission_arg = transmission_arg + (distance_in_layer/visibility); + } + else + { + transmission_arg = transmission_arg + (distance_in_layer/avisibility); + } + + + + transmission = fog_func(transmission_arg, 0.0); + float lightArg = terminator/100000.0; + + +float r = length(vertex); +float mix_factor = 0.3 + 0.7 * smoothstep(0.0, 0.5, r); + +// directionality + +vec3 nViewDir = normalize(viewDir); +vec3 nPointingVec = normalize(pointing_vec); +float direction = dot (nViewDir, nPointingVec ); + +float fade; +vec2 offset = vec2 (0.0, 0.0); + +if (is_directional) + { + fade = directional_fade(direction); + } +else + {fade = 1.0;} + + + +// time evolution + +if (is_strobe) {fade = strobe_fade (fade);} + +fade *= intensity_scale; + +// disc size correction for daylight + +// shape of the light disc +float glare = length(light_color_center)/1.7321 * (1.0 - smoothstep(-5.0, 10.0, lightArg)); +float intensity = shape(vertex, noise, fade, transmission, glare, lightArg); + +// coloring of the light disc +vec3 light_color = mix(light_color_base, light_color_center, intensity*intensity); + + +gl_FragColor = vec4 (light_color.rgb, intensity * transmission ); + + +} diff --git a/Shaders/light-ALS.vert b/Shaders/light-ALS.vert new file mode 100644 index 000000000..da585c7d7 --- /dev/null +++ b/Shaders/light-ALS.vert @@ -0,0 +1,87 @@ +// -*-C++-*- + +#version 120 + +// doing directionality is surprisingly complicated - with just the vector and the eye we can't +// do a spherical billboard, but the animation itself operates before the shader, so +// the model-coordinate to eye relationship is always the same +// thus we need to use pitch, yaw and roll to get the current model space coordinates + +uniform float pitch; +uniform float roll; +uniform float hdg; + + +varying vec3 vertex; +varying vec3 relPos; +varying vec3 normal; + + + +void main() +{ + +vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0); + + vec4 l = gl_ModelViewMatrixInverse * vec4(0.0,0.0,1.0,1.0); + vec3 u = normalize(ep.xyz - l.xyz); + + vec3 absu = abs(u); + vec3 r = normalize(vec3(-u.y, u.x, 0.0)); + vec3 w = cross(u, r); + +vertex = gl_Vertex.xyz; +relPos = vertex - ep.xyz; +normal = gl_NormalMatrix * gl_Normal; + + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + gl_Position.xyz = gl_Vertex.x * u; + gl_Position.xyz += gl_Vertex.y * r; + gl_Position.xyz += gl_Vertex.z * w; + gl_Position = gl_ModelViewProjectionMatrix * gl_Position; + +//gl_Position = ftransform(); +gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + +gl_FrontColor = vec4 (1.0,1.0,1.0,1.0); +gl_BackColor = gl_FrontColor; +} + +/* + +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, + 0.0 , cosRx , -sinRx * cosRx, 0.0, + -sinRy, sinRx * cosRy, cosRx * cosRy , 0.0, + 0.0 , 0.0 , 0.0 , 1.0 ); +} + +void rotationMatrixH(in float sinRz, in float cosRz, out mat4 rotmat) +{ + rotmat = mat4( cosRz, -sinRz, 0.0, 0.0, + sinRz, cosRz, 0.0, 0.0, + 0.0 , 0.0 , 1.0, 0.0, + 0.0 , 0.0 , 0.0, 1.0 ); +} + +//prepare rotation matrix +mat4 RotMatPR; +mat4 RotMatH; +float _roll = roll; +if (_roll>90.0 || _roll < -90.0) {_roll = -_roll;} +float cosRx = cos(radians(_roll)); +float sinRx = sin(radians(_roll)); +float cosRy = cos(radians(-pitch)); +float sinRy = sin(radians(-pitch)); +float cosRz = cos(radians(hdg)); +float sinRz = sin(radians(hdg)); +rotationMatrixPR(sinRx, cosRx, sinRy, cosRy, RotMatPR); +rotationMatrixH(sinRz, cosRz, RotMatH); + +vec3 model_x = (RotMatH * RotMatPR * vec4 (1.0, 0.0, 0.0, 0.0)).xyz; +vec3 model_y = (RotMatH * RotMatPR * vec4 (0.0, 1.0, 0.0, 0.0)).xyz; +vec3 model_z = (RotMatH * RotMatPR * vec4 (0.0, 0.0, 1.0, 0.0)).xyz; + +vec3 pointingVec = normalize(pointing_x * model_x + pointing_y * model_y + pointing_z * model_z); +pointing_angle = dot (viewDir, pointingVec);*/