diff --git a/Compositor/HDR/bloom-buffer.xml b/Compositor/HDR/bloom-buffer.xml index f58997479..7c02f2365 100644 --- a/Compositor/HDR/bloom-buffer.xml +++ b/Compositor/HDR/bloom-buffer.xml @@ -7,4 +7,6 @@ <format>rgb16f</format> <min-filter>linear</min-filter> <mag-filter>linear</mag-filter> + <wrap-s>clamp-to-edge</wrap-s> + <wrap-t>clamp-to-edge</wrap-t> </PropertyList> diff --git a/Compositor/HDR/bloom-horizontal-blur-pass.xml b/Compositor/HDR/bloom-downsample-rest.xml similarity index 63% rename from Compositor/HDR/bloom-horizontal-blur-pass.xml rename to Compositor/HDR/bloom-downsample-rest.xml index 38bf09543..c2c44cc7e 100644 --- a/Compositor/HDR/bloom-horizontal-blur-pass.xml +++ b/Compositor/HDR/bloom-downsample-rest.xml @@ -2,5 +2,5 @@ <PropertyList> <type>quad</type> - <effect>Effects/HDR/horizontal-blur</effect> + <effect>Effects/HDR/bloom-downsample-rest</effect> </PropertyList> diff --git a/Compositor/HDR/bloom-copy-pass.xml b/Compositor/HDR/bloom-upsample.xml similarity index 66% rename from Compositor/HDR/bloom-copy-pass.xml rename to Compositor/HDR/bloom-upsample.xml index 58efb9fe5..b7bc73e13 100644 --- a/Compositor/HDR/bloom-copy-pass.xml +++ b/Compositor/HDR/bloom-upsample.xml @@ -2,5 +2,5 @@ <PropertyList> <type>quad</type> - <effect>Effects/HDR/trivial</effect> + <effect>Effects/HDR/bloom-upsample</effect> </PropertyList> diff --git a/Compositor/HDR/bloom-vertical-blur-pass.xml b/Compositor/HDR/bloom-vertical-blur-pass.xml deleted file mode 100644 index 0fa9f0641..000000000 --- a/Compositor/HDR/bloom-vertical-blur-pass.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<PropertyList> - <type>quad</type> - <effect>Effects/HDR/vertical-blur</effect> -</PropertyList> diff --git a/Compositor/HDR/env-capture-pass.xml b/Compositor/HDR/env-capture-pass.xml index 403051d22..a661e8317 100644 --- a/Compositor/HDR/env-capture-pass.xml +++ b/Compositor/HDR/env-capture-pass.xml @@ -12,4 +12,8 @@ <unit>13</unit> <buffer>sky-view</buffer> </binding> + <binding> + <unit>14</unit> + <buffer>prev-luminance</buffer> + </binding> </PropertyList> diff --git a/Compositor/HDR/hdr.xml b/Compositor/HDR/hdr.xml index 01e637c0a..f22feaa88 100644 --- a/Compositor/HDR/hdr.xml +++ b/Compositor/HDR/hdr.xml @@ -209,44 +209,29 @@ <!-- Bloom buffers --> <buffer include="bloom-buffer.xml"> - <name>bloom0</name> + <name>bloomA</name> <screen-width-scale>0.5</screen-width-scale> <screen-height-scale>0.5</screen-height-scale> </buffer> <buffer include="bloom-buffer.xml"> - <name>bloom1</name> + <name>bloomB</name> <screen-width-scale>0.25</screen-width-scale> <screen-height-scale>0.25</screen-height-scale> </buffer> <buffer include="bloom-buffer.xml"> - <name>bloom2</name> + <name>bloomC</name> <screen-width-scale>0.125</screen-width-scale> <screen-height-scale>0.125</screen-height-scale> </buffer> <buffer include="bloom-buffer.xml"> - <name>bloom3</name> + <name>bloomD</name> <screen-width-scale>0.0625</screen-width-scale> <screen-height-scale>0.0625</screen-height-scale> </buffer> <buffer include="bloom-buffer.xml"> - <name>bloom0-tmp</name> - <screen-width-scale>0.5</screen-width-scale> - <screen-height-scale>0.5</screen-height-scale> - </buffer> - <buffer include="bloom-buffer.xml"> - <name>bloom1-tmp</name> - <screen-width-scale>0.25</screen-width-scale> - <screen-height-scale>0.25</screen-height-scale> - </buffer> - <buffer include="bloom-buffer.xml"> - <name>bloom2-tmp</name> - <screen-width-scale>0.125</screen-width-scale> - <screen-height-scale>0.125</screen-height-scale> - </buffer> - <buffer include="bloom-buffer.xml"> - <name>bloom3-tmp</name> - <screen-width-scale>0.0625</screen-width-scale> - <screen-height-scale>0.0625</screen-height-scale> + <name>bloomE</name> + <screen-width-scale>0.03125</screen-width-scale> + <screen-height-scale>0.03125</screen-height-scale> </buffer> <!-- SMAA buffers --> @@ -758,7 +743,7 @@ of the pixel in HDR. --> <pass> - <name>shading</name> + <name>shading-opaque</name> <type>quad</type> <effect>Effects/HDR/shading-opaque</effect> <use-shadow-pass>csm0</use-shadow-pass> @@ -769,7 +754,7 @@ <pass>geometry</pass> <clusters-bind-unit>5</clusters-bind-unit> <indices-bind-unit>6</indices-bind-unit> - <pointlights-bind-unit>14</pointlights-bind-unit> + <pointlights-bind-unit>13</pointlights-bind-unit> <spotlights-bind-unit>15</spotlights-bind-unit> </use-clustered-uniforms> <binding> @@ -815,6 +800,10 @@ <unit>12</unit> <buffer>transmittance</buffer> </binding> + <binding> + <unit>14</unit> + <buffer>prev-luminance</buffer> + </binding> <attachment> <component>color0</component> <buffer>hdr-result</buffer> @@ -853,6 +842,10 @@ <unit>12</unit> <buffer>transmittance</buffer> </binding> + <binding> + <unit>14</unit> + <buffer>prev-luminance</buffer> + </binding> <attachment> <component>color0</component> <buffer>hdr-result</buffer> @@ -908,6 +901,10 @@ <unit>13</unit> <buffer>sky-view</buffer> </binding> + <binding> + <unit>14</unit> + <buffer>prev-luminance</buffer> + </binding> <attachment> <component>color0</component> <buffer>hdr-result</buffer> @@ -946,6 +943,10 @@ <unit>0</unit> <buffer>hdr-result</buffer> </binding> + <binding> + <unit>14</unit> + <buffer>prev-luminance</buffer> + </binding> <attachment> <component>color0</component> <buffer>histogram-partial</buffer> @@ -996,165 +997,110 @@ </pass> <!-- - Generate a threshold texture for bloom - The HDR lighting buffer is filtered so we are left with an image that only - contains the brightest spots. This image is then progressively - downscaled, blurred and upscaled until we are left with the final bloom - to be applied. + Bloom effect from: + "Next Generation Post Processing in Call of Duty Advanced Warfare", + ACM Siggraph (2014). --> <pass> - <name>bloom-threshold</name> + <name>bloom-downsample1</name> <type>quad</type> - <effect>Effects/HDR/bloom-threshold</effect> + <effect>Effects/HDR/bloom-downsample-first</effect> <binding> <unit>0</unit> <buffer>hdr-result</buffer> </binding> + <attachment> + <component>color0</component> + <buffer>bloomA</buffer> + </attachment> + </pass> + <pass include="bloom-downsample-rest.xml"> + <name>bloom-downsample2</name> <binding> - <unit>1</unit> - <buffer>histogram-luminance</buffer> + <unit>0</unit> + <buffer>bloomA</buffer> </binding> <attachment> <component>color0</component> - <buffer>bloom0</buffer> + <buffer>bloomB</buffer> + </attachment> + </pass> + <pass include="bloom-downsample-rest.xml"> + <name>bloom-downsample3</name> + <binding> + <unit>0</unit> + <buffer>bloomB</buffer> + </binding> + <attachment> + <component>color0</component> + <buffer>bloomC</buffer> + </attachment> + </pass> + <pass include="bloom-downsample-rest.xml"> + <name>bloom-downsample4</name> + <binding> + <unit>0</unit> + <buffer>bloomC</buffer> + </binding> + <attachment> + <component>color0</component> + <buffer>bloomD</buffer> + </attachment> + </pass> + <pass include="bloom-downsample-rest.xml"> + <name>bloom-downsample5</name> + <binding> + <unit>0</unit> + <buffer>bloomD</buffer> + </binding> + <attachment> + <component>color0</component> + <buffer>bloomE</buffer> </attachment> </pass> - <pass include="bloom-copy-pass.xml"> - <name>bloom-copy1</name> + <pass include="bloom-upsample.xml"> + <name>bloom-upsample1</name> <binding> <unit>0</unit> - <buffer>bloom0</buffer> + <buffer>bloomE</buffer> </binding> <attachment> <component>color0</component> - <buffer>bloom1</buffer> + <buffer>bloomD</buffer> </attachment> </pass> - <pass include="bloom-copy-pass.xml"> - <name>bloom-copy2</name> + <pass include="bloom-upsample.xml"> + <name>bloom-upsample2</name> <binding> <unit>0</unit> - <buffer>bloom1</buffer> + <buffer>bloomD</buffer> </binding> <attachment> <component>color0</component> - <buffer>bloom2</buffer> + <buffer>bloomC</buffer> </attachment> </pass> - <pass include="bloom-copy-pass.xml"> - <name>bloom-copy3</name> + <pass include="bloom-upsample.xml"> + <name>bloom-upsample3</name> <binding> <unit>0</unit> - <buffer>bloom2</buffer> + <buffer>bloomC</buffer> </binding> <attachment> <component>color0</component> - <buffer>bloom3</buffer> + <buffer>bloomB</buffer> </attachment> </pass> - - <pass include="bloom-horizontal-blur-pass.xml"> - <name>bloom-hblur3</name> + <pass include="bloom-upsample.xml"> + <name>bloom-upsample4</name> <binding> <unit>0</unit> - <buffer>bloom3</buffer> + <buffer>bloomB</buffer> </binding> <attachment> <component>color0</component> - <buffer>bloom3-tmp</buffer> - </attachment> - </pass> - <pass include="bloom-vertical-blur-pass.xml"> - <name>bloom-vblur3</name> - <binding> - <unit>0</unit> - <buffer>bloom3-tmp</buffer> - </binding> - <attachment> - <component>color0</component> - <buffer>bloom3</buffer> - </attachment> - </pass> - - <pass include="bloom-horizontal-blur-pass.xml"> - <name>bloom-hblur2</name> - <binding> - <unit>0</unit> - <buffer>bloom2</buffer> - </binding> - <binding> - <unit>1</unit> - <buffer>bloom3</buffer> - </binding> - <attachment> - <component>color0</component> - <buffer>bloom2-tmp</buffer> - </attachment> - </pass> - <pass include="bloom-vertical-blur-pass.xml"> - <name>bloom-vblur2</name> - <binding> - <unit>0</unit> - <buffer>bloom2-tmp</buffer> - </binding> - <attachment> - <component>color0</component> - <buffer>bloom2</buffer> - </attachment> - </pass> - - <pass include="bloom-horizontal-blur-pass.xml"> - <name>bloom-hblur1</name> - <binding> - <unit>0</unit> - <buffer>bloom1</buffer> - </binding> - <binding> - <unit>1</unit> - <buffer>bloom2</buffer> - </binding> - <attachment> - <component>color0</component> - <buffer>bloom1-tmp</buffer> - </attachment> - </pass> - <pass include="bloom-vertical-blur-pass.xml"> - <name>bloom-vblur1</name> - <binding> - <unit>0</unit> - <buffer>bloom1-tmp</buffer> - </binding> - <attachment> - <component>color0</component> - <buffer>bloom1</buffer> - </attachment> - </pass> - - <pass include="bloom-horizontal-blur-pass.xml"> - <name>bloom-hblur0</name> - <binding> - <unit>0</unit> - <buffer>bloom0</buffer> - </binding> - <binding> - <unit>1</unit> - <buffer>bloom1</buffer> - </binding> - <attachment> - <component>color0</component> - <buffer>bloom0-tmp</buffer> - </attachment> - </pass> - <pass include="bloom-vertical-blur-pass.xml"> - <name>bloom-vblur0</name> - <binding> - <unit>0</unit> - <buffer>bloom0-tmp</buffer> - </binding> - <attachment> - <component>color0</component> - <buffer>bloom0</buffer> + <buffer>bloomA</buffer> </attachment> </pass> @@ -1174,11 +1120,7 @@ </binding> <binding> <unit>1</unit> - <buffer>histogram-luminance</buffer> - </binding> - <binding> - <unit>4</unit> - <buffer>bloom0</buffer> + <buffer>bloomA</buffer> </binding> <attachment> <component>color0</component> diff --git a/Effects/HDR/bloom-downsample-first.eff b/Effects/HDR/bloom-downsample-first.eff new file mode 100644 index 000000000..21017ef1c --- /dev/null +++ b/Effects/HDR/bloom-downsample-first.eff @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<PropertyList> + <name>Effects/HDR/bloom-downsample-first</name> + <inherits-from>Effects/HDR/bloom-downsample</inherits-from> + <parameters> + <is-first-downsample type="bool">true</is-first-downsample> + </parameters> +</PropertyList> diff --git a/Effects/HDR/bloom-downsample-rest.eff b/Effects/HDR/bloom-downsample-rest.eff new file mode 100644 index 000000000..04c2e6a95 --- /dev/null +++ b/Effects/HDR/bloom-downsample-rest.eff @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<PropertyList> + <name>Effects/HDR/bloom-downsample-rest</name> + <inherits-from>Effects/HDR/bloom-downsample</inherits-from> + <parameters> + <is-first-downsample type="bool">false</is-first-downsample> + </parameters> +</PropertyList> diff --git a/Effects/HDR/bloom-downsample.eff b/Effects/HDR/bloom-downsample.eff new file mode 100644 index 000000000..c4ff8de0d --- /dev/null +++ b/Effects/HDR/bloom-downsample.eff @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<PropertyList> + <name>Effects/HDR/bloom-downsample</name> + <technique n="1"> + <pass> + <program> + <vertex-shader>Shaders/HDR/quad_matrix.vert</vertex-shader> + <fragment-shader>Shaders/HDR/bloom_downsample.frag</fragment-shader> + <fragment-shader>Shaders/HDR/color.glsl</fragment-shader> + </program> + <uniform> + <name>tex</name> + <type>sampler-2d</type> + <value type="int">0</value> + </uniform> + <uniform> + <name>is_first_downsample</name> + <type>bool</type> + <value><use>is-first-downsample</use></value> + </uniform> + </pass> + </technique> +</PropertyList> diff --git a/Effects/HDR/bloom-threshold.eff b/Effects/HDR/bloom-threshold.eff deleted file mode 100644 index 58c61d4cd..000000000 --- a/Effects/HDR/bloom-threshold.eff +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<PropertyList> - <name>Effects/HDR/bloom-threshold</name> - <parameters> - <bloom-threshold><use>/sim/rendering/hdr/bloom-threshold</use></bloom-threshold> - <exposure-compensation> - <use>/sim/rendering/hdr/exposure-compensation</use> - </exposure-compensation> - </parameters> - <technique n="1"> - <pass> - <program> - <vertex-shader>Shaders/HDR/quad.vert</vertex-shader> - <fragment-shader>Shaders/HDR/bloom_threshold.frag</fragment-shader> - <fragment-shader>Shaders/HDR/exposure.glsl</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_threshold</name> - <type>float</type> - <value><use>bloom-threshold</use></value> - </uniform> - <!-- exposure.glsl --> - <uniform> - <name>exposure_compensation</name> - <type>float</type> - <value><use>exposure-compensation</use></value> - </uniform> - </pass> - </technique> -</PropertyList> diff --git a/Effects/HDR/bloom-upsample.eff b/Effects/HDR/bloom-upsample.eff new file mode 100644 index 000000000..57e20962e --- /dev/null +++ b/Effects/HDR/bloom-upsample.eff @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<PropertyList> + <name>Effects/HDR/bloom-upsample</name> + <parameters> + <filter-radius><use>/sim/rendering/hdr/bloom/filter-radius</use></filter-radius> + </parameters> + <technique n="1"> + <pass> + <blend> + <active>true</active> + <source>one</source> + <destination>one</destination> + </blend> + <program> + <vertex-shader>Shaders/HDR/quad.vert</vertex-shader> + <fragment-shader>Shaders/HDR/bloom_upsample.frag</fragment-shader> + </program> + <uniform> + <name>tex</name> + <type>sampler-2d</type> + <value type="int">0</value> + </uniform> + <uniform> + <name>filter_radius</name> + <type>float</type> + <value><use>filter-radius</use></value> + </uniform> + </pass> + </technique> +</PropertyList> diff --git a/Effects/HDR/blur.eff b/Effects/HDR/blur.eff deleted file mode 100644 index 5a1e463a3..000000000 --- a/Effects/HDR/blur.eff +++ /dev/null @@ -1,30 +0,0 @@ -<?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/quad.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> diff --git a/Effects/HDR/histogram-column.eff b/Effects/HDR/histogram-column.eff index 2cac7205a..f49941844 100644 --- a/Effects/HDR/histogram-column.eff +++ b/Effects/HDR/histogram-column.eff @@ -1,6 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> <PropertyList> <name>Effects/HDR/histogram-column</name> + <parameters> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> + </parameters> <technique n="1"> <pass> <program> @@ -8,12 +14,24 @@ <fragment-shader>Shaders/HDR/histogram_column.frag</fragment-shader> <fragment-shader>Shaders/HDR/color.glsl</fragment-shader> <fragment-shader>Shaders/HDR/histogram.glsl</fragment-shader> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <uniform> <name>hdr_tex</name> <type>sampler-2d</type> <value type="int">0</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> diff --git a/Effects/HDR/horizontal-blur.eff b/Effects/HDR/horizontal-blur.eff deleted file mode 100644 index 3bfb39ddb..000000000 --- a/Effects/HDR/horizontal-blur.eff +++ /dev/null @@ -1,8 +0,0 @@ -<?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> diff --git a/Effects/HDR/postprocess.eff b/Effects/HDR/postprocess.eff index 76b95fdb2..99345a278 100644 --- a/Effects/HDR/postprocess.eff +++ b/Effects/HDR/postprocess.eff @@ -2,18 +2,14 @@ <PropertyList> <name>Effects/HDR/postprocess</name> <parameters> - <bloom-magnitude><use>/sim/rendering/hdr/bloom-magnitude</use></bloom-magnitude> + <bloom-strength><use>/sim/rendering/hdr/bloom/strength</use></bloom-strength> <debug-ev100><use>/sim/rendering/hdr/debug/display-ev100</use></debug-ev100> - <exposure-compensation> - <use>/sim/rendering/hdr/exposure-compensation</use> - </exposure-compensation> </parameters> <technique n="1"> <pass> <program> <vertex-shader>Shaders/HDR/quad.vert</vertex-shader> <fragment-shader>Shaders/HDR/postprocess.frag</fragment-shader> - <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> <fragment-shader>Shaders/HDR/aces.glsl</fragment-shader> <fragment-shader>Shaders/HDR/color.glsl</fragment-shader> </program> @@ -23,31 +19,20 @@ <value type="int">0</value> </uniform> <uniform> - <name>lum_tex</name> + <name>bloom_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> - <uniform> - <name>bloom_magnitude</name> + <name>bloom_strength</name> <type>float</type> - <value><use>bloom-magnitude</use></value> + <value><use>bloom-strength</use></value> </uniform> <uniform> <name>debug_ev100</name> <type>bool</type> <value><use>debug-ev100</use></value> </uniform> - <!-- exposure.glsl --> - <uniform> - <name>exposure_compensation</name> - <type>float</type> - <value><use>exposure-compensation</use></value> - </uniform> </pass> </technique> </PropertyList> diff --git a/Effects/HDR/shading-opaque.eff b/Effects/HDR/shading-opaque.eff index 84122ff45..fa31bc150 100644 --- a/Effects/HDR/shading-opaque.eff +++ b/Effects/HDR/shading-opaque.eff @@ -20,6 +20,10 @@ <show-shadow-cascades> <use>/sim/rendering/hdr/debug/show-shadow-cascades</use> </show-shadow-cascades> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <technique n="1"> <pass> @@ -52,6 +56,7 @@ <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> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <!-- gbuffer_unpack.glsl --> <uniform> @@ -127,6 +132,17 @@ <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> diff --git a/Effects/HDR/vertical-blur.eff b/Effects/HDR/vertical-blur.eff deleted file mode 100644 index 178930ee3..000000000 --- a/Effects/HDR/vertical-blur.eff +++ /dev/null @@ -1,8 +0,0 @@ -<?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> diff --git a/Effects/HDR/water-shading.eff b/Effects/HDR/water-shading.eff index d0670c65e..94659d378 100644 --- a/Effects/HDR/water-shading.eff +++ b/Effects/HDR/water-shading.eff @@ -1,6 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> <PropertyList> <name>Effects/HDR/water-shading</name> + <parameters> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> + </parameters> <technique n="1"> <pass> <stencil> @@ -15,6 +21,7 @@ <fragment-shader>Shaders/HDR/pos_from_depth.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> </program> <uniform> <name>gbuffer0_tex</name> @@ -48,6 +55,17 @@ <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> diff --git a/Effects/cloud-impostor.eff b/Effects/cloud-impostor.eff index 988fe4947..4b4ac6879 100644 --- a/Effects/cloud-impostor.eff +++ b/Effects/cloud-impostor.eff @@ -20,7 +20,11 @@ <use_night_vision><use>/sim/rendering/als-filters/use-night-vision</use></use_night_vision> <use_IR_vision><use>/sim/rendering/als-filters/use-IR-vision</use></use_IR_vision> <display_xsize><use>/sim/startup/xsize</use></display_xsize> - <display_ysize><use>/sim/startup/ysize</use></display_ysize> + <display_ysize><use>/sim/startup/ysize</use></display_ysize> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <technique n="9"> @@ -263,6 +267,7 @@ <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader> <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader> <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <uniform> <name>base_tex</name> @@ -280,6 +285,17 @@ <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> diff --git a/Effects/cloud-noctilucent.eff b/Effects/cloud-noctilucent.eff index d42fb1db9..6ffc58b28 100644 --- a/Effects/cloud-noctilucent.eff +++ b/Effects/cloud-noctilucent.eff @@ -8,6 +8,10 @@ <altitude><use>/sim/rendering/eye-altitude-m</use></altitude> <cloud_self_shading><use>/environment/cloud-self-shading</use></cloud_self_shading> <moonlight><use>/environment/moonlight</use></moonlight> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <technique n="9"> @@ -183,6 +187,7 @@ <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader> <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader> <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <uniform> <name>base_tex</name> @@ -200,6 +205,17 @@ <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> diff --git a/Effects/cloud-static.eff b/Effects/cloud-static.eff index da0794bda..b34feceda 100644 --- a/Effects/cloud-static.eff +++ b/Effects/cloud-static.eff @@ -20,6 +20,10 @@ <use_IR_vision><use>/sim/rendering/als-filters/use-IR-vision</use></use_IR_vision> <display_xsize><use>/sim/startup/xsize</use></display_xsize> <display_ysize><use>/sim/startup/ysize</use></display_ysize> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <technique n="8"> @@ -391,6 +395,7 @@ <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader> <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader> <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <uniform> <name>base_tex</name> @@ -408,6 +413,17 @@ <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> diff --git a/Effects/cloud.eff b/Effects/cloud.eff index e7ee2fad5..0a0b8ae92 100644 --- a/Effects/cloud.eff +++ b/Effects/cloud.eff @@ -27,6 +27,10 @@ <use_IR_vision><use>/sim/rendering/als-filters/use-IR-vision</use></use_IR_vision> <display_xsize><use>/sim/startup/xsize</use></display_xsize> <display_ysize><use>/sim/startup/ysize</use></display_ysize> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <technique n="8"> @@ -504,6 +508,7 @@ <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader> <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader> <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> <attribute> <name>usrAttr1</name> <index>10</index> @@ -539,6 +544,17 @@ <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> diff --git a/Effects/model-pbr-transparent.eff b/Effects/model-pbr-transparent.eff index 5b6d3e13f..dbb07c5bd 100644 --- a/Effects/model-pbr-transparent.eff +++ b/Effects/model-pbr-transparent.eff @@ -18,6 +18,10 @@ <wrap-t>clamp-to-edge</wrap-t> <internal-format>normalized</internal-format> </texture> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <technique n="108"> @@ -100,6 +104,7 @@ <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> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> <attribute> <name>tangent</name> <index>6</index> @@ -192,6 +197,17 @@ <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> diff --git a/Effects/model-transparent.eff b/Effects/model-transparent.eff index cc692842f..6f716bed1 100644 --- a/Effects/model-transparent.eff +++ b/Effects/model-transparent.eff @@ -20,6 +20,10 @@ <wrap-t>clamp-to-edge</wrap-t> <internal-format>normalized</internal-format> </texture> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <!-- Place objects in render bin 111 (frontmost transparent objects). @@ -105,6 +109,7 @@ <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> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <uniform> <name>color_tex</name> @@ -154,6 +159,17 @@ <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> diff --git a/Effects/skydome.eff b/Effects/skydome.eff index 63291f23f..75bbded4e 100644 --- a/Effects/skydome.eff +++ b/Effects/skydome.eff @@ -44,6 +44,10 @@ <fact_black><use>/sim/rendering/als-filters/black-factor</use></fact_black> <delta_T>-50.0</delta_T> <air_pollution><use>/environment/air-pollution-norm</use></air_pollution> + <!-- exposure.glsl --> + <exposure-compensation> + <use>/sim/rendering/hdr/exposure-compensation</use> + </exposure-compensation> </parameters> <technique n="8"> <predicate> @@ -316,11 +320,12 @@ <fragment-shader>Shaders/HDR/skydome.frag</fragment-shader> <fragment-shader>Shaders/HDR/math.glsl</fragment-shader> <fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <uniform> - <name>sun_disk</name> + <name>is_envmap</name> <type>bool</type> - <value type="bool">true</value> + <value type="bool">false</value> </uniform> <uniform> <name>transmittance_tex</name> @@ -332,6 +337,17 @@ <type>sampler-2d</type> <value type="int">13</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> <technique n="139"> @@ -346,11 +362,12 @@ <fragment-shader>Shaders/HDR/skydome.frag</fragment-shader> <fragment-shader>Shaders/HDR/math.glsl</fragment-shader> <fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader> + <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader> </program> <uniform> - <name>sun_disk</name> + <name>is_envmap</name> <type>bool</type> - <value type="bool">false</value> + <value type="bool">true</value> </uniform> <uniform> <name>transmittance_tex</name> @@ -362,6 +379,17 @@ <type>sampler-2d</type> <value type="int">13</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> diff --git a/Shaders/HDR/3dcloud.frag b/Shaders/HDR/3dcloud.frag index d3d8798e0..a25e76aa4 100644 --- a/Shaders/HDR/3dcloud.frag +++ b/Shaders/HDR/3dcloud.frag @@ -19,6 +19,8 @@ const int STEPS = 8; // aerial_perspective.glsl vec3 mix_aerial_perspective(vec3 color, vec4 ap); +// exposure.glsl +vec3 apply_exposure(vec3 color); void main() { @@ -59,9 +61,12 @@ void main() 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(1.0, T, fade); + color.rgb *= base.a * mix(0.5, T, fade); color.rgb = mix_aerial_perspective(color.rgb, ap_color); + // Pre-expose + color.rgb = apply_exposure(color.rgb); + fragColor = color; } diff --git a/Shaders/HDR/bloom_downsample.frag b/Shaders/HDR/bloom_downsample.frag new file mode 100644 index 000000000..67899eb67 --- /dev/null +++ b/Shaders/HDR/bloom_downsample.frag @@ -0,0 +1,89 @@ +/* + * Bloom - downsampling step + * "Next Generation Post Processing in Call of Duty Advanced Warfare" + * ACM Siggraph (2014) + * Based on the implementation by Alexander Christensen + * https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom + */ + +#version 330 core + +layout(location = 0) out vec3 fragColor; + +in vec2 texcoord; + +uniform sampler2D tex; +uniform bool is_first_downsample; + +// color.glsl +float linear_srgb_to_luminance(vec3 color); +vec3 eotf_sRGB(vec3 linear_srgb); + +float karis_average(vec3 color) +{ + return 1.0 / (1.0 + linear_srgb_to_luminance(color)); +} + +void main() +{ + vec2 texel_size = 1.0 / vec2(textureSize(tex, 0)); + float x = texel_size.x; + float y = texel_size.y; + + // Take 13 samples around current texel + // a - b - c + // - j - k - + // d - e - f + // - l - m - + // g - h - i + // === ('e' is the current texel) === + vec3 a = texture(tex, vec2(texcoord.x - 2*x, texcoord.y + 2*y)).rgb; + vec3 b = texture(tex, vec2(texcoord.x, texcoord.y + 2*y)).rgb; + vec3 c = texture(tex, vec2(texcoord.x + 2*x, texcoord.y + 2*y)).rgb; + + vec3 d = texture(tex, vec2(texcoord.x - 2*x, texcoord.y)).rgb; + vec3 e = texture(tex, vec2(texcoord.x, texcoord.y)).rgb; + vec3 f = texture(tex, vec2(texcoord.x + 2*x, texcoord.y)).rgb; + + vec3 g = texture(tex, vec2(texcoord.x - 2*x, texcoord.y - 2*y)).rgb; + vec3 h = texture(tex, vec2(texcoord.x, texcoord.y - 2*y)).rgb; + vec3 i = texture(tex, vec2(texcoord.x + 2*x, texcoord.y - 2*y)).rgb; + + vec3 j = texture(tex, vec2(texcoord.x - x, texcoord.y + y)).rgb; + vec3 k = texture(tex, vec2(texcoord.x + x, texcoord.y + y)).rgb; + vec3 l = texture(tex, vec2(texcoord.x - x, texcoord.y - y)).rgb; + vec3 m = texture(tex, vec2(texcoord.x + x, texcoord.y - y)).rgb; + + vec3 downsample; + if (is_first_downsample) { + // Apply Karis average to each block of 4 samples to prevent fireflies. + // Only done on the first downsampling step. + vec3 group0 = (a+b+d+e) * 0.25; + vec3 group1 = (b+c+e+f) * 0.25; + vec3 group2 = (d+e+g+h) * 0.25; + vec3 group3 = (e+f+h+i) * 0.25; + vec3 group4 = (j+k+l+m) * 0.25; + float kw0 = karis_average(group0); + float kw1 = karis_average(group1); + float kw2 = karis_average(group2); + float kw3 = karis_average(group3); + float kw4 = karis_average(group4); + float kw_sum = kw0 + kw1 + kw2 + kw3 + kw4; + downsample = + kw0 * group0 + + kw1 * group1 + + kw2 * group2 + + kw3 * group3 + + kw4 * group4; + downsample /= kw_sum; + } else { + // Apply weighted distribution: + // 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1 + downsample = e*0.125; + downsample += (a+c+g+i)*0.03125; + downsample += (b+d+f+h)*0.0625; + downsample += (j+k+l+m)*0.125; + } + + fragColor = downsample; +} diff --git a/Shaders/HDR/bloom_threshold.frag b/Shaders/HDR/bloom_threshold.frag deleted file mode 100644 index 4140d75b7..000000000 --- a/Shaders/HDR/bloom_threshold.frag +++ /dev/null @@ -1,25 +0,0 @@ -#version 330 core - -layout(location = 0) out vec3 fragColor; - -in vec2 texcoord; - -uniform sampler2D hdr_tex; -uniform sampler2D lum_tex; - -uniform float bloom_threshold; - -// exposure.glsl -vec3 apply_exposure(vec3 color, float avg_lum, float threshold); - -void main() -{ - vec3 hdr_color = texture(hdr_tex, texcoord).rgb; - float avg_lum = texelFetch(lum_tex, ivec2(0), 0).r; - - vec3 exposed_hdr_color = apply_exposure(hdr_color, avg_lum, bloom_threshold); - if (dot(exposed_hdr_color, vec3(0.333)) <= 0.001) - fragColor = vec3(0.0); - else - fragColor = exposed_hdr_color; -} diff --git a/Shaders/HDR/bloom_upsample.frag b/Shaders/HDR/bloom_upsample.frag new file mode 100644 index 000000000..d07149a6a --- /dev/null +++ b/Shaders/HDR/bloom_upsample.frag @@ -0,0 +1,52 @@ +/* + * Bloom - upsampling step + * "Next Generation Post Processing in Call of Duty Advanced Warfare" + * ACM Siggraph (2014) + * Based on the implementation by Alexander Christensen + * https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom + */ + +#version 330 core + +layout(location = 0) out vec3 fragColor; + +in vec2 texcoord; + +uniform sampler2D tex; +uniform float filter_radius; + +void main() +{ + // The filter kernel is applied with a radius, specified in texture + // coordinates, so that the radius will vary across mip resolutions. + float x = filter_radius; + float y = filter_radius; + + // Take 9 samples around current texel: + // a - b - c + // d - e - f + // g - h - i + // === ('e' is the current texel) === + vec3 a = texture(tex, vec2(texcoord.x - x, texcoord.y + y)).rgb; + vec3 b = texture(tex, vec2(texcoord.x, texcoord.y + y)).rgb; + vec3 c = texture(tex, vec2(texcoord.x + x, texcoord.y + y)).rgb; + + vec3 d = texture(tex, vec2(texcoord.x - x, texcoord.y)).rgb; + vec3 e = texture(tex, vec2(texcoord.x, texcoord.y)).rgb; + vec3 f = texture(tex, vec2(texcoord.x + x, texcoord.y)).rgb; + + vec3 g = texture(tex, vec2(texcoord.x - x, texcoord.y - y)).rgb; + vec3 h = texture(tex, vec2(texcoord.x, texcoord.y - y)).rgb; + vec3 i = texture(tex, vec2(texcoord.x + x, texcoord.y - y)).rgb; + + // Apply weighted distribution, by using a 3x3 tent filter: + // 1 | 1 2 1 | + // -- * | 2 4 2 | + // 16 | 1 2 1 | + vec3 upsample = e * 4.0; + upsample += (b+d+f+h) * 2.0; + upsample += (a+c+g+i); + upsample /= 16.0; + + fragColor = upsample; +} diff --git a/Shaders/HDR/blur.frag b/Shaders/HDR/blur.frag deleted file mode 100644 index de372e74e..000000000 --- a/Shaders/HDR/blur.frag +++ /dev/null @@ -1,33 +0,0 @@ -#version 330 core - -layout(location = 0) 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; -} diff --git a/Shaders/HDR/color.glsl b/Shaders/HDR/color.glsl index 0e79860e5..bd19d25ec 100644 --- a/Shaders/HDR/color.glsl +++ b/Shaders/HDR/color.glsl @@ -2,7 +2,7 @@ float linear_srgb_to_luminance(vec3 color) { - return dot(color, vec3(0.2125, 0.7154, 0.0721)); + return dot(color, vec3(0.2126, 0.7152, 0.0722)); } /* diff --git a/Shaders/HDR/exposure.glsl b/Shaders/HDR/exposure.glsl index 4421d43c1..8e67f20e2 100644 --- a/Shaders/HDR/exposure.glsl +++ b/Shaders/HDR/exposure.glsl @@ -1,5 +1,6 @@ #version 330 core +uniform sampler2D lum_tex; uniform float exposure_compensation; const float one_over_log10 = 1.0 / log(10.0); @@ -18,11 +19,21 @@ float key_value(float L) return 1.0 - 2.0 / (log10(L + 1.0) + 2.0); } -vec3 apply_exposure(vec3 color, float avg_lum, float threshold) +float get_exposure() { - avg_lum = max(avg_lum, 0.001); + float avg_lum = max(texelFetch(lum_tex, ivec2(0), 0).r, 0.001); float linear_exposure = key_value(avg_lum) / avg_lum; float exposure = log2(max(linear_exposure, 0.0001)); - exposure += exposure_compensation - threshold; - return color * exp2(exposure); + exposure += exposure_compensation; + return exposure; +} + +vec3 apply_exposure(vec3 color) +{ + return color * exp2(get_exposure()); +} + +vec3 undo_exposure(vec3 color) +{ + return color / exp2(get_exposure()); } diff --git a/Shaders/HDR/histogram_column.frag b/Shaders/HDR/histogram_column.frag index bd3202ba0..cd1083b76 100644 --- a/Shaders/HDR/histogram_column.frag +++ b/Shaders/HDR/histogram_column.frag @@ -8,6 +8,8 @@ uniform sampler2D hdr_tex; float linear_srgb_to_luminance(vec3 color); // histogram.glsl uint luminance_to_bin_index(float luminance); +// exposure.glsl +vec3 undo_exposure(vec3 color); void main() { @@ -19,6 +21,7 @@ void main() for (int row = 0; row < hdr_tex_size.y; ++row) { vec3 hdr_color = texelFetch(hdr_tex, ivec2(column, row), 0).rgb; + hdr_color = undo_exposure(hdr_color); // sRGB to relative luminance float lum = linear_srgb_to_luminance(hdr_color); // Get the bin index corresponding to the given pixel luminance diff --git a/Shaders/HDR/postprocess.frag b/Shaders/HDR/postprocess.frag index f3853c029..87ced3d8a 100644 --- a/Shaders/HDR/postprocess.frag +++ b/Shaders/HDR/postprocess.frag @@ -5,16 +5,13 @@ layout(location = 0) out vec4 fragColor; in vec2 texcoord; uniform sampler2D hdr_tex; -uniform sampler2D lum_tex; uniform sampler2D bloom_tex; uniform vec2 fg_BufferSize; -uniform float bloom_magnitude; +uniform float bloom_strength; uniform bool debug_ev100; -// exposure.glsl -vec3 apply_exposure(vec3 color, float avg_lum, float threshold); // aces.glsl vec3 aces_fitted(vec3 color); // color.glsl @@ -53,24 +50,20 @@ float rand2D(vec2 co) void main() { vec3 hdr_color = texture(hdr_tex, texcoord).rgb; - float avg_lum = texelFetch(lum_tex, ivec2(0), 0).r; - - // Exposure - vec3 exposed_hdr_color = apply_exposure(hdr_color, avg_lum, 0.0); if (debug_ev100) { - fragColor = vec4(get_ev100_color(exposed_hdr_color), 1.0); + fragColor = vec4(get_ev100_color(hdr_color), 1.0); return; } + // Apply bloom + vec3 bloom = texture(bloom_tex, texcoord).rgb; + hdr_color = mix(hdr_color, bloom, bloom_strength); + // Tonemap - vec3 color = aces_fitted(exposed_hdr_color); + vec3 color = aces_fitted(hdr_color); // Gamma correction color = eotf_sRGB(color); - // Bloom - vec3 bloom = texture(bloom_tex, texcoord).rgb; - color += bloom.rgb * bloom_magnitude; - // Dithering color += mix(-0.5/255.0, 0.5/255.0, rand2D(texcoord)); diff --git a/Shaders/HDR/shading_opaque.glsl b/Shaders/HDR/shading_opaque.glsl index fdb8156af..be4cdbe5f 100644 --- a/Shaders/HDR/shading_opaque.glsl +++ b/Shaders/HDR/shading_opaque.glsl @@ -24,6 +24,8 @@ vec3 get_sun_radiance(vec3 p); // clustered.glsl vec3 eval_scene_lights(vec3 base_color, float metallic, float roughness, vec3 f0, vec3 P, vec3 N, vec3 V); +// exposure.glsl +vec3 apply_exposure(vec3 color); vec3 eval_lights( vec3 base_color, float metallic, float roughness, float occlusion, @@ -60,6 +62,9 @@ vec3 eval_lights( // Add aerial perspective color = add_aerial_perspective(color, uv, length(P)); + // Pre-expose + color = apply_exposure(color); + color = debug_shadow_color(color, P, N, fg_SunDirection); return color; diff --git a/Shaders/HDR/shading_transparent.glsl b/Shaders/HDR/shading_transparent.glsl index 9353f8ea0..fea405a60 100644 --- a/Shaders/HDR/shading_transparent.glsl +++ b/Shaders/HDR/shading_transparent.glsl @@ -21,6 +21,8 @@ vec3 get_sun_radiance(vec3 p); // clustered.glsl vec3 eval_scene_lights(vec3 base_color, float metallic, float roughness, vec3 f0, vec3 P, vec3 N, vec3 V); +// exposure.glsl +vec3 apply_exposure(vec3 color); vec3 eval_lights_transparent( vec3 base_color, float metallic, float roughness, float occlusion, @@ -54,6 +56,9 @@ vec3 eval_lights_transparent( // Add aerial perspective color = mix_aerial_perspective(color, ap); + // Pre-expose + color = apply_exposure(color); + color = debug_shadow_color(color, P, N, fg_SunDirection); return color; diff --git a/Shaders/HDR/skydome.frag b/Shaders/HDR/skydome.frag index 3c7116e74..85ac14079 100644 --- a/Shaders/HDR/skydome.frag +++ b/Shaders/HDR/skydome.frag @@ -5,7 +5,7 @@ layout(location = 0) out vec4 fragColor; in vec3 ray_dir; in vec3 ray_dir_view; -uniform bool sun_disk; +uniform bool is_envmap; uniform sampler2D sky_view_tex; uniform sampler2D transmittance_tex; @@ -15,19 +15,36 @@ uniform float fg_EarthRadius; uniform vec3 fg_CameraViewUp; const float ATMOSPHERE_RADIUS = 6471e3; -const float sun_solid_angle = radians(0.545); // ~half a degree -const float sun_cos_solid_angle = cos(sun_solid_angle); -// Limb darkening constants, sampled for -// 630, 560, 490, 430 nanometers -const vec4 u = vec4(1.0); -const vec4 alpha = vec4(0.429, 0.502, 0.575, 0.643); +const float SUN_HALF_ANGULAR_DIAMETER = 0.0047560222116845481; // radians(0.545 deg / 2) +const float SUN_COS_HALF_ANGULAR_DIAMETER = 0.9999886901476798392; // cos(radians(0.545 deg / 2)) +const float SUN_SIN_HALF_ANGULAR_DIAMETER = 0.0047560042817014138; // sin(radians(0.545 deg / 2)) // math.glsl float M_PI(); +float sqr(float x); +float saturate(float x); // atmos_spectral.glsl vec4 get_sun_spectral_irradiance(); vec3 linear_srgb_from_spectral_samples(vec4 L); +// exposure.glsl +vec3 apply_exposure(vec3 color); + +/* + * Limb darkening + * http://www.physics.hmc.edu/faculty/esin/a101/limbdarkening.pdf + */ +vec4 get_sun_darkening_factor(float cos_theta) +{ + // Coefficients sampled for wavelengths 630, 560, 490, 430 nm + const vec4 u = vec4(1.0); + const vec4 alpha = vec4(0.429, 0.502, 0.575, 0.643); + float sin_theta = sqrt(1.0 - sqr(cos_theta)); + float center_to_edge = saturate(sin_theta / SUN_SIN_HALF_ANGULAR_DIAMETER); + float mu = sqrt(1.0 - sqr(center_to_edge)); + vec4 factor = vec4(1.0) - u * (vec4(1.0) - pow(vec4(mu), alpha)); + return factor; +} void main() { @@ -42,34 +59,44 @@ void main() // Now multiply by the sun irradiance. sky_radiance *= get_sun_spectral_irradiance(); - if (sun_disk) { + if (is_envmap == false) { // Render the Sun disk - vec3 ray_dir_view = normalize(ray_dir_view); - float cos_theta = dot(ray_dir_view, fg_SunDirection); + vec3 vs_ray_dir = normalize(ray_dir_view); + float cos_theta = dot(vs_ray_dir, fg_SunDirection); - if (cos_theta >= sun_cos_solid_angle) { + if (cos_theta >= SUN_COS_HALF_ANGULAR_DIAMETER) { float normalized_altitude = (fg_CameraDistanceToEarthCenter - fg_EarthRadius) / (ATMOSPHERE_RADIUS - fg_EarthRadius); - float sun_zenith_cos_theta = dot(-ray_dir_view, fg_CameraViewUp); + float sun_zenith_cos_theta = dot(-vs_ray_dir, fg_CameraViewUp); vec2 uv = vec2(sun_zenith_cos_theta * 0.5 + 0.5, clamp(normalized_altitude, 0.0, 1.0)); vec4 transmittance = texture(transmittance_tex, uv); - // Limb darkening - // http://www.physics.hmc.edu/faculty/esin/a101/limbdarkening.pdf - float center_to_edge = 1.0 - (cos_theta - sun_cos_solid_angle) - / (1.0 - sun_cos_solid_angle); - float mu = sqrt(max(1.0 - center_to_edge*center_to_edge, 0.0)); - vec4 factor = vec4(1.0) - u * (vec4(1.0) - pow(vec4(mu), alpha)); + vec4 darkening_factor = get_sun_darkening_factor(cos_theta); + + // To get the actual sun radiance we should divide the irradiance + // by the solid angle subtended by the Sun, but the resulting + // radiance is too big to store in an rgb16f buffer. Also the bloom + // gets blown out too much. + // Instead, just multiply by a fixed value that looks good enough. + vec4 sun_radiance = get_sun_spectral_irradiance() * 500.0; + + sun_radiance *= transmittance * darkening_factor; - vec4 sun_radiance = get_sun_spectral_irradiance() * transmittance * factor; sky_radiance += sun_radiance; } } vec3 sky_color = linear_srgb_from_spectral_samples(sky_radiance); + + if (is_envmap == false) { + // Only pre-expose when not rendering to the environment map. + // We want the non-exposed radiance values for IBL. + sky_color = apply_exposure(sky_color); + } + fragColor = vec4(sky_color, 1.0); } diff --git a/Shaders/HDR/water.frag b/Shaders/HDR/water.frag index 3a1537b32..987f28806 100644 --- a/Shaders/HDR/water.frag +++ b/Shaders/HDR/water.frag @@ -6,7 +6,7 @@ layout(location = 1) out vec4 outGBuffer1; in vec4 waterTex1; in vec4 waterTex2; in mat3 TBN; -in vec3 ecPosition; +in vec3 relpos; in vec2 TopoUV; uniform sampler2D perlin_normalmap; @@ -132,10 +132,11 @@ void main() // there's no need to do wave patterns or foam for pixels which are so // far away that we can't actually see them // we only need detail in the near zone or where the sun reflection is - float dist = length(ecPosition); - bool detailed = (dist < 15000.0) - || (dot(fg_SunDirection, normalize(ecPosition)) >= 0.7); - if (detailed) { + int detail_flag; + float dist = length(relpos); + if ((dist > 15000.0) && (dot(normalize(vec3(fg_SunDirection.x, fg_SunDirection.y, 0.0) ), normalize(relpos)) < 0.7 )) {detail_flag = 0;} + else {detail_flag = 1;} + if (detail_flag == 1) { angle = 0.0; wave0.freq = WaveFreq ; wave0.amp = WaveAmp; diff --git a/Shaders/HDR/water.vert b/Shaders/HDR/water.vert index 8a6078a76..61c80451c 100644 --- a/Shaders/HDR/water.vert +++ b/Shaders/HDR/water.vert @@ -6,13 +6,14 @@ layout(location = 3) in vec4 multiTexCoord0; out vec4 waterTex1; out vec4 waterTex2; out mat3 TBN; -out vec3 ecPosition; +out vec3 relpos; out vec2 TopoUV; uniform float WindE, WindN; uniform float osg_SimulationTime; uniform mat4 osg_ModelViewMatrix; +uniform mat4 osg_ModelViewMatrixInverse; uniform mat4 osg_ModelViewProjectionMatrix; uniform mat4 osg_ViewMatrixInverse; uniform mat3 osg_NormalMatrix; @@ -34,7 +35,13 @@ void rotationmatrix(float angle, out mat4 rotmat) void main() { gl_Position = osg_ModelViewProjectionMatrix * pos; - ecPosition = (osg_ModelViewMatrix * pos).xyz; + + // first current altitude of eye position in model space + vec4 ep = osg_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0); + // and relative position to vector + relpos = pos.xyz - ep.xyz; + + vec3 rawPos = (osg_ViewMatrixInverse * osg_ModelViewMatrix * pos).xyz; // Using precalculated vectors // vec3 T = normalize(osg_NormalMatrix * tangent); @@ -67,7 +74,6 @@ void main() waterTex2 = multiTexCoord0 * RotationMatrix - t2 * windFactor; // Geodesy lookup for depth map - vec3 rawPos = (osg_ViewMatrixInverse * vec4(ecPosition, 1.0)).xyz; float e2 = abs(1.0 - squash * squash); float ra2 = 1.0/(a * a); float e4 = e2 * e2; diff --git a/Shaders/HDR/water_shading.frag b/Shaders/HDR/water_shading.frag index d69656bf5..d84ad1c79 100644 --- a/Shaders/HDR/water_shading.frag +++ b/Shaders/HDR/water_shading.frag @@ -23,6 +23,8 @@ vec3 get_view_space_from_depth(vec2 uv); // aerial_perspective.glsl vec3 add_aerial_perspective(vec3 color, vec2 coord, float depth); vec3 get_sun_radiance_sea_level(); +// exposure.glsl +vec3 apply_exposure(vec3 color); float F_Schlick(float VdotH, float F0) { @@ -74,5 +76,8 @@ void main() color = add_aerial_perspective(color, texcoord, length(P)); + // Pre-expose + color = apply_exposure(color); + fragColor = color; } diff --git a/defaults.xml b/defaults.xml index f9a41d9b6..bb1371f12 100644 --- a/defaults.xml +++ b/defaults.xml @@ -535,8 +535,10 @@ 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> - <bloom-magnitude type="float">0.5</bloom-magnitude> - <bloom-threshold type="float">8.0</bloom-threshold> + <bloom> + <strength type="float">0.01</strength> + <filter-radius type="float">0.005</filter-radius> + </bloom> <ambient-occlusion> <enabled type="bool" userarchive="y">true</enabled> <world-radius type="float">0.2</world-radius>