diff --git a/Effects/skydome.eff b/Effects/skydome.eff new file mode 100644 index 000000000..5bfcc713b --- /dev/null +++ b/Effects/skydome.eff @@ -0,0 +1,64 @@ + + + Effects/skydome + + /sim/rendering/mie + /sim/rendering/rayleigh + /sim/rendering/dome-density + + + + + /sim/rendering/shader-effects + /sim/rendering/scattering-shader + + + 2.0 + + + + GL_ARB_shader_objects + GL_ARB_shading_language_100 + GL_ARB_vertex_shader + GL_ARB_fragment_shader + + + + + + + true + smooth + back + + Shaders/skydome.vert + Shaders/skydome.frag + + + mK + float + mie + + + rK + float + rayleigh + + + density + float + density + + + + + + + + false + smooth + back + + + + diff --git a/Shaders/skydome.frag b/Shaders/skydome.frag new file mode 100644 index 000000000..a120eb2aa --- /dev/null +++ b/Shaders/skydome.frag @@ -0,0 +1,40 @@ +#version 120 + +// Atmospheric scattering shader for flightgear +// Written by Lauri Peltonen (Zan) +// Implementation of O'Neil's algorithm + +varying vec3 rayleigh; +varying vec3 mie; +varying vec3 eye; + +float miePhase(in float cosTheta, in float g) +{ + float g2 = g*g; + float a = 1.5 * (1.0 - g2); + float b = (2.0 + g2); + float c = 1.0 + cosTheta*cosTheta; + float d = pow(1.0 + g2 - 2.0 * g * cosTheta, 0.6667); + + return (a*c) / (b*d); +} + +float rayleighPhase(in float cosTheta) +{ + //return 1.5 * (1.0 + cosTheta*cosTheta); + return 1.5 * (2.0 + 0.5*cosTheta*cosTheta); +} + + + +void main() +{ + float cosTheta = dot(normalize(eye), gl_LightSource[0].position.xyz); + + vec3 color = rayleigh * rayleighPhase(cosTheta); + color += mie * miePhase(cosTheta, -0.8); + + gl_FragColor = vec4(color, 1.0); + gl_FragDepth = 0.1; +} + diff --git a/Shaders/skydome.vert b/Shaders/skydome.vert new file mode 100644 index 000000000..917aba508 --- /dev/null +++ b/Shaders/skydome.vert @@ -0,0 +1,172 @@ +#version 120 + +// Atmospheric scattering shader for flightgear +// Written by Lauri Peltonen (Zan) +// Implementation of O'Neil's algorithm + + +uniform mat4 osg_ViewMatrix; +uniform mat4 osg_ViewMatrixInverse; + +varying vec3 rayleigh; +varying vec3 mie; +varying vec3 eye; + +// Dome parameters from FG and screen +const float domeSize = 80000.0; +const float realDomeSize = 100000.0; +const float groundRadius = 0.984503332 * domeSize; +const float altitudeScale = domeSize - groundRadius; + +// Dome parameters when calculating scattering +// Assuming dome size is 5.0 +const float groundLevel = 0.984503332 * 5.0; +const float heightScale = (5.0 - groundLevel); + +// Integration parameters +const int nSamples = 7; +const float fSamples = float(nSamples); + +// Scattering parameters +uniform float rK = 0.0003; //0.00015; +uniform float mK = 0.003; //0.0025; +uniform float density = 0.5; //1.0 +vec3 rayleighK = rK * vec3(5.602, 7.222, 19.644); +vec3 mieK = vec3(mK); +vec3 sunIntensity = 10.0*vec3(120.0, 125.0, 130.0); + +// Find intersections of ray to skydome +// ray must be normalized +// cheight is camera height +float intersection (in float cheight, in vec3 ray, in float rad2) +{ + float B = 2.0 * cheight*ray.y; + float C = cheight*cheight - rad2; // 25.0 is skydome radius * radius + float fDet = max(0.0, B*B - 4.0 * C); + return 0.5 * (-B - sqrt(fDet)); +} + +// Return the scale function at height = 0 for different thetas +float outscatterscale(in float costheta) +{ + float x = 1.0 - costheta; + + float a = 1.16941; + float b = 0.618989; + float c = 6.34484; + float d = -31.4138; + float e = 75.3249; + float f = -80.1643; + float g = 32.2878; + + return exp(a+x*(b+x*(c+x*(d+x*(e+x*(f+x*g)))))); +} + +// Return the amount of outscatter for different heights and thetas +// assuming view ray hits the skydome +// height is 0 at ground level and 1 at space +// Assuming average density of atmosphere is at 1/4 height +// and atmosphere height is 100 km +float outscatter(in float costheta, in float height) +{ + return density * outscatterscale(costheta) * exp(-4.0 * height); +} + + +void main() +{ + // Make sure the dome is of a correct size + vec4 realVertex = gl_Vertex; //vec4(normalize(gl_Vertex.xyz) * domeSize, 1.0); + + // Ground point (skydome center) in eye coordinates + vec4 groundPoint = gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0); + + // Calculate altitude as the distance from skydome center to camera + // Make it so that 0.0 is ground level and 1.0 is 100km (space) level + float altitude = distance(groundPoint, vec4(0.0, 0.0, 0.0, 1.0)); + float scaledAltitude = altitude / realDomeSize; + + // Camera's position, z is up! + float cameraRealAltitude = groundLevel + heightScale*scaledAltitude; + vec3 camera = vec3(0.0, 0.0, cameraRealAltitude); + vec3 sample = 5.0 * realVertex.xyz / domeSize; // Sample is the dome vertex + vec3 relativePosition = camera - sample; // Relative position + + // Find intersection of skydome and view ray + float space = intersection(cameraRealAltitude, -normalize(relativePosition), 25.0); + if(space > 0.0) { + // We are in space, calculate correct positiondelta! + relativePosition -= space * normalize(relativePosition); + } + + vec3 positionDelta = relativePosition / fSamples; + float deltaLength = length(positionDelta); // Should multiply by something? + + vec3 lightDirection = gl_LightSource[0].position.xyz; + + // Cos theta of camera's position and sample point + // Since camera is 0,0,z, dot porduct is just the z coordinate + float cameraCosTheta; + + // If sample is above camera, reverse ray direction + if(positionDelta.z < 0.0) cameraCosTheta = -positionDelta.z / deltaLength; + else cameraCosTheta = positionDelta.z / deltaLength; + + // Total attenuation from camera to skydome + float totalCameraScatter = outscatter(cameraCosTheta, scaledAltitude); + + + // Do numerical integration of scsattering function from skydome to camera + vec3 color = vec3(0.0); + for(int i = 0; i < nSamples; i++) + { + // Altitude of the sample point 0...1 + float sampleAltitude = (length(sample) - groundLevel) / heightScale; + + // Cosine between the angle of sample's up vector and sun + // Since lightDirection is in eye space, we must transform sample too + vec3 sampleUp = gl_NormalMatrix * normalize(sample); + float cosTheta = dot(sampleUp, lightDirection); + + // Scattering from sky to sample point + float skyScatter = outscatter(cosTheta, sampleAltitude); + + // Calculate the attenuation from this point to camera + // Again, reverse the direction if vertex is over the camera + float cameraScatter; + if(relativePosition.z < 0.0) { // Vertex is over the camera + cameraCosTheta = -dot(normalize(positionDelta), normalize(sample)); + cameraScatter = totalCameraScatter - outscatter(cameraCosTheta, sampleAltitude); + } else { // Vertex is below camera + cameraCosTheta = dot(normalize(positionDelta), normalize(sample)); + cameraScatter = outscatter(cameraCosTheta, sampleAltitude) - totalCameraScatter; + } + + // Total attenuation + vec3 totalAttenuate = 4.0 * 3.14159 * (rayleighK + mieK) * (-skyScatter - cameraScatter); + + vec3 inScatter = exp(totalAttenuate - sampleAltitude*4.0); + + color += inScatter * deltaLength; + sample += positionDelta; + } + + color *= sunIntensity; + + rayleigh = rayleighK * color; + mie = mieK * color; + eye = gl_NormalMatrix * positionDelta; + + + + // We need to move the camera so that the dome appears to be centered around earth + // to make the dome render correctly! + float moveDown = -altitude; // Center dome on camera + moveDown += groundRadius; + moveDown += scaledAltitude * altitudeScale; // And move correctly according to altitude + + // Vertex transformed correctly so that at 100km we are at space border + vec4 finalVertex = realVertex - vec4(0.0, 0.0, 1.0, 0.0) * moveDown; + // Transform + gl_Position = gl_ModelViewProjectionMatrix * finalVertex; +} diff --git a/gui/dialogs/rendering.xml b/gui/dialogs/rendering.xml index d266a1be5..fe6197cb1 100644 --- a/gui/dialogs/rendering.xml +++ b/gui/dialogs/rendering.xml @@ -1,74 +1,78 @@ - rendering - false - vbox - 20 + rendering + false + vbox + 20 - - hbox - 1 + + hbox + + 1 + - - - + + + - 1 + + 1 + - - + + - + - - center - hbox + + center + hbox - - vbox + + vbox - - left - - - - left - - + + left + + + + left + + - - hbox - - - left - - - true - - - - - left - - wireframe - /sim/rendering/wireframe - - dialog-apply - wireframe - - + + hbox + + + left + + + true + + - - - hbox - - - left - - - true - - + + hbox + + + left + + + true + + - - left - - particles - /sim/rendering/particles - - dialog-apply - particles - - + + left + + particles + /sim/rendering/particles + + dialog-apply + particles + + - - left - - precipitation - /sim/rendering/precipitation-gui-enable - - dialog-apply - precipitation - - + + left + + precipitation + /sim/rendering/precipitation-gui-enable + + dialog-apply + precipitation + + - - - left - - random-objects - /sim/rendering/random-objects - - dialog-apply - random-objects - - - reinit - tile-manager - - + + left + + random-objects + /sim/rendering/random-objects + + dialog-apply + random-objects + + + reinit + tile-manager + + - - left - - random-vegetation - - /sim/rendering/shader-effects - - /sim/rendering/random-vegetation - - dialog-apply - random-vegetation - - + + left + + random-vegetation + + /sim/rendering/shader-effects + + /sim/rendering/random-vegetation + + dialog-apply + random-vegetation + + - - hbox - - - left - - - true - - + + hbox + + + left + + + true + + - - - left - - 3d-clouds - - /sim/rendering/shader-effects - - /sim/rendering/clouds3d-enable - - dialog-apply - 3d-clouds - - + + left + + 3d-clouds + + /sim/rendering/shader-effects + + /sim/rendering/clouds3d-enable + + dialog-apply + 3d-clouds + + - - hbox - right - - - - - /sim/rendering/shader-effects - /sim/rendering/clouds3d-enable - - - - - cloud-density - - - /sim/rendering/shader-effects - /sim/rendering/clouds3d-enable - - - 0 - 1.0 - /sim/rendering/clouds3d-density - - dialog-apply - cloud-density - - - property-toggle - /sim/rendering/clouds3d-enable - - - property-toggle - /sim/rendering/clouds3d-enable - - - - - - /sim/rendering/shader-effects - /sim/rendering/clouds3d-enable - - - - %.2f - true - /sim/rendering/clouds3d-density - - + + hbox + right + + + + + /sim/rendering/shader-effects + /sim/rendering/clouds3d-enable + + + + + cloud-density + + + /sim/rendering/shader-effects + /sim/rendering/clouds3d-enable + + + 0 + 1.0 + /sim/rendering/clouds3d-density + + dialog-apply + cloud-density + + + property-toggle + /sim/rendering/clouds3d-enable + + + property-toggle + /sim/rendering/clouds3d-enable + + + + + + /sim/rendering/shader-effects + /sim/rendering/clouds3d-enable + + + + %.2f + true + /sim/rendering/clouds3d-density + + - - hbox - right - - - - - /sim/rendering/shader-effects - /sim/rendering/clouds3d-enable - - - - - cloud-vis-range - - - /sim/rendering/shader-effects - /sim/rendering/clouds3d-enable - - - 100.0 - 20000.0 - /sim/rendering/clouds3d-vis-range - - dialog-apply - cloud-vis-range - - - - - - /sim/rendering/shader-effects - /sim/rendering/clouds3d-enable - - - - %.fm - true - /sim/rendering/clouds3d-vis-range - - + + hbox + right + + + + + /sim/rendering/shader-effects + /sim/rendering/clouds3d-enable + + + + + cloud-vis-range + + + /sim/rendering/shader-effects + /sim/rendering/clouds3d-enable + + + 100.0 + 20000.0 + /sim/rendering/clouds3d-vis-range + + dialog-apply + cloud-vis-range + + + + + + /sim/rendering/shader-effects + /sim/rendering/clouds3d-enable + + + + %.fm + true + /sim/rendering/clouds3d-vis-range + + - - vbox - 1 - + + vbox + 1 + - + - + - - vbox + + vbox - - hbox - - - left - - - true - - + + hbox + + + left + + + true + + - - left - - material-shaders - /sim/rendering/shader-effects - - dialog-apply - material-shaders - - + + left + + material-shaders + /sim/rendering/shader-effects + + dialog-apply + material-shaders + + - - vbox - 10 + + vbox + 10 - - left - - crop-texture - - /sim/rendering/shader-effects - - /sim/rendering/crop-shader - - dialog-apply - crop-texture - - + + left + + crop-texture + + /sim/rendering/shader-effects + + /sim/rendering/crop-shader + + dialog-apply + crop-texture + + - - left - - landmass-effects - - /sim/rendering/shader-effects - - /sim/rendering/landmass-shader - - dialog-apply - landmass-effects - - + + left + + landmass-effects + + /sim/rendering/shader-effects + + /sim/rendering/landmass-shader + + dialog-apply + landmass-effects + + - - left - - water-reflection - - /sim/rendering/shader-effects - - /sim/rendering/water-shader - - dialog-apply - water-reflection - - + + left + + water-reflection + + /sim/rendering/shader-effects + + /sim/rendering/water-shader + + dialog-apply + water-reflection + + - - left - - urban-effects - - /sim/rendering/shader-effects - - /sim/rendering/urban-shader - - dialog-apply - urban-effects - - + + left + + urban-effects + + /sim/rendering/shader-effects + + /sim/rendering/urban-shader + + dialog-apply + urban-effects + + - - left - - transition-effects - - /sim/rendering/shader-effects - - /sim/rendering/transition-shader - - dialog-apply - transition-effects - - + + left + + transition-effects + + /sim/rendering/shader-effects + + /sim/rendering/transition-shader + + dialog-apply + transition-effects + + - - left - - persistent-contrails - - /sim/rendering/shader-effects - - /sim/rendering/contrail-shader - - dialog-apply - persistent-contrails - - - + + left + + persistent-contrails + + /sim/rendering/shader-effects + + /sim/rendering/contrail-shader + + dialog-apply + persistent-contrails + + + - - hbox - right - - - - - /sim/rendering/shader-effects - - /sim/rendering/crop-shader - /sim/rendering/landmass-shader - /sim/rendering/urban-shader - - - - - - snow-level - - - /sim/rendering/shader-effects - - /sim/rendering/crop-shader - /sim/rendering/landmass-shader - /sim/rendering/urban-shader - - - - 0.0 - 5000.0 - /sim/rendering/snow-level-m - - dialog-apply - snow-level - - - - - - /sim/rendering/shader-effects - - /sim/rendering/crop-shader - /sim/rendering/landmass-shader - /sim/rendering/urban-shader - - - - - %.fm - true - /sim/rendering/snow-level-m - - + + hbox + right + + + + + /sim/rendering/shader-effects + + /sim/rendering/crop-shader + /sim/rendering/landmass-shader + /sim/rendering/urban-shader + + + + + + snow-level + + + /sim/rendering/shader-effects + + /sim/rendering/crop-shader + /sim/rendering/landmass-shader + /sim/rendering/urban-shader + + + + 0.0 + 5000.0 + /sim/rendering/snow-level-m + + dialog-apply + snow-level + + + + + + /sim/rendering/shader-effects + + /sim/rendering/crop-shader + /sim/rendering/landmass-shader + /sim/rendering/urban-shader + + + + + %.fm + true + /sim/rendering/snow-level-m + + - - hbox - right - - - - /sim/rendering/shader-effects - - - - quality-level - - /sim/rendering/shader-effects - - 0.0 - 5.0 - 0.5 - /sim/rendering/quality-level - - dialog-apply - quality-level - - - - - /sim/rendering/shader-effects - - - %.1f - true - /sim/rendering/quality-level - - + + hbox + right + + + + /sim/rendering/shader-effects + + + + quality-level + + /sim/rendering/shader-effects + + 0.0 + 5.0 + 0.5 + /sim/rendering/quality-level + + dialog-apply + quality-level + + + + + /sim/rendering/shader-effects + + + %.1f + true + /sim/rendering/quality-level + + - - + + hbox + + + left + + + true + + + + + vbox + 10 + + left + + skydome-scattering + + /sim/rendering/shader-effects + + /sim/rendering/scattering-shader + + dialog-apply + skydome-scattering + + + - + + hbox + right + + + + /sim/rendering/shader-effects + + + + mie-factor + + /sim/rendering/shader-effects + + 0.0 + 0.01 + 0.001 + /sim/rendering/mie + + dialog-apply + mie-factor + + + + + /sim/rendering/shader-effects + + + %.3f + true + /sim/rendering/mie + + + + + hbox + right + + + + /sim/rendering/shader-effects + + + + rayleigh-factor + + /sim/rendering/shader-effects + + 0.0 + 0.001 + 0.0001 + /sim/rendering/rayleigh + + dialog-apply + rayleigh-factor + + + + + /sim/rendering/shader-effects + + + %.4f + true + /sim/rendering/rayleigh + + - + + hbox + right + + + + /sim/rendering/shader-effects + + + + density-factor + + /sim/rendering/shader-effects + + 0.0 + 1.0 + 0.1 + /sim/rendering/dome-density + + dialog-apply + density-factor + + + + + /sim/rendering/shader-effects + + + %.1f + true + /sim/rendering/dome-density + + - - - gui.enable_widgets(cmdarg(), "shadows-debug", getprop("/sim/gui/devel-widgets")); - - + + + + + + + + + + + + gui.enable_widgets(cmdarg(), "shadows-debug", getprop("/sim/gui/devel-widgets")); + +