diff --git a/Aircraft/Generic/Effects/window_frost.png b/Aircraft/Generic/Effects/window_frost.png new file mode 100644 index 000000000..33f257f52 Binary files /dev/null and b/Aircraft/Generic/Effects/window_frost.png differ diff --git a/Effects/glass.eff b/Effects/glass.eff new file mode 100644 index 000000000..ce686580f --- /dev/null +++ b/Effects/glass.eff @@ -0,0 +1,252 @@ +<?xml version="1.0" encoding="utf-8"?> + +<PropertyList> + <name>Effects/glass</name> + <inherits-from>Effects/model-default</inherits-from> + +<parameters> + <texture n="1"> + <image>Aircraft/Generic/Effects/window_frost.png</image> + <type>2d</type> + <filter>linear-mipmap-linear</filter> + <wrap-s>repeat</wrap-s> + <wrap-t>repeat</wrap-t> + <internal-format>normalized</internal-format> + </texture> + <!-- placeholder for the function texture used for fogging, wiper area,...--> + <texture n="2"> + <type>white</type> + </texture> + <texture n="3"> + <type>cubemap</type> + <images> + <positive-x>Aircraft/Generic/Effects/CubeMaps/fair-sky/fair-sky_px.png</positive-x> + <negative-x>Aircraft/Generic/Effects/CubeMaps/fair-sky/fair-sky_nx.png</negative-x> + <positive-y>Aircraft/Generic/Effects/CubeMaps/fair-sky/fair-sky_py.png</positive-y> + <negative-y>Aircraft/Generic/Effects/CubeMaps/fair-sky/fair-sky_ny.png</negative-y> + <positive-z>Aircraft/Generic/Effects/CubeMaps/fair-sky/fair-sky_pz.png</positive-z> + <negative-z>Aircraft/Generic/Effects/CubeMaps/fair-sky/fair-sky_nz.png</negative-z> + </images> + </texture> + <!--<glass-tint type="vec4d" n="0"> 0.5 0.5 1.0 2.0</glass-tint>--> + <glass-tint type="vec4d" n="0"> 1.0 1.0 1.0 0.4</glass-tint> + <splash-x><use>/environment/aircraft-effects/splash-vector-x</use></splash-x> + <splash-y><use>/environment/aircraft-effects/splash-vector-y</use></splash-y> + <splash-z><use>/environment/aircraft-effects/splash-vector-z</use></splash-z> + <rnorm><use>/environment/rain-norm</use></rnorm> + <gsnorm><use>/environment/aircraft-effects/ground-splash-norm</use></gsnorm> + <frost-level><use>/environment/aircraft-effects/frost-level</use></frost-level> + <use-reflection type="int">1</use-reflection> +</parameters> + +<technique n="4"> + <predicate> + <and> + <property>/sim/rendering/shaders/skydome</property> + <or> + <less-equal> + <value type="float">2.0</value> + <glversion/> + </less-equal> + <and> + <extension-supported>GL_ARB_shader_objects</extension-supported> + <extension-supported>GL_ARB_shading_language_100</extension-supported> + <extension-supported>GL_ARB_vertex_shader</extension-supported> + <extension-supported>GL_ARB_fragment_shader</extension-supported> + </and> + </or> + </and> + </predicate> + <pass> + <lighting>true</lighting> + <material> + <active><use>material/active</use></active> + <ambient><use>material/ambient</use></ambient> + <diffuse><use>material/diffuse</use></diffuse> + <specular><use>material/specular</use></specular> + <emissive><use>material/emissive</use></emissive> + <shininess><use>material/shininess</use></shininess> + <color-mode><use>material/color-mode</use></color-mode> + </material> + <blend> + <active><use>blend/active</use></active> + <source><use>blend/source</use></source> + <destination><use>blend/destination</use></destination> + </blend> + <shade-model><use>shade-model</use></shade-model> + <cull-face><use>cull-face</use></cull-face> + <!--<render-bin> + <bin-number>1</bin-number> + <bin-name>RenderBin</bin-name> + </render-bin>--> + <rendering-hint><use>rendering-hint</use></rendering-hint> + <texture-unit> + <!-- The texture unit is always active because the shaders expect + that. --> + <unit>0</unit> + <!-- If there is a texture, the type in the derived effect + will be "2d". --> + <type><use>texture[0]/type</use></type> + <image><use>texture[0]/image</use></image> + <filter><use>texture[0]/filter</use></filter> + <wrap-s><use>texture[0]/wrap-s</use></wrap-s> + <wrap-t><use>texture[0]/wrap-t</use></wrap-t> + <!-- + <internal-format> + <use>texture[0]/internal-format</use> + </internal-format> + --> + </texture-unit> + <texture-unit> + <unit>1</unit> + <type><use>texture[1]/type</use></type> + <image><use>texture[1]/image</use></image> + <filter><use>texture[1]/filter</use></filter> + <wrap-s><use>texture[1]/wrap-s</use></wrap-s> + <wrap-t><use>texture[1]/wrap-t</use></wrap-t> + <internal-format> + <use>texture[1]/internal-format</use> + </internal-format> + </texture-unit> + <texture-unit> + <unit>2</unit> + <type><use>texture[2]/type</use></type> + <image><use>texture[2]/image</use></image> + <filter><use>texture[2]/filter</use></filter> + <wrap-s><use>texture[2]/wrap-s</use></wrap-s> + <wrap-t><use>texture[2]/wrap-t</use></wrap-t> + <internal-format> + <use>texture[2]/internal-format</use> + </internal-format> + </texture-unit> + <texture-unit> + <unit>3</unit> + <type><use>texture[3]/type</use></type> + <images><use>texture[3]/images</use></images> + </texture-unit> + <vertex-program-two-side> + <use>vertex-program-two-side</use> + </vertex-program-two-side> + <program> + <vertex-shader>Shaders/glass-ALS.vert</vertex-shader> + <fragment-shader>Shaders/glass-ALS.frag</fragment-shader> + <fragment-shader>Shaders/noise.frag</fragment-shader> + </program> + + <uniform> + <name>tint</name> + <type>float-vec4</type> + <value><use>glass-tint</use></value> + </uniform> + <uniform> + <name>splash_x</name> + <type>float</type> + <value><use>splash-x</use></value> + </uniform> + <uniform> + <name>splash_y</name> + <type>float</type> + <value><use>splash-y</use></value> + </uniform> + <uniform> + <name>splash_z</name> + <type>float</type> + <value><use>splash-z</use></value> + </uniform> + <uniform> + <name>rain_norm</name> + <type>float</type> + <value><use>rnorm</use></value> + </uniform> + <uniform> + <name>ground_splash_norm</name> + <type>float</type> + <value><use>gsnorm</use></value> + </uniform> + <uniform> + <name>frost_level</name> + <type>float</type> + <value><use>frost-level</use></value> + </uniform> + <uniform> + <name>scattering</name> + <type>float</type> + <value><use>scattering</use></value> + </uniform> + <uniform> + <name>terminator</name> + <type>float</type> + <value><use>terminator</use></value> + </uniform> + <uniform> + <name>ground_scattering</name> + <type>float</type> + <value><use>ground_scattering</use></value> + </uniform> + <uniform> + <name>terminator</name> + <type>float</type> + <value><use>terminator</use></value> + </uniform> + <uniform> + <name>overcast</name> + <type>float</type> + <value><use>overcast</use></value> + </uniform> + <uniform> + <name>eye_alt</name> + <type>float</type> + <value><use>eye_alt</use></value> + </uniform> + <uniform> + <name>cloud_self_shading</name> + <type>float</type> + <value><use>cloud_self_shading</use></value> + </uniform> + <uniform> + <name>moonlight</name> + <type>float</type> + <value><use>moonlight</use></value> + </uniform> + <uniform> + <name>air_pollution</name> + <type>float</type> + <value><use>air_pollution</use></value> + </uniform> + <uniform> + <name>texture</name> + <type>sampler-2d</type> + <value type="int">0</value> + </uniform> + <uniform> + <name>frost_texture</name> + <type>sampler-2d</type> + <value type="int">1</value> + </uniform> + <uniform> + <name>func_texture</name> + <type>sampler-2d</type> + <value type="int">2</value> + </uniform> + <uniform> + <name>cube_texture</name> + <type>sampler-cube</type> + <value type="int">3</value> + </uniform> + <uniform> + <name>use_reflection</name> + <type>int</type> + <value><use>use_reflection</use></value> + </uniform> + <uniform> + <name>colorMode</name> + <type>int</type> + <value><use>material/color-mode-uniform</use></value> + </uniform> + </pass> + </technique> + + +</PropertyList> + + diff --git a/Environment/environment.xml b/Environment/environment.xml index 7d0cd67da..d5df729dd 100644 --- a/Environment/environment.xml +++ b/Environment/environment.xml @@ -449,4 +449,14 @@ <clip-distance type="float" userarchive="n">5.0</clip-distance> </precipitation-control> +<!-- definitions for environent/aircraft interaction effects --> + <aircraft-effects> + <splash-vector-x type="float" userarchive="n">0.0</splash-vector-x> + <splash-vector-y type="float" userarchive="n">0.1</splash-vector-y> + <splash-vector-z type="float" userarchive="n">1.0</splash-vector-z> + <frost-level type="float" userarchive="n">0.0</frost-level> + <ground-splash-norm type="float" userarchive="n">0.0</ground-splash-norm> + </aircraft-effects> + + </PropertyList> diff --git a/Shaders/glass-ALS.frag b/Shaders/glass-ALS.frag new file mode 100644 index 000000000..4accba8da --- /dev/null +++ b/Shaders/glass-ALS.frag @@ -0,0 +1,143 @@ +// -*-C++-*- + +varying vec2 rawPos; +varying vec3 vertPos; +varying vec3 normal; +varying vec3 refl_vec; +varying vec3 light_diffuse; +varying float splash_angle; +varying float Mie; + +uniform sampler2D texture; +uniform sampler2D frost_texture; +uniform sampler2D func_texture; +uniform samplerCube cube_texture; + +uniform vec4 tint; + + +uniform float rain_norm; +uniform float ground_splash_norm; +uniform float frost_level; +uniform float splash_x; +uniform float splash_y; +uniform float splash_z; +uniform float osg_SimulationTime; + +uniform int use_reflection; + +float DotNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dot_density); +float DropletNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dot_density); +float Noise2D(in vec2 coord, in float wavelength); + +void main() +{ + +vec4 texel; +vec4 frost_texel; +//vec4 func_texel; + +texel = texture2D(texture, gl_TexCoord[0].st); +texel *=gl_Color; + +frost_texel = texture2D(frost_texture, vertPos.xy * 7.0); + + +float noise_003m = Noise2D(vertPos.xy, 0.03); +float noise_0003m = Noise2D(vertPos.xy, 0.003); + +float fth = (1.0-frost_level) * 0.4 + 0.3; +float fbl = 0.2 * frost_level; + + + + +float frost_factor = (fbl + (1.0-fbl)* smoothstep(fth,fth+0.2,noise_003m)) * (4.0 + 4.0* Mie); + + +float background_frost = 0.5 * smoothstep(0.7,1.0,frost_level); +frost_texel.rgb = mix(frost_texel.rgb, vec3 (0.5,0.5,0.5), (1.0- smoothstep(0.0,0.02,frost_texel.a))); +frost_texel.a =max(frost_texel.a, background_frost * (1.0- smoothstep(0.0,0.02,frost_texel.a))); + +frost_texel *= vec4(light_diffuse.rgb,1.0); + +frost_factor = max(frost_factor, 0.8*background_frost); +texel.rgb = mix(texel.rgb, frost_texel.rgb, frost_texel.a * frost_factor * smoothstep(0.0,0.1,frost_level)); +texel.a = max(texel.a, frost_texel.a * frost_level); + +//texel.rgb = mix(texel.rgb, vec3 (1.0,1.0,1.0), 0.4 * smoothstep(0.7,1.0,frost_level) + 0.4*Mie); + +vec3 splash_vec = vec3 (splash_x, splash_y, splash_z); +float splash_speed = length(splash_vec); + + +float rain_factor = 0.0; + +float rnorm = max(rain_norm, ground_splash_norm); + +if (rnorm > 0.0) + { + float droplet_size = (0.5 + 0.8 * rnorm) * (1.0 - 0.1 * splash_speed); + vec2 rainPos = vec2 (rawPos.x * splash_speed, rawPos.y / splash_speed ); + rainPos.y = rainPos.y - 0.1 * smoothstep(1.0,2.0, splash_speed) * osg_SimulationTime; + if (splash_angle> 0.0) + { + // the dynamically impacting raindrops + //float time_shape = (1.0 - fract(8.0*osg_SimulationTime / 3.14)) * 1.7; + float time_shape = 1.0; + float base_rate = 6.0 + 3.0 * rnorm + 4.0 * (splash_speed - 1.0); + float base_density = 0.6 * rnorm + 0.4 * (splash_speed -1.0); + + float time_fact1 = (sin(base_rate*osg_SimulationTime)); + float time_fact2 = (sin(base_rate*osg_SimulationTime + 1.570)); + float time_fact3 = (sin(base_rate*osg_SimulationTime + 3.1415)); + float time_fact4 = (sin(base_rate*osg_SimulationTime + 4.712)); + + time_fact1 = smoothstep(0.0,1.0, time_fact1); + time_fact2 = smoothstep(0.0,1.0, time_fact2); + time_fact3 = smoothstep(0.0,1.0, time_fact3); + time_fact4 = smoothstep(0.0,1.0, time_fact4); + + rain_factor += DotNoise2D(rawPos.xy, 0.02 * droplet_size ,0.5, base_density ) * time_fact1; + rain_factor += DotNoise2D(rainPos.xy, 0.03 * droplet_size,0.4, base_density) * time_fact2; + rain_factor += DotNoise2D(rawPos.xy, 0.04 * droplet_size ,0.3, base_density)* time_fact3; + rain_factor += DotNoise2D(rainPos.xy, 0.05 * droplet_size ,0.25, base_density)* time_fact4; + } + + + // the static pattern of small droplets created by the splashes + + float sweep = min(1./splash_speed,1.0); + rain_factor += DropletNoise2D(rainPos.xy, 0.02 * droplet_size ,0.5, 0.6* rnorm * sweep); + rain_factor += DotNoise2D(rainPos.xy, 0.012 * droplet_size ,0.7, 0.6* rnorm * sweep); + } + +rain_factor = smoothstep(0.1,0.2, rain_factor) * (1.0 - smoothstep(0.4,1.0, rain_factor) * (0.2+0.8*noise_0003m)); + + +vec4 rainColor = vec4 (0.2,0.2, 0.2, 0.6 - 0.3 * smoothstep(1.0,2.0, splash_speed)); +rainColor.rgb *= length(light_diffuse)/1.73; + +// environment reflection + +vec4 reflection = textureCube(cube_texture, refl_vec); + +if (use_reflection ==1) + {texel.rgb = mix(texel.rgb, reflection.rgb, 0.5);} + +// glass tint + +vec4 fragColor = texel * tint; + +fragColor = mix(fragColor, rainColor, rain_factor); + +// fogging + +//vec3 fogColor = vec3 (1.0,1.0,1.0); +//fragColor.rgb = mix(fragColor.rgb, fogColor.rgb, func_texel.r); + + +gl_FragColor = fragColor; + +//gl_FragColor = reflection; +} diff --git a/Shaders/glass-ALS.vert b/Shaders/glass-ALS.vert new file mode 100644 index 000000000..fb3fba500 --- /dev/null +++ b/Shaders/glass-ALS.vert @@ -0,0 +1,124 @@ +// -*-C++-*- + +varying vec2 rawPos; +varying vec3 vertPos; +varying vec3 normal; +varying vec3 light_diffuse; +varying vec3 refl_vec; +varying float splash_angle; +varying float Mie; + +uniform float ground_scattering; +uniform float hazeLayerAltitude; +uniform float moonlight; +uniform float terminator; +uniform float splash_x; +uniform float splash_y; +uniform float splash_z; + +const float EarthRadius = 5800000.0; +const float terminator_width = 200000.0; + +float light_func (in float x, in float a, in float b, in float c, in float d, in float e) +{ +//x = x - 0.5; + +// use the asymptotics to shorten computations +if (x < -15.0) {return 0.0;} + +return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d)); +} + + +void main() +{ + +vec3 shadedFogColor = vec3(0.55, 0.67, 0.88); +vec3 moonLightColor = vec3 (0.095, 0.095, 0.15) * moonlight; + +// geometry for lighting +vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0); +vec3 relPos = gl_Vertex.xyz - ep.xyz; +vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz; +vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0)); +float dist = length(relPos); +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 yprime_alt = - sqrt(2.0 * EarthRadius * vertex_alt); +float earthShade = 0.6 * (1.0 - smoothstep(-terminator_width+ terminator, terminator_width + terminator, yprime_alt)) + 0.4; +float lightArg = (terminator-yprime_alt)/100000.0; + +// light computation + +vec3 light_ambient; + +light_diffuse.b = light_func(lightArg, 1.330e-05, 0.264, 3.827, 1.08e-05, 1.0); +light_diffuse.g = light_func(lightArg, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0); +light_diffuse.r = light_func(lightArg, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0); +light_diffuse = light_diffuse * scattering; + + +light_ambient.r = light_func(lightArg, 0.236, 0.253, 1.073, 0.572, 0.33); +light_ambient.g = light_ambient.r * 0.4/0.33; +light_ambient.b = light_ambient.r * 0.5/0.33; + +float intensity; + +if (earthShade < 0.5) + { + intensity = length(light_ambient.xyz); + + light_ambient.rgb = intensity * normalize(mix(light_ambient.rgb, shadedFogColor, 1.0 -smoothstep(0.4, 0.8,earthShade) )); + light_ambient.rgb = light_ambient.rgb + moonLightColor * (1.0 - smoothstep(0.4, 0.5, earthShade)); + + intensity = length(light_diffuse.xyz); + light_diffuse.rgb = intensity * normalize(mix(light_diffuse.rgb, shadedFogColor, 1.0 -smoothstep(0.4, 0.7,earthShade) )); + } + + +float MieFactor = dot(normalize(lightFull), normalize(relPos)); +Mie = smoothstep(0.9,1.0, MieFactor); + + +// get a reflection vector for cube map + +vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; +normal = normalize(gl_NormalMatrix * gl_Normal); +vec4 reflect_eye = vec4(reflect(ecPosition.xyz, normal), 0.0); +vec3 reflVec_stat = normalize(gl_ModelViewMatrixInverse * reflect_eye).xyz; +refl_vec = reflVec_stat; + +// get a projection plane orthogonal to the splash vector + +vec3 splash_vec = vec3 (splash_x, splash_y, splash_z); +vec3 corrected_splash = normalize(splash_vec); + +vec3 base_1 = vec3 (-corrected_splash.y, corrected_splash.x, 0.0); +vec3 base_2 = cross (corrected_splash, base_1); + +base_1 = normalize(base_1); +base_2 = normalize(base_2); + +rawPos = vec2 (dot(gl_Vertex.xyz, base_1), dot(gl_Vertex.xyz, base_2)); +vertPos = gl_Vertex.xyz; + +splash_angle = dot(gl_Normal, corrected_splash); + + + + + + + +gl_Position = ftransform(); +gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + +vec4 diffuse_color = gl_FrontMaterial.diffuse; +vec4 ambient_color = gl_FrontMaterial.ambient; + +vec4 constant_term = gl_FrontMaterial.emission + ambient_color * vec4 (light_diffuse.rgb + light_ambient.rgb,1.0); + +gl_FrontColor = constant_term; +gl_BackColor = gl_FrontColor; + +} diff --git a/Shaders/noise.frag b/Shaders/noise.frag index b0e4c86d7..60448a0e7 100644 --- a/Shaders/noise.frag +++ b/Shaders/noise.frag @@ -7,6 +7,8 @@ // * Noise3D(in vec3 coord, in float wavelength) is 3d Perlin noise // * DotNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dDensity) // is sparse dot noise and takes a dot density parameter +// * DropletNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dDensity) +// is sparse dot noise modified to look like liquid and takes a dot density parameter // * VoronoiNoise2D(in vec2 coord, in float wavelength, in float xrand, in float yrand) // is a function mapping the terrain into random domains, based on Voronoi tiling of a regular grid // distorted with xrand and yrand @@ -135,6 +137,43 @@ float DotNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSi return dotNoise2D(coord.x/wavelength, coord.y/wavelength, fractionalMaxDotSize, dDensity); } +float dropletNoise2D(in float x, in float y, in float fractionalMaxDotSize, in float dDensity) +{ + float integer_x = x - fract(x); + float fractional_x = x - integer_x; + + float integer_y = y - fract(y); + float fractional_y = y - integer_y; + + if (rand2D(vec2(integer_x+1.0, integer_y +1.0)) > dDensity) + {return 0.0;} + + float xoffset = (rand2D(vec2(integer_x, integer_y)) -0.5); + float yoffset = (rand2D(vec2(integer_x+1.0, integer_y)) - 0.5); + float dotSize = 0.5 * fractionalMaxDotSize * max(0.25,rand2D(vec2(integer_x, integer_y+1.0))); + + float x1offset = 2.0 * (rand2D(vec2(integer_x+5.0, integer_y)) -0.5); + float y1offset = 2.0 * (rand2D(vec2(integer_x, integer_y + 5.0)) - 0.5); + float x2offset = 2.0 * (rand2D(vec2(integer_x-5.0, integer_y)) -0.5); + float y2offset = 2.0 * (rand2D(vec2(integer_x-5.0, integer_y -5.0)) - 0.5); + float smear = (rand2D(vec2(integer_x + 3.0, integer_y)) -0.5); + + + vec2 truePos = vec2 (0.5 + xoffset * (1.0 - 4.0 * dotSize) , 0.5 + yoffset * (1.0 -4.0 * dotSize)); + vec2 secondPos = truePos + vec2 (dotSize * x1offset, dotSize * y1offset); + vec2 thirdPos = truePos + vec2 (dotSize * x2offset, dotSize * y2offset); + + float distance = length(truePos - vec2(fractional_x, fractional_y)); + float dist1 = length(secondPos - vec2(fractional_x, fractional_y)); + float dist2 = length(thirdPos - vec2(fractional_x, fractional_y)); + + return clamp(3.0 - smoothstep (0.3 * dotSize, 1.0* dotSize, distance) - smoothstep (0.3 * dotSize, 1.0* dotSize, dist1) - smoothstep ((0.1 + 0.5 * smear) * dotSize, 1.0* dotSize, dist2), 0.0,1.0); +} + +float DropletNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dDensity) +{ +return dropletNoise2D(coord.x/wavelength, coord.y/wavelength, fractionalMaxDotSize, dDensity); +} float voronoiNoise2D(in float x, in float y, in float xrand, in float yrand) {