1
0
Fork 0

Earthview orbital rendering based on the NASA Visible Earth image collection

This commit is contained in:
Thorsten Renk 2014-04-24 10:37:41 +03:00
parent 6fa9d8ac88
commit 23d7f41481
8 changed files with 797 additions and 0 deletions

View file

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/planet</name>
<!-- <inherits-from>Effects/shadow</inherits-from> -->
<parameters>
<texture n ="0">
<type>white</type>
</texture>
<vertex-program-two-side type="bool">false</vertex-program-two-side>
<material>
<color-mode-uniform>1</color-mode-uniform>
<!-- DIFFUSE -->
</material>
<visibility><use>/environment/visibility-m</use></visibility>
</parameters>
<technique n="10">
<predicate>
<and>
<property>/sim/rendering/shaders/generic</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>
<source>src-alpha</source>
<destination>one-minus-src-alpha</destination>
</blend>
<shade-model>
<use>shade-model</use>
</shade-model>
<cull-face>
<use>cull-face</use>
</cull-face>
<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>
<!--<vertex-program-two-side>
<use>vertex-program-two-side</use>
</vertex-program-two-side>-->
<program>
<vertex-shader>Shaders/planet.vert</vertex-shader>
<fragment-shader>Shaders/planet-cloudlayer.frag</fragment-shader>
</program>
<uniform>
<name>texture</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>colorMode</name>
<type>int</type>
<value>
<use>material/color-mode-uniform</use>
</value>
</uniform>
<uniform>
<name>visibility</name>
<type>float</type>
<value>
<use>visibility</use>
</value>
</uniform>
</pass>
</technique>
<technique n="11">
<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>
<rendering-hint>
<use>rendering-hint</use>
</rendering-hint>
<texture-unit>
<active>
<use>texture[0]/active</use>
</active>
<unit>0</unit>
<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>
-->
<environment>
<mode>modulate</mode>
</environment>
</texture-unit>
<!-- A two-sided lighting model is set by default near the root
of the scene graph. Perhaps that ought to be set in this
effect?
-->
</pass>
</technique>
</PropertyList>

218
Effects/planet.eff Normal file
View file

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/planet</name>
<!-- <inherits-from>Effects/shadow</inherits-from> -->
<parameters>
<texture n ="0">
<type>white</type>
</texture>
<texture n="1">
<image>Textures/Terrain/void.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>
<vertex-program-two-side type="bool">false</vertex-program-two-side>
<material>
<color-mode-uniform>1</color-mode-uniform>
<!-- DIFFUSE -->
</material>
<visibility><use>/environment/visibility-m</use></visibility>
</parameters>
<generate>
<tangent type="int">6</tangent>
</generate>
<technique n="10">
<predicate>
<and>
<property>/sim/rendering/shaders/generic</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><use>transparent</use></blend>
<alpha-test><use>transparent</use></alpha-test>
<shade-model>
<use>shade-model</use>
</shade-model>
<cull-face>
<use>cull-face</use>
</cull-face>
<rendering-hint>
<use>rendering-hint</use>
</rendering-hint>
<texture-unit>
<unit>0</unit>
<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>
</texture-unit>
<texture-unit>
<unit>1</unit>
<image><use>texture[1]/image</use></image>
<type><use>texture[1]/type</use></type>
<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>
<program>
<vertex-shader>Shaders/planet.vert</vertex-shader>
<fragment-shader>Shaders/planet.frag</fragment-shader>
<attribute>
<name>tangent</name>
<index>6</index>
</attribute>
</program>
<uniform>
<name>texture</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>shadowtex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>colorMode</name>
<type>int</type>
<value>
<use>material/color-mode-uniform</use>
</value>
</uniform>
<uniform>
<name>visibility</name>
<type>float</type>
<value>
<use>visibility</use>
</value>
</uniform>
</pass>
</technique>
<technique n="11">
<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>
<rendering-hint>
<use>rendering-hint</use>
</rendering-hint>
<texture-unit>
<active>
<use>texture[0]/active</use>
</active>
<unit>0</unit>
<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>
-->
<environment>
<mode>modulate</mode>
</environment>
</texture-unit>
<!-- A two-sided lighting model is set by default near the root
of the scene graph. Perhaps that ought to be set in this
effect?
-->
</pass>
</technique>
</PropertyList>

104
Nasal/earthview.nas Normal file
View file

@ -0,0 +1,104 @@
###########################################################
# Earthview orbital rendering
###########################################################
var start = func() {
var lat = getprop("/position/latitude-deg");
var lon = getprop("/position/longitude-deg");
earth_model.node = earthview.place_earth_model("Models/Astro/earth.xml",lat, lon, 0.0, 0.0, 0.0, 0.0);
cloudsphere_model.node = earthview.place_earth_model("Models/Astro/cloudsphere.xml",lat, lon, 0.0, 0.0, 0.0, 0.0);
}
var stop = func () {
earth_model.node.remove();
cloudsphere_model.node.remove();
setprop("/earthview/control_loop_flag",0);
}
var place_earth_model = func(path, lat, lon, alt, heading, pitch, roll) {
var m = props.globals.getNode("models", 1);
for (var i = 0; 1; i += 1)
if (m.getChild("model", i, 0) == nil)
break;
var model = m.getChild("model", i, 1);
var R1 = 5800000.0;
var R2 = 58000.0;
var altitude1 = getprop("/position/altitude-ft");
var altitude2 = R2/R1 * altitude1;
var model_alt = altitude1 - altitude2 - R2 * m_to_ft;
setprop("/earthview/latitude-deg", lat);
setprop("/earthview/longitude-deg", lon);
setprop("/earthview/elevation-ft", model_alt);
setprop("/earthview/heading-deg", heading);
setprop("/earthview/pitch-deg", pitch);
setprop("/earthview/roll-deg", roll);
setprop("/earthview/yaw-deg", 0.0);
var eview = props.globals.getNode("earthview", 1);
var latN = eview.getNode("latitude-deg",1);
var lonN = eview.getNode("longitude-deg",1);
var altN = eview.getNode("elevation-ft",1);
var headN = eview.getNode("heading-deg",1);
var pitchN = eview.getNode("pitch-deg",1);
var rollN = eview.getNode("roll-deg",1);
model.getNode("path", 1).setValue(path);
model.getNode("latitude-deg-prop", 1).setValue(latN.getPath());
model.getNode("longitude-deg-prop", 1).setValue(lonN.getPath());
model.getNode("elevation-ft-prop", 1).setValue(altN.getPath());
model.getNode("heading-deg-prop", 1).setValue(headN.getPath());
model.getNode("pitch-deg-prop", 1).setValue(pitchN.getPath());
model.getNode("roll-deg-prop", 1).setValue(rollN.getPath());
model.getNode("load", 1).remove();
setprop("/earthview/heading-deg",90);
setprop("/earthview/control_loop_flag",1);
control_loop();
return model;
}
var control_loop = func {
var R1 = 5800000.0;
var R2 = 58000.0;
var altitude1 = getprop("/position/altitude-ft");
var altitude2 = R2/R1 * altitude1;
var model_alt = altitude1 - altitude2 - R2 * m_to_ft;
setprop("/earthview/elevation-ft", model_alt);
var lat = getprop("/position/latitude-deg");
var lon = getprop("/position/longitude-deg");
setprop("/earthview/latitude-deg", lat);
setprop("/earthview/longitude-deg", lon);
setprop("/earthview/roll-deg", -(90-lat));
setprop("/earthview/yaw-deg", -lon);
if (getprop("/earthview/control_loop_flag") ==1) {settimer( func {control_loop(); },0);}
}
var ft_to_m = 0.30480;
var m_to_ft = 1.0/ft_to_m;
var earth_model = {};
var cloudsphere_model = {};

View file

@ -0,0 +1,61 @@
// -*-C++-*-
// Ambient term comes in gl_Color.rgb.
#version 120
varying vec4 diffuse_term;
varying vec3 normal;
varying vec3 ecViewDir;
varying vec3 VTangent;
uniform sampler2D texture;
float luminance(vec3 color)
{
return dot(vec3(0.212671, 0.715160, 0.072169), color);
}
void main()
{
vec3 n;
float NdotL, NdotHV;
vec4 color = gl_Color;
vec3 lightDir = gl_LightSource[0].position.xyz;
vec3 halfVector = normalize(normalize(lightDir) + normalize(ecViewDir));
vec4 texel;
vec4 fragColor;
vec4 specular = vec4(0.0);
// If gl_Color.a == 0, this is a back-facing polygon and the
// normal should be reversed.
n = (2.0 * gl_Color.a - 1.0) * normal;
n = normalize(n);
vec3 light_specular = vec3 (1.0, 1.0, 1.0);
NdotL = dot(n, lightDir);
if (NdotL > 0.0) {
color += diffuse_term * NdotL ;
NdotHV = max(dot(n, halfVector), 0.0);
if (gl_FrontMaterial.shininess > 0.0)
specular.rgb = (gl_FrontMaterial.specular.rgb
* light_specular
* pow(NdotHV, gl_FrontMaterial.shininess));
}
color.a = diffuse_term.a;
// This shouldn't be necessary, but our lighting becomes very
// saturated. Clamping the color before modulating by the texture
// is closer to what the OpenGL fixed function pipeline does.
color = clamp(color, 0.0, 1.0);
texel = texture2D(texture, gl_TexCoord[0].st);
fragColor = color * texel + specular;
gl_FragColor = fragColor;
//gl_FragColor = (0.5,0.5,0.5,1.0);
}

80
Shaders/planet.frag Normal file
View file

@ -0,0 +1,80 @@
// -*-C++-*-
// Ambient term comes in gl_Color.rgb.
#version 120
varying vec4 diffuse_term;
varying vec3 normal;
varying vec3 ecViewDir;
varying vec3 VTangent;
uniform float visibility;
uniform sampler2D texture;
uniform sampler2D shadowtex;
float luminance(vec3 color)
{
return dot(vec3(0.212671, 0.715160, 0.072169), color);
}
void main()
{
vec3 n;
float NdotL, NdotHV;
vec4 color = gl_Color;
vec3 lightDir = gl_LightSource[0].position.xyz;
//vec3 halfVector = gl_LightSource[0].halfVector.xyz;
vec3 halfVector = normalize(normalize(lightDir) + normalize(ecViewDir));
vec4 texel;
vec4 shadowTexel;
vec4 fragColor;
vec4 specular = vec4(0.0);
// If gl_Color.a == 0, this is a back-facing polygon and the
// normal should be reversed.
n = (2.0 * gl_Color.a - 1.0) * normal;
n = normalize(n);
vec3 VBinormal;
VBinormal = cross(normal, VTangent);
float xOffset = -0.005 * dot(normalize(lightDir), normalize(VTangent));
float yOffset = -0.005 * dot(normalize(lightDir), normalize(VBinormal));
shadowTexel = texture2D(shadowtex, vec2(gl_TexCoord[0].s-xOffset, gl_TexCoord[0].t-yOffset));
vec3 light_specular = vec3 (1.0, 1.0, 1.0);
NdotL = dot(n, lightDir);
if (NdotL > 0.0) {
color += diffuse_term * NdotL * (1.0-shadowTexel.a);
NdotHV = max(dot(n, halfVector), 0.0);
if (gl_FrontMaterial.shininess > 0.0)
specular.rgb = (gl_FrontMaterial.specular.rgb
* light_specular * (1.0-shadowTexel.a)
* pow(NdotHV, gl_FrontMaterial.shininess));
}
color.a = diffuse_term.a;
// This shouldn't be necessary, but our lighting becomes very
// saturated. Clamping the color before modulating by the texture
// is closer to what the OpenGL fixed function pipeline does.
color = clamp(color, 0.0, 1.0);
texel = texture2D(texture, gl_TexCoord[0].st);
fragColor = color * texel + specular;
//fragColor = fragColor * (1.0 - 0.5 * shadowTexel.a);
//fragColor = mix(fragColor, shadowTexel, shadowTexel.a);
float angle = dot(normalize(ecViewDir), normalize(normal));
float distance_through_atmosphere = 10.0 / ((angle)+0.001);
vec4 fogColor = vec4 (0.83,0.9,1.0,1.0) * clamp(length(diffuse_term.rgb * max(NdotL,0.0)),0.0,1.0);
//float visibility = 80.0;
float fogFactor = exp(-distance_through_atmosphere/(visibility/1000.0));
fragColor = mix(fogColor, fragColor, fogFactor);
//fragColor.rgb = fog_Func(fragColor.rgb, fogType);
gl_FragColor = fragColor;
//gl_FragColor = (0.5,0.5,0.5,1.0);
}

69
Shaders/planet.vert Normal file
View file

@ -0,0 +1,69 @@
// -*-C++-*-
// Shader that uses OpenGL state values to do per-pixel lighting
//
// The only light used is gl_LightSource[0], which is assumed to be
// directional.
//
// Diffuse colors come from the gl_Color, ambient from the material. This is
// equivalent to osg::Material::DIFFUSE.
#version 120
#define MODE_OFF 0
#define MODE_DIFFUSE 1
#define MODE_AMBIENT_AND_DIFFUSE 2
// The constant term of the lighting equation that doesn't depend on
// the surface normal is passed in gl_{Front,Back}Color. The alpha
// component is set to 1 for front, 0 for back in order to work around
// bugs with gl_FrontFacing in the fragment shader.
varying vec4 diffuse_term;
varying vec3 normal;
varying vec3 ecViewDir;
varying vec3 VTangent;
uniform int colorMode;
attribute vec3 tangent;//, binormal;
void main()
{
vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
ecViewDir = (gl_ModelViewMatrix * (ep - gl_Vertex)).xyz;
gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
normal = gl_NormalMatrix * gl_Normal;
VTangent = gl_NormalMatrix * tangent;
vec4 ambient_color, diffuse_color;
if (colorMode == MODE_DIFFUSE) {
diffuse_color = gl_Color;
ambient_color = gl_FrontMaterial.ambient;
} else if (colorMode == MODE_AMBIENT_AND_DIFFUSE) {
diffuse_color = gl_Color;
ambient_color = gl_Color;
} else {
diffuse_color = gl_FrontMaterial.diffuse;
ambient_color = gl_FrontMaterial.ambient;
}
vec4 light_diffuse = vec4 (1.0,1.0,1.0,1.0);
vec4 light_ambient = vec4 (0.05, 0.05, 0.05, 1.0);
diffuse_term = diffuse_color * light_diffuse;//gl_LightSource[0].diffuse;
vec4 constant_term = gl_FrontMaterial.emission + ambient_color *
(gl_LightModel.ambient + light_ambient);
// Super hack: if diffuse material alpha is less than 1, assume a
// transparency animation is at work
if (gl_FrontMaterial.diffuse.a < 1.0)
diffuse_term.a = gl_FrontMaterial.diffuse.a;
else
diffuse_term.a = gl_Color.a;
// Another hack for supporting two-sided lighting without using
// gl_FrontFacing in the fragment shader.
gl_FrontColor.rgb = constant_term.rgb; gl_FrontColor.a = 1.0;
gl_BackColor.rgb = constant_term.rgb; gl_BackColor.a = 0.0;
//fogCoord = abs(ecPosition.z / ecPosition.w);
//fog_Func(fogType);
}

45
gui/dialogs/earthview.xml Normal file
View file

@ -0,0 +1,45 @@
<?xml version="1.0"?>
<PropertyList>
<name>earthview</name>
<width>150</width>
<height>50</height>
<modal>false</modal>
<button>
<x>10</x>
<y>10</y>
<legend>Start</legend>
<equal>true</equal>
<binding>
<command>nasal</command>
<script>earthview.start()</script>
</binding>
</button>
<button>
<x>50</x>
<y>10</y>
<legend>Stop</legend>
<equal>true</equal>
<binding>
<command>nasal</command>
<script>earthview.stop()</script>
</binding>
</button>
<button>
<x>90</x>
<y>10</y>
<legend>Cancel</legend>
<equal>true</equal>
<key>Esc</key>
<binding>
<command>dialog-close</command>
</binding>
</button>
</PropertyList>

View file

@ -168,6 +168,16 @@
</binding>
</item>
<item>
<label>Earthview orbital rendering</label>
<name>earthview</name>
<binding>
<command>dialog-show</command>
<dialog-name>earthview</dialog-name>
</binding>
<enabled>true</enabled>
</item>
<item>
<name>stereoscopic-options</name>
<binding>