HDR: Improve stars rendering
Previously we did not take into account the atmospheric transmittance to render the stars, leading to stars being incorrectly rendered in low visibility conditions. Also place the stars in the correct render bin.
This commit is contained in:
parent
00b4275ee8
commit
7b0211031a
3 changed files with 69 additions and 4 deletions
|
@ -4,7 +4,7 @@
|
|||
<name>Effects/stars</name>
|
||||
|
||||
<parameters>
|
||||
<max-radiance type="float">2.0</max-radiance>
|
||||
<max-radiance type="float">50.0</max-radiance>
|
||||
</parameters>
|
||||
|
||||
<!-- Fixed-pipeline fallback -->
|
||||
|
@ -20,6 +20,7 @@
|
|||
<technique n="129">
|
||||
<scheme>hdr-forward</scheme>
|
||||
<pass>
|
||||
<!-- Disable depth testing -->
|
||||
<depth>
|
||||
<enabled>false</enabled>
|
||||
</depth>
|
||||
|
@ -28,21 +29,44 @@
|
|||
<function>equal</function>
|
||||
<value>0</value>
|
||||
</stencil>
|
||||
<!-- Make sure we render after the skydome -->
|
||||
<render-bin>
|
||||
<bin-number>-9</bin-number>
|
||||
<bin-name>RenderBin</bin-name>
|
||||
</render-bin>
|
||||
<cull-face>off</cull-face>
|
||||
<!-- Additive blending to add the sky in-scattering from the skydome -->
|
||||
<blend>
|
||||
<active>true</active>
|
||||
<source>src-alpha</source>
|
||||
<destination>one-minus-src-alpha</destination>
|
||||
<source>one</source>
|
||||
<destination>one</destination>
|
||||
</blend>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/stars.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/stars.frag</fragment-shader>
|
||||
<fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>max_radiance</name>
|
||||
<type>float</type>
|
||||
<value><use>max-radiance</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>transmittance_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">12</value>
|
||||
</uniform>
|
||||
<!-- exposure.glsl -->
|
||||
<uniform>
|
||||
<name>lum_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">14</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>exposure_compensation</name>
|
||||
<type>float</type>
|
||||
<value><use>exposure-compensation</use></value>
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
||||
|
|
|
@ -4,11 +4,49 @@ layout(location = 0) out vec4 fragColor;
|
|||
|
||||
in VS_OUT {
|
||||
vec4 color;
|
||||
vec3 view_vector;
|
||||
} fs_in;
|
||||
|
||||
uniform sampler2D transmittance_tex;
|
||||
|
||||
uniform float max_radiance;
|
||||
|
||||
uniform float fg_CameraDistanceToEarthCenter;
|
||||
uniform float fg_EarthRadius;
|
||||
uniform vec3 fg_CameraViewUp;
|
||||
|
||||
const float ATMOSPHERE_RADIUS = 6471e3;
|
||||
|
||||
// exposure.glsl
|
||||
vec3 apply_exposure(vec3 color);
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(fs_in.color.rgb * max_radiance, fs_in.color.a);
|
||||
vec3 color = fs_in.color.rgb * fs_in.color.a * max_radiance;
|
||||
|
||||
vec3 V = normalize(fs_in.view_vector);
|
||||
|
||||
// Apply aerial perspective
|
||||
float normalized_altitude =
|
||||
(fg_CameraDistanceToEarthCenter - fg_EarthRadius)
|
||||
/ (ATMOSPHERE_RADIUS - fg_EarthRadius);
|
||||
float cos_theta = dot(-V, fg_CameraViewUp);
|
||||
|
||||
vec2 uv = vec2(cos_theta * 0.5 + 0.5, clamp(normalized_altitude, 0.0, 1.0));
|
||||
vec4 transmittance = texture(transmittance_tex, uv);
|
||||
|
||||
// The proper thing would be to have spectral data for the stars' radiance.
|
||||
// This could be approximated by taking the star's temperature and using
|
||||
// Plank's law to obtain the spectral radiance for our 4 wavelengths.
|
||||
// That's too complicated for now, so instead we just average the four
|
||||
// spectral samples from the atmospheric transmittance.
|
||||
color *= dot(transmittance, vec4(0.25));
|
||||
|
||||
// Pre-expose
|
||||
color = apply_exposure(color);
|
||||
|
||||
// Final color = transmittance * star radiance + sky inscattering
|
||||
// In this frag shader we output the multiplication part, and the sky
|
||||
// in-scattering is added by doing additive blending on top of the skydome.
|
||||
fragColor = vec4(color, 1.0);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,15 @@ layout(location = 2) in vec4 vertex_color;
|
|||
|
||||
out VS_OUT {
|
||||
vec4 color;
|
||||
vec3 view_vector;
|
||||
} vs_out;
|
||||
|
||||
uniform mat4 osg_ModelViewMatrix;
|
||||
uniform mat4 osg_ModelViewProjectionMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = osg_ModelViewProjectionMatrix * pos;
|
||||
vs_out.color = vertex_color;
|
||||
vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue