1
0
Fork 0

Initial commit of the HDR pipeline

This commit is contained in:
Fernando García Liñán 2021-04-10 11:14:16 +02:00
parent 1732f1339f
commit 96313e7eb0
73 changed files with 3183 additions and 3 deletions

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<type>2d</type>
<width>screen</width>
<height>screen</height>
<format>rgb16f</format>
<min-filter>linear</min-filter>
<mag-filter>linear</mag-filter>
</PropertyList>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<type>quad</type>
<effect>Effects/HDR/trivial</effect>
</PropertyList>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<type>quad</type>
<effect>Effects/HDR/horizontal-blur</effect>
</PropertyList>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<type>quad</type>
<effect>Effects/HDR/vertical-blur</effect>
</PropertyList>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<type>csm</type>
<effect-scheme>hdr-shadow</effect-scheme>
<!-- Only render objects with the CAST_SHADOW bit flag -->
<cull-mask>0x000004</cull-mask>
<render-at-night>false</render-at-night>
<attachment>
<buffer>sun-shadowmap-atlas</buffer>
<component>depth</component>
</attachment>
</PropertyList>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<type>scene</type>
<implicit-attachment-mask>depth</implicit-attachment-mask>
<effect-scheme>hdr-envmap</effect-scheme>
<!-- Only render the skydome and terrain -->
<!-- TODO: Explicitly select the LOD level -->
<cull-mask>0x801</cull-mask>
</PropertyList>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<type>quad</type>
<binding>
<unit>0</unit>
<buffer>envmap</buffer>
</binding>
</PropertyList>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList include="env-prefilter-pass.xml">
<effect>Effects/HDR/envmap-prefilter1</effect>
</PropertyList>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList include="env-prefilter-pass.xml">
<effect>Effects/HDR/envmap-prefilter2</effect>
</PropertyList>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList include="env-prefilter-pass.xml">
<effect>Effects/HDR/envmap-prefilter3</effect>
</PropertyList>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList include="env-prefilter-pass.xml">
<effect>Effects/HDR/envmap-prefilter4</effect>
</PropertyList>

1024
Compositor/HDR/hdr.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/Fallback/hdr-geometry</name>
<technique n="110">
<scheme>hdr-geometry</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>
<cull-face>back</cull-face>
<program>
<vertex-shader>Shaders/HDR/geometry.vert</vertex-shader>
<fragment-shader>Shaders/HDR/geometry.frag</fragment-shader>
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
</program>
<uniform>
<name>color_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/Fallback/hdr-shadow</name>
<technique n="120">
<scheme>hdr-shadow</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>
<color-mask type="vec4d">0 0 0 0</color-mask>
<cull-face>back</cull-face>
<blend>
<active>false</active>
</blend>
<program>
<vertex-shader>Shaders/HDR/geometry-shadow.vert</vertex-shader>
<fragment-shader>Shaders/HDR/geometry-shadow.frag</fragment-shader>
</program>
<uniform>
<name>color_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/adapt-luminance</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/adapt-luminance.vert</vertex-shader>
<fragment-shader>Shaders/HDR/adapt-luminance.frag</fragment-shader>
</program>
<uniform>
<name>prev_lum_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>current_lum_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
</pass>
</technique>
</PropertyList>

23
Effects/HDR/ao.eff Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/ao</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/ao.frag</fragment-shader>
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
</program>
<uniform>
<name>depth_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>normal_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/atmosphere</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/atmosphere.frag</fragment-shader>
<fragment-shader>Shaders/HDR/atmosphere-include.frag</fragment-shader>
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
</program>
<uniform>
<name>hdr_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>depth_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/bloom-threshold</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/bloom-threshold.frag</fragment-shader>
</program>
<uniform>
<name>hdr_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>lum_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
</pass>
</technique>
</PropertyList>

30
Effects/HDR/blur.eff Normal file
View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/blur</name>
<parameters>
<is-vertical>false</is-vertical>
</parameters>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/blur.frag</fragment-shader>
</program>
<uniform>
<name>tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>prev_pass_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>vertical</name>
<type>bool</type>
<value type="bool"><use>is-vertical</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/copy-prev-luminance</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/adapt-luminance.vert</vertex-shader>
<fragment-shader>Shaders/HDR/copy-prev-luminance.frag</fragment-shader>
</program>
<uniform>
<name>lum_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

17
Effects/HDR/display.eff Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/display</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/display.vert</vertex-shader>
<fragment-shader>Shaders/HDR/display.frag</fragment-shader>
</program>
<uniform>
<name>tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/envmap-prefilter</name>
<parameters>
<roughness type="float">0.0</roughness>
</parameters>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial-cubemap.vert</vertex-shader>
<fragment-shader>Shaders/HDR/envmap-prefilter.frag</fragment-shader>
</program>
<uniform>
<name>envmap</name>
<type>sampler-cube</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>roughness</name>
<type>float</type>
<value><use>roughness</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/envmap-prefilter1</name>
<inherits-from>Effects/HDR/envmap-prefilter</inherits-from>
<parameters>
<roughness type="float">0.25</roughness>
</parameters>
</PropertyList>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/envmap-prefilter2</name>
<inherits-from>Effects/HDR/envmap-prefilter</inherits-from>
<parameters>
<roughness type="float">0.5</roughness>
</parameters>
</PropertyList>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/envmap-prefilter3</name>
<inherits-from>Effects/HDR/envmap-prefilter</inherits-from>
<parameters>
<roughness type="float">0.75</roughness>
</parameters>
</PropertyList>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/envmap-prefilter4</name>
<inherits-from>Effects/HDR/envmap-prefilter</inherits-from>
<parameters>
<roughness type="float">1.0</roughness>
</parameters>
</PropertyList>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/horizontal-blur</name>
<inherits-from>Effects/HDR/blur</inherits-from>
<parameters>
<is-vertical>false</is-vertical>
</parameters>
</PropertyList>

72
Effects/HDR/lighting.eff Normal file
View file

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/lighting</name>
<parameters>
<texture n="7">
<image>Textures/PBR/dfg_lut.png</image>
<type>2d</type>
<filter>linear</filter>
<wrap-s>clamp-to-border</wrap-s>
<wrap-t>clamp-to-border</wrap-t>
<internal-format>normalized</internal-format>
</texture>
</parameters>
<technique n="1">
<pass>
<texture-unit>
<unit>7</unit>
<image><use>texture[7]/image</use></image>
<type><use>texture[7]/type</use></type>
<filter><use>texture[7]/filter</use></filter>
<wrap-s><use>texture[7]/wrap-s</use></wrap-s>
<wrap-t><use>texture[7]/wrap-t</use></wrap-t>
<internal-format><use>texture[7]/internal-format</use></internal-format>
</texture-unit>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/lighting.frag</fragment-shader>
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
</program>
<uniform>
<name>gbuffer0_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>gbuffer1_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>gbuffer2_tex</name>
<type>sampler-2d</type>
<value type="int">2</value>
</uniform>
<uniform>
<name>depth_tex</name>
<type>sampler-2d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>dfg_lut</name>
<type>sampler-2d</type>
<value type="int">7</value>
</uniform>
<uniform>
<name>ao_tex</name>
<type>sampler-2d</type>
<value type="int">8</value>
</uniform>
<uniform>
<name>prefiltered_envmap</name>
<type>sampler-cube</type>
<value type="int">9</value>
</uniform>
<uniform>
<name>shadow_tex</name>
<type>sampler-2d-shadow</type>
<value type="int">10</value>
</uniform>
</pass>
</technique>
</PropertyList>

17
Effects/HDR/luminance.eff Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/luminance</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/luminance.frag</fragment-shader>
</program>
<uniform>
<name>hdr_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/postprocess</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/postprocess.frag</fragment-shader>
</program>
<uniform>
<name>hdr_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>lum_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>bloom_tex</name>
<type>sampler-2d</type>
<value type="int">4</value>
</uniform>
</pass>
</technique>
</PropertyList>

17
Effects/HDR/trivial.eff Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/trivial</name>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
<fragment-shader>Shaders/HDR/trivial.frag</fragment-shader>
</program>
<uniform>
<name>tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/HDR/vertical-blur</name>
<inherits-from>Effects/HDR/blur</inherits-from>
<parameters>
<is-vertical>true</is-vertical>
</parameters>
</PropertyList>

View file

@ -514,7 +514,15 @@
</pass>
</technique>
<!-- Don't use the usual scheme because model-combined requires technique
number 7. We need to place this technique before it. -->
<technique n="1">
<scheme>hdr-geometry</scheme>
</technique>
<!-- TODO: Actually implement a glass shader instead of just hiding it -->
<technique n="2">
<scheme>hdr-forward</scheme>
</technique>
</PropertyList>

View file

@ -6,4 +6,11 @@ and fallback to plain transparency when the model shader is disabled.
<PropertyList>
<name>Effects/model-combined-transparent</name>
<inherits-from>Effects/model-combined</inherits-from>
<technique n="1">
<scheme>hdr-geometry</scheme>
</technique>
<technique n="2">
<scheme>hdr-forward</scheme>
</technique>
</PropertyList>

View file

@ -1295,9 +1295,43 @@ please see Docs/README.model-combined.eff for documentation
</technique>
<technique n="7">
<predicate><value type="bool">false</value></predicate>
<scheme>hdr-geometry</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>
<texture-unit>
<unit>1</unit>
<type><use>texture[2]/type</use></type>
<image><use>texture[2]/image</use></image>
<filter><use>texture[2]/filter</use></filter>
<wrap-s><use>texture[2]/wrap-s</use></wrap-s>
<wrap-t><use>texture[2]/wrap-t</use></wrap-t>
</texture-unit>
<cull-face>back</cull-face>
<program>
<vertex-shader>Shaders/HDR/geometry-combined.vert</vertex-shader>
<fragment-shader>Shaders/HDR/geometry-combined.frag</fragment-shader>
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
</program>
<uniform>
<name>color_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>normal_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
</pass>
</technique>
<technique n="9">
<predicate><value type="bool">false</value></predicate>
</technique>

View file

@ -650,4 +650,34 @@
-->
</pass>
</technique>
<technique n="109">
<scheme>hdr-geometry</scheme>
<pass>
<cull-face><use>cull-face</use></cull-face>
<rendering-hint>opaque</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>
<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/HDR/geometry.vert</vertex-shader>
<fragment-shader>Shaders/HDR/geometry.frag</fragment-shader>
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
</program>
<uniform>
<name>color_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

137
Effects/model-pbr.eff Normal file
View file

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/model-pbr</name>
<parameters>
<!-- Albedo -->
<texture n="0">
<type>white</type>
</texture>
<!-- Normalmap -->
<texture n="1">
<image>Aircraft/Generic/Effects/null_bumpspec.png</image>
<type>2d</type>
<filter>linear-mipmap-linear</filter>
<wrap-s>clamp</wrap-s>
<wrap-t>clamp</wrap-t>
<internal-format>normalized</internal-format>
</texture>
<!-- Metalness -->
<texture n="2">
<image>Aircraft/Generic/Effects/ReflectMaps/null_reflectdirt.png</image>
<type>2d</type>
<filter>linear-mipmap-linear</filter>
<wrap-s>clamp</wrap-s>
<wrap-t>clamp</wrap-t>
<internal-format>normalized</internal-format>
</texture>
<!-- Roughness -->
<texture n="3">
<image>Aircraft/Generic/Effects/greymap.png</image>
<type>2d</type>
<filter>linear-mipmap-linear</filter>
<wrap-s>clamp</wrap-s>
<wrap-t>clamp</wrap-t>
<internal-format>normalized</internal-format>
</texture>
<!-- Cavity -->
<texture n="4">
<type>white</type>
</texture>
</parameters>
<generate>
<tangent type="int">6</tangent>
<binormal type="int">7</binormal>
</generate>
<technique n="20">
<scheme>hdr-geometry</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>
<internal-format><use>texture[0]/internal-format</use></internal-format>
</texture-unit>
<texture-unit>
<unit>1</unit>
<type><use>texture[1]/type</use></type>
<image><use>texture[1]/image</use></image>
<filter><use>texture[1]/filter</use></filter>
<wrap-s><use>texture[1]/wrap-s</use></wrap-s>
<wrap-t><use>texture[1]/wrap-t</use></wrap-t>
<internal-format><use>texture[1]/internal-format</use></internal-format>
</texture-unit>
<texture-unit>
<unit>2</unit>
<type><use>texture[2]/type</use></type>
<image><use>texture[2]/image</use></image>
<filter><use>texture[2]/filter</use></filter>
<wrap-s><use>texture[2]/wrap-s</use></wrap-s>
<wrap-t><use>texture[2]/wrap-t</use></wrap-t>
<internal-format><use>texture[2]/internal-format</use></internal-format>
</texture-unit>
<texture-unit>
<unit>3</unit>
<type><use>texture[3]/type</use></type>
<image><use>texture[3]/image</use></image>
<filter><use>texture[3]/filter</use></filter>
<wrap-s><use>texture[3]/wrap-s</use></wrap-s>
<wrap-t><use>texture[3]/wrap-t</use></wrap-t>
<internal-format><use>texture[3]/internal-format</use></internal-format>
</texture-unit>
<texture-unit>
<unit>4</unit>
<type><use>texture[4]/type</use></type>
<image><use>texture[4]/image</use></image>
<filter><use>texture[4]/filter</use></filter>
<wrap-s><use>texture[4]/wrap-s</use></wrap-s>
<wrap-t><use>texture[4]/wrap-t</use></wrap-t>
<internal-format><use>texture[4]/internal-format</use></internal-format>
</texture-unit>
<cull-face>back</cull-face>
<program>
<vertex-shader>Shaders/HDR/geometry-pbr.vert</vertex-shader>
<fragment-shader>Shaders/HDR/geometry-pbr.frag</fragment-shader>
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
<attribute>
<name>tangent</name>
<index>6</index>
</attribute>
<attribute>
<name>binormal</name>
<index>7</index>
</attribute>
</program>
<uniform>
<name>albedo_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>normal_tex</name>
<type>sampler-2d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>metalness_tex</name>
<type>sampler-2d</type>
<value type="int">2</value>
</uniform>
<uniform>
<name>roughness_tex</name>
<type>sampler-2d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>cavity_tex</name>
<type>sampler-2d</type>
<value type="int">4</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -117,4 +117,12 @@
-->
</pass>
</technique>
<technique n="109">
<scheme>hdr-geometry</scheme>
</technique>
<technique n="129">
<scheme>hdr-forward</scheme>
</technique>
</PropertyList>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<!-- Classic -->
<scheme>
<name>classic-shadow</name>
<fallback>Effects/Fallback/classic-shadow</fallback>
</scheme>
<!-- HDR -->
<scheme>
<name>hdr-geometry</name>
<fallback>Effects/Fallback/hdr-geometry</fallback>
</scheme>
<scheme>
<name>hdr-shadow</name>
<fallback>Effects/Fallback/hdr-shadow</fallback>
</scheme>
</PropertyList>

View file

@ -297,4 +297,35 @@
</pass>
</technique>
<technique n="109">
<scheme>hdr-geometry</scheme>
</technique>
<technique n="139">
<scheme>hdr-envmap</scheme>
<pass>
<cull-face>back</cull-face>
<depth>
<function>lequal</function>
<near>0.0</near>
<far>1.0</far>
<write-mask>true</write-mask>
</depth>
<program>
<vertex-shader>Shaders/HDR/skydome.vert</vertex-shader>
<fragment-shader>Shaders/HDR/skydome.frag</fragment-shader>
<fragment-shader>Shaders/HDR/atmosphere-include.frag</fragment-shader>
</program>
<uniform>
<name>sun_disk</name>
<type>bool</type>
<value type="bool">false</value>
</uniform>
<uniform>
<name>num_samples</name>
<type>int</type>
<value type="int">16</value>
</uniform>
</pass>
</technique>
</PropertyList>

23
Effects/stars.eff Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>Effects/stars</name>
<!-- Fixed-pipeline fallback -->
<technique n="11">
<pass>
<!--
An empty pass should be fine as we are filling the stateset manually
in simgear/scene/sky/stars.cxx
-->
</pass>
</technique>
<technique n="20">
<scheme>hdr-geometry</scheme>
</technique>
<technique n="21">
<scheme>hdr-forward</scheme>
</technique>
</PropertyList>

View file

@ -1674,4 +1674,29 @@
</texture-unit>
</pass>
</technique>
<technique n="139">
<scheme>hdr-envmap</scheme>
<pass>
<cull-face>back</cull-face>
<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>
<internal-format><use>texture[0]/internal-format</use></internal-format>
</texture-unit>
<program>
<vertex-shader>Shaders/HDR/forward.vert</vertex-shader>
<fragment-shader>Shaders/HDR/forward.frag</fragment-shader>
</program>
<uniform>
<name>color_tex</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -0,0 +1,19 @@
#version 330 core
out float adaptedLum;
uniform sampler2D prev_lum_tex;
uniform sampler2D current_lum_tex;
uniform float osg_DeltaFrameTime;
// Higher values give faster eye adaptation times
const float TAU = 4.0;
void main()
{
float prevLum = texelFetch(prev_lum_tex, ivec2(0), 0).r;
float currentLum = exp2(textureLod(current_lum_tex, vec2(0.5), 10.0).r);
adaptedLum = prevLum + (currentLum - prevLum) *
(1.0 - exp(-osg_DeltaFrameTime * TAU));
}

View file

@ -0,0 +1,10 @@
#version 330 core
layout(location = 0) in vec4 pos;
uniform mat4 osg_ModelViewProjectionMatrix;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
}

71
Shaders/HDR/ao.frag Normal file
View file

@ -0,0 +1,71 @@
#version 330 core
#pragma optionNV (unroll all)
out float fragColor;
in vec2 texCoord;
uniform sampler2D depth_tex;
uniform sampler2D normal_tex;
uniform mat4 fg_ProjectionMatrix;
const float RADIUS = 0.04;
const float BIAS = 0.05;
const float SCALE = 3.0;
const float MAX_DISTANCE = 0.08;
const float INTENSITY = 1.5;
const vec2 kernel[4] = vec2[](
vec2( 0.0, 1.0), // top
vec2( 1.0, 0.0), // right
vec2( 0.0, -1.0), // bottom
vec2(-1.0, 0.0)); // left
vec3 positionFromDepth(vec2 pos, float depth);
vec3 decodeNormal(vec2 enc);
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float sampleAO(vec3 fragPos, vec3 normal, vec2 coords)
{
float sampleDepth = texture(depth_tex, coords).r * 2.0 - 1.0;
vec3 samplePoint = positionFromDepth(coords * 2.0 - 1.0, sampleDepth);
vec3 diff = samplePoint - fragPos;
float l = length(diff);
vec3 v = diff / l;
float d = l * SCALE;
float ao = max(0.0, dot(normal, v) - BIAS) * (1.0 / (1.0 + d));
ao *= smoothstep(MAX_DISTANCE, MAX_DISTANCE * 0.5, l);
return ao;
}
void main()
{
float fragDepth = texture(depth_tex, texCoord).r;
vec3 fragPos = positionFromDepth(texCoord * 2.0 - 1.0, fragDepth * 2.0 - 1.0);
vec3 normal = normalize(decodeNormal(texture(normal_tex, texCoord).rg));
vec2 randomVec = normalize(vec2(rand(texCoord) * 2.0 - 1.0,
rand(texCoord+1.0) * 2.0 - 1.0));
const float sin45 = 0.707107;
float occlusion = 0.0;
for (int i = 0; i < 4; ++i) {
vec2 k1 = reflect(kernel[i], randomVec) * RADIUS;
vec2 k2 = vec2(k1.x * sin45 - k1.y * sin45, k1.x * sin45 + k1.y * sin45);
occlusion += sampleAO(fragPos, normal, texCoord + k1);
occlusion += sampleAO(fragPos, normal, texCoord + k2 * 0.75);
occlusion += sampleAO(fragPos, normal, texCoord + k1 * 0.5);
occlusion += sampleAO(fragPos, normal, texCoord + k2 * 0.25);
}
occlusion /= 16.0;
fragColor = clamp(1.0 - occlusion * INTENSITY, 0.0, 1.0);
}

View file

@ -0,0 +1,152 @@
#version 330 core
uniform bool sun_disk = true;
uniform vec3 beta_rayleigh = vec3(5.5e-6, 13.0e-6, 22.4e-6);
uniform float beta_mie = 21e-6;
uniform vec3 beta_absortion = vec3(2.04e-5, 4.97e-5, 1.95e-6);
uniform float beta_ambient = 0.0;
uniform float rayleigh_scale_height = 8e3;
uniform float mie_scale_height = 1.2e3;
uniform float absortion_scale_height = 30e3;
uniform float absortion_falloff = 3e3;
uniform int num_samples = 64;
uniform int num_light_samples = 4;
const float PI = 3.141592653;
const float ATMOSPHERE_RADIUS = 6471e3;
const vec3 SUN_INTENSITY = vec3(20.0);
const float COS_SUN_ANGULAR_DIAMETER = 0.999956676946448443553574619906976478926848692873900859324;
vec2 raySphereIntersection(vec3 r0, vec3 rd, float radius)
{
float a = dot(rd, rd);
float b = 2.0 * dot(rd, r0);
float c = dot(r0, r0) - (radius * radius);
float d = (b*b) - 4.0*a*c;
if (d < 0.0) return vec2(1e5, -1e5);
return vec2((-b - sqrt(d))/(2.0*a), (-b + sqrt(d))/(2.0*a));
}
vec3 calculateScattering(vec3 rayOrigin,
vec3 rayDir,
vec3 sceneColor,
float depth,
float maxDist,
float earthRadius,
vec3 lightDir)
{
vec2 hit = raySphereIntersection(rayOrigin, rayDir, ATMOSPHERE_RADIUS);
if (hit.x > hit.y) {
// The ray did not hit the atmosphere, we are in outer space
return sceneColor;
}
hit.x = max(hit.x, 0.0); // Do not sample behind the camera
// Avoid clamping the ray to the far plane when there is no geometry in
// front of the sky
if (depth < 1.0) {
// Stop the ray at the geometry
hit.y = min(hit.y, maxDist);
} else {
// If there is no geometry, simulate a collision with the Earth at sea
// level. This only happens when FG hasn't loaded any terrain
vec2 hitEarth = raySphereIntersection(
rayOrigin, rayDir, earthRadius - 1.0);
if (hitEarth.x < hitEarth.y && hitEarth.x > 0.0) {
hit.y = min(hit.y, hitEarth.x);
}
}
float stepSize = (hit.y - hit.x) / float(num_samples);
const float g = 0.758; // Mie scattering direction
const float gg = g*g;
float mu = dot(rayDir, lightDir);
float mumu = mu*mu;
float phaseRayleigh = 3.0 / (50.2654824574 /* 16*PI */) * (1.0 + mumu);
float phaseMie = 3.0 / (25.1327412287 /* 8*PI */) * ((1.0 - gg) * (mumu + 1.0)) /
(pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg));
float opticalDepthRayleigh = 0.0;
float opticalDepthMie = 0.0;
float opticalDepthAbsortion = 0.0;
float primaryTime = hit.x;
vec3 extinctionFactor = vec3(0.0);
vec3 totalRayleigh = vec3(0.0);
vec3 totalMie = vec3(0.0);
for (int i = 0; i < num_samples; ++i) {
vec3 samplePoint = rayOrigin + rayDir * (primaryTime + stepSize * 0.5);
float altitude = length(samplePoint) - earthRadius;
float densityRayleigh = exp(-altitude / rayleigh_scale_height);
float densityMie = exp(-altitude / mie_scale_height);
float densityAbsortion = clamp((1.0 / cosh((absortion_scale_height - altitude) / absortion_falloff)) * densityRayleigh, 0.0, 1.0);
float stepOpticalDepthRayleigh = densityRayleigh * stepSize;
float stepOpticalDepthMie = densityMie * stepSize;
float stepOpticalDepthAbsortion = densityAbsortion * stepSize;
opticalDepthRayleigh += stepOpticalDepthRayleigh;
opticalDepthMie += stepOpticalDepthMie;
opticalDepthAbsortion += stepOpticalDepthAbsortion;
vec2 pl = raySphereIntersection(samplePoint, lightDir, ATMOSPHERE_RADIUS);
float stepSizeLight = pl.y / float(num_light_samples);
float opticalDepthLightRayleigh = 0.0;
float opticalDepthLightMie = 0.0;
float opticalDepthLightAbsortion = 0.0;
float secondaryTime = 0.0;
for (int j = 0; j < num_light_samples; ++j) {
vec3 samplePointLight = samplePoint + lightDir *
(secondaryTime + stepSizeLight * 0.5);
float altitudeLight = length(samplePointLight) - earthRadius;
float densityLightRayleigh = exp(-altitudeLight / rayleigh_scale_height);
float densityLightMie = exp(-altitudeLight / mie_scale_height);
float densityLightAbsortion = clamp((1.0 / cosh((absortion_scale_height - altitudeLight) / absortion_falloff)) * densityLightRayleigh, 0.0, 1.0);
opticalDepthLightRayleigh += densityLightRayleigh * stepSizeLight;
opticalDepthLightMie += densityLightMie * stepSizeLight;
opticalDepthLightAbsortion += densityLightAbsortion * stepSizeLight;
secondaryTime += stepSizeLight;
}
vec3 tau =
beta_rayleigh * (opticalDepthRayleigh + opticalDepthLightRayleigh) +
beta_mie * (opticalDepthMie + opticalDepthLightMie) +
beta_absortion * (opticalDepthAbsortion + opticalDepthLightAbsortion);
vec3 attenuation = exp(-tau);
extinctionFactor += attenuation;
totalRayleigh += stepOpticalDepthRayleigh * attenuation;
totalMie += stepOpticalDepthMie * attenuation;
primaryTime += stepSize;
}
vec3 opacity = exp(-(beta_rayleigh * opticalDepthRayleigh +
beta_mie * opticalDepthMie +
beta_absortion * opticalDepthAbsortion));
vec3 color = SUN_INTENSITY *
(totalRayleigh * beta_rayleigh * phaseRayleigh +
totalMie * beta_mie * phaseMie +
opticalDepthRayleigh * beta_ambient)
+ sceneColor * opacity;
if (sun_disk && (depth >= 1.0)) {
float costheta = dot(rayDir, lightDir);
float sundisk = smoothstep(COS_SUN_ANGULAR_DIAMETER,
COS_SUN_ANGULAR_DIAMETER + 0.00002,
costheta);
color += SUN_INTENSITY * extinctionFactor * sundisk;
}
return color;
}

View file

@ -0,0 +1,48 @@
#version 330 core
out vec3 fragColor;
in vec2 texCoord;
uniform mat4 fg_ViewMatrixInverse;
uniform mat4 fg_ProjectionMatrixInverse;
uniform vec3 fg_CameraPositionCart;
uniform vec3 fg_CameraPositionGeod;
uniform vec3 fg_SunDirection;
uniform vec2 fg_BufferSize;
uniform sampler2D hdr_tex;
uniform sampler2D depth_tex;
vec3 calculateScattering(vec3 rayOrigin,
vec3 rayDir,
vec3 sceneColor,
float depth,
float maxDist,
float earthRadius,
vec3 lightDir);
vec3 positionFromDepth(vec2 pos, float depth);
void main()
{
float depth = texture(depth_tex, texCoord).r;
vec3 fragPos = positionFromDepth(texCoord * 2.0 - 1.0,
depth * 2.0 - 1.0);
vec3 rayDir = vec4(fg_ViewMatrixInverse * vec4(normalize(fragPos), 0.0)).xyz;
// Since FG internally uses WG84 coordinates, we use the current Earth
// radius under the camera, which varies with the latitude. For practical
// purposes we model the Earth as a perfect sphere with this radius.
float earthRadius = length(fg_CameraPositionCart) - fg_CameraPositionGeod.z;
vec3 sceneColor = texture(hdr_tex, texCoord).rgb;
vec3 color = calculateScattering(fg_CameraPositionCart,
rayDir,
sceneColor,
depth,
length(fragPos),
earthRadius,
fg_SunDirection);
fragColor = color;
}

View file

@ -0,0 +1,23 @@
#version 330 core
out vec3 fragColor;
in vec2 texCoord;
uniform sampler2D hdr_tex;
uniform sampler2D lum_tex;
void main()
{
vec3 hdrColor = texture(hdr_tex, texCoord).rgb;
float avgLuminance = texture(lum_tex, texCoord).r;
// XXX: Maybe we should actually control the EV compensation value itself
// instead of hardcoding a factor?
float exposure = 1.0 / (200.0 * avgLuminance);
hdrColor *= exposure;
if (dot(hdrColor, vec3(0.333)) <= 0.001)
fragColor = vec3(0.0);
else
fragColor = hdrColor;
}

33
Shaders/HDR/blur.frag Normal file
View file

@ -0,0 +1,33 @@
#version 330 core
out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D tex;
uniform sampler2D prev_pass_tex;
uniform bool vertical = false;
void main()
{
vec2 offset = 1.0 / textureSize(tex, 0);
if (vertical) offset.x = 0.0;
else offset.y = 0.0;
vec4 sum = texture(prev_pass_tex, texCoord);
sum += texture(tex, texCoord - 4.0 * offset) * 0.0162162162;
sum += texture(tex, texCoord - 3.0 * offset) * 0.0540540541;
sum += texture(tex, texCoord - 2.0 * offset) * 0.1216216216;
sum += texture(tex, texCoord - 1.0 * offset) * 0.1945945946;
sum += texture(tex, texCoord) * 0.2270270270;
sum += texture(tex, texCoord + 1.0 * offset) * 0.1945945946;
sum += texture(tex, texCoord + 2.0 * offset) * 0.1216216216;
sum += texture(tex, texCoord + 3.0 * offset) * 0.0540540541;
sum += texture(tex, texCoord + 4.0 * offset) * 0.0162162162;
fragColor = sum;
}

View file

@ -0,0 +1,10 @@
#version 330 core
out float prevLum;
uniform sampler2D lum_tex;
void main()
{
prevLum = texelFetch(lum_tex, ivec2(0), 0).r;
}

63
Shaders/HDR/display.frag Normal file
View file

@ -0,0 +1,63 @@
#version 330 core
out vec4 fragColor;
in vec2 texCoord;
in vec4 posPos;
uniform vec2 fg_BufferSize;
uniform sampler2D tex;
const float FXAA_SPAN_MAX = 8.0;
const float FXAA_REDUCE_MUL = 1.0/8.0;
const float FXAA_REDUCE_MIN = 1.0/128.0;
vec3 fxaa()
{
vec2 rcpFrame = 1.0 / textureSize(tex, 0);
vec3 rgbNW = textureLod(tex, posPos.zw, 0.0).xyz;
vec3 rgbNE = textureLodOffset(tex, posPos.zw, 0.0, ivec2(1,0)).xyz;
vec3 rgbSW = textureLodOffset(tex, posPos.zw, 0.0, ivec2(0,1)).xyz;
vec3 rgbSE = textureLodOffset(tex, posPos.zw, 0.0, ivec2(1,1)).xyz;
vec3 rgbM = textureLod(tex, posPos.xy, 0.0).xyz;
const vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir * rcpDirMin)) * rcpFrame.xy;
vec3 rgbA = 0.5 * (
textureLod(tex, posPos.xy + dir * (1.0/3.0 - 0.5), 0.0).xyz +
textureLod(tex, posPos.xy + dir * (2.0/3.0 - 0.5), 0.0).xyz);
vec3 rgbB = rgbA * 0.5 + 0.25 * (
textureLod(tex, posPos.xy + dir * (0.0/3.0 - 0.5), 0.0).xyz +
textureLod(tex, posPos.xy + dir * (3.0/3.0 - 0.5), 0.0).xyz);
float lumaB = dot(rgbB, luma);
if((lumaB < lumaMin) || (lumaB > lumaMax))
return rgbA;
return rgbB;
}
void main()
{
fragColor = vec4(fxaa(), 1.0);
}

22
Shaders/HDR/display.vert Normal file
View file

@ -0,0 +1,22 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 3) in vec4 multiTexCoord0;
out vec2 texCoord;
out vec4 posPos;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform sampler2D tex;
const float FXAA_SUBPIX_SHIFT = 1.0/4.0;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
texCoord = multiTexCoord0.st;
vec2 rcpFrame = 1.0 / textureSize(tex, 0);
posPos.xy = multiTexCoord0.xy;
posPos.zw = multiTexCoord0.xy - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT));
}

View file

@ -0,0 +1,74 @@
#version 330 core
out vec3 fragColor;
in vec3 cubemapCoord;
uniform samplerCube envmap;
uniform float roughness;
uniform int fg_CubemapFace;
const float PI = 3.14159265359;
float RadicalInverse_VdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
}
vec3 ImportanceSampleGGX(vec2 Xi, vec3 n, float r)
{
float a = r*r;
float phi = 2.0 * PI * Xi.x;
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
vec3 h;
h.x = sinTheta * cos(phi);
h.y = sinTheta * sin(phi);
h.z = cosTheta;
vec3 up = abs(n.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
vec3 tangent = normalize(cross(up, n));
vec3 bitangent = cross(n, tangent);
vec3 sampleVec = tangent * h.x + bitangent * h.y + n * h.z;
return normalize(sampleVec);
}
void main()
{
vec3 n = normalize(cubemapCoord);
vec3 v = n; // n = v simplification
vec3 prefilteredColor = vec3(0.0);
float totalWeight = 0.0;
const uint NUM_SAMPLES = 1024u;
for (uint i = 0u; i < NUM_SAMPLES; ++i) {
vec2 Xi = Hammersley(i, NUM_SAMPLES);
vec3 h = ImportanceSampleGGX(Xi, n, roughness);
vec3 l = normalize(2.0 * dot(v, h) * h - v);
float NdotL = max(dot(n, l), 0.0);
if (NdotL > 0.0) {
prefilteredColor += textureLod(envmap, l, 0.0).rgb * NdotL;
totalWeight += NdotL;
}
}
prefilteredColor /= totalWeight;
fragColor = prefilteredColor;
}

13
Shaders/HDR/forward.frag Normal file
View file

@ -0,0 +1,13 @@
#version 330 core
layout(location = 0) out vec4 fragColor;
in vec3 normalVS;
in vec2 texCoord;
uniform sampler2D color_tex;
void main()
{
fragColor = texture(color_tex, texCoord);
}

18
Shaders/HDR/forward.vert Normal file
View file

@ -0,0 +1,18 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 1) in vec3 normal;
layout(location = 3) in vec4 multiTexCoord0;
out vec3 normalVS;
out vec2 texCoord;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat3 osg_NormalMatrix;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
normalVS = normalize(osg_NormalMatrix * normal);
texCoord = multiTexCoord0.st;
}

View file

@ -0,0 +1,32 @@
#version 330 core
uniform mat4 fg_ProjectionMatrixInverse;
// https://aras-p.info/texts/CompactNormalStorage.html
// Method #4: Spheremap Transform
// Lambert Azimuthal Equal-Area projection
vec2 encodeNormal(vec3 n)
{
float p = sqrt(n.z * 8.0 + 8.0);
return vec2(n.xy / p + 0.5);
}
vec3 decodeNormal(vec2 enc)
{
vec2 fenc = enc * 4.0 - 2.0;
float f = dot(fenc, fenc);
float g = sqrt(1.0 - f / 4.0);
vec3 n;
n.xy = fenc * g;
n.z = 1.0 - f / 2.0;
return n;
}
// Given a position in clip space (values in the range [-1,1]), return
// the view space position.
vec3 positionFromDepth(vec2 pos, float depth)
{
vec4 p = fg_ProjectionMatrixInverse * vec4(pos, depth, 1.0);
p.xyz /= p.w;
return p.xyz;
}

View file

@ -0,0 +1,31 @@
#version 330 core
layout(location = 0) out vec4 gbuffer0;
layout(location = 1) out vec2 gbuffer1;
layout(location = 2) out vec4 gbuffer2;
in vec2 texCoord;
in mat3 TBN;
uniform sampler2D color_tex;
uniform sampler2D normal_tex;
const float DEFAULT_COMBINED_METALNESS = 0.0;
const float DEFAULT_COMBINED_ROUGHNESS = 0.1;
vec2 encodeNormal(vec3 n);
void main()
{
gbuffer0.rgb = pow(texture(color_tex, texCoord).rgb, vec3(2.2)); // Gamma correction
gbuffer0.a = 1.0;
vec3 normal = texture(normal_tex, texCoord).rgb * 2.0 - 1.0;
normal = normalize(TBN * normal);
gbuffer1 = encodeNormal(normal);
gbuffer2 = vec4(DEFAULT_COMBINED_METALNESS,
DEFAULT_COMBINED_ROUGHNESS,
0.0,
0.0);
}

View file

@ -0,0 +1,25 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 1) in vec3 normal;
layout(location = 3) in vec4 multiTexCoord0;
out vec2 texCoord;
out mat3 TBN;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat3 osg_NormalMatrix;
attribute vec3 tangent;
attribute vec3 binormal;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
texCoord = multiTexCoord0.st;
vec3 T = normalize(osg_NormalMatrix * tangent);
vec3 B = normalize(osg_NormalMatrix * binormal);
vec3 N = normalize(osg_NormalMatrix * normal);
TBN = mat3(T, B, N);
}

View file

@ -0,0 +1,31 @@
#version 330 core
layout(location = 0) out vec4 gbuffer0;
layout(location = 1) out vec2 gbuffer1;
layout(location = 2) out vec4 gbuffer2;
in vec2 texCoord;
in mat3 TBN;
uniform sampler2D albedo_tex;
uniform sampler2D normal_tex;
uniform sampler2D metalness_tex;
uniform sampler2D roughness_tex;
uniform sampler2D cavity_tex;
vec2 encodeNormal(vec3 n);
void main()
{
gbuffer0.rgb = pow(texture(albedo_tex, texCoord).rgb, vec3(2.2)); // Gamma correction
gbuffer0.a = texture(cavity_tex, texCoord).r;
vec3 normal = texture(normal_tex, texCoord).rgb * 2.0 - 1.0;
normal = normalize(TBN * normal);
gbuffer1 = encodeNormal(normal);
float metalness = texture(metalness_tex, texCoord).r;
float roughness = texture(roughness_tex, texCoord).r;
gbuffer2 = vec4(metalness, roughness, 0.0, 0.0);
}

View file

@ -0,0 +1,25 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 1) in vec3 normal;
layout(location = 3) in vec4 multiTexCoord0;
out vec2 texCoord;
out mat3 TBN;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat3 osg_NormalMatrix;
attribute vec3 tangent;
attribute vec3 binormal;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
texCoord = multiTexCoord0.st;
vec3 T = normalize(osg_NormalMatrix * tangent);
vec3 B = normalize(osg_NormalMatrix * binormal);
vec3 N = normalize(osg_NormalMatrix * normal);
TBN = mat3(T, B, N);
}

View file

@ -0,0 +1,17 @@
#version 330 core
layout(location = 0) out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D color_tex;
const float ALPHA_THRESHOLD = 0.5;
void main()
{
fragColor = vec4(1.0);
float alpha = texture(color_tex, texCoord).a;
if (alpha <= ALPHA_THRESHOLD)
discard;
}

View file

@ -0,0 +1,14 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 3) in vec4 multiTexCoord0;
out vec2 texCoord;
uniform mat4 osg_ModelViewProjectionMatrix;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
texCoord = multiTexCoord0.st;
}

26
Shaders/HDR/geometry.frag Normal file
View file

@ -0,0 +1,26 @@
#version 330 core
layout(location = 0) out vec4 gbuffer0;
layout(location = 1) out vec2 gbuffer1;
layout(location = 2) out vec4 gbuffer2;
in vec3 normalVS;
in vec2 texCoord;
uniform sampler2D color_tex;
const float DEFAULT_METALNESS = 0.0;
const float DEFAULT_ROUGHNESS = 0.8;
vec2 encodeNormal(vec3 n);
void main()
{
gbuffer0.rgb = pow(texture(color_tex, texCoord).rgb, vec3(2.2)); // Gamma correction
gbuffer0.a = 1.0;
gbuffer1 = encodeNormal(normalVS);
gbuffer2 = vec4(DEFAULT_METALNESS,
DEFAULT_ROUGHNESS,
0.0,
0.0);
}

18
Shaders/HDR/geometry.vert Normal file
View file

@ -0,0 +1,18 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 1) in vec3 normal;
layout(location = 3) in vec4 multiTexCoord0;
out vec3 normalVS;
out vec2 texCoord;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat3 osg_NormalMatrix;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
normalVS = normalize(osg_NormalMatrix * normal);
texCoord = multiTexCoord0.st;
}

370
Shaders/HDR/lighting.frag Normal file
View file

@ -0,0 +1,370 @@
#version 330 core
out vec3 fragHdrColor;
in vec2 texCoord;
uniform sampler2D gbuffer0_tex;
uniform sampler2D gbuffer1_tex;
uniform sampler2D gbuffer2_tex;
uniform sampler2D depth_tex;
uniform sampler2D ao_tex;
uniform samplerCube prefiltered_envmap;
uniform sampler2DShadow shadow_tex;
uniform sampler2D dfg_lut;
uniform mat4 fg_ViewMatrix;
uniform mat4 fg_ViewMatrixInverse;
uniform vec3 fg_SunDirection;
uniform vec3 fg_CameraPositionCart;
uniform mat4 fg_LightMatrix_csm0;
uniform mat4 fg_LightMatrix_csm1;
uniform mat4 fg_LightMatrix_csm2;
uniform mat4 fg_LightMatrix_csm3;
const float PI = 3.14159265359;
const float RECIPROCAL_PI = 0.31830988618;
const int sun_atlas_size = 8192;
const float DEPTH_BIAS = 2.0;
const float BAND_SIZE = 0.1;
const vec2 BAND_BOTTOM_LEFT = vec2(BAND_SIZE);
const vec2 BAND_TOP_RIGHT = vec2(1.0 - BAND_SIZE);
// Ideally these should be passed as an uniform, but we don't support uniform
// arrays yet
const vec2 uv_shifts[4] = vec2[4](
vec2(0.0, 0.0), vec2(0.5, 0.0),
vec2(0.0, 0.5), vec2(0.5, 0.5));
const vec2 uv_factor = vec2(0.5, 0.5);
const float MAX_PREFILTERED_LOD = 4.0;
const vec3 SUN_INTENSITY = vec3(20.0);
vec3 decodeNormal(vec2 enc);
vec3 positionFromDepth(vec2 pos, float depth);
//------------------------------------------------------------------------------
// Shadow mapping related stuff
float sampleOffset(vec4 pos, vec2 offset, vec2 invTexelSize)
{
return texture(
shadow_tex, vec3(
pos.xy + offset * invTexelSize,
pos.z - DEPTH_BIAS * invTexelSize));
}
// OptimizedPCF from https://github.com/TheRealMJP/Shadows
// Original by Ignacio Castaño for The Witness
// Released under The MIT License
float sampleOptimizedPCF(vec4 pos)
{
vec2 invTexSize = vec2(1.0 / float(sun_atlas_size));
vec2 uv = pos.xy * sun_atlas_size;
vec2 base_uv = floor(uv + 0.5);
float s = (uv.x + 0.5 - base_uv.x);
float t = (uv.y + 0.5 - base_uv.y);
base_uv -= vec2(0.5);
base_uv *= invTexSize;
pos.xy = base_uv.xy;
float sum = 0.0;
float uw0 = (4.0 - 3.0 * s);
float uw1 = 7.0;
float uw2 = (1.0 + 3.0 * s);
float u0 = (3.0 - 2.0 * s) / uw0 - 2.0;
float u1 = (3.0 + s) / uw1;
float u2 = s / uw2 + 2.0;
float vw0 = (4.0 - 3.0 * t);
float vw1 = 7.0;
float vw2 = (1.0 + 3.0 * t);
float v0 = (3.0 - 2.0 * t) / vw0 - 2.0;
float v1 = (3.0 + t) / vw1;
float v2 = t / vw2 + 2.0;
sum += uw0 * vw0 * sampleOffset(pos, vec2(u0, v0), invTexSize);
sum += uw1 * vw0 * sampleOffset(pos, vec2(u1, v0), invTexSize);
sum += uw2 * vw0 * sampleOffset(pos, vec2(u2, v0), invTexSize);
sum += uw0 * vw1 * sampleOffset(pos, vec2(u0, v1), invTexSize);
sum += uw1 * vw1 * sampleOffset(pos, vec2(u1, v1), invTexSize);
sum += uw2 * vw1 * sampleOffset(pos, vec2(u2, v1), invTexSize);
sum += uw0 * vw2 * sampleOffset(pos, vec2(u0, v2), invTexSize);
sum += uw1 * vw2 * sampleOffset(pos, vec2(u1, v2), invTexSize);
sum += uw2 * vw2 * sampleOffset(pos, vec2(u2, v2), invTexSize);
return sum / 144.0;
}
float sampleCascade(vec4 p, vec2 shift)
{
vec4 pos = p;
pos.xy *= uv_factor;
pos.xy += shift;
return sampleOptimizedPCF(pos);
}
float sampleAndBlendBand(vec4 p1, vec4 p2, vec2 s1, vec2 s2)
{
vec2 s = smoothstep(vec2(0.0), BAND_BOTTOM_LEFT, p1.xy)
- smoothstep(BAND_TOP_RIGHT, vec2(1.0), p1.xy);
float blend = 1.0 - s.x * s.y;
return mix(sampleCascade(p1, s1),
sampleCascade(p2, s2),
blend);
}
bool checkWithinBounds(vec2 coords, vec2 bottomLeft, vec2 topRight)
{
vec2 r = step(bottomLeft, coords) - step(topRight, coords);
return bool(r.x * r.y);
}
bool isInsideCascade(vec4 p)
{
return checkWithinBounds(p.xy, vec2(0.0), vec2(1.0)) && ((p.z / p.w) <= 1.0);
}
bool isInsideBand(vec4 p)
{
return !checkWithinBounds(p.xy, BAND_BOTTOM_LEFT, BAND_TOP_RIGHT);
}
/**
* Get the light space position of point p.
* Both p and n must be in view space. The light matrix is also assumed to
* transform from view space to light space.
*/
vec4 getLightSpacePosition(vec3 p, vec3 n, float NdotL, float bias,
mat4 lightMatrix)
{
float sinTheta = sqrt(1.0 - NdotL * NdotL);
vec3 offset = p + n * (sinTheta * bias);
return lightMatrix * vec4(offset, 1.0);
}
/**
* Get shadowing factor for a given position. 1.0 corresponds to a fragment
* being completely lit, and 0.0 to a fragment being completely in shadow.
* Both p and n must be in view space.
*/
float getShadowing(vec3 p, vec3 n, float NdotL)
{
float shadow = 1.0;
vec4 lightSpacePos[4];
lightSpacePos[0] = getLightSpacePosition(p, n, NdotL, 0.01, fg_LightMatrix_csm0);
lightSpacePos[1] = getLightSpacePosition(p, n, NdotL, 0.01, fg_LightMatrix_csm1);
lightSpacePos[2] = getLightSpacePosition(p, n, NdotL, 0.01, fg_LightMatrix_csm2);
lightSpacePos[3] = getLightSpacePosition(p, n, NdotL, 0.01, fg_LightMatrix_csm3);
for (int i = 0; i < 4; ++i) {
// Map-based cascade selection
// We test if we are inside the cascade bounds to find the tightest
// map that contains the fragment.
if (isInsideCascade(lightSpacePos[i])) {
if (isInsideBand(lightSpacePos[i]) && ((i+1) < 4)) {
// Blend between cascades if the fragment is near the
// next cascade to avoid abrupt transitions.
shadow = clamp(sampleAndBlendBand(lightSpacePos[i],
lightSpacePos[i+1],
uv_shifts[i],
uv_shifts[i+1]),
0.0, 1.0);
} else {
// We are far away from the borders of the cascade, so
// we skip the blending to avoid the performance cost
// of sampling the shadow map twice.
shadow = clamp(sampleCascade(lightSpacePos[i], uv_shifts[i]),
0.0, 1.0);
}
break;
}
}
return shadow;
}
//------------------------------------------------------------------------------
// BRDF related stuff
/**
* Indirect diffuse irradiance
* To get better results we should be precomputing the irradiance into a cubemap
* or calculating spherical harmonics coefficients on the CPU.
* Sampling the roughness=1 mipmap level of the prefiltered specular map
* works too. :)
*/
vec3 IBL_DiffuseIrradiance(vec3 n)
{
vec4 worldSpaceNormal = fg_ViewMatrixInverse * vec4(n, 0.0);
vec3 coord = worldSpaceNormal.xyz;
int roughnessOneLevel = int(MAX_PREFILTERED_LOD);
ivec2 s = textureSize(prefiltered_envmap, roughnessOneLevel);
float du = 1.0 / float(s.x);
float dv = 1.0 / float(s.y);
vec3 m0 = normalize(cross(n, vec3(0.0, 1.0, 0.0)));
vec3 m1 = cross(m0, n);
vec3 m0du = m0 * du;
vec3 m1dv = m1 * dv;
vec3 c;
c = textureLod(prefiltered_envmap, coord - m0du - m1dv, roughnessOneLevel).rgb;
c += textureLod(prefiltered_envmap, coord + m0du - m1dv, roughnessOneLevel).rgb;
c += textureLod(prefiltered_envmap, coord + m0du + m1dv, roughnessOneLevel).rgb;
c += textureLod(prefiltered_envmap, coord - m0du + m1dv, roughnessOneLevel).rgb;
return c * 0.25;
}
/**
* Indirect specular (ambient specular)
* Sample from the prefiltered environment map.
*/
vec3 IBL_Specular(vec3 n, vec3 v, float NdotV, float roughness, vec3 F)
{
vec4 reflectVec = vec4(reflect(-v, n), 0.0);
vec4 worldReflectVec = fg_ViewMatrixInverse * reflectVec;
vec3 prefilteredColor = textureLod(prefiltered_envmap,
worldReflectVec.xyz,
roughness * MAX_PREFILTERED_LOD).rgb;
vec2 envBRDF = texture(dfg_lut, vec2(NdotV, roughness)).rg;
return prefilteredColor * (F * envBRDF.x + envBRDF.y);
}
/**
* Fresnel term with included roughness to get a pleasant visual result.
* See https://seblagarde.wordpress.com/2011/08/17/hello-world/
*/
vec3 F_SchlickRoughness(float NdotV, vec3 F0, float r)
{
return F0 + (max(vec3(1.0 - r), F0) - F0) * pow(max(1.0 - NdotV, 0.0), 5.0);
}
/**
* Fresnel (specular F)
* Schlick's approximation for the Cook-Torrance BRDF.
*/
vec3 F_Schlick(float VdotH, vec3 F0)
{
return F0 + (vec3(1.0) - F0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);
}
/**
* Normal distribution function (NDF) (specular D)
* Trowbridge-Reitz/GGX microfacet distribution. Includes Disney's
* reparametrization of a=roughness*roughness
*/
float D_GGX(float NdotH, float a2)
{
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
return a2 / (PI * f * f);
}
/**
* Geometric attenuation (specular G)
* Smith-GGX formulation.
*/
float G_SmithGGX(float NdotV, float NdotL, float a2)
{
float attV = 2.0 * NdotV / (NdotV + sqrt(a2 + (1.0 - a2) * (NdotV * NdotV)));
float attL = 2.0 * NdotL / (NdotL + sqrt(a2 + (1.0 - a2) * (NdotL * NdotL)));
return attV * attL;
}
/**
* Basic Lambertian diffuse BRDF
*/
vec3 BRDF_Diffuse_Lambert(vec3 c_diff)
{
return c_diff * RECIPROCAL_PI;
}
vec3 BRDF(in vec3 albedo, in float metalness, in float roughness,
in float clearcoat, in float clearcoatRoughness,
in float NdotL, in float NdotV, in float NdotH, in float VdotH,
out vec3 f0)
{
const float dielectricSpecular = 0.04;
vec3 c_diff = mix(albedo * (1.0 - dielectricSpecular), vec3(0.0), metalness);
f0 = mix(vec3(dielectricSpecular), albedo, metalness);
float a = roughness * roughness;
float a2 = a * a;
vec3 F = F_Schlick(VdotH, f0);
float D = D_GGX(NdotH, a2);
float G = G_SmithGGX(NdotV, NdotL, a2);
// Diffuse term
// Lambertian diffuse model
vec3 f_diffuse = (vec3(1.0) - F) * BRDF_Diffuse_Lambert(c_diff);
// Specular term
// Cook-Torrance specular microfacet model
vec3 f_specular = F * D * G / (4.0 * NdotV * NdotL);
return f_diffuse + f_specular;
}
//------------------------------------------------------------------------------
void main()
{
vec4 gbuffer0 = texture(gbuffer0_tex, texCoord);
vec2 gbuffer1 = texture(gbuffer1_tex, texCoord).rg;
vec4 gbuffer2 = texture(gbuffer2_tex, texCoord);
float depth = texture(depth_tex, texCoord).r * 2.0 - 1.0; // Clip space
float ao = texture(ao_tex, texCoord).r;
vec3 pos = positionFromDepth(texCoord * 2.0 - 1.0, depth);
vec3 v = normalize(-pos);
vec3 n = decodeNormal(gbuffer1);
vec3 albedo = gbuffer0.rgb;
float cavity = gbuffer0.a;
float metalness = gbuffer2.r;
float roughness = gbuffer2.g;
float clearcoat = gbuffer2.b;
float clearcoatRoughness = gbuffer2.a;
vec3 l = normalize(vec4(fg_ViewMatrix * vec4(fg_SunDirection, 0.0)).xyz);
vec3 h = normalize(v + l);
float NdotL = clamp(dot(n, l), 0.001, 1.0);
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
float NdotH = clamp(dot(n, h), 0.0, 1.0);
float VdotH = clamp(dot(v, h), 0.0, 1.0);
vec3 f0;
vec3 brdf = BRDF(albedo, metalness, roughness,
clearcoat, clearcoatRoughness,
NdotL, NdotV, NdotH, VdotH,
f0);
vec3 sunIlluminance = SUN_INTENSITY * NdotL;
vec3 f = F_SchlickRoughness(NdotV, f0, roughness);
vec3 indirectSpecular = IBL_Specular(n, v, NdotV, roughness, f);
vec3 indirectDiffuse = IBL_DiffuseIrradiance(n) * albedo
* (vec3(1.0) - f) * (1.0 - metalness);
vec3 ambient = (indirectDiffuse + indirectSpecular) * ao * cavity;
float shadowFactor = getShadowing(pos, n, NdotL);
vec3 color = ambient + brdf * sunIlluminance * shadowFactor;
fragHdrColor = color;
}

View file

@ -0,0 +1,13 @@
#version 330 core
out float luminance;
in vec2 texCoord;
uniform sampler2D hdr_tex;
void main()
{
vec3 hdrColor = texture(hdr_tex, texCoord).rgb;
luminance = log2(max(dot(hdrColor, vec3(0.299, 0.587, 0.114)), 0.0001));
}

View file

@ -0,0 +1,60 @@
#version 330 core
out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D hdr_tex;
uniform sampler2D lum_tex;
uniform sampler2D bloom_tex;
uniform vec2 fg_BufferSize;
const float BLOOM_INTENSITY = 1.0;
const float EXPOSURE_THRESHOLD = 0.0;
vec3 ACESFilm(vec3 x)
{
const float a = 2.51;
const float b = 0.03;
const float c = 2.43;
const float d = 0.59;
const float e = 0.14;
return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
}
float log10(float x)
{
return (1.0 / log(10.0)) * log(x);
}
float autokey(float lum)
{
return 1.03 - 2.0 / (2.0 + log10(lum + 1.0));
}
void main()
{
vec3 hdrColor = texture(hdr_tex, texCoord).rgb;
float avgLuminance = texelFetch(lum_tex, ivec2(0), 0).r;
avgLuminance = max(avgLuminance, 0.001);
// Auto-expose
float linearExposure = autokey(avgLuminance) / avgLuminance;
float exposure = log2(max(linearExposure, 0.0001));
exposure -= EXPOSURE_THRESHOLD;
hdrColor *= exp2(exposure);
// Tonemap
vec3 color = ACESFilm(hdrColor);
// Gamma correction
color = pow(color, vec3(1.0/2.2));
// Apply bloom
vec3 bloom = texture(bloom_tex, texCoord).rgb;
bloom *= BLOOM_INTENSITY;
color += bloom;
fragColor = vec4(color, 1.0);
}

40
Shaders/HDR/skydome.frag Normal file
View file

@ -0,0 +1,40 @@
#version 330 core
out vec4 fragColor;
in vec3 rayDirVertex;
uniform mat4 osg_ModelViewMatrix;
uniform mat4 osg_ViewMatrix;
uniform vec3 fg_SunDirection;
vec3 calculateScattering(vec3 rayOrigin,
vec3 rayDir,
vec3 sceneColor,
float depth,
float maxDist,
float earthRadius,
vec3 lightDir);
void main()
{
// Ground point (skydome center) in eye coordinates
vec4 groundPoint = inverse(osg_ViewMatrix) * osg_ModelViewMatrix
* vec4(0.0, 0.0, 0.0, 1.0);
// HACK: WGS84 models the Earth as an oblate spheroid, so we can't use
// a constant Earth radius. This should be precomputed!
float earthRadius = length(groundPoint);
vec3 cameraPos = vec4(inverse(osg_ViewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
vec3 rayDir = normalize(rayDirVertex);
vec3 color = calculateScattering(cameraPos,
rayDir,
vec3(0.0),
1.0,
3.0 * earthRadius,
earthRadius,
fg_SunDirection);
fragColor = vec4(color, 1.0);
}

18
Shaders/HDR/skydome.vert Normal file
View file

@ -0,0 +1,18 @@
#version 330 core
layout(location = 0) in vec4 pos;
out vec3 rayDirVertex;
uniform mat4 osg_ModelViewMatrix;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ViewMatrix;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
vec4 rayDirView = normalize(osg_ModelViewMatrix * pos);
rayDirView.w = 0.0;
rayDirVertex = vec4(inverse(osg_ViewMatrix) * rayDirView).xyz;
rayDirVertex = normalize(rayDirVertex);
}

View file

@ -0,0 +1,40 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 3) in vec4 multiTexCoord0;
out vec3 cubemapCoord;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform int fg_CubemapFace;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
vec2 texCoord = multiTexCoord0.xy * 2.0 - 1.0;
// Map the quad texture coordinates to a direction vector to sample
// the cubemap. This assumes that we are using the weird left-handed
// orientations given by the OpenGL spec.
// See https://www.khronos.org/opengl/wiki/Cubemap_Texture#Upload_and_orientation
switch(fg_CubemapFace) {
case 0: // +X
cubemapCoord = vec3(1.0, -texCoord.y, -texCoord.x);
break;
case 1: // -X
cubemapCoord = vec3(-1.0, -texCoord.y, texCoord.x);
break;
case 2: // +Y
cubemapCoord = vec3(texCoord.x, 1.0, texCoord.y);
break;
case 3: // -Y
cubemapCoord = vec3(texCoord.x, -1.0, -texCoord.y);
break;
case 4: // +Z
cubemapCoord = vec3(texCoord.x, -texCoord.y, 1.0);
break;
case 5: // -Z
cubemapCoord = vec3(-texCoord.x, -texCoord.y, -1.0);
break;
}
}

12
Shaders/HDR/trivial.frag Normal file
View file

@ -0,0 +1,12 @@
#version 330 core
out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D tex;
void main()
{
fragColor = texture(tex, texCoord);
}

14
Shaders/HDR/trivial.vert Normal file
View file

@ -0,0 +1,14 @@
#version 330 core
layout(location = 0) in vec4 pos;
layout(location = 3) in vec4 multiTexCoord0;
out vec2 texCoord;
uniform mat4 osg_ModelViewProjectionMatrix;
void main()
{
gl_Position = osg_ModelViewProjectionMatrix * pos;
texCoord = multiTexCoord0.st;
}

BIN
Textures/PBR/dfg_lut.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB