Browse Source

21-deferred: Added texture array frame buffer option.

Бранимир Караџић 6 years ago
parent
commit
82550fa842

+ 69 - 16
examples/21-deferred/deferred.cpp

@@ -281,6 +281,17 @@ public:
 		m_debugProgram   = loadProgram("vs_deferred_debug",      "fs_deferred_debug");
 		m_debugProgram   = loadProgram("vs_deferred_debug",      "fs_deferred_debug");
 		m_lineProgram    = loadProgram("vs_deferred_debug_line", "fs_deferred_debug_line");
 		m_lineProgram    = loadProgram("vs_deferred_debug_line", "fs_deferred_debug_line");
 
 
+		m_useTArray = false;
+
+		if (0 != (BGFX_CAPS_TEXTURE_2D_ARRAY & bgfx::getCaps()->supported) )
+		{
+			m_lightTaProgram = loadProgram("vs_deferred_light", "fs_deferred_light_ta");
+		}
+		else
+		{
+			m_lightTaProgram = BGFX_INVALID_HANDLE;
+		}
+
 		// Load diffuse texture.
 		// Load diffuse texture.
 		m_textureColor  = loadTexture("textures/fieldstone-rgba.dds");
 		m_textureColor  = loadTexture("textures/fieldstone-rgba.dds");
 
 
@@ -290,8 +301,8 @@ public:
 		m_gbufferTex[0].idx = bgfx::kInvalidHandle;
 		m_gbufferTex[0].idx = bgfx::kInvalidHandle;
 		m_gbufferTex[1].idx = bgfx::kInvalidHandle;
 		m_gbufferTex[1].idx = bgfx::kInvalidHandle;
 		m_gbufferTex[2].idx = bgfx::kInvalidHandle;
 		m_gbufferTex[2].idx = bgfx::kInvalidHandle;
-		m_gbuffer.idx = bgfx::kInvalidHandle;
-		m_lightBuffer.idx = bgfx::kInvalidHandle;
+		m_gbuffer.idx       = bgfx::kInvalidHandle;
+		m_lightBuffer.idx   = bgfx::kInvalidHandle;
 
 
 		// Imgui.
 		// Imgui.
 		imguiCreate();
 		imguiCreate();
@@ -337,6 +348,12 @@ public:
 
 
 		bgfx::destroy(m_geomProgram);
 		bgfx::destroy(m_geomProgram);
 		bgfx::destroy(m_lightProgram);
 		bgfx::destroy(m_lightProgram);
+
+		if (bgfx::isValid(m_lightTaProgram) )
+		{
+			bgfx::destroy(m_lightTaProgram);
+		}
+
 		bgfx::destroy(m_combineProgram);
 		bgfx::destroy(m_combineProgram);
 		bgfx::destroy(m_debugProgram);
 		bgfx::destroy(m_debugProgram);
 		bgfx::destroy(m_lineProgram);
 		bgfx::destroy(m_lineProgram);
@@ -402,19 +419,24 @@ public:
 			}
 			}
 			else
 			else
 			{
 			{
-				if (m_oldWidth  != m_width
-				||  m_oldHeight != m_height
-				||  m_oldReset  != m_reset
+				if (m_oldWidth     != m_width
+				||  m_oldHeight    != m_height
+				||  m_oldReset     != m_reset
+				||  m_oldUseTArray != m_useTArray
 				||  !bgfx::isValid(m_gbuffer) )
 				||  !bgfx::isValid(m_gbuffer) )
 				{
 				{
 					// Recreate variable size render targets when resolution changes.
 					// Recreate variable size render targets when resolution changes.
-					m_oldWidth  = m_width;
-					m_oldHeight = m_height;
-					m_oldReset  = m_reset;
+					m_oldWidth     = m_width;
+					m_oldHeight    = m_height;
+					m_oldReset     = m_reset;
+					m_oldUseTArray = m_useTArray;
 
 
 					if (bgfx::isValid(m_gbuffer) )
 					if (bgfx::isValid(m_gbuffer) )
 					{
 					{
 						bgfx::destroy(m_gbuffer);
 						bgfx::destroy(m_gbuffer);
+						m_gbufferTex[0].idx = bgfx::kInvalidHandle;
+						m_gbufferTex[1].idx = bgfx::kInvalidHandle;
+						m_gbufferTex[2].idx = bgfx::kInvalidHandle;
 					}
 					}
 
 
 					const uint64_t tsFlags = 0
 					const uint64_t tsFlags = 0
@@ -425,10 +447,27 @@ public:
 						| BGFX_SAMPLER_U_CLAMP
 						| BGFX_SAMPLER_U_CLAMP
 						| BGFX_SAMPLER_V_CLAMP
 						| BGFX_SAMPLER_V_CLAMP
 						;
 						;
-					m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, tsFlags);
-					m_gbufferTex[1] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, tsFlags);
+
+					bgfx::Attachment at[3];
+
+					if (m_useTArray)
+					{
+						m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 2, bgfx::TextureFormat::BGRA8, tsFlags);
+						at[0].init(m_gbufferTex[0], bgfx::Access::Write, 0);
+						at[1].init(m_gbufferTex[0], bgfx::Access::Write, 1);
+					}
+					else
+					{
+						m_gbufferTex[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, tsFlags);
+						m_gbufferTex[1] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::BGRA8, tsFlags);
+						at[0].init(m_gbufferTex[0]);
+						at[1].init(m_gbufferTex[1]);
+					}
+
 					m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::D24S8, tsFlags);
 					m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::D24S8, tsFlags);
-					m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(m_gbufferTex), m_gbufferTex, true);
+					at[2].init(m_gbufferTex[2]);
+
+					m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(at), at, true);
 
 
 					if (bgfx::isValid(m_lightBuffer) )
 					if (bgfx::isValid(m_lightBuffer) )
 					{
 					{
@@ -454,6 +493,16 @@ public:
 				ImGui::SliderInt("Num lights", &m_numLights, 1, 2048);
 				ImGui::SliderInt("Num lights", &m_numLights, 1, 2048);
 				ImGui::Checkbox("Show G-Buffer.", &m_showGBuffer);
 				ImGui::Checkbox("Show G-Buffer.", &m_showGBuffer);
 				ImGui::Checkbox("Show light scissor.", &m_showScissorRects);
 				ImGui::Checkbox("Show light scissor.", &m_showScissorRects);
+
+				if (bgfx::isValid(m_lightTaProgram) )
+				{
+					ImGui::Checkbox("Use texture array frame buffer.", &m_useTArray);
+				}
+				else
+				{
+					ImGui::Text("Texture array frame buffer is not supported.");
+				}
+
 				ImGui::Checkbox("Animate mesh.", &m_animateMesh);
 				ImGui::Checkbox("Animate mesh.", &m_animateMesh);
 				ImGui::SliderFloat("Anim.speed", &m_lightAnimationSpeed, 0.0f, 0.4f);
 				ImGui::SliderFloat("Anim.speed", &m_lightAnimationSpeed, 0.0f, 0.4f);
 
 
@@ -668,7 +717,7 @@ public:
 								| BGFX_STATE_BLEND_ADD
 								| BGFX_STATE_BLEND_ADD
 								);
 								);
 						screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft);
 						screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft);
-						bgfx::submit(RENDER_PASS_LIGHT_ID, m_lightProgram);
+						bgfx::submit(RENDER_PASS_LIGHT_ID, bgfx::isValid(m_lightTaProgram) && m_useTArray ? m_lightTaProgram : m_lightProgram);
 					}
 					}
 				}
 				}
 
 
@@ -691,10 +740,10 @@ public:
 					{
 					{
 						float mtx[16];
 						float mtx[16];
 						bx::mtxSRT(mtx
 						bx::mtxSRT(mtx
-								, aspectRatio, 1.0f, 1.0f
-								, 0.0f, 0.0f, 0.0f
-								, -7.9f - BX_COUNTOF(m_gbufferTex)*0.1f*0.5f + ii*2.1f*aspectRatio, 4.0f, 0.0f
-								);
+							, aspectRatio, 1.0f, 1.0f
+							, 0.0f, 0.0f, 0.0f
+							, -7.9f - BX_COUNTOF(m_gbufferTex)*0.1f*0.5f + ii*2.1f*aspectRatio, 4.0f, 0.0f
+							);
 
 
 						bgfx::setTransform(mtx);
 						bgfx::setTransform(mtx);
 						bgfx::setVertexBuffer(0, m_vbh);
 						bgfx::setVertexBuffer(0, m_vbh);
@@ -734,6 +783,7 @@ public:
 
 
 	bgfx::ProgramHandle m_geomProgram;
 	bgfx::ProgramHandle m_geomProgram;
 	bgfx::ProgramHandle m_lightProgram;
 	bgfx::ProgramHandle m_lightProgram;
+	bgfx::ProgramHandle m_lightTaProgram;
 	bgfx::ProgramHandle m_combineProgram;
 	bgfx::ProgramHandle m_combineProgram;
 	bgfx::ProgramHandle m_debugProgram;
 	bgfx::ProgramHandle m_debugProgram;
 	bgfx::ProgramHandle m_lineProgram;
 	bgfx::ProgramHandle m_lineProgram;
@@ -753,6 +803,9 @@ public:
 	uint32_t m_oldHeight;
 	uint32_t m_oldHeight;
 	uint32_t m_oldReset;
 	uint32_t m_oldReset;
 
 
+	bool m_useTArray;
+	bool m_oldUseTArray;
+
 	int32_t m_scrollArea;
 	int32_t m_scrollArea;
 	int32_t m_numLights;
 	int32_t m_numLights;
 	float m_lightAnimationSpeed;
 	float m_lightAnimationSpeed;

+ 91 - 0
examples/21-deferred/fs_deferred_light_ta.sc

@@ -0,0 +1,91 @@
+$input v_texcoord0
+
+/*
+ * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
+ */
+
+#include "../common/common.sh"
+
+SAMPLER2DARRAY(s_normal, 0);
+SAMPLER2D(s_depth,  1);
+
+uniform vec4 u_lightPosRadius[1];
+uniform vec4 u_lightRgbInnerR[1];
+uniform mat4 u_mtx;
+
+vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir)
+{
+	float ndotl = dot(_normal, _lightDir);
+	vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal);
+	float rdotv = dot(reflected, _viewDir);
+	return vec2(ndotl, rdotv);
+}
+
+float fresnel(float _ndotl, float _bias, float _pow)
+{
+	float facing = (1.0 - _ndotl);
+	return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0);
+}
+
+vec4 lit(float _ndotl, float _rdotv, float _m)
+{
+	float diff = max(0.0, _ndotl);
+	float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m);
+	return vec4(1.0, diff, spec, 1.0);
+}
+
+vec4 powRgba(vec4 _rgba, float _pow)
+{
+	vec4 result;
+	result.xyz = pow(_rgba.xyz, vec3_splat(_pow) );
+	result.w = _rgba.w;
+	return result;
+}
+
+vec3 calcLight(int _idx, vec3 _wpos, vec3 _normal, vec3 _view)
+{
+	vec3 lp = u_lightPosRadius[_idx].xyz - _wpos;
+	float attn = 1.0 - smoothstep(u_lightRgbInnerR[_idx].w, 1.0, length(lp) / u_lightPosRadius[_idx].w);
+	vec3 lightDir = normalize(lp);
+	vec2 bln = blinn(lightDir, _normal, _view);
+	vec4 lc = lit(bln.x, bln.y, 1.0);
+	vec3 rgb = u_lightRgbInnerR[_idx].xyz * saturate(lc.y) * attn;
+	return rgb;
+}
+
+float toClipSpaceDepth(float _depthTextureZ)
+{
+#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL
+	return _depthTextureZ;
+#else
+	return _depthTextureZ * 2.0 - 1.0;
+#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL
+}
+
+vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos)
+{
+	vec4 wpos = mul(_invViewProj, vec4(_clipPos, 1.0) );
+	return wpos.xyz / wpos.w;
+}
+
+void main()
+{
+	vec3  normal      = decodeNormalUint(texture2DArray(s_normal, vec3(v_texcoord0, 1.0) ).xyz);
+	float deviceDepth = texture2D(s_depth, v_texcoord0).x;
+	float depth       = toClipSpaceDepth(deviceDepth);
+
+	vec3 clip = vec3(v_texcoord0 * 2.0 - 1.0, depth);
+#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL
+	clip.y = -clip.y;
+#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_PSSL || BGFX_SHADER_LANGUAGE_METAL
+	vec3 wpos = clipToWorld(u_mtx, clip);
+
+	vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz;
+	view = -normalize(view);
+
+	vec3 lightColor;
+	lightColor = calcLight(0, wpos, normal, view);
+	gl_FragColor.xyz = toGamma(lightColor.xyz);
+	gl_FragColor.w = 1.0;
+}

BIN
examples/runtime/shaders/dx11/fs_deferred_light_ta.bin


BIN
examples/runtime/shaders/glsl/fs_deferred_light_ta.bin


BIN
examples/runtime/shaders/metal/fs_deferred_light_ta.bin