21-deferred: Added texture array frame buffer option.

This commit is contained in:
Бранимир Караџић 2019-02-07 18:04:19 -08:00
parent dd10b04651
commit 82550fa842
5 changed files with 160 additions and 16 deletions

View File

@ -281,6 +281,17 @@ public:
m_debugProgram = loadProgram("vs_deferred_debug", "fs_deferred_debug");
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.
m_textureColor = loadTexture("textures/fieldstone-rgba.dds");
@ -290,8 +301,8 @@ public:
m_gbufferTex[0].idx = bgfx::kInvalidHandle;
m_gbufferTex[1].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.
imguiCreate();
@ -337,6 +348,12 @@ public:
bgfx::destroy(m_geomProgram);
bgfx::destroy(m_lightProgram);
if (bgfx::isValid(m_lightTaProgram) )
{
bgfx::destroy(m_lightTaProgram);
}
bgfx::destroy(m_combineProgram);
bgfx::destroy(m_debugProgram);
bgfx::destroy(m_lineProgram);
@ -402,19 +419,24 @@ public:
}
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) )
{
// 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) )
{
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
@ -425,10 +447,27 @@ public:
| BGFX_SAMPLER_U_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_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) )
{
@ -454,6 +493,16 @@ public:
ImGui::SliderInt("Num lights", &m_numLights, 1, 2048);
ImGui::Checkbox("Show G-Buffer.", &m_showGBuffer);
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::SliderFloat("Anim.speed", &m_lightAnimationSpeed, 0.0f, 0.4f);
@ -668,7 +717,7 @@ public:
| BGFX_STATE_BLEND_ADD
);
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];
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::setVertexBuffer(0, m_vbh);
@ -734,6 +783,7 @@ public:
bgfx::ProgramHandle m_geomProgram;
bgfx::ProgramHandle m_lightProgram;
bgfx::ProgramHandle m_lightTaProgram;
bgfx::ProgramHandle m_combineProgram;
bgfx::ProgramHandle m_debugProgram;
bgfx::ProgramHandle m_lineProgram;
@ -753,6 +803,9 @@ public:
uint32_t m_oldHeight;
uint32_t m_oldReset;
bool m_useTArray;
bool m_oldUseTArray;
int32_t m_scrollArea;
int32_t m_numLights;
float m_lightAnimationSpeed;

View File

@ -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;
}

Binary file not shown.

Binary file not shown.