1
0
Fork 0

HDR: Improved environment mapping

- Terrain and clouds and now rendered on the envmap, with correct aerial
  perspective.
- Each face is rendered on a separate frame to help with performance.
- All faces are updated every 1.5 minutes. This can be changed through a
  property.
This commit is contained in:
Fernando García Liñán 2023-05-03 01:57:20 +02:00
parent d8c0e6c22f
commit 1e66c4104a
29 changed files with 1264 additions and 269 deletions

View file

@ -5,9 +5,17 @@
<implicit-attachment-mask>depth</implicit-attachment-mask>
<effect-scheme>hdr-envmap</effect-scheme>
<clear-mask>depth</clear-mask>
<!-- Only render the skydome and terrain -->
<!-- TODO: Explicitly select the LOD level -->
<cull-mask>0x800</cull-mask>
<!--
Only render:
- Terrain (both WS 2.0 and 3.0)
- Clouds
- Skydome
-->
<cull-mask>0x1801</cull-mask>
<binding>
<unit>12</unit>
<buffer>transmittance</buffer>
</binding>
<binding>
<unit>13</unit>
<buffer>sky-view</buffer>

View file

@ -6,4 +6,7 @@
<unit>0</unit>
<buffer>envmap</buffer>
</binding>
<render-condition>
<property>/sim/rendering/hdr/envmap/should-prefilter</property>
</render-condition>
</PropertyList>

View file

@ -343,6 +343,9 @@
<buffer>envmap</buffer>
<face>0</face>
</attachment>
<render-condition>
<property>/sim/rendering/hdr/envmap/should-render-face-0</property>
</render-condition>
</pass>
<pass include="env-capture-pass.xml">
<name>env-capture1</name>
@ -352,6 +355,9 @@
<buffer>envmap</buffer>
<face>1</face>
</attachment>
<render-condition>
<property>/sim/rendering/hdr/envmap/should-render-face-1</property>
</render-condition>
</pass>
<pass include="env-capture-pass.xml">
<name>env-capture2</name>
@ -361,6 +367,9 @@
<buffer>envmap</buffer>
<face>2</face>
</attachment>
<render-condition>
<property>/sim/rendering/hdr/envmap/should-render-face-2</property>
</render-condition>
</pass>
<pass include="env-capture-pass.xml">
<name>env-capture3</name>
@ -370,6 +379,9 @@
<buffer>envmap</buffer>
<face>3</face>
</attachment>
<render-condition>
<property>/sim/rendering/hdr/envmap/should-render-face-3</property>
</render-condition>
</pass>
<pass include="env-capture-pass.xml">
<name>env-capture4</name>
@ -379,6 +391,9 @@
<buffer>envmap</buffer>
<face>4</face>
</attachment>
<render-condition>
<property>/sim/rendering/hdr/envmap/should-render-face-4</property>
</render-condition>
</pass>
<pass include="env-capture-pass.xml">
<name>env-capture5</name>
@ -390,6 +405,9 @@
<!-- Generate the mips after writing to the last face -->
<mipmap-generation>true</mipmap-generation>
</attachment>
<render-condition>
<property>/sim/rendering/hdr/envmap/should-render-face-5</property>
</render-condition>
</pass>
<!--

View file

@ -53,6 +53,7 @@
<fragment-shader>Shaders/HDR/ibl.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/shadows.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/gtao.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/sun.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/clustered.glsl</fragment-shader>
@ -127,6 +128,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>

View file

@ -19,6 +19,7 @@
<fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/pos_from_depth.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/sun.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
@ -50,6 +51,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>

View file

@ -25,6 +25,43 @@
<exposure-compensation>
<use>/sim/rendering/hdr/exposure-compensation</use>
</exposure-compensation>
<!-- atmos.glsl -->
<aerosol-absorption-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[3]</use>
</aerosol-absorption-cross-section>
<aerosol-scattering-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[3]</use>
</aerosol-scattering-cross-section>
<aerosol-base-density>
<use>/sim/rendering/hdr/atmos/aerosol-base-density</use>
</aerosol-base-density>
<aerosol-relative-background-density>
<use>/sim/rendering/hdr/atmos/aerosol-relative-background-density</use>
</aerosol-relative-background-density>
<aerosol-scale-height>
<use>/sim/rendering/hdr/atmos/aerosol-scale-height</use>
</aerosol-scale-height>
<fog-density>
<use>/sim/rendering/hdr/atmos/fog-density</use>
</fog-density>
<fog-scale-height>
<use>/sim/rendering/hdr/atmos/fog-scale-height</use>
</fog-scale-height>
<ozone-mean-dobson>
<use>/sim/rendering/hdr/atmos/ozone-mean-dobson</use>
</ozone-mean-dobson>
<ground-albedo type="vec4d">
<use>/sim/rendering/hdr/atmos/ground-albedo[0]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[1]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[2]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[3]</use>
</ground-albedo>
</parameters>
<technique n="9">
@ -263,9 +300,12 @@
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/cloud_static.vert</vertex-shader>
<vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
</program>
@ -280,6 +320,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
@ -298,4 +339,92 @@
</uniform>
</pass>
</technique>
<technique n="139">
<scheme>hdr-envmap</scheme>
<pass>
<depth>
<write-mask>false</write-mask>
</depth>
<texture-unit>
<unit>0</unit>
<type>2d</type>
<image><use>texture[0]/image</use></image>
<wrap-s>clamp-to-border</wrap-s>
<wrap-t>clamp-to-border</wrap-t>
</texture-unit>
<blend>1</blend>
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/cloud_static_envmap.vert</vertex-shader>
<vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/math.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective_envmap.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud_envmap.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective_envmap.glsl</fragment-shader>
</program>
<uniform>
<name>base_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<!-- sun.glsl -->
<!-- aerial_perspective_envmap.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
<value type="int">12</value>
</uniform>
<!-- atmos.glsl -->
<uniform>
<name>aerosol_absorption_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-absorption-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_scattering_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-scattering-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_base_density</name>
<type>float</type>
<value><use>aerosol-base-density</use></value>
</uniform>
<uniform>
<name>aerosol_relative_background_density</name>
<type>float</type>
<value><use>aerosol-relative-background-density</use></value>
</uniform>
<uniform>
<name>aerosol_scale_height</name>
<type>float</type>
<value><use>aerosol-scale-height</use></value>
</uniform>
<uniform>
<name>fog_density</name>
<type>float</type>
<value><use>fog-density</use></value>
</uniform>
<uniform>
<name>fog_scale_height</name>
<type>float</type>
<value><use>fog-scale-height</use></value>
</uniform>
<uniform>
<name>ozone_mean_dobson</name>
<type>float</type>
<value><use>ozone-mean-dobson</use></value>
</uniform>
<uniform>
<name>ground_albedo</name>
<type>float-vec4</type>
<value><use>ground-albedo</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -12,6 +12,43 @@
<exposure-compensation>
<use>/sim/rendering/hdr/exposure-compensation</use>
</exposure-compensation>
<!-- atmos.glsl -->
<aerosol-absorption-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[3]</use>
</aerosol-absorption-cross-section>
<aerosol-scattering-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[3]</use>
</aerosol-scattering-cross-section>
<aerosol-base-density>
<use>/sim/rendering/hdr/atmos/aerosol-base-density</use>
</aerosol-base-density>
<aerosol-relative-background-density>
<use>/sim/rendering/hdr/atmos/aerosol-relative-background-density</use>
</aerosol-relative-background-density>
<aerosol-scale-height>
<use>/sim/rendering/hdr/atmos/aerosol-scale-height</use>
</aerosol-scale-height>
<fog-density>
<use>/sim/rendering/hdr/atmos/fog-density</use>
</fog-density>
<fog-scale-height>
<use>/sim/rendering/hdr/atmos/fog-scale-height</use>
</fog-scale-height>
<ozone-mean-dobson>
<use>/sim/rendering/hdr/atmos/ozone-mean-dobson</use>
</ozone-mean-dobson>
<ground-albedo type="vec4d">
<use>/sim/rendering/hdr/atmos/ground-albedo[0]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[1]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[2]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[3]</use>
</ground-albedo>
</parameters>
<technique n="9">
@ -183,9 +220,12 @@
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/cloud_static.vert</vertex-shader>
<vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
</program>
@ -200,6 +240,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
@ -218,4 +259,92 @@
</uniform>
</pass>
</technique>
<technique n="139">
<scheme>hdr-envmap</scheme>
<pass>
<depth>
<write-mask>false</write-mask>
</depth>
<texture-unit>
<unit>0</unit>
<type>2d</type>
<image><use>texture[0]/image</use></image>
<wrap-s>clamp-to-border</wrap-s>
<wrap-t>clamp-to-border</wrap-t>
</texture-unit>
<blend>1</blend>
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/cloud_static_envmap.vert</vertex-shader>
<vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/math.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective_envmap.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud_envmap.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective_envmap.glsl</fragment-shader>
</program>
<uniform>
<name>base_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<!-- sun.glsl -->
<!-- aerial_perspective_envmap.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
<value type="int">12</value>
</uniform>
<!-- atmos.glsl -->
<uniform>
<name>aerosol_absorption_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-absorption-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_scattering_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-scattering-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_base_density</name>
<type>float</type>
<value><use>aerosol-base-density</use></value>
</uniform>
<uniform>
<name>aerosol_relative_background_density</name>
<type>float</type>
<value><use>aerosol-relative-background-density</use></value>
</uniform>
<uniform>
<name>aerosol_scale_height</name>
<type>float</type>
<value><use>aerosol-scale-height</use></value>
</uniform>
<uniform>
<name>fog_density</name>
<type>float</type>
<value><use>fog-density</use></value>
</uniform>
<uniform>
<name>fog_scale_height</name>
<type>float</type>
<value><use>fog-scale-height</use></value>
</uniform>
<uniform>
<name>ozone_mean_dobson</name>
<type>float</type>
<value><use>ozone-mean-dobson</use></value>
</uniform>
<uniform>
<name>ground_albedo</name>
<type>float-vec4</type>
<value><use>ground-albedo</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -24,6 +24,43 @@
<exposure-compensation>
<use>/sim/rendering/hdr/exposure-compensation</use>
</exposure-compensation>
<!-- atmos.glsl -->
<aerosol-absorption-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[3]</use>
</aerosol-absorption-cross-section>
<aerosol-scattering-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[3]</use>
</aerosol-scattering-cross-section>
<aerosol-base-density>
<use>/sim/rendering/hdr/atmos/aerosol-base-density</use>
</aerosol-base-density>
<aerosol-relative-background-density>
<use>/sim/rendering/hdr/atmos/aerosol-relative-background-density</use>
</aerosol-relative-background-density>
<aerosol-scale-height>
<use>/sim/rendering/hdr/atmos/aerosol-scale-height</use>
</aerosol-scale-height>
<fog-density>
<use>/sim/rendering/hdr/atmos/fog-density</use>
</fog-density>
<fog-scale-height>
<use>/sim/rendering/hdr/atmos/fog-scale-height</use>
</fog-scale-height>
<ozone-mean-dobson>
<use>/sim/rendering/hdr/atmos/ozone-mean-dobson</use>
</ozone-mean-dobson>
<ground-albedo type="vec4d">
<use>/sim/rendering/hdr/atmos/ground-albedo[0]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[1]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[2]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[3]</use>
</ground-albedo>
</parameters>
<technique n="8">
@ -391,9 +428,12 @@
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/cloud_static.vert</vertex-shader>
<vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
</program>
@ -408,6 +448,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
@ -426,4 +467,92 @@
</uniform>
</pass>
</technique>
<technique n="139">
<scheme>hdr-envmap</scheme>
<pass>
<depth>
<write-mask>false</write-mask>
</depth>
<texture-unit>
<unit>0</unit>
<type>2d</type>
<image><use>texture[0]/image</use></image>
<wrap-s>clamp-to-border</wrap-s>
<wrap-t>clamp-to-border</wrap-t>
</texture-unit>
<blend>1</blend>
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/cloud_static_envmap.vert</vertex-shader>
<vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/math.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective_envmap.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud_envmap.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective_envmap.glsl</fragment-shader>
</program>
<uniform>
<name>base_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<!-- sun.glsl -->
<!-- aerial_perspective_envmap.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
<value type="int">12</value>
</uniform>
<!-- atmos.glsl -->
<uniform>
<name>aerosol_absorption_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-absorption-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_scattering_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-scattering-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_base_density</name>
<type>float</type>
<value><use>aerosol-base-density</use></value>
</uniform>
<uniform>
<name>aerosol_relative_background_density</name>
<type>float</type>
<value><use>aerosol-relative-background-density</use></value>
</uniform>
<uniform>
<name>aerosol_scale_height</name>
<type>float</type>
<value><use>aerosol-scale-height</use></value>
</uniform>
<uniform>
<name>fog_density</name>
<type>float</type>
<value><use>fog-density</use></value>
</uniform>
<uniform>
<name>fog_scale_height</name>
<type>float</type>
<value><use>fog-scale-height</use></value>
</uniform>
<uniform>
<name>ozone_mean_dobson</name>
<type>float</type>
<value><use>ozone-mean-dobson</use></value>
</uniform>
<uniform>
<name>ground_albedo</name>
<type>float-vec4</type>
<value><use>ground-albedo</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -31,6 +31,43 @@
<exposure-compensation>
<use>/sim/rendering/hdr/exposure-compensation</use>
</exposure-compensation>
<!-- atmos.glsl -->
<aerosol-absorption-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[3]</use>
</aerosol-absorption-cross-section>
<aerosol-scattering-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[3]</use>
</aerosol-scattering-cross-section>
<aerosol-base-density>
<use>/sim/rendering/hdr/atmos/aerosol-base-density</use>
</aerosol-base-density>
<aerosol-relative-background-density>
<use>/sim/rendering/hdr/atmos/aerosol-relative-background-density</use>
</aerosol-relative-background-density>
<aerosol-scale-height>
<use>/sim/rendering/hdr/atmos/aerosol-scale-height</use>
</aerosol-scale-height>
<fog-density>
<use>/sim/rendering/hdr/atmos/fog-density</use>
</fog-density>
<fog-scale-height>
<use>/sim/rendering/hdr/atmos/fog-scale-height</use>
</fog-scale-height>
<ozone-mean-dobson>
<use>/sim/rendering/hdr/atmos/ozone-mean-dobson</use>
</ozone-mean-dobson>
<ground-albedo type="vec4d">
<use>/sim/rendering/hdr/atmos/ground-albedo[0]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[1]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[2]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[3]</use>
</ground-albedo>
</parameters>
<technique n="8">
@ -504,9 +541,12 @@
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/3dcloud.vert</vertex-shader>
<vertex-shader>Shaders/HDR/3dcloud_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
<attribute>
@ -539,6 +579,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
@ -557,4 +598,110 @@
</uniform>
</pass>
</technique>
<technique n="139">
<scheme>hdr-envmap</scheme>
<pass>
<depth>
<write-mask>false</write-mask>
</depth>
<texture-unit>
<unit>0</unit>
<type>2d</type>
<image><use>texture[0]/image</use></image>
<wrap-s>clamp-to-border</wrap-s>
<wrap-t>clamp-to-border</wrap-t>
</texture-unit>
<blend>1</blend>
<rendering-hint>transparent</rendering-hint>
<program>
<vertex-shader>Shaders/HDR/3dcloud_envmap.vert</vertex-shader>
<vertex-shader>Shaders/HDR/3dcloud_common.vert</vertex-shader>
<vertex-shader>Shaders/HDR/math.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/aerial_perspective_envmap.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos.glsl</vertex-shader>
<vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
<fragment-shader>Shaders/HDR/3dcloud_envmap.frag</fragment-shader>
<fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective_envmap.glsl</fragment-shader>
<attribute>
<name>usrAttr1</name>
<index>10</index>
</attribute>
<attribute>
<name>usrAttr2</name>
<index>11</index>
</attribute>
</program>
<uniform>
<name>base_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>range</name>
<type>float</type>
<value><use>range</use></value>
</uniform>
<uniform>
<name>detail_range</name>
<type>float</type>
<value><use>detail</use></value>
</uniform>
<!-- sun.glsl -->
<!-- aerial_perspective_envmap.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
<value type="int">12</value>
</uniform>
<!-- atmos.glsl -->
<uniform>
<name>aerosol_absorption_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-absorption-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_scattering_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-scattering-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_base_density</name>
<type>float</type>
<value><use>aerosol-base-density</use></value>
</uniform>
<uniform>
<name>aerosol_relative_background_density</name>
<type>float</type>
<value><use>aerosol-relative-background-density</use></value>
</uniform>
<uniform>
<name>aerosol_scale_height</name>
<type>float</type>
<value><use>aerosol-scale-height</use></value>
</uniform>
<uniform>
<name>fog_density</name>
<type>float</type>
<value><use>fog-density</use></value>
</uniform>
<uniform>
<name>fog_scale_height</name>
<type>float</type>
<value><use>fog-scale-height</use></value>
</uniform>
<uniform>
<name>ozone_mean_dobson</name>
<type>float</type>
<value><use>ozone-mean-dobson</use></value>
</uniform>
<uniform>
<name>ground_albedo</name>
<type>float-vec4</type>
<value><use>ground-albedo</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -102,6 +102,7 @@
<fragment-shader>Shaders/HDR/surface.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/ibl.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/shadows.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/sun.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/clustered.glsl</fragment-shader>
@ -185,6 +186,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>

View file

@ -106,6 +106,7 @@
<fragment-shader>Shaders/HDR/surface.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/ibl.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/shadows.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/sun.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/clustered.glsl</fragment-shader>
@ -154,6 +155,7 @@
<type>sampler-2d</type>
<value type="int">11</value>
</uniform>
<!-- sun.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>

View file

@ -189,6 +189,43 @@
<use>/sim/rendering/shadows/sun-atlas-size</use>
</sun_atlas_size>
<!-- END shadows include -->
<!-- atmos.glsl -->
<aerosol-absorption-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[3]</use>
</aerosol-absorption-cross-section>
<aerosol-scattering-cross-section type="vec4d">
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[0]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[1]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[2]</use>
<use>/sim/rendering/hdr/atmos/aerosol-scattering-cross-section[3]</use>
</aerosol-scattering-cross-section>
<aerosol-base-density>
<use>/sim/rendering/hdr/atmos/aerosol-base-density</use>
</aerosol-base-density>
<aerosol-relative-background-density>
<use>/sim/rendering/hdr/atmos/aerosol-relative-background-density</use>
</aerosol-relative-background-density>
<aerosol-scale-height>
<use>/sim/rendering/hdr/atmos/aerosol-scale-height</use>
</aerosol-scale-height>
<fog-density>
<use>/sim/rendering/hdr/atmos/fog-density</use>
</fog-density>
<fog-scale-height>
<use>/sim/rendering/hdr/atmos/fog-scale-height</use>
</fog-scale-height>
<ozone-mean-dobson>
<use>/sim/rendering/hdr/atmos/ozone-mean-dobson</use>
</ozone-mean-dobson>
<ground-albedo type="vec4d">
<use>/sim/rendering/hdr/atmos/ground-albedo[0]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[1]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[2]</use>
<use>/sim/rendering/hdr/atmos/ground-albedo[3]</use>
</ground-albedo>
</parameters>
<!-- put techniques at a "high" index to allow derived effects to
insert their own techniques first. -->
@ -1714,4 +1751,95 @@
</uniform>
</pass>
</technique>
<technique n="139">
<scheme>hdr-envmap</scheme>
<pass>
<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>
<blend>0</blend>
<rendering-hint>opaque</rendering-hint>
<cull-face>back</cull-face>
<program>
<vertex-shader>Shaders/HDR/terrain_envmap.vert</vertex-shader>
<fragment-shader>Shaders/HDR/terrain_envmap.frag</fragment-shader>
<fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/sun.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/aerial_perspective_envmap.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/atmos.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader>
</program>
<uniform>
<name>color_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<!-- Orthophoto include -->
<uniform>
<name>orthophoto_tex</name>
<type>sampler-2d</type>
<value type="int">15</value>
</uniform>
<!-- sun.glsl -->
<!-- aerial_perspective_envmap.glsl -->
<uniform>
<name>transmittance_tex</name>
<type>sampler-2d</type>
<value type="int">12</value>
</uniform>
<!-- atmos.glsl -->
<uniform>
<name>aerosol_absorption_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-absorption-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_scattering_cross_section</name>
<type>float-vec4</type>
<value><use>aerosol-scattering-cross-section</use></value>
</uniform>
<uniform>
<name>aerosol_base_density</name>
<type>float</type>
<value><use>aerosol-base-density</use></value>
</uniform>
<uniform>
<name>aerosol_relative_background_density</name>
<type>float</type>
<value><use>aerosol-relative-background-density</use></value>
</uniform>
<uniform>
<name>aerosol_scale_height</name>
<type>float</type>
<value><use>aerosol-scale-height</use></value>
</uniform>
<uniform>
<name>fog_density</name>
<type>float</type>
<value><use>fog-density</use></value>
</uniform>
<uniform>
<name>fog_scale_height</name>
<type>float</type>
<value><use>fog-scale-height</use></value>
</uniform>
<uniform>
<name>ozone_mean_dobson</name>
<type>float</type>
<value><use>ozone-mean-dobson</use></value>
</uniform>
<uniform>
<name>ground_albedo</name>
<type>float-vec4</type>
<value><use>ground-albedo</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -10,6 +10,9 @@
# by the shaders directly.
#-------------------------------------------------------------------------------
################################################################################
# Atmosphere
################################################################################
setprop("/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[0]", 2.8722e-24);
setprop("/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[1]", 4.6168e-24);
setprop("/sim/rendering/hdr/atmos/aerosol-absorption-cross-section[2]", 7.9706e-24);
@ -31,3 +34,63 @@ setprop("/sim/rendering/hdr/atmos/ground-albedo[0]", 0.4);
setprop("/sim/rendering/hdr/atmos/ground-albedo[1]", 0.4);
setprop("/sim/rendering/hdr/atmos/ground-albedo[2]", 0.4);
setprop("/sim/rendering/hdr/atmos/ground-albedo[3]", 0.4);
################################################################################
# Environment map
################################################################################
var is_envmap_updating = false;
var current_envmap_face = 0;
var update_envmap_face = func {
if (current_envmap_face < 6) {
# Render the current face
setprop("/sim/rendering/hdr/envmap/should-render-face-"
~ current_envmap_face, true);
}
if (current_envmap_face > 0) {
# Stop rendering the previous face
setprop("/sim/rendering/hdr/envmap/should-render-face-"
~ (current_envmap_face - 1), false);
}
if (current_envmap_face < 6) {
# Go to next face and update it next frame
current_envmap_face += 1;
settimer(update_envmap_face, 0);
} else {
# We have finished updating all faces, reset the face counter, end the
# update loop and prefilter the envmap.
current_envmap_face = 0;
setprop("/sim/rendering/hdr/envmap/should-prefilter", true);
settimer(func {
setprop("/sim/rendering/hdr/envmap/should-prefilter", false);
is_envmap_updating = false;
}, 0);
}
}
var update_envmap = func {
if (!is_envmap_updating) {
is_envmap_updating = true;
settimer(update_envmap_face, 0);
}
}
var update_envmap_periodically = func {
update_envmap();
var update_rate = getprop("/sim/rendering/hdr/envmap/update-rate-s");
settimer(update_envmap_periodically, update_rate);
}
# Start updating the envmap on FDM initialization
setlistener("/sim/signals/fdm-initialized", func {
update_envmap_periodically();
# Do a single update after 5 seconds when most of the scenery is loaded
settimer(update_envmap, 5)
});
setlistener("/sim/rendering/hdr/envmap/force-update", func(p) {
if (p.getValue()) {
update_envmap();
p.setValue(false);
}
}, 0, 0);

View file

@ -2,70 +2,17 @@
layout(location = 0) out vec4 fragColor;
in vec2 texcoord;
in vec4 cloud_color;
in vec4 ap_color;
uniform sampler2D base_tex;
uniform mat4 osg_ProjectionMatrix;
uniform vec4 fg_Viewport;
uniform vec3 fg_SunDirection;
uniform float density = 30.0;
uniform float max_sample_dist = 0.05;
const int STEPS = 8;
// aerial_perspective.glsl
vec3 mix_aerial_perspective(vec3 color, vec4 ap);
// 3dcloud_common.frag
vec4 cloud_common_frag();
// exposure.glsl
vec3 apply_exposure(vec3 color);
void main()
{
vec4 base = texture(base_tex, texcoord);
vec4 color = cloud_common_frag();
// Directly discard fragments below a threshold
if (base.a < 0.02)
discard;
// Pixel position in screen space [-1, 1]
vec2 screen_uv = ((gl_FragCoord.xy - fg_Viewport.xy) / fg_Viewport.zw) * 2.0 - 1.0;
// XXX: Sun's screen-space position. This should be passed as an uniform
vec4 sun_dir_screen = osg_ProjectionMatrix * vec4(fg_SunDirection, 0.0);
sun_dir_screen.xyz /= sun_dir_screen.w;
sun_dir_screen.xyz = normalize(sun_dir_screen.xyz);
// Direction from pixel to Sun in screen space
vec2 sun_dir = screen_uv - sun_dir_screen.xy;
// Flip the x axis
sun_dir.x = -sun_dir.x;
float dt = max_sample_dist / STEPS;
// 2D ray march along the Sun's direction to estimate the transmittance
float T = 1.0;
for (int i = 0; i < STEPS; ++i) {
float t = (float(i) + 0.5) * dt;
vec2 uv_t = texcoord - sun_dir * t;
vec4 texel = texture(base_tex, uv_t);
// Beer-Lambert's law
T *= exp(-texel.a * dt * density);
}
// When the camera is facing perpendicularly to the Sun, the Sun's
// screen-space location can tend toward infinity. Fade the effect toward
// the perpendicular.
float fade = smoothstep(0.1, 0.5, dot(vec3(0.0, 0.0, -1.0), fg_SunDirection));
vec4 color = base * cloud_color;
color.rgb *= base.a * mix(0.5, T, fade);
color.rgb = mix_aerial_perspective(color.rgb, ap_color);
// Pre-expose
// Only pre-expose when not rendering to the environment map.
// We want the non-exposed radiance values for IBL.
color.rgb = apply_exposure(color.rgb);
fragColor = color;

View file

@ -1,116 +1,19 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 2) in vec4 vertex_color;
layout(location = 3) in vec4 multitexcoord0;
layout(location = 10) in vec4 usrAttr1;
layout(location = 11) in vec4 usrAttr2;
out vec2 texcoord;
out vec4 cloud_color;
out vec4 ap_color;
uniform float range;
uniform float detail_range;
uniform mat4 osg_ModelViewMatrix;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ViewMatrixInverse;
uniform vec3 fg_SunDirectionWorld;
// 3dcloud_common.vert
void cloud_common_vert(out vec4 vs_pos, out vec4 ws_pos);
// aerial_perspective.glsl
vec4 get_aerial_perspective(vec2 coord, float depth);
vec3 get_sun_radiance(vec3 p);
void main()
{
float alpha_factor = usrAttr1.r;
float shade_factor = usrAttr1.g;
float cloud_height = usrAttr1.b;
float bottom_factor = usrAttr2.r;
float middle_factor = usrAttr2.g;
float top_factor = usrAttr2.b;
vec4 vs_pos, ws_pos;
cloud_common_vert(vs_pos, ws_pos);
texcoord = multitexcoord0.st;
// XXX: Should be sent as an uniform
mat4 inverseModelViewMatrix = inverse(osg_ModelViewMatrix);
vec4 ep = inverseModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);
vec4 l = inverseModelViewMatrix * vec4(0.0, 0.0, 1.0, 1.0);
vec3 u = normalize(ep.xyz - l.xyz);
// Find a rotation matrix that rotates 1,0,0 into u. u, r and w are
// the columns of that matrix.
vec3 absu = abs(u);
vec3 r = normalize(vec3(-u.y, u.x, 0.0));
vec3 w = cross(u, r);
// Do the matrix multiplication by [ u r w pos]. Assume no
// scaling in the homogeneous component of pos.
vec4 final_pos = vec4(0.0, 0.0, 0.0, 1.0);
final_pos.xyz = pos.x * u;
final_pos.xyz += pos.y * r;
final_pos.xyz += pos.z * w;
// Apply Z scaling to allow sprites to be squashed in the z-axis
final_pos.z = final_pos.z * vertex_color.w;
// Now shift the sprite to the correct position in the cloud.
final_pos.xyz += vertex_color.xyz;
// Determine the position - used for fog and shading calculations
float fogCoord = length(vec3(osg_ModelViewMatrix * vec4(vertex_color.xyz, 1.0)));
float center_dist = length(vec3(osg_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)));
if ((fogCoord > detail_range) && (fogCoord > center_dist) && (shade_factor < 0.7)) {
// More than detail_range away, so discard all sprites on opposite side of
// cloud center by shifting them beyond the view fustrum
gl_Position = vec4(0.0, 0.0, 10.0, 1.0);
cloud_color = vec4(0.0);
} else {
gl_Position = osg_ModelViewProjectionMatrix * final_pos;
vec4 final_view_pos = osg_ModelViewMatrix * final_pos;
vec4 final_world_pos = osg_ViewMatrixInverse * final_view_pos;
// Determine a lighting normal based on the vertex position from the
// center of the cloud, so that sprite on the opposite side of the cloud
// to the sun are darker.
vec3 n = normalize(vec3(osg_ViewMatrixInverse *
osg_ModelViewMatrix * vec4(-final_pos.xyz, 0.0)));
float NdotL = dot(-fg_SunDirectionWorld, n);
// Determine the shading of the vertex. We shade it based on it's position
// in the cloud relative to the sun, and it's vertical position in the cloud.
float shade = mix(shade_factor, top_factor, smoothstep(-0.3, 0.3, NdotL));
if (final_pos.z < 0.5 * cloud_height) {
shade = min(shade, mix(bottom_factor, middle_factor,
final_pos.z * 2.0 / cloud_height));
} else {
shade = min(shade, mix(middle_factor, top_factor,
final_pos.z * 2.0 / cloud_height - 1.0));
}
cloud_color.rgb = shade * get_sun_radiance(final_world_pos.xyz);
// Perspective division and scale to [0, 1] to get the screen position
// of the vertex.
vec2 coord = (gl_Position.xy / gl_Position.w) * 0.5 + 0.5;
ap_color = get_aerial_perspective(coord, length(final_view_pos));
if ((fogCoord > (0.9 * detail_range))
&& (fogCoord > center_dist)
&& (shade_factor < 0.7)) {
// cloudlet is almost at the detail range, so fade it out.
cloud_color.a = 1.0 - smoothstep(0.9 * detail_range, detail_range, fogCoord);
} else {
// As we get within 100m of the sprite, it is faded out.
// Equally at large distances it also fades out.
cloud_color.a = min(smoothstep(10.0, 100.0, fogCoord),
1.0 - smoothstep(0.9 * range, range, fogCoord));
}
cloud_color.a *= alpha_factor;
}
// Perspective division and scale to [0, 1] to get the screen position
// of the vertex.
vec2 coord = (gl_Position.xy / gl_Position.w) * 0.5 + 0.5;
ap_color = get_aerial_perspective(coord, length(vs_pos.xyz));
}

View file

@ -0,0 +1,65 @@
#version 330 core
in vec2 texcoord;
in vec4 cloud_color;
in vec4 ap_color;
uniform sampler2D base_tex;
uniform mat4 osg_ProjectionMatrix;
uniform vec4 fg_Viewport;
uniform vec3 fg_SunDirection;
uniform float density = 30.0;
uniform float max_sample_dist = 0.05;
const int STEPS = 8;
// aerial_perspective.glsl
vec3 mix_aerial_perspective(vec3 color, vec4 ap);
vec4 cloud_common_frag()
{
vec4 base = texture(base_tex, texcoord);
// Directly discard fragments below a threshold
if (base.a < 0.02)
discard;
// Pixel position in screen space [-1, 1]
vec2 screen_uv = ((gl_FragCoord.xy - fg_Viewport.xy) / fg_Viewport.zw) * 2.0 - 1.0;
// XXX: Sun's screen-space position. This should be passed as an uniform
vec4 sun_dir_screen = osg_ProjectionMatrix * vec4(fg_SunDirection, 0.0);
sun_dir_screen.xyz /= sun_dir_screen.w;
sun_dir_screen.xyz = normalize(sun_dir_screen.xyz);
// Direction from pixel to Sun in screen space
vec2 sun_dir = screen_uv - sun_dir_screen.xy;
// Flip the x axis
sun_dir.x = -sun_dir.x;
float dt = max_sample_dist / STEPS;
// 2D ray march along the Sun's direction to estimate the transmittance
float T = 1.0;
for (int i = 0; i < STEPS; ++i) {
float t = (float(i) + 0.5) * dt;
vec2 uv_t = texcoord - sun_dir * t;
vec4 texel = texture(base_tex, uv_t);
// Beer-Lambert's law
T *= exp(-texel.a * dt * density);
}
// When the camera is facing perpendicularly to the Sun, the Sun's
// screen-space location can tend toward infinity. Fade the effect toward
// the perpendicular.
float fade = smoothstep(0.1, 0.5, dot(vec3(0.0, 0.0, -1.0), fg_SunDirection));
vec4 color = base * cloud_color;
color.rgb *= base.a * mix(0.5, T, fade);
color.rgb = mix_aerial_perspective(color.rgb, ap_color);
return color;
}

View file

@ -0,0 +1,109 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 2) in vec4 vertex_color;
layout(location = 3) in vec4 multitexcoord0;
layout(location = 10) in vec4 usrAttr1;
layout(location = 11) in vec4 usrAttr2;
out vec2 texcoord;
out vec4 cloud_color;
uniform float range;
uniform float detail_range;
uniform mat4 osg_ModelViewMatrix;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ViewMatrixInverse;
uniform vec3 fg_SunDirectionWorld;
// sun.glsl
vec3 get_sun_radiance(vec3 p);
void cloud_common_vert(out vec4 vs_pos, out vec4 ws_pos)
{
float alpha_factor = usrAttr1.r;
float shade_factor = usrAttr1.g;
float cloud_height = usrAttr1.b;
float bottom_factor = usrAttr2.r;
float middle_factor = usrAttr2.g;
float top_factor = usrAttr2.b;
texcoord = multitexcoord0.st;
// XXX: Should be sent as an uniform
mat4 inverseModelViewMatrix = inverse(osg_ModelViewMatrix);
vec4 ep = inverseModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);
vec4 l = inverseModelViewMatrix * vec4(0.0, 0.0, 1.0, 1.0);
vec3 u = normalize(ep.xyz - l.xyz);
// Find a rotation matrix that rotates 1,0,0 into u. u, r and w are
// the columns of that matrix.
vec3 absu = abs(u);
vec3 r = normalize(vec3(-u.y, u.x, 0.0));
vec3 w = cross(u, r);
// Do the matrix multiplication by [ u r w pos]. Assume no
// scaling in the homogeneous component of pos.
vec4 final_pos = vec4(0.0, 0.0, 0.0, 1.0);
final_pos.xyz = pos.x * u;
final_pos.xyz += pos.y * r;
final_pos.xyz += pos.z * w;
// Apply Z scaling to allow sprites to be squashed in the z-axis
final_pos.z = final_pos.z * vertex_color.w;
// Now shift the sprite to the correct position in the cloud.
final_pos.xyz += vertex_color.xyz;
// Determine the position - used for fog and shading calculations
float fogCoord = length(vec3(osg_ModelViewMatrix * vec4(vertex_color.xyz, 1.0)));
float center_dist = length(vec3(osg_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)));
if ((fogCoord > detail_range) && (fogCoord > center_dist) && (shade_factor < 0.7)) {
// More than detail_range away, so discard all sprites on opposite side of
// cloud center by shifting them beyond the view fustrum
gl_Position = vec4(0.0, 0.0, 10.0, 1.0);
cloud_color = vec4(0.0);
} else {
gl_Position = osg_ModelViewProjectionMatrix * final_pos;
vs_pos = osg_ModelViewMatrix * final_pos;
ws_pos = osg_ViewMatrixInverse * vs_pos;
// Determine a lighting normal based on the vertex position from the
// center of the cloud, so that sprite on the opposite side of the cloud
// to the sun are darker.
vec3 n = normalize(vec3(osg_ViewMatrixInverse *
osg_ModelViewMatrix * vec4(-final_pos.xyz, 0.0)));
float NdotL = dot(-fg_SunDirectionWorld, n);
// Determine the shading of the vertex. We shade it based on it's position
// in the cloud relative to the sun, and it's vertical position in the cloud.
float shade = mix(shade_factor, top_factor, smoothstep(-0.3, 0.3, NdotL));
if (final_pos.z < 0.5 * cloud_height) {
shade = min(shade, mix(bottom_factor, middle_factor,
final_pos.z * 2.0 / cloud_height));
} else {
shade = min(shade, mix(middle_factor, top_factor,
final_pos.z * 2.0 / cloud_height - 1.0));
}
cloud_color.rgb = shade * get_sun_radiance(ws_pos.xyz);
if ((fogCoord > (0.9 * detail_range))
&& (fogCoord > center_dist)
&& (shade_factor < 0.7)) {
// cloudlet is almost at the detail range, so fade it out.
cloud_color.a = 1.0 - smoothstep(0.9 * detail_range, detail_range, fogCoord);
} else {
// As we get within 100m of the sprite, it is faded out.
// Equally at large distances it also fades out.
cloud_color.a = min(smoothstep(10.0, 100.0, fogCoord),
1.0 - smoothstep(0.9 * range, range, fogCoord));
}
cloud_color.a *= alpha_factor;
}
}

View file

@ -0,0 +1,12 @@
#version 330 core
layout(location = 0) out vec4 fragColor;
// 3dcloud_common.frag
vec4 cloud_common_frag();
void main()
{
vec4 color = cloud_common_frag();
fragColor = color;
}

View file

@ -0,0 +1,16 @@
#version 330 core
out vec4 ap_color;
// 3dcloud_common.vert
void cloud_common_vert(out vec4 vs_pos, out vec4 ws_pos);
// aerial_perspective_envmap.glsl
vec4 get_aerial_perspective(vec3 pos);
void main()
{
vec4 vs_pos, ws_pos;
cloud_common_vert(vs_pos, ws_pos);
ap_color = get_aerial_perspective(ws_pos.xyz);
}

View file

@ -1,12 +1,6 @@
#version 330 core
uniform sampler2D aerial_perspective_tex;
uniform sampler2D transmittance_tex;
uniform vec3 fg_SunDirectionWorld;
uniform float fg_CameraDistanceToEarthCenter;
uniform float fg_SunZenithCosTheta;
uniform float fg_EarthRadius;
const float AP_SLICE_COUNT = 32.0;
const float AP_MAX_DEPTH = 128000.0;
@ -14,12 +8,6 @@ const float AP_SLICE_WIDTH_PIXELS = 32.0;
const float AP_SLICE_SIZE = 1.0 / AP_SLICE_COUNT;
const float AP_TEXEL_WIDTH = 1.0 / (AP_SLICE_COUNT * AP_SLICE_WIDTH_PIXELS);
const float ATMOSPHERE_RADIUS = 6471e3;
// atmos_spectral.glsl
vec4 get_sun_spectral_irradiance();
vec3 linear_srgb_from_spectral_samples(vec4 L);
vec4 sample_aerial_perspective_slice(sampler2D lut, vec2 coord, float slice)
{
// Sample at the pixel center
@ -62,33 +50,3 @@ vec3 add_aerial_perspective(vec3 color, vec2 coord, float depth)
{
return mix_aerial_perspective(color, get_aerial_perspective(coord, depth));
}
/*
* Get the Sun radiance at a point 'p' in world space.
* We cannot use the Sun extraterrestial irradiance directly because it will be
* attenuated by the transmittance of the atmospheric medium.
*/
vec3 get_sun_radiance(vec3 p)
{
float distance_to_earth_center = length(p);
float normalized_altitude = (distance_to_earth_center - fg_EarthRadius)
/ (ATMOSPHERE_RADIUS - fg_EarthRadius);
vec3 zenith_dir = p / distance_to_earth_center;
float sun_cos_theta = dot(zenith_dir, fg_SunDirectionWorld);
float u = sun_cos_theta * 0.5 + 0.5;
float v = clamp(normalized_altitude, 0.0, 1.0);
vec4 transmittance = texture(transmittance_tex, vec2(u, v));
vec4 L = get_sun_spectral_irradiance() * transmittance;
return linear_srgb_from_spectral_samples(L);
}
vec3 get_sun_radiance_sea_level()
{
vec2 uv = vec2(fg_SunZenithCosTheta * 0.5 + 0.5, 0.0);
vec4 transmittance = texture(transmittance_tex, uv);
vec4 L = get_sun_spectral_irradiance() * transmittance;
return linear_srgb_from_spectral_samples(L);
}

View file

@ -0,0 +1,60 @@
#version 330 core
uniform sampler2D transmittance_tex;
uniform vec3 fg_CameraPositionCart;
uniform vec3 fg_SunDirectionWorld;
const int AERIAL_PERSPECTIVE_ENVMAP_STEPS = 4;
// atmos.glsl
float get_earth_radius();
float get_ray_end(vec3 ray_origin, vec3 ray_dir, float t_max);
vec4 compute_inscattering(in vec3 ray_origin,
in vec3 ray_dir,
in float t_max,
in vec3 sun_dir,
in int steps,
in sampler2D transmittance_lut,
out vec4 transmittance);
// atmos_spectral.glsl
vec4 get_sun_spectral_irradiance();
vec3 linear_srgb_from_spectral_samples(vec4 L);
vec4 get_aerial_perspective(vec3 pos)
{
vec3 ray_origin = fg_CameraPositionCart;
vec3 ray_end = pos;
// Make sure both ray ends are above the ground.
// We also apply a small bias to the ray end to prevent both points from
// being at the exact same place due to floating point precision.
float radius = get_earth_radius();
ray_origin += max(0.0, radius - length(ray_origin));
ray_end += max(0.0, radius - length(ray_end)) + 1.0;
vec3 ray_dir = ray_end - ray_origin;
float t_d = length(ray_dir);
ray_dir /= t_d;
float t_max = get_ray_end(ray_origin, ray_dir, t_d);
vec4 transmittance;
vec4 L = compute_inscattering(ray_origin,
ray_dir,
t_max,
fg_SunDirectionWorld,
AERIAL_PERSPECTIVE_ENVMAP_STEPS,
transmittance_tex,
transmittance);
vec4 ap;
ap.rgb = linear_srgb_from_spectral_samples(L * get_sun_spectral_irradiance());
ap.a = dot(transmittance, vec4(0.25));
return ap;
}
vec3 mix_aerial_perspective(vec3 color, vec4 ap)
{
return color * ap.a + ap.rgb;
}

View file

@ -203,8 +203,8 @@ void get_atmosphere_collision_coefficients(in float h,
out vec4 molecular_scattering,
out vec4 extinction)
{
h = max(h, 1e-3); // In case height is negative
h *= 1e-3; // To km
h = max(h, 0.0); // In case height is negative
// Molecules
molecular_absorption = get_molecular_absorption_coefficient(h);

View file

@ -1,74 +1,19 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 2) in vec4 vertex_color;
layout(location = 3) in vec4 multitexcoord0;
out vec2 texcoord;
out vec4 cloud_color;
out vec4 ap_color;
uniform mat4 osg_ModelViewMatrix;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ViewMatrixInverse;
uniform vec3 fg_SunDirectionWorld;
const float shade = 0.8;
const float cloud_height = 1000.0;
// cloud_static_common.vert
void cloud_static_common_vert(out vec4 vs_pos, out vec4 ws_pos);
// aerial_perspective.glsl
vec4 get_aerial_perspective(vec2 coord, float depth);
vec3 get_sun_radiance(vec3 p);
void main()
{
texcoord = multitexcoord0.st;
// XXX: Should be sent as an uniform
mat4 inverseModelViewMatrix = inverse(osg_ModelViewMatrix);
vec4 ep = inverseModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);
vec4 l = inverseModelViewMatrix * vec4(0.0, 0.0, 1.0, 1.0);
vec3 u = normalize(ep.xyz - l.xyz);
vec4 final_pos = vec4(0.0, 0.0, 0.0, 1.0);
final_pos.x = pos.x;
final_pos.y = pos.y;
final_pos.z = pos.z;
final_pos.xyz += vertex_color.xyz;
gl_Position = osg_ModelViewProjectionMatrix * final_pos;
// Determine a lighting normal based on the vertex position from the
// center of the cloud, so that sprite on the opposite side of the cloud
// to the sun are darker.
vec3 n = normalize(vec3(osg_ViewMatrixInverse *
osg_ModelViewMatrix * vec4(-final_pos.xyz, 0.0)));
float NdotL = dot(-fg_SunDirectionWorld, n);
vec4 final_view_pos = osg_ModelViewMatrix * final_pos;
vec4 final_world_pos = osg_ViewMatrixInverse * final_view_pos;
float fogCoord = abs(final_view_pos.z);
float fract = smoothstep(0.0, cloud_height, final_pos.z + cloud_height);
vec3 sun_radiance = get_sun_radiance(final_world_pos.xyz);
// Determine the shading of the sprite based on its vertical position and
// position relative to the sun.
NdotL = min(smoothstep(-0.5, 0.0, NdotL), fract);
// Determine the shading based on a mixture from the backlight to the front
vec3 backlight = shade * sun_radiance;
cloud_color.rgb = mix(backlight, sun_radiance, NdotL);
vec4 vs_pos, ws_pos;
cloud_static_common_vert(vs_pos, ws_pos);
// Perspective division and scale to [0, 1] to get the screen position
// of the vertex.
vec2 coord = (gl_Position.xy / gl_Position.w) * 0.5 + 0.5;
ap_color = get_aerial_perspective(coord, length(final_view_pos));
// As we get within 100m of the sprite, it is faded out. Equally at large
// distances it also fades out.
cloud_color.a = min(smoothstep(100.0, 250.0, fogCoord),
1.0 - smoothstep(70000.0, 75000.0, fogCoord));
ap_color = get_aerial_perspective(coord, length(vs_pos));
}

View file

@ -0,0 +1,67 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 2) in vec4 vertex_color;
layout(location = 3) in vec4 multitexcoord0;
out vec2 texcoord;
out vec4 cloud_color;
uniform mat4 osg_ModelViewMatrix;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ViewMatrixInverse;
uniform vec3 fg_SunDirectionWorld;
const float shade = 0.8;
const float cloud_height = 1000.0;
// sun.glsl
vec3 get_sun_radiance(vec3 p);
void cloud_static_common_vert(out vec4 vs_pos, out vec4 ws_pos)
{
texcoord = multitexcoord0.st;
// XXX: Should be sent as an uniform
mat4 inverseModelViewMatrix = inverse(osg_ModelViewMatrix);
vec4 ep = inverseModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);
vec4 l = inverseModelViewMatrix * vec4(0.0, 0.0, 1.0, 1.0);
vec3 u = normalize(ep.xyz - l.xyz);
vec4 final_pos = vec4(0.0, 0.0, 0.0, 1.0);
final_pos.x = pos.x;
final_pos.y = pos.y;
final_pos.z = pos.z;
final_pos.xyz += vertex_color.xyz;
gl_Position = osg_ModelViewProjectionMatrix * final_pos;
// Determine a lighting normal based on the vertex position from the
// center of the cloud, so that sprite on the opposite side of the cloud
// to the sun are darker.
vec3 n = normalize(vec3(osg_ViewMatrixInverse *
osg_ModelViewMatrix * vec4(-final_pos.xyz, 0.0)));
float NdotL = dot(-fg_SunDirectionWorld, n);
vs_pos = osg_ModelViewMatrix * final_pos;
ws_pos = osg_ViewMatrixInverse * vs_pos;
float fogCoord = abs(vs_pos.z);
float fract = smoothstep(0.0, cloud_height, final_pos.z + cloud_height);
vec3 sun_radiance = get_sun_radiance(ws_pos.xyz);
// Determine the shading of the sprite based on its vertical position and
// position relative to the sun.
NdotL = min(smoothstep(-0.5, 0.0, NdotL), fract);
// Determine the shading based on a mixture from the backlight to the front
vec3 backlight = shade * sun_radiance;
cloud_color.rgb = mix(backlight, sun_radiance, NdotL);
// As we get within 100m of the sprite, it is faded out. Equally at large
// distances it also fades out.
cloud_color.a = min(smoothstep(100.0, 250.0, fogCoord),
1.0 - smoothstep(70000.0, 75000.0, fogCoord));
}

View file

@ -0,0 +1,16 @@
#version 330 core
out vec4 ap_color;
// cloud_static_common.vert
void cloud_static_common_vert(out vec4 vs_pos, out vec4 ws_pos);
// aerial_perspective_envmap.glsl
vec4 get_aerial_perspective(vec3 pos);
void main()
{
vec4 vs_pos, ws_pos;
cloud_static_common_vert(vs_pos, ws_pos);
ap_color = get_aerial_perspective(ws_pos.xyz);
}

44
Shaders/HDR/sun.glsl Normal file
View file

@ -0,0 +1,44 @@
#version 330 core
uniform sampler2D transmittance_tex;
uniform float fg_EarthRadius;
uniform vec3 fg_SunDirectionWorld;
uniform float fg_CameraDistanceToEarthCenter;
uniform float fg_SunZenithCosTheta;
const float ATMOSPHERE_RADIUS = 6471e3;
// atmos_spectral.glsl
vec4 get_sun_spectral_irradiance();
vec3 linear_srgb_from_spectral_samples(vec4 L);
/*
* Get the Sun radiance at a point 'p' in world space.
* We cannot use the Sun extraterrestial irradiance directly because it will be
* attenuated by the transmittance of the atmospheric medium.
*/
vec3 get_sun_radiance(vec3 p)
{
float distance_to_earth_center = length(p);
float normalized_altitude = (distance_to_earth_center - fg_EarthRadius)
/ (ATMOSPHERE_RADIUS - fg_EarthRadius);
vec3 zenith_dir = p / distance_to_earth_center;
float sun_cos_theta = dot(zenith_dir, fg_SunDirectionWorld);
float u = sun_cos_theta * 0.5 + 0.5;
float v = clamp(normalized_altitude, 0.0, 1.0);
vec4 transmittance = texture(transmittance_tex, vec2(u, v));
vec4 L = get_sun_spectral_irradiance() * transmittance;
return linear_srgb_from_spectral_samples(L);
}
vec3 get_sun_radiance_sea_level()
{
vec2 uv = vec2(fg_SunZenithCosTheta * 0.5 + 0.5, 0.0);
vec4 transmittance = texture(transmittance_tex, uv);
vec4 L = get_sun_spectral_irradiance() * transmittance;
return linear_srgb_from_spectral_samples(L);
}

View file

@ -0,0 +1,52 @@
#version 330 core
layout(location = 0) out vec4 fragColor;
in VS_OUT {
vec2 texcoord;
vec2 orthophoto_texcoord;
vec3 vertex_normal;
vec3 world_vector;
} fs_in;
uniform sampler2D color_tex;
uniform sampler2D orthophoto_tex;
uniform bool orthophotoAvailable;
uniform vec3 fg_SunDirectionWorld;
uniform vec4 fg_Viewport;
// math.glsl
float M_1_PI();
// color.glsl
vec3 eotf_inverse_sRGB(vec3 srgb);
// sun.glsl
vec3 get_sun_radiance_sea_level();
// aerial_perspective_envmap.glsl
vec4 get_aerial_perspective(vec3 pos);
vec3 mix_aerial_perspective(vec3 color, vec4 ap);
void main()
{
vec3 texel = texture(color_tex, fs_in.texcoord).rgb;
if (orthophotoAvailable) {
vec4 sat_texel = texture(orthophoto_tex, fs_in.orthophoto_texcoord);
if (sat_texel.a > 0.0) {
texel.rgb = sat_texel.rgb;
}
}
vec3 color = eotf_inverse_sRGB(texel);
vec3 sun_radiance = get_sun_radiance_sea_level();
vec3 N = normalize(fs_in.vertex_normal);
float NdotL = max(dot(N, fg_SunDirectionWorld), 1e-4);
// Assume a perfectly diffuse Lambertian surface
color = M_1_PI() * color * sun_radiance * NdotL;
vec4 ap = get_aerial_perspective(fs_in.world_vector);
color = mix_aerial_perspective(color, ap);
fragColor = vec4(color, 1.0);
}

View file

@ -0,0 +1,28 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 1) in vec3 normal;
layout(location = 3) in vec4 multitexcoord0;
layout(location = 5) in vec4 multitexcoord2;
out VS_OUT {
vec2 texcoord;
vec2 orthophoto_texcoord;
vec3 vertex_normal;
vec3 world_vector;
} vs_out;
uniform mat4 osg_ModelViewMatrix;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat3 osg_NormalMatrix;
uniform mat4 osg_ViewMatrixInverse;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
vs_out.texcoord = multitexcoord0.st;
vs_out.orthophoto_texcoord = multitexcoord2.st;
vs_out.vertex_normal = (osg_ViewMatrixInverse
* vec4(osg_NormalMatrix * normal, 0.0)).xyz;
vs_out.world_vector = (osg_ViewMatrixInverse * osg_ModelViewMatrix * pos).xyz;
}

View file

@ -535,6 +535,17 @@ Started September 2000 by David Megginson, david@megginson.com
<hdr>
<antialiasing-technique type="int" userarchive="y">2</antialiasing-technique>
<exposure-compensation type="float">0.0</exposure-compensation>
<envmap>
<force-update type="bool">false</force-update>
<update-rate-s type="float">90.0</update-rate-s>
<should-prefilter type="bool">false</should-prefilter>
<should-render-face-0 type="bool">false</should-render-face-0>
<should-render-face-1 type="bool">false</should-render-face-1>
<should-render-face-2 type="bool">false</should-render-face-2>
<should-render-face-3 type="bool">false</should-render-face-3>
<should-render-face-4 type="bool">false</should-render-face-4>
<should-render-face-5 type="bool">false</should-render-face-5>
</envmap>
<bloom>
<strength type="float">0.01</strength>
<filter-radius type="float">0.005</filter-radius>