HDR: Optimize the G-Buffer and do not separate the occlusion texture
- The G-Buffer layout has been redesigned to be 96 bits per pixel. There are 24 unused bits that can be used for extra material parameters later (like clearcoat). - Add better debug views for the G-Buffer. - Use octahedron normal encoding. This yields the same results as the previous method but uses 16 bits less. - Use rg11fb10f for the environment mapping cubemaps. - Tweak the shadow mapping parameters and add a colored debug mode. - Only render shadow maps for objects that inherit from model-default.eff or model-pbr.eff instead of having a fallback Effect. Now transparent objects should be ignored (if they are marked as such with model-transparent or similar). - Remove the separate occlusion texture. Now the PBR Effect expects a single texture where R=occlusion, G=roughness and B=metallic.
This commit is contained in:
parent
a789c24209
commit
9f39644199
34 changed files with 509 additions and 253 deletions
|
@ -7,29 +7,42 @@
|
|||
<use-vertex-attribute-aliasing>true</use-vertex-attribute-aliasing>
|
||||
|
||||
<!--
|
||||
G-Buffer
|
||||
.........................................................
|
||||
: Buffer : Red : Green : Blue : Alpha :
|
||||
:........:...........:...........:..........:...........:
|
||||
: RT0 : albedo.r : albedo.g : albedo.b : AO/Cavity :
|
||||
: RT1 : normal.x : normal.y :
|
||||
: RT2 : Metalness : Roughness : Clearcoat :
|
||||
: RT3 : Depth :
|
||||
:........:...........:...........:..........:...........:
|
||||
G-Buffer layout
|
||||
..........................................................................
|
||||
: : Red : Green : Blue : Alpha :
|
||||
:.......................:...........:.........:............:.............:
|
||||
: G-Buffer 0 (RGB10_A2) : Normal : Roughness : Material ID :
|
||||
: G-Buffer 1 (RGBA8) : Base Color : Metallic :
|
||||
: G-Buffer 2 (RGBA8) : Material specific params : Occlusion :
|
||||
: Depth/Stencil : DEPTH32F_STENCIL8 (Reversed depth) :
|
||||
:.......................:............:.........:...........:.............:
|
||||
|
||||
Notes:
|
||||
- Two 10-bit channels is enough for normals, as long as we are using
|
||||
octahedron normal encoding.
|
||||
- Since the Material ID is stored in 2 bits, we can only have 4 different
|
||||
material types. The maximum value (3 or 1.0) is reserved for the standard
|
||||
PBR metallic-roughness material.
|
||||
- In 'Material specific params' fancier materials can use up to 24 bits
|
||||
to encode any information they might need (e.g. a clearcoat layer needs
|
||||
to store the clearcoat amount and roughness).
|
||||
- Materials that are very different from the standard should write
|
||||
whatever they need in the G-Buffer without adhering to this layout and use
|
||||
the stencil buffer and a separate render pass.
|
||||
-->
|
||||
<buffer>
|
||||
<name>gbuffer0</name>
|
||||
<type>2d</type>
|
||||
<width>screen</width>
|
||||
<height>screen</height>
|
||||
<format>rgba8</format>
|
||||
<format>rgb10-a2</format>
|
||||
</buffer>
|
||||
<buffer>
|
||||
<name>gbuffer1</name>
|
||||
<type>2d</type>
|
||||
<width>screen</width>
|
||||
<height>screen</height>
|
||||
<format>rg16f</format>
|
||||
<format>rgba8</format>
|
||||
</buffer>
|
||||
<buffer>
|
||||
<name>gbuffer2</name>
|
||||
|
@ -116,7 +129,7 @@
|
|||
<type>cubemap</type>
|
||||
<width>128</width>
|
||||
<height>128</height>
|
||||
<format>rgb16f</format>
|
||||
<format>r11f-g11f-b10f</format>
|
||||
<min-filter>linear-mipmap-linear</min-filter>
|
||||
<mag-filter>linear</mag-filter>
|
||||
<wrap-s>clamp-to-edge</wrap-s>
|
||||
|
@ -128,7 +141,7 @@
|
|||
<type>cubemap</type>
|
||||
<width>128</width>
|
||||
<height>128</height>
|
||||
<format>rgb16f</format>
|
||||
<format>r11f-g11f-b10f</format>
|
||||
<min-filter>linear-mipmap-linear</min-filter>
|
||||
<mag-filter>linear</mag-filter>
|
||||
<wrap-s>clamp-to-edge</wrap-s>
|
||||
|
@ -157,7 +170,7 @@
|
|||
<type>2d</type>
|
||||
<width>1024</width>
|
||||
<height>1024</height>
|
||||
<format>r16f</format>
|
||||
<format>r32f</format>
|
||||
<min-filter>linear-mipmap-nearest</min-filter>
|
||||
<mag-filter>nearest</mag-filter>
|
||||
<mipmap-levels>10</mipmap-levels>
|
||||
|
@ -167,7 +180,7 @@
|
|||
<type>2d</type>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
<format>r16f</format>
|
||||
<format>r32f</format>
|
||||
<min-filter>nearest</min-filter>
|
||||
<mag-filter>nearest</mag-filter>
|
||||
</buffer>
|
||||
|
@ -176,7 +189,7 @@
|
|||
<type>2d</type>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
<format>r16f</format>
|
||||
<format>r32f</format>
|
||||
<min-filter>nearest</min-filter>
|
||||
<mag-filter>nearest</mag-filter>
|
||||
</buffer>
|
||||
|
@ -260,6 +273,31 @@
|
|||
|
||||
<!--=======================================================================-->
|
||||
|
||||
<!--
|
||||
Clear the G-Buffer if we are debugging it to avoid the dreaded
|
||||
'Solitaire Effect' :)
|
||||
-->
|
||||
<pass>
|
||||
<name>debug-clear-gbuffer</name>
|
||||
<type>quad</type>
|
||||
<effect>Effects/HDR/gbuffer-debug-clear</effect>
|
||||
<condition>
|
||||
<property>/sim/rendering/hdr/debug/show-gbuffer</property>
|
||||
</condition>
|
||||
<attachment>
|
||||
<component>color0</component>
|
||||
<buffer>gbuffer0</buffer>
|
||||
</attachment>
|
||||
<attachment>
|
||||
<component>color1</component>
|
||||
<buffer>gbuffer1</buffer>
|
||||
</attachment>
|
||||
<attachment>
|
||||
<component>color2</component>
|
||||
<buffer>gbuffer2</buffer>
|
||||
</attachment>
|
||||
</pass>
|
||||
|
||||
<!--
|
||||
Generate the atmospheric scattering related LUTs
|
||||
This is an implementation of Sébastien Hillaire's "A Scalable and
|
||||
|
@ -641,7 +679,7 @@
|
|||
<pass include="csm-pass.xml">
|
||||
<name>csm0</name>
|
||||
<near-m>0.1</near-m>
|
||||
<far-m>3.0</far-m>
|
||||
<far-m>2.0</far-m>
|
||||
<viewport>
|
||||
<x>0.0</x>
|
||||
<y>0.0</y>
|
||||
|
@ -651,8 +689,8 @@
|
|||
</pass>
|
||||
<pass include="csm-pass.xml">
|
||||
<name>csm1</name>
|
||||
<near-m>3.0</near-m>
|
||||
<far-m>70.0</far-m>
|
||||
<near-m>2.0</near-m>
|
||||
<far-m>40.0</far-m>
|
||||
<viewport>
|
||||
<x>0.5</x>
|
||||
<y>0.0</y>
|
||||
|
@ -662,8 +700,8 @@
|
|||
</pass>
|
||||
<pass include="csm-pass.xml">
|
||||
<name>csm2</name>
|
||||
<near-m>70.0</near-m>
|
||||
<far-m>300.0</far-m>
|
||||
<near-m>40.0</near-m>
|
||||
<far-m>150.0</far-m>
|
||||
<viewport>
|
||||
<x>0.0</x>
|
||||
<y>0.5</y>
|
||||
|
@ -673,8 +711,8 @@
|
|||
</pass>
|
||||
<pass include="csm-pass.xml">
|
||||
<name>csm3</name>
|
||||
<near-m>300.0</near-m>
|
||||
<far-m>1000.0</far-m>
|
||||
<near-m>150.0</near-m>
|
||||
<far-m>500.0</far-m>
|
||||
<viewport>
|
||||
<x>0.5</x>
|
||||
<y>0.5</y>
|
||||
|
@ -690,11 +728,11 @@
|
|||
<effect>Effects/HDR/ao</effect>
|
||||
<binding>
|
||||
<unit>0</unit>
|
||||
<buffer>depth-stencil</buffer>
|
||||
<buffer>gbuffer0</buffer>
|
||||
</binding>
|
||||
<binding>
|
||||
<unit>1</unit>
|
||||
<buffer>gbuffer1</buffer>
|
||||
<buffer>depth-stencil</buffer>
|
||||
</binding>
|
||||
<attachment>
|
||||
<component>color0</component>
|
||||
|
@ -1198,36 +1236,36 @@
|
|||
|
||||
<!-- Debug passes -->
|
||||
<pass include="debug-pass.xml">
|
||||
<name>debug-albedo</name>
|
||||
<effect>Effects/HDR/trivial</effect>
|
||||
<name>debug-color</name>
|
||||
<effect>Effects/HDR/gbuffer-debug-color</effect>
|
||||
<geometry>
|
||||
<left>0.0</left>
|
||||
<bottom>0.0</bottom>
|
||||
<width>0.2</width>
|
||||
<height>0.2</height>
|
||||
</geometry>
|
||||
<binding>
|
||||
<unit>0</unit>
|
||||
<buffer>gbuffer0</buffer>
|
||||
</binding>
|
||||
</pass>
|
||||
<pass include="debug-pass.xml">
|
||||
<name>debug-normals</name>
|
||||
<effect>Effects/HDR/trivial</effect>
|
||||
<geometry>
|
||||
<left>0.8</left>
|
||||
<bottom>0.0</bottom>
|
||||
<width>0.2</width>
|
||||
<height>0.2</height>
|
||||
</geometry>
|
||||
<binding>
|
||||
<unit>0</unit>
|
||||
<buffer>gbuffer1</buffer>
|
||||
</binding>
|
||||
</pass>
|
||||
<pass include="debug-pass.xml">
|
||||
<name>debug-materials</name>
|
||||
<effect>Effects/HDR/trivial</effect>
|
||||
<name>debug-normals</name>
|
||||
<effect>Effects/HDR/gbuffer-debug-normal</effect>
|
||||
<geometry>
|
||||
<left>0.8</left>
|
||||
<bottom>0.0</bottom>
|
||||
<width>0.2</width>
|
||||
<height>0.2</height>
|
||||
</geometry>
|
||||
<binding>
|
||||
<unit>0</unit>
|
||||
<buffer>gbuffer0</buffer>
|
||||
</binding>
|
||||
</pass>
|
||||
<pass include="debug-pass.xml">
|
||||
<name>debug-orm</name>
|
||||
<effect>Effects/HDR/gbuffer-debug-orm</effect>
|
||||
<geometry>
|
||||
<left>0.0</left>
|
||||
<bottom>0.8</bottom>
|
||||
|
@ -1236,9 +1274,31 @@
|
|||
</geometry>
|
||||
<binding>
|
||||
<unit>0</unit>
|
||||
<buffer>gbuffer0</buffer>
|
||||
</binding>
|
||||
<binding>
|
||||
<unit>1</unit>
|
||||
<buffer>gbuffer1</buffer>
|
||||
</binding>
|
||||
<binding>
|
||||
<unit>2</unit>
|
||||
<buffer>gbuffer2</buffer>
|
||||
</binding>
|
||||
</pass>
|
||||
<pass include="debug-pass.xml">
|
||||
<name>debug-matid</name>
|
||||
<effect>Effects/HDR/gbuffer-debug-matid</effect>
|
||||
<geometry>
|
||||
<left>0.0</left>
|
||||
<bottom>0.57</bottom>
|
||||
<width>0.2</width>
|
||||
<height>0.2</height>
|
||||
</geometry>
|
||||
<binding>
|
||||
<unit>0</unit>
|
||||
<buffer>gbuffer0</buffer>
|
||||
</binding>
|
||||
</pass>
|
||||
<pass include="debug-pass.xml">
|
||||
<name>debug-depth</name>
|
||||
<effect>Effects/HDR/visualize-depth</effect>
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
<fragment-shader>Shaders/HDR/gbuffer-include.frag</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>depth_tex</name>
|
||||
<name>gbuffer0_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">0</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>normal_tex</name>
|
||||
<name>depth_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">1</value>
|
||||
</uniform>
|
||||
|
|
12
Effects/HDR/gbuffer-debug-clear.eff
Normal file
12
Effects/HDR/gbuffer-debug-clear.eff
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/HDR/gbuffer-debug-clear</name>
|
||||
<technique n="1">
|
||||
<pass>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/gbuffer-debug-clear.frag</fragment-shader>
|
||||
</program>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
17
Effects/HDR/gbuffer-debug-color.eff
Normal file
17
Effects/HDR/gbuffer-debug-color.eff
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/HDR/gbuffer-debug-color</name>
|
||||
<technique n="1">
|
||||
<pass>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/gbuffer-debug-color.frag</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>gbuffer1_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">0</value>
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
17
Effects/HDR/gbuffer-debug-matid.eff
Normal file
17
Effects/HDR/gbuffer-debug-matid.eff
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/HDR/gbuffer-debug-matid</name>
|
||||
<technique n="1">
|
||||
<pass>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/gbuffer-debug-matid.frag</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>gbuffer0_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">0</value>
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
17
Effects/HDR/gbuffer-debug-normal.eff
Normal file
17
Effects/HDR/gbuffer-debug-normal.eff
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/HDR/gbuffer-debug-normal</name>
|
||||
<technique n="1">
|
||||
<pass>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/gbuffer-debug-normal.frag</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>gbuffer0_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">0</value>
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
27
Effects/HDR/gbuffer-debug-orm.eff
Normal file
27
Effects/HDR/gbuffer-debug-orm.eff
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/HDR/gbuffer-debug-orm</name>
|
||||
<technique n="1">
|
||||
<pass>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/trivial.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/gbuffer-debug-orm.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>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
|
@ -11,6 +11,9 @@
|
|||
<wrap-t>clamp-to-edge</wrap-t>
|
||||
<internal-format>normalized</internal-format>
|
||||
</texture>
|
||||
<show-shadow-cascades>
|
||||
<use>/sim/rendering/hdr/debug/show-shadow-cascades</use>
|
||||
</show-shadow-cascades>
|
||||
</parameters>
|
||||
<technique n="1">
|
||||
<pass>
|
||||
|
@ -61,6 +64,11 @@
|
|||
<type>sampler-2d</type>
|
||||
<value type="int">7</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>debug_shadow_cascades</name>
|
||||
<type>bool</type>
|
||||
<value><use>show-shadow-cascades</use></value>
|
||||
</uniform>
|
||||
<!-- Shadows include -->
|
||||
<uniform>
|
||||
<name>shadow_tex</name>
|
||||
|
|
|
@ -699,4 +699,21 @@
|
|||
</pass>
|
||||
</technique>
|
||||
|
||||
<technique n="119">
|
||||
<scheme>hdr-shadow</scheme>
|
||||
<pass>
|
||||
<color-mask type="vec4d">0 0 0 0</color-mask>
|
||||
<cull-face>back</cull-face>
|
||||
<blend>0</blend>
|
||||
<polygon-offset>
|
||||
<factor>1.1</factor>
|
||||
<units>4.0</units>
|
||||
</polygon-offset>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/geometry-shadow.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/geometry-shadow.frag</fragment-shader>
|
||||
</program>
|
||||
</pass>
|
||||
</technique>
|
||||
|
||||
</PropertyList>
|
||||
|
|
|
@ -68,15 +68,6 @@
|
|||
<wrap-s><use>texture[3]/wrap-s</use></wrap-s>
|
||||
<wrap-t><use>texture[3]/wrap-t</use></wrap-t>
|
||||
</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>
|
||||
<mag-filter><use>texture[4]/mag-filter</use></mag-filter>
|
||||
<wrap-s><use>texture[4]/wrap-s</use></wrap-s>
|
||||
<wrap-t><use>texture[4]/wrap-t</use></wrap-t>
|
||||
</texture-unit>
|
||||
<texture-unit>
|
||||
<unit>8</unit>
|
||||
<image><use>texture[8]/image</use></image>
|
||||
|
@ -117,19 +108,14 @@
|
|||
<value type="int">1</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>metallic_roughness_tex</name>
|
||||
<name>orm_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">2</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>occlusion_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">3</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>emissive_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">4</value>
|
||||
<value type="int">3</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>base_color_factor</name>
|
||||
|
|
|
@ -12,18 +12,14 @@
|
|||
<texture n="1">
|
||||
<type>null-normalmap</type>
|
||||
</texture>
|
||||
<!-- Metallic and Roughness -->
|
||||
<!-- ORM Texture (Occlusion R, Roughness G and Metallic B) -->
|
||||
<texture n="2">
|
||||
<type>white</type>
|
||||
</texture>
|
||||
<metallic-factor type="float">1.0</metallic-factor>
|
||||
<roughness-factor type="float">1.0</roughness-factor>
|
||||
<!-- Occlusion -->
|
||||
<texture n="3">
|
||||
<type>white</type>
|
||||
</texture>
|
||||
<!-- Emissive -->
|
||||
<texture n="4">
|
||||
<texture n="3">
|
||||
<type>white</type>
|
||||
</texture>
|
||||
<emissive-factor type="vec3d">0.0 0.0 0.0</emissive-factor>
|
||||
|
@ -88,15 +84,6 @@
|
|||
<wrap-s><use>texture[3]/wrap-s</use></wrap-s>
|
||||
<wrap-t><use>texture[3]/wrap-t</use></wrap-t>
|
||||
</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>
|
||||
<mag-filter><use>texture[0]/mag-filter</use></mag-filter>
|
||||
<wrap-s><use>texture[4]/wrap-s</use></wrap-s>
|
||||
<wrap-t><use>texture[4]/wrap-t</use></wrap-t>
|
||||
</texture-unit>
|
||||
<blend>0</blend>
|
||||
<rendering-hint>opaque</rendering-hint>
|
||||
<cull-face><use>cull-face</use></cull-face>
|
||||
|
@ -124,19 +111,14 @@
|
|||
<value type="int">1</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>metallic_roughness_tex</name>
|
||||
<name>orm_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">2</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>occlusion_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">3</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>emissive_tex</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">4</value>
|
||||
<value type="int">3</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>base_color_factor</name>
|
||||
|
@ -165,4 +147,21 @@
|
|||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
|
||||
<technique n="119">
|
||||
<scheme>hdr-shadow</scheme>
|
||||
<pass>
|
||||
<color-mask type="vec4d">0 0 0 0</color-mask>
|
||||
<cull-face>back</cull-face>
|
||||
<blend>0</blend>
|
||||
<polygon-offset>
|
||||
<factor>1.1</factor>
|
||||
<units>4.0</units>
|
||||
</polygon-offset>
|
||||
<program>
|
||||
<vertex-shader>Shaders/HDR/geometry-shadow.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/HDR/geometry-shadow.frag</fragment-shader>
|
||||
</program>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
||||
|
|
|
@ -5,16 +5,4 @@
|
|||
<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>
|
||||
|
|
|
@ -5,8 +5,8 @@ out float fragColor;
|
|||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D gbuffer0_tex;
|
||||
uniform sampler2D depth_tex;
|
||||
uniform sampler2D normal_tex;
|
||||
|
||||
uniform mat4 fg_ProjectionMatrix;
|
||||
|
||||
|
@ -22,11 +22,11 @@ const vec2 kernel[4] = vec2[](
|
|||
vec2( 0.0, -1.0), // bottom
|
||||
vec2(-1.0, 0.0)); // left
|
||||
|
||||
vec3 decodeNormal(vec2 f);
|
||||
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);
|
||||
return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float sampleAO(vec3 fragPos, vec3 normal, vec2 coords)
|
||||
|
@ -46,10 +46,12 @@ float sampleAO(vec3 fragPos, vec3 normal, vec2 coords)
|
|||
|
||||
void main()
|
||||
{
|
||||
float fragDepth = texture(depth_tex, texCoord).r;
|
||||
vec3 fragPos = positionFromDepth(texCoord, fragDepth);
|
||||
vec4 gbuffer0 = texture(gbuffer0_tex, texCoord);
|
||||
float depth = texture(depth_tex, texCoord).r;
|
||||
|
||||
vec3 normal = normalize(decodeNormal(texture(normal_tex, texCoord).rg));
|
||||
vec3 normal = decodeNormal(gbuffer0.rg);
|
||||
|
||||
vec3 fragPos = positionFromDepth(texCoord, depth);
|
||||
|
||||
vec2 randomVec = normalize(vec2(rand(texCoord) * 2.0 - 1.0,
|
||||
rand(texCoord+1.0) * 2.0 - 1.0));
|
||||
|
|
12
Shaders/HDR/gbuffer-debug-clear.frag
Normal file
12
Shaders/HDR/gbuffer-debug-clear.frag
Normal file
|
@ -0,0 +1,12 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 outGBuffer0;
|
||||
layout(location = 1) out vec4 outGBuffer1;
|
||||
layout(location = 2) out vec4 outGBuffer2;
|
||||
|
||||
void main()
|
||||
{
|
||||
outGBuffer0 = vec4(0.0);
|
||||
outGBuffer1 = vec4(0.0);
|
||||
outGBuffer2 = vec4(0.0);
|
||||
}
|
12
Shaders/HDR/gbuffer-debug-color.frag
Normal file
12
Shaders/HDR/gbuffer-debug-color.frag
Normal file
|
@ -0,0 +1,12 @@
|
|||
#version 330 core
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D gbuffer1_tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(texture(gbuffer1_tex, texCoord).rgb, 1.0);
|
||||
}
|
12
Shaders/HDR/gbuffer-debug-matid.frag
Normal file
12
Shaders/HDR/gbuffer-debug-matid.frag
Normal file
|
@ -0,0 +1,12 @@
|
|||
#version 330 core
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D gbuffer0_tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(vec3(texture(gbuffer0_tex, texCoord).a), 1.0);
|
||||
}
|
12
Shaders/HDR/gbuffer-debug-normal.frag
Normal file
12
Shaders/HDR/gbuffer-debug-normal.frag
Normal file
|
@ -0,0 +1,12 @@
|
|||
#version 330 core
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D gbuffer0_tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(texture(gbuffer0_tex, texCoord).rg, 0.0, 1.0);
|
||||
}
|
17
Shaders/HDR/gbuffer-debug-orm.frag
Normal file
17
Shaders/HDR/gbuffer-debug-orm.frag
Normal file
|
@ -0,0 +1,17 @@
|
|||
#version 330 core
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D gbuffer0_tex;
|
||||
uniform sampler2D gbuffer1_tex;
|
||||
uniform sampler2D gbuffer2_tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(texture(gbuffer2_tex, texCoord).a,
|
||||
texture(gbuffer0_tex, texCoord).b,
|
||||
texture(gbuffer1_tex, texCoord).a,
|
||||
1.0);
|
||||
}
|
|
@ -3,24 +3,30 @@
|
|||
uniform mat4 fg_ProjectionMatrixInverse;
|
||||
uniform vec2 fg_NearFar;
|
||||
|
||||
// https://aras-p.info/texts/CompactNormalStorage.html
|
||||
// Method #4: Spheremap Transform
|
||||
// Lambert Azimuthal Equal-Area projection
|
||||
vec2 encodeNormal(vec3 n)
|
||||
// Octahedron normal encoding
|
||||
// https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/
|
||||
vec2 msign(vec2 v)
|
||||
{
|
||||
float p = sqrt(n.z * 8.0 + 8.0);
|
||||
return vec2(n.xy / p + 0.5);
|
||||
return vec2((v.x >= 0.0) ? 1.0 : -1.0,
|
||||
(v.y >= 0.0) ? 1.0 : -1.0);
|
||||
}
|
||||
|
||||
vec3 decodeNormal(vec2 enc)
|
||||
vec2 encodeNormal(vec3 n)
|
||||
{
|
||||
vec2 fenc = enc * 4.0 - 2.0;
|
||||
float f = dot(fenc, fenc);
|
||||
float g = sqrt(1.0 - f * 0.25);
|
||||
vec3 n;
|
||||
n.xy = fenc * g;
|
||||
n.z = 1.0 - f * 0.5;
|
||||
return n;
|
||||
n /= (abs(n.x) + abs(n.y) + abs(n.z));
|
||||
n.xy = (n.z >= 0) ? n.xy : (1.0 - abs(n.yx)) * msign(n.xy);
|
||||
n.xy = n.xy * 0.5 + 0.5;
|
||||
return n.xy;
|
||||
}
|
||||
|
||||
vec3 decodeNormal(vec2 f)
|
||||
{
|
||||
f = f * 2.0 - 1.0;
|
||||
vec3 n = vec3(f, 1.0 - abs(f.x) - abs(f.y));
|
||||
float t = max(-n.z, 0.0);
|
||||
n.x += (n.x > 0.0) ? -t : t;
|
||||
n.y += (n.y > 0.0) ? -t : t;
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
// Given a 2D coordinate in the range [0,1] and a depth value from a depth
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 gbuffer0;
|
||||
layout(location = 1) out vec2 gbuffer1;
|
||||
layout(location = 2) out vec4 gbuffer2;
|
||||
layout(location = 0) out vec4 outGBuffer0;
|
||||
layout(location = 1) out vec4 outGBuffer1;
|
||||
layout(location = 2) out vec4 outGBuffer2;
|
||||
|
||||
in vec3 normalVS;
|
||||
|
||||
const float CHROME_METALNESS = 1.0;
|
||||
const float CHROME_ROUGHNESS = 0.1;
|
||||
|
||||
vec2 encodeNormal(vec3 n);
|
||||
|
||||
void main()
|
||||
{
|
||||
gbuffer0 = vec4(1.0);
|
||||
gbuffer1 = encodeNormal(normalVS);
|
||||
gbuffer2 = vec4(1.0, 0.1, 0.0, 0.0);
|
||||
outGBuffer0.rg = encodeNormal(normalVS);
|
||||
outGBuffer0.b = CHROME_ROUGHNESS;
|
||||
outGBuffer0.a = 1.0;
|
||||
outGBuffer1.rgb = vec3(1.0);
|
||||
outGBuffer1.a = CHROME_METALNESS;
|
||||
outGBuffer2.rgb = vec3(0.0);
|
||||
outGBuffer2.a = 1.0;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 gbuffer0;
|
||||
layout(location = 1) out vec2 gbuffer1;
|
||||
layout(location = 2) out vec4 gbuffer2;
|
||||
layout(location = 0) out vec4 outGBuffer0;
|
||||
layout(location = 1) out vec4 outGBuffer1;
|
||||
layout(location = 2) out vec4 outGBuffer2;
|
||||
|
||||
in vec2 texCoord;
|
||||
in mat3 TBN;
|
||||
|
@ -21,8 +21,7 @@ vec3 decodeSRGB(vec3 screenRGB);
|
|||
|
||||
void main()
|
||||
{
|
||||
gbuffer0.rgb = decodeSRGB(texture(color_tex, texCoord).rgb);
|
||||
gbuffer0.a = 1.0;
|
||||
vec3 color = decodeSRGB(texture(color_tex, texCoord).rgb);
|
||||
|
||||
vec3 normal = vec3(0.0, 0.0, 1.0);
|
||||
if (normalmap_enabled > 0) {
|
||||
|
@ -32,10 +31,12 @@ void main()
|
|||
normal = -normal;
|
||||
}
|
||||
normal = normalize(TBN * normal);
|
||||
gbuffer1 = encodeNormal(normal);
|
||||
|
||||
gbuffer2 = vec4(DEFAULT_COMBINED_METALNESS,
|
||||
DEFAULT_COMBINED_ROUGHNESS,
|
||||
0.0,
|
||||
0.0);
|
||||
outGBuffer0.rg = encodeNormal(normal);
|
||||
outGBuffer0.b = DEFAULT_COMBINED_ROUGHNESS;
|
||||
outGBuffer0.a = 1.0;
|
||||
outGBuffer1.rgb = color;
|
||||
outGBuffer1.a = DEFAULT_COMBINED_METALNESS;
|
||||
outGBuffer2.rgb = vec3(0.0);
|
||||
outGBuffer2.a = 1.0;
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ in vec3 ecPos;
|
|||
|
||||
uniform sampler2D base_color_tex;
|
||||
uniform sampler2D normal_tex;
|
||||
uniform sampler2D metallic_roughness_tex;
|
||||
uniform sampler2D occlusion_tex;
|
||||
uniform sampler2D orm_tex;
|
||||
uniform sampler2D emissive_tex;
|
||||
uniform vec4 base_color_factor;
|
||||
uniform float metallic_factor;
|
||||
|
@ -29,8 +28,6 @@ vec3 evaluateLight(
|
|||
vec3 baseColor,
|
||||
float metallic,
|
||||
float roughness,
|
||||
float clearcoat,
|
||||
float clearcoatRoughness,
|
||||
vec3 f0,
|
||||
vec3 intensity,
|
||||
float occlusion,
|
||||
|
@ -59,13 +56,13 @@ void main()
|
|||
if (baseColor.a < alpha_cutoff)
|
||||
discard;
|
||||
|
||||
float occlusion = texture(occlusion_tex, texCoord).r;
|
||||
vec3 n = texture(normal_tex, texCoord).rgb * 2.0 - 1.0;
|
||||
n = normalize(TBN * n);
|
||||
|
||||
vec4 metallicRoughness = texture(metallic_roughness_tex, texCoord);
|
||||
float metallic = metallicRoughness.r * metallic_factor;
|
||||
float roughness = metallicRoughness.g * roughness_factor;
|
||||
vec3 orm = texture(orm_tex, texCoord).rgb;
|
||||
float occlusion = orm.r;
|
||||
float roughness = orm.g * roughness_factor;
|
||||
float metallic = orm.b * metallic_factor;
|
||||
|
||||
vec3 emissive = texture(emissive_tex, texCoord).rgb * emissive_factor;
|
||||
|
||||
|
@ -83,8 +80,6 @@ void main()
|
|||
vec3 color = evaluateLight(baseColor.rgb,
|
||||
metallic,
|
||||
roughness,
|
||||
0.0,
|
||||
0.0,
|
||||
f0,
|
||||
sunIlluminance,
|
||||
shadowFactor,
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 gbuffer0;
|
||||
layout(location = 1) out vec2 gbuffer1;
|
||||
layout(location = 2) out vec4 gbuffer2;
|
||||
layout(location = 0) out vec4 outGBuffer0;
|
||||
layout(location = 1) out vec4 outGBuffer1;
|
||||
layout(location = 2) out vec4 outGBuffer2;
|
||||
|
||||
in vec2 texCoord;
|
||||
in mat3 TBN;
|
||||
|
||||
uniform sampler2D base_color_tex;
|
||||
uniform sampler2D normal_tex;
|
||||
uniform sampler2D metallic_roughness_tex;
|
||||
uniform sampler2D occlusion_tex;
|
||||
uniform sampler2D orm_tex;
|
||||
uniform sampler2D emissive_tex;
|
||||
uniform vec4 base_color_factor;
|
||||
uniform float metallic_factor;
|
||||
|
@ -22,22 +21,24 @@ vec3 decodeSRGB(vec3 screenRGB);
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 baseColorTexel = texture(base_color_tex, texCoord);
|
||||
vec4 baseColor = vec4(decodeSRGB(baseColorTexel.rgb), baseColorTexel.a)
|
||||
* base_color_factor;
|
||||
gbuffer0.rgb = baseColor.rgb;
|
||||
|
||||
float occlusion = texture(occlusion_tex, texCoord).r;
|
||||
gbuffer0.a = occlusion;
|
||||
vec3 baseColorTexel = texture(base_color_tex, texCoord).rgb; // Ignore alpha
|
||||
vec3 baseColor = decodeSRGB(baseColorTexel.rgb) * base_color_factor.rgb;
|
||||
|
||||
vec3 normal = texture(normal_tex, texCoord).rgb * 2.0 - 1.0;
|
||||
normal = normalize(TBN * normal);
|
||||
gbuffer1 = encodeNormal(normal);
|
||||
|
||||
vec4 metallicRoughness = texture(metallic_roughness_tex, texCoord);
|
||||
float metallic = metallicRoughness.r * metallic_factor;
|
||||
float roughness = metallicRoughness.g * roughness_factor;
|
||||
gbuffer2 = vec4(metallic, roughness, 0.0, 0.0);
|
||||
vec3 orm = texture(orm_tex, texCoord).rgb;
|
||||
float occlusion = orm.r;
|
||||
float roughness = orm.g * roughness_factor;
|
||||
float metallic = orm.b * metallic_factor;
|
||||
|
||||
vec3 emissive = texture(emissive_tex, texCoord).rgb * emissive_factor;
|
||||
|
||||
outGBuffer0.rg = encodeNormal(normal);
|
||||
outGBuffer0.b = roughness;
|
||||
outGBuffer0.a = 1.0;
|
||||
outGBuffer1.rgb = baseColor;
|
||||
outGBuffer1.a = metallic;
|
||||
outGBuffer2.rgb = vec3(0.0);
|
||||
outGBuffer2.a = occlusion;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform sampler2D color_tex;
|
||||
|
||||
const float ALPHA_THRESHOLD = 0.5;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(1.0);
|
||||
float alpha = texture(color_tex, texCoord).a;
|
||||
if (alpha <= ALPHA_THRESHOLD)
|
||||
discard;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
#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;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ uniform mat4 osg_ProjectionMatrix;
|
|||
uniform vec4 fg_Viewport;
|
||||
uniform vec3 fg_SunDirection;
|
||||
|
||||
const float DEFAULT_TRANSPARENT_METALNESS = 0.0;
|
||||
const float DEFAULT_TRANSPARENT_ROUGHNESS = 0.1;
|
||||
|
||||
vec3 decodeSRGB(vec3 screenRGB);
|
||||
|
@ -23,8 +24,6 @@ vec3 evaluateLight(
|
|||
vec3 baseColor,
|
||||
float metallic,
|
||||
float roughness,
|
||||
float clearcoat,
|
||||
float clearcoatRoughness,
|
||||
vec3 f0,
|
||||
vec3 intensity,
|
||||
float occlusion,
|
||||
|
@ -64,10 +63,8 @@ void main()
|
|||
float shadowFactor = getShadowing(ecPos, n, l, osg_ProjectionMatrix);
|
||||
|
||||
vec3 color = evaluateLight(baseColor,
|
||||
0.0,
|
||||
DEFAULT_TRANSPARENT_METALNESS,
|
||||
DEFAULT_TRANSPARENT_ROUGHNESS,
|
||||
0.0,
|
||||
0.0,
|
||||
f0,
|
||||
sunIlluminance,
|
||||
shadowFactor,
|
||||
|
@ -78,7 +75,7 @@ void main()
|
|||
vec3 worldReflected = (osg_ViewMatrixInverse * vec4(reflect(-v, n), 0.0)).xyz;
|
||||
|
||||
color += evaluateIBL(baseColor,
|
||||
0.0,
|
||||
DEFAULT_TRANSPARENT_METALNESS,
|
||||
DEFAULT_TRANSPARENT_ROUGHNESS,
|
||||
f0,
|
||||
1.0,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 gbuffer0;
|
||||
layout(location = 1) out vec2 gbuffer1;
|
||||
layout(location = 0) out vec4 outGBuffer0;
|
||||
layout(location = 1) out vec4 outGBuffer1;
|
||||
|
||||
in vec4 waterTex1;
|
||||
in vec4 waterTex2;
|
||||
|
@ -207,8 +207,9 @@ void main()
|
|||
N0.g += (ddy + ddy1 + ddy2 + ddy3);
|
||||
|
||||
vec3 N = normalize(mix(N0, N1, mixFactor) * waveRoughness);
|
||||
gbuffer1 = encodeNormal(TBN * N);
|
||||
|
||||
vec3 floorColor = decodeSRGB(texture(water_colormap, TopoUV).rgb);
|
||||
gbuffer0.rgb = floorColor;
|
||||
|
||||
outGBuffer0.rg = encodeNormal(TBN * N);
|
||||
outGBuffer1.rgb = floorColor;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 gbuffer0;
|
||||
layout(location = 1) out vec2 gbuffer1;
|
||||
layout(location = 2) out vec4 gbuffer2;
|
||||
layout(location = 0) out vec4 outGBuffer0;
|
||||
layout(location = 1) out vec4 outGBuffer1;
|
||||
layout(location = 2) out vec4 outGBuffer2;
|
||||
|
||||
in vec3 normalVS;
|
||||
in vec2 texCoord;
|
||||
|
@ -11,7 +11,7 @@ in vec4 materialColor;
|
|||
uniform sampler2D color_tex;
|
||||
|
||||
const float DEFAULT_METALNESS = 0.0;
|
||||
const float DEFAULT_ROUGHNESS = 0.8;
|
||||
const float DEFAULT_ROUGHNESS = 0.5;
|
||||
|
||||
vec2 encodeNormal(vec3 n);
|
||||
vec3 decodeSRGB(vec3 screenRGB);
|
||||
|
@ -20,11 +20,12 @@ void main()
|
|||
{
|
||||
vec3 texel = texture(color_tex, texCoord).rgb;
|
||||
vec3 color = decodeSRGB(texel) * materialColor.rgb; // Ignore transparency
|
||||
gbuffer0.rgb = color;
|
||||
gbuffer0.a = 1.0;
|
||||
gbuffer1 = encodeNormal(normalVS);
|
||||
gbuffer2 = vec4(DEFAULT_METALNESS,
|
||||
DEFAULT_ROUGHNESS,
|
||||
0.0,
|
||||
0.0);
|
||||
|
||||
outGBuffer0.rg = encodeNormal(normalVS);
|
||||
outGBuffer0.b = DEFAULT_ROUGHNESS;
|
||||
outGBuffer0.a = 1.0;
|
||||
outGBuffer1.rgb = color;
|
||||
outGBuffer1.a = DEFAULT_METALNESS;
|
||||
outGBuffer2.rgb = vec3(0.0);
|
||||
outGBuffer2.a = 1.0;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ vec3 F_Schlick(float VdotH, vec3 F0)
|
|||
return F0 + (vec3(1.0) - F0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
float F_Schlick(float VdotH, float F0)
|
||||
{
|
||||
return F0 + (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
|
||||
|
@ -137,8 +142,6 @@ vec3 evaluateLight(
|
|||
vec3 baseColor,
|
||||
float metallic,
|
||||
float roughness,
|
||||
float clearcoat,
|
||||
float clearcoatRoughness,
|
||||
vec3 f0, // Use getF0Reflectance() to obtain this
|
||||
vec3 intensity,
|
||||
float occlusion,
|
||||
|
@ -169,14 +172,13 @@ vec3 evaluateLight(
|
|||
float D = D_GGX(NdotH, a2);
|
||||
float G = G_SmithGGX(NdotV, NdotL, a2);
|
||||
|
||||
// Diffuse term
|
||||
// Lambertian diffuse model
|
||||
vec3 diffuse = (vec3(1.0) - F) * Fd_Lambert(c_diff);
|
||||
// Specular term
|
||||
// Cook-Torrance specular microfacet model
|
||||
vec3 specular = ((D * G) * F) / (4.0 * NdotV * NdotL);
|
||||
// Diffuse term: Lambertian diffuse model
|
||||
vec3 f_diffuse = (vec3(1.0) - F) * Fd_Lambert(c_diff);
|
||||
|
||||
vec3 material = diffuse + specular;
|
||||
// Specular term: Cook-Torrance specular microfacet model
|
||||
vec3 f_specular = ((D * G) * F) / (4.0 * NdotV * NdotL);
|
||||
|
||||
vec3 material = f_diffuse + f_specular;
|
||||
|
||||
vec3 color = material * intensity * occlusion;
|
||||
return color;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#version 330 core
|
||||
|
||||
out vec3 fragHdrColor;
|
||||
out vec3 fragColor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
|
@ -10,20 +10,21 @@ uniform sampler2D gbuffer2_tex;
|
|||
uniform sampler2D depth_tex;
|
||||
uniform sampler2D ao_tex;
|
||||
|
||||
uniform bool debug_shadow_cascades;
|
||||
|
||||
uniform mat4 fg_ViewMatrixInverse;
|
||||
uniform mat4 fg_ProjectionMatrix;
|
||||
uniform vec3 fg_SunDirection;
|
||||
|
||||
vec3 decodeNormal(vec2 enc);
|
||||
vec3 decodeNormal(vec2 f);
|
||||
vec3 positionFromDepth(vec2 pos, float depth);
|
||||
float getShadowing(vec3 p, vec3 n, vec3 l, mat4 viewToClip);
|
||||
vec3 debugShadowColor(vec3 p, vec3 n, vec3 l);
|
||||
vec3 getF0Reflectance(vec3 baseColor, float metallic);
|
||||
vec3 evaluateLight(
|
||||
vec3 baseColor,
|
||||
float metallic,
|
||||
float roughness,
|
||||
float clearcoat,
|
||||
float clearcoatRoughness,
|
||||
vec3 f0,
|
||||
vec3 intensity,
|
||||
float occlusion,
|
||||
|
@ -46,26 +47,27 @@ vec3 getSunIntensity();
|
|||
|
||||
void main()
|
||||
{
|
||||
float depth = texture(depth_tex, texCoord).r;
|
||||
vec4 gbuffer0 = texture(gbuffer0_tex, texCoord);
|
||||
vec2 gbuffer1 = texture(gbuffer1_tex, texCoord).rg;
|
||||
vec4 gbuffer1 = texture(gbuffer1_tex, texCoord);
|
||||
vec4 gbuffer2 = texture(gbuffer2_tex, texCoord);
|
||||
float ao = texture(ao_tex, texCoord).r;
|
||||
float depth = texture(depth_tex, texCoord).r;
|
||||
|
||||
// Unpack G-Buffer
|
||||
vec3 n = decodeNormal(gbuffer0.rg);
|
||||
float roughness = gbuffer0.b;
|
||||
uint matId = uint(gbuffer0.a * 4.0);
|
||||
vec3 baseColor = gbuffer1.rgb;
|
||||
float metallic = gbuffer1.a;
|
||||
float occlusion = gbuffer2.a;
|
||||
|
||||
vec3 pos = positionFromDepth(texCoord, depth);
|
||||
vec3 v = normalize(-pos);
|
||||
vec3 n = decodeNormal(gbuffer1);
|
||||
vec3 l = fg_SunDirection;
|
||||
|
||||
float NdotL = dot(n, l);
|
||||
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
||||
|
||||
vec3 baseColor = gbuffer0.rgb;
|
||||
float cavity = gbuffer0.a;
|
||||
float metallic = gbuffer2.r;
|
||||
float roughness = gbuffer2.g;
|
||||
float clearcoat = gbuffer2.b;
|
||||
float clearcoatRoughness = gbuffer2.a;
|
||||
float ao = texture(ao_tex, texCoord).r;
|
||||
|
||||
vec3 f0 = getF0Reflectance(baseColor, metallic);
|
||||
|
||||
|
@ -75,15 +77,13 @@ void main()
|
|||
vec3 color = evaluateLight(baseColor,
|
||||
metallic,
|
||||
roughness,
|
||||
clearcoat,
|
||||
clearcoatRoughness,
|
||||
f0,
|
||||
sunIlluminance,
|
||||
shadowFactor,
|
||||
n, l, v,
|
||||
NdotL, NdotV);
|
||||
|
||||
float ambientOcclusion = ao * cavity;
|
||||
float ambientOcclusion = ao * occlusion;
|
||||
vec3 worldNormal = (fg_ViewMatrixInverse * vec4(n, 0.0)).xyz;
|
||||
vec3 worldReflected = (fg_ViewMatrixInverse * vec4(reflect(-v, n), 0.0)).xyz;
|
||||
|
||||
|
@ -98,5 +98,8 @@ void main()
|
|||
|
||||
color = addAerialPerspective(color, texCoord, length(pos));
|
||||
|
||||
fragHdrColor = color;
|
||||
if (debug_shadow_cascades)
|
||||
color *= debugShadowColor(pos, n, l);
|
||||
|
||||
fragColor = color;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ const vec2 uv_shifts[4] = vec2[4](
|
|||
const vec2 uv_factor = vec2(0.5, 0.5);
|
||||
|
||||
const float SSS_THICKNESS = 0.1;
|
||||
const uint SSS_NUM_STEPS = 32u;
|
||||
const uint SSS_NUM_STEPS = 16u;
|
||||
const float SSS_MAX_DISTANCE = 0.05;
|
||||
const vec3 DITHER_MAGIC = vec3(0.06711056, 0.00583715, 52.9829189);
|
||||
|
||||
|
@ -76,14 +76,11 @@ float sampleCascade(vec4 p, vec2 shift, vec2 mapSize)
|
|||
return sampleOptimizedPCF(pos, mapSize);
|
||||
}
|
||||
|
||||
float sampleAndBlendBand(vec4 p1, vec4 p2, vec2 s1, vec2 s2, vec2 mapSize)
|
||||
float getBlendFactor(vec2 uv, vec2 bottomLeft, vec2 topRight)
|
||||
{
|
||||
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, mapSize),
|
||||
sampleCascade(p2, s2, mapSize),
|
||||
blend);
|
||||
vec2 s = smoothstep(vec2(0.0), bottomLeft, uv)
|
||||
- smoothstep(topRight, vec2(1.0), uv);
|
||||
return 1.0 - s.x * s.y;
|
||||
}
|
||||
|
||||
bool checkWithinBounds(vec2 coords, vec2 bottomLeft, vec2 topRight)
|
||||
|
@ -151,7 +148,9 @@ float getContactShadow(vec3 p, vec3 l, mat4 viewToClip)
|
|||
float dz = samplePos.z - sampleDepth;
|
||||
if (dz > 0.00001 && dz < SSS_THICKNESS) {
|
||||
shadow = 1.0;
|
||||
// TODO: Add screen fading
|
||||
vec2 screenFade = smoothstep(vec2(0.0), vec2(0.07), samplePos.xy)
|
||||
- smoothstep(vec2(0.93), vec2(1.0), samplePos.xy);
|
||||
shadow *= screenFade.x * screenFade.y;
|
||||
break;
|
||||
}
|
||||
t += dt;
|
||||
|
@ -184,30 +183,62 @@ float getShadowing(vec3 p, vec3 n, vec3 l, mat4 viewToClip)
|
|||
// 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)) {
|
||||
if (isInsideBand(lightSpacePos[i])) {
|
||||
// Blend between cascades if the fragment is near the
|
||||
// next cascade to avoid abrupt transitions.
|
||||
visibility = clamp(sampleAndBlendBand(lightSpacePos[i],
|
||||
lightSpacePos[i+1],
|
||||
uv_shifts[i],
|
||||
uv_shifts[i+1],
|
||||
mapSize),
|
||||
0.0, 1.0);
|
||||
float blend = getBlendFactor(lightSpacePos[i].xy,
|
||||
BAND_BOTTOM_LEFT,
|
||||
BAND_TOP_RIGHT);
|
||||
float cascade0 = sampleCascade(lightSpacePos[i],
|
||||
uv_shifts[i],
|
||||
mapSize);
|
||||
float cascade1;
|
||||
if (i == 3) {
|
||||
// Handle special case of the last cascade
|
||||
cascade1 = 1.0;
|
||||
} else {
|
||||
cascade1 = sampleCascade(lightSpacePos[i+1],
|
||||
uv_shifts[i+1],
|
||||
mapSize);
|
||||
}
|
||||
visibility = mix(cascade0, cascade1, blend);
|
||||
} 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.
|
||||
visibility = clamp(sampleCascade(lightSpacePos[i],
|
||||
uv_shifts[i],
|
||||
mapSize),
|
||||
0.0, 1.0);
|
||||
visibility = sampleCascade(lightSpacePos[i],
|
||||
uv_shifts[i],
|
||||
mapSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
visibility = clamp(visibility, 0.0, 1.0);
|
||||
|
||||
if (visibility > 0.0)
|
||||
visibility *= getContactShadow(p, l, viewToClip);
|
||||
|
||||
return visibility;
|
||||
}
|
||||
|
||||
vec3 debugShadowColor(vec3 p, vec3 n, vec3 l)
|
||||
{
|
||||
float NdotL = clamp(dot(n, l), 0.0, 1.0);
|
||||
|
||||
vec4 lightSpacePos[4];
|
||||
lightSpacePos[0] = getLightSpacePosition(p, n, NdotL, fg_LightMatrix_csm0);
|
||||
lightSpacePos[1] = getLightSpacePosition(p, n, NdotL, fg_LightMatrix_csm1);
|
||||
lightSpacePos[2] = getLightSpacePosition(p, n, NdotL, fg_LightMatrix_csm2);
|
||||
lightSpacePos[3] = getLightSpacePosition(p, n, NdotL, fg_LightMatrix_csm3);
|
||||
|
||||
if (isInsideCascade(lightSpacePos[0]))
|
||||
return vec3(1.0, 0.0, 0.0);
|
||||
else if (isInsideCascade(lightSpacePos[1]))
|
||||
return vec3(0.0, 1.0, 0.0);
|
||||
else if (isInsideCascade(lightSpacePos[2]))
|
||||
return vec3(0.0, 0.0, 1.0);
|
||||
else if (isInsideCascade(lightSpacePos[3]))
|
||||
return vec3(1.0, 0.0, 1.0);
|
||||
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ const float RECIPROCAL_PI = 0.31830988618;
|
|||
const float MAX_PREFILTERED_LOD = 4.0;
|
||||
const vec3 EXTRATERRESTRIAL_SOLAR_ILLUMINANCE = vec3(128.0);
|
||||
|
||||
vec3 decodeNormal(vec2 enc);
|
||||
vec3 decodeNormal(vec2 f);
|
||||
vec3 positionFromDepth(vec2 pos, float depth);
|
||||
vec3 addAerialPerspective(vec3 color, vec2 coord, float depth);
|
||||
|
||||
|
@ -36,11 +36,17 @@ float D_GGX(float NdotH, float a2)
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 gbuffer0 = texture(gbuffer0_tex, texCoord);
|
||||
vec4 gbuffer1 = texture(gbuffer1_tex, texCoord);
|
||||
float depth = texture(depth_tex, texCoord).r;
|
||||
|
||||
// Unpack G-Buffer
|
||||
vec3 n = decodeNormal(gbuffer0.rg);
|
||||
vec3 seaColor = gbuffer1.rgb;
|
||||
|
||||
vec3 pos = positionFromDepth(texCoord, depth);
|
||||
|
||||
vec3 v = normalize(-pos);
|
||||
vec3 n = decodeNormal(texture(gbuffer1_tex, texCoord).rg);
|
||||
vec3 l = fg_SunDirection;
|
||||
|
||||
vec3 reflected = reflect(-v, n);
|
||||
|
@ -62,7 +68,6 @@ void main()
|
|||
float fresnel = F_Schlick(NdotV, f0);
|
||||
|
||||
// Refracted light
|
||||
vec3 seaColor = texture(gbuffer0_tex, texCoord).rgb;
|
||||
vec3 Esky = textureLod(prefiltered_envmap, worldNormal, MAX_PREFILTERED_LOD).rgb;
|
||||
vec3 refracted = seaColor * Esky * RECIPROCAL_PI;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 gbuffer0;
|
||||
layout(location = 1) out vec2 gbuffer1;
|
||||
layout(location = 2) out vec4 gbuffer2;
|
||||
layout(location = 0) out vec4 outGBuffer0;
|
||||
layout(location = 1) out vec4 outGBuffer1;
|
||||
layout(location = 2) out vec4 outGBuffer2;
|
||||
|
||||
in vec3 normalVS;
|
||||
in vec2 texCoord;
|
||||
|
@ -44,11 +44,14 @@ void main()
|
|||
st = -st;
|
||||
}
|
||||
|
||||
vec3 texel = texture(atlas, vec3(st, lc)).rgb;
|
||||
|
||||
gbuffer0.rgb = decodeSRGB(texel);
|
||||
gbuffer0.a = 1.0;
|
||||
gbuffer1 = encodeNormal(normalVS);
|
||||
vec3 texel = decodeSRGB(texture(atlas, vec3(st, lc)).rgb);
|
||||
float specularity = clamp(dot(specular.rgb, vec3(0.333)), 0.0, 1.0);
|
||||
gbuffer2 = vec4(0.0, 1.0-specularity, 0.0, 0.0);
|
||||
|
||||
outGBuffer0.rg = encodeNormal(normalVS);
|
||||
outGBuffer0.b = 1.0 - specularity;
|
||||
outGBuffer0.a = 1.0;
|
||||
outGBuffer1.rgb = texel;
|
||||
outGBuffer1.a = 0.0;
|
||||
outGBuffer2.rgb = vec3(0.0);
|
||||
outGBuffer2.a = 1.0;
|
||||
}
|
||||
|
|
|
@ -389,8 +389,9 @@ Started September 2000 by David Megginson, david@megginson.com
|
|||
<bloom-magnitude type="float">0.5</bloom-magnitude>
|
||||
<bloom-threshold type="float">8.0</bloom-threshold>
|
||||
<debug>
|
||||
<show-gbuffer type="bool">false</show-gbuffer>
|
||||
<display-ev100 type="bool">false</display-ev100>
|
||||
<show-gbuffer type="bool">false</show-gbuffer>
|
||||
<show-shadow-cascades type="bool">false</show-shadow-cascades>
|
||||
</debug>
|
||||
</hdr>
|
||||
<composite-viewer-enabled type="bool">true</composite-viewer-enabled>
|
||||
|
|
Loading…
Reference in a new issue