summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/examples/16-shadowmaps/shadowmaps.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/examples/16-shadowmaps/shadowmaps.cpp')
-rw-r--r--3rdparty/bgfx/examples/16-shadowmaps/shadowmaps.cpp3621
1 files changed, 1851 insertions, 1770 deletions
diff --git a/3rdparty/bgfx/examples/16-shadowmaps/shadowmaps.cpp b/3rdparty/bgfx/examples/16-shadowmaps/shadowmaps.cpp
index 191a3426df3..9ee44d7fbbb 100644
--- a/3rdparty/bgfx/examples/16-shadowmaps/shadowmaps.cpp
+++ b/3rdparty/bgfx/examples/16-shadowmaps/shadowmaps.cpp
@@ -12,12 +12,20 @@
#include <bgfx/bgfx.h>
#include <bx/timer.h>
-#include <bx/fpumath.h>
-#include <bx/crtimpl.h>
+#include <bx/math.h>
+#include <bx/file.h>
#include "entry/entry.h"
#include "camera.h"
#include "imgui/imgui.h"
+namespace bgfx
+{
+ int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
+}
+
+namespace
+{
+
#define RENDERVIEW_SHADOWMAP_0_ID 1
#define RENDERVIEW_SHADOWMAP_1_ID 2
#define RENDERVIEW_SHADOWMAP_2_ID 3
@@ -38,31 +46,6 @@
#define RENDERVIEW_DRAWDEPTH_2_ID 18
#define RENDERVIEW_DRAWDEPTH_3_ID 19
-uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w)
-{
- union
- {
- uint32_t ui32;
- uint8_t arr[4];
- } un;
-
- un.arr[0] = _x;
- un.arr[1] = _y;
- un.arr[2] = _z;
- un.arr[3] = _w;
-
- return un.ui32;
-}
-
-uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f)
-{
- const uint8_t xx = uint8_t(_x*127.0f + 128.0f);
- const uint8_t yy = uint8_t(_y*127.0f + 128.0f);
- const uint8_t zz = uint8_t(_z*127.0f + 128.0f);
- const uint8_t ww = uint8_t(_w*127.0f + 128.0f);
- return packUint32(xx, yy, zz, ww);
-}
-
struct LightType
{
enum Enum
@@ -160,33 +143,6 @@ struct ShadowMapRenderTargets
};
};
-void imguiEnum(SmImpl::Enum& _enum)
-{
- _enum = (SmImpl::Enum)imguiChoose(_enum
- , "Hard"
- , "PCF"
- , "VSM"
- , "ESM"
- );
-}
-
-void imguiEnum(DepthImpl::Enum& _enum)
-{
- _enum = (DepthImpl::Enum)imguiChoose(_enum
- , "InvZ"
- , "Linear"
- );
-}
-
-void imguiEnum(LightType::Enum& _enum)
-{
- _enum = (LightType::Enum)imguiChoose(_enum
- , "Spot light"
- , "Point light"
- , "Directional light"
- );
-}
-
struct PosNormalTexcoordVertex
{
float m_x;
@@ -200,18 +156,18 @@ struct PosNormalTexcoordVertex
static const float s_texcoord = 5.0f;
static PosNormalTexcoordVertex s_hplaneVertices[] =
{
- { -1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), s_texcoord, s_texcoord },
- { 1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), s_texcoord, 0.0f },
- { -1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), 0.0f, s_texcoord },
- { 1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), 0.0f, 0.0f },
+ { -1.0f, 0.0f, 1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), s_texcoord, s_texcoord },
+ { 1.0f, 0.0f, 1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), s_texcoord, 0.0f },
+ { -1.0f, 0.0f, -1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), 0.0f, s_texcoord },
+ { 1.0f, 0.0f, -1.0f, encodeNormalRgba8(0.0f, 1.0f, 0.0f), 0.0f, 0.0f },
};
static PosNormalTexcoordVertex s_vplaneVertices[] =
{
- { -1.0f, 1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 1.0f, 1.0f },
- { 1.0f, 1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 1.0f, 0.0f },
- { -1.0f, -1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 0.0f, 1.0f },
- { 1.0f, -1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 0.0f, 0.0f },
+ { -1.0f, 1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 1.0f, 1.0f },
+ { 1.0f, 1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 1.0f, 0.0f },
+ { -1.0f, -1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 0.0f, 1.0f },
+ { 1.0f, -1.0f, 0.0f, encodeNormalRgba8(0.0f, 0.0f, -1.0f), 0.0f, 0.0f },
};
static const uint16_t s_planeIndices[] =
@@ -536,34 +492,34 @@ struct Uniforms
void destroy()
{
- bgfx::destroyUniform(u_params0);
- bgfx::destroyUniform(u_params1);
- bgfx::destroyUniform(u_params2);
- bgfx::destroyUniform(u_color);
- bgfx::destroyUniform(u_smSamplingParams);
- bgfx::destroyUniform(u_csmFarDistances);
-
- bgfx::destroyUniform(u_materialKa);
- bgfx::destroyUniform(u_materialKd);
- bgfx::destroyUniform(u_materialKs);
-
- bgfx::destroyUniform(u_tetraNormalGreen);
- bgfx::destroyUniform(u_tetraNormalYellow);
- bgfx::destroyUniform(u_tetraNormalBlue);
- bgfx::destroyUniform(u_tetraNormalRed);
-
- bgfx::destroyUniform(u_shadowMapMtx0);
- bgfx::destroyUniform(u_shadowMapMtx1);
- bgfx::destroyUniform(u_shadowMapMtx2);
- bgfx::destroyUniform(u_shadowMapMtx3);
-
- bgfx::destroyUniform(u_lightMtx);
- bgfx::destroyUniform(u_lightPosition);
- bgfx::destroyUniform(u_lightAmbientPower);
- bgfx::destroyUniform(u_lightDiffusePower);
- bgfx::destroyUniform(u_lightSpecularPower);
- bgfx::destroyUniform(u_lightSpotDirectionInner);
- bgfx::destroyUniform(u_lightAttenuationSpotOuter);
+ bgfx::destroy(u_params0);
+ bgfx::destroy(u_params1);
+ bgfx::destroy(u_params2);
+ bgfx::destroy(u_color);
+ bgfx::destroy(u_smSamplingParams);
+ bgfx::destroy(u_csmFarDistances);
+
+ bgfx::destroy(u_materialKa);
+ bgfx::destroy(u_materialKd);
+ bgfx::destroy(u_materialKs);
+
+ bgfx::destroy(u_tetraNormalGreen);
+ bgfx::destroy(u_tetraNormalYellow);
+ bgfx::destroy(u_tetraNormalBlue);
+ bgfx::destroy(u_tetraNormalRed);
+
+ bgfx::destroy(u_shadowMapMtx0);
+ bgfx::destroy(u_shadowMapMtx1);
+ bgfx::destroy(u_shadowMapMtx2);
+ bgfx::destroy(u_shadowMapMtx3);
+
+ bgfx::destroy(u_lightMtx);
+ bgfx::destroy(u_lightPosition);
+ bgfx::destroy(u_lightAmbientPower);
+ bgfx::destroy(u_lightDiffusePower);
+ bgfx::destroy(u_lightSpecularPower);
+ bgfx::destroy(u_lightSpotDirectionInner);
+ bgfx::destroy(u_lightAttenuationSpotOuter);
}
union
@@ -841,8 +797,8 @@ struct Group
void reset()
{
- m_vbh.idx = bgfx::invalidHandle;
- m_ibh.idx = bgfx::invalidHandle;
+ m_vbh.idx = bgfx::kInvalidHandle;
+ m_ibh.idx = bgfx::kInvalidHandle;
m_prims.clear();
}
@@ -854,11 +810,6 @@ struct Group
PrimitiveArray m_prims;
};
-namespace bgfx
-{
- int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
-}
-
struct Mesh
{
void load(const void* _vertices, uint32_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
@@ -973,11 +924,11 @@ struct Mesh
for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
{
const Group& group = *it;
- bgfx::destroyVertexBuffer(group.m_vbh);
+ bgfx::destroy(group.m_vbh);
- if (bgfx::invalidHandle != group.m_ibh.idx)
+ if (bgfx::kInvalidHandle != group.m_ibh.idx)
{
- bgfx::destroyIndexBuffer(group.m_ibh);
+ bgfx::destroy(group.m_ibh);
}
}
m_groups.clear();
@@ -1001,10 +952,10 @@ struct Mesh
// Set model matrix for rendering.
bgfx::setTransform(_mtx);
bgfx::setIndexBuffer(group.m_ibh);
- bgfx::setVertexBuffer(group.m_vbh);
+ bgfx::setVertexBuffer(0, group.m_vbh);
// Set textures.
- if (bgfx::invalidHandle != _texture.idx)
+ if (bgfx::kInvalidHandle != _texture.idx)
{
bgfx::setTexture(0, s_texColor, _texture);
}
@@ -1106,17 +1057,17 @@ void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBott
vertex[2].m_u = maxu;
vertex[2].m_v = maxv;
- bgfx::setVertexBuffer(&vb);
+ bgfx::setVertexBuffer(0, &vb);
}
}
void worldSpaceFrustumCorners(float* _corners24f
- , float _near
- , float _far
- , float _projWidth
- , float _projHeight
- , const float* __restrict _invViewMtx
- )
+ , float _near
+ , float _far
+ , float _projWidth
+ , float _projHeight
+ , const float* __restrict _invViewMtx
+ )
{
// Define frustum corners in view space.
const float nw = _near * _projWidth;
@@ -1239,7 +1190,7 @@ struct Programs
{
for (uint8_t kk = 0; kk < SmImpl::Count; ++kk)
{
- bgfx::destroyProgram(m_colorLighting[ii][jj][kk]);
+ bgfx::destroy(m_colorLighting[ii][jj][kk]);
}
}
}
@@ -1249,32 +1200,32 @@ struct Programs
{
for (uint8_t jj = 0; jj < PackDepth::Count; ++jj)
{
- bgfx::destroyProgram(m_packDepth[ii][jj]);
+ bgfx::destroy(m_packDepth[ii][jj]);
}
}
// Draw depth.
for (uint8_t ii = 0; ii < PackDepth::Count; ++ii)
{
- bgfx::destroyProgram(m_drawDepth[ii]);
+ bgfx::destroy(m_drawDepth[ii]);
}
// Hblur.
for (uint8_t ii = 0; ii < PackDepth::Count; ++ii)
{
- bgfx::destroyProgram(m_hBlur[ii]);
+ bgfx::destroy(m_hBlur[ii]);
}
// Vblur.
for (uint8_t ii = 0; ii < PackDepth::Count; ++ii)
{
- bgfx::destroyProgram(m_vBlur[ii]);
+ bgfx::destroy(m_vBlur[ii]);
}
// Misc.
- bgfx::destroyProgram(m_colorTexture);
- bgfx::destroyProgram(m_texture);
- bgfx::destroyProgram(m_black);
+ bgfx::destroy(m_colorTexture);
+ bgfx::destroy(m_texture);
+ bgfx::destroy(m_black);
}
bgfx::ProgramHandle m_black;
@@ -1310,1863 +1261,1993 @@ struct ShadowMapSettings
#undef IMGUI_FLOAT_PARAM
};
-int _main_(int _argc, char** _argv)
+struct SceneSettings
{
- Args args(_argc, _argv);
-
- uint32_t debug = BGFX_DEBUG_TEXT;
- uint32_t reset = BGFX_RESET_VSYNC;
-
- ViewState viewState(1280, 720);
- ClearValues clearValues(0x00000000, 1.0f, 0);
-
- bgfx::init(args.m_type, args.m_pciId);
- bgfx::reset(viewState.m_width, viewState.m_height, reset);
-
- // Enable debug text.
- bgfx::setDebug(debug);
+ LightType::Enum m_lightType;
+ DepthImpl::Enum m_depthImpl;
+ SmImpl::Enum m_smImpl;
+ float m_spotOuterAngle;
+ float m_spotInnerAngle;
+ float m_fovXAdjust;
+ float m_fovYAdjust;
+ float m_coverageSpotL;
+ float m_splitDistribution;
+ int m_numSplits;
+ bool m_updateLights;
+ bool m_updateScene;
+ bool m_drawDepthBuffer;
+ bool m_showSmCoverage;
+ bool m_stencilPack;
+ bool m_stabilize;
+};
- // Setup root path for binary shaders. Shader binaries are different
- // for each renderer.
- switch (bgfx::getRendererType() )
+class ExampleShadowmaps : public entry::AppI
+{
+public:
+ ExampleShadowmaps(const char* _name, const char* _description)
+ : entry::AppI(_name, _description)
{
- case bgfx::RendererType::Direct3D9:
- s_texelHalf = 0.5f;
- break;
-
- case bgfx::RendererType::OpenGL:
- case bgfx::RendererType::OpenGLES:
- s_flipV = true;
- break;
-
- default:
- break;
}
- // Imgui.
- imguiCreate();
-
- // Uniforms.
- s_uniforms.init();
- s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
- s_shadowMap[0] = bgfx::createUniform("s_shadowMap0", bgfx::UniformType::Int1);
- s_shadowMap[1] = bgfx::createUniform("s_shadowMap1", bgfx::UniformType::Int1);
- s_shadowMap[2] = bgfx::createUniform("s_shadowMap2", bgfx::UniformType::Int1);
- s_shadowMap[3] = bgfx::createUniform("s_shadowMap3", bgfx::UniformType::Int1);
-
- // Programs.
- s_programs.init();
-
- // Vertex declarations.
- bgfx::VertexDecl PosNormalTexcoordDecl;
- PosNormalTexcoordDecl.begin()
- .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
- .add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true)
- .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
- .end();
-
- bgfx::VertexDecl posDecl;
- posDecl.begin();
- posDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
- posDecl.end();
-
- PosColorTexCoord0Vertex::init();
-
- // Textures.
- bgfx::TextureHandle texFigure = loadTexture("textures/figure-rgba.dds");
- bgfx::TextureHandle texFlare = loadTexture("textures/flare.dds");
- bgfx::TextureHandle texFieldstone = loadTexture("textures/fieldstone-rgba.dds");
-
- // Meshes.
- Mesh bunnyMesh;
- Mesh treeMesh;
- Mesh cubeMesh;
- Mesh hollowcubeMesh;
- Mesh hplaneMesh;
- Mesh vplaneMesh;
- bunnyMesh.load("meshes/bunny.bin");
- treeMesh.load("meshes/tree.bin");
- cubeMesh.load("meshes/cube.bin");
- hollowcubeMesh.load("meshes/hollowcube.bin");
- hplaneMesh.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordDecl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
- vplaneMesh.load(s_vplaneVertices, BX_COUNTOF(s_vplaneVertices), PosNormalTexcoordDecl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
-
- // Materials.
- Material defaultMaterial =
+ void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
{
- { { 1.0f, 1.0f, 1.0f, 0.0f } }, //ambient
- { { 1.0f, 1.0f, 1.0f, 0.0f } }, //diffuse
- { { 1.0f, 1.0f, 1.0f, 0.0f } }, //specular, exponent
- };
+ Args args(_argc, _argv);
- // Lights.
- Light pointLight =
- {
- { { 0.0f, 0.0f, 0.0f, 1.0f } }, //position
- { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
- { { 1.0f, 1.0f, 1.0f, 0.0f } }, //ambient
- { { 1.0f, 1.0f, 1.0f, 850.0f } }, //diffuse
- { { 1.0f, 1.0f, 1.0f, 0.0f } }, //specular
- { { 0.0f,-0.4f,-0.6f, 0.0f } }, //spotdirection, spotexponent
- { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
- { { 1.0f, 0.0f, 1.0f, 91.0f } }, //attenuation, spotcutoff
- };
+ m_debug = BGFX_DEBUG_NONE;
+ m_reset = BGFX_RESET_VSYNC;
- Light directionalLight =
- {
- { { 0.5f,-1.0f, 0.1f, 0.0f } }, //position
- { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
- { { 1.0f, 1.0f, 1.0f, 0.02f } }, //ambient
- { { 1.0f, 1.0f, 1.0f, 0.4f } }, //diffuse
- { { 1.0f, 1.0f, 1.0f, 0.0f } }, //specular
- { { 0.0f, 0.0f, 0.0f, 1.0f } }, //spotdirection, spotexponent
- { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
- { { 0.0f, 0.0f, 0.0f, 1.0f } }, //attenuation, spotcutoff
- };
+ m_width = _width;
+ m_height = _height;
+ m_viewState = ViewState(uint16_t(m_width), uint16_t(m_height));
+ m_clearValues = ClearValues(0x00000000, 1.0f, 0);
- // Setup uniforms.
- float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- float lightMtx[16];
- float shadowMapMtx[ShadowMapRenderTargets::Count][16];
- s_uniforms.setPtrs(&defaultMaterial
- , &pointLight
- , color
- , lightMtx
- , &shadowMapMtx[ShadowMapRenderTargets::First][0]
- , &shadowMapMtx[ShadowMapRenderTargets::Second][0]
- , &shadowMapMtx[ShadowMapRenderTargets::Third][0]
- , &shadowMapMtx[ShadowMapRenderTargets::Fourth][0]
- );
- s_uniforms.submitConstUniforms();
-
- // Settings.
- ShadowMapSettings smSettings[LightType::Count][DepthImpl::Count][SmImpl::Count] =
- {
- { //LightType::Spot
-
- { //DepthImpl::InvZ
-
- { //SmImpl::Hard
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0035f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.0012f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::Hard] //m_progDraw
- },
- { //SmImpl::PCF
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 99.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.007f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::PCF] //m_progDraw
- },
- { //SmImpl::VSM
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 8.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.045f, 0.0f, 0.1f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
- , 450.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::VSM] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::VSM] //m_progDraw
- },
- { //SmImpl::ESM
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 3.0f, 1.0f, 10.0f, 0.01f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.02f, 0.0f, 0.3f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 9000.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::ESM] //m_progDraw
- }
+ bgfx::init(args.m_type, args.m_pciId);
+ bgfx::reset(m_viewState.m_width, m_viewState.m_height, m_reset);
- },
- { //DepthImpl::Linear
-
- { //SmImpl::Hard
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0025f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.0012f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::Hard] //m_progDraw
- },
- { //SmImpl::PCF
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 99.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0025f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 2000.0f, 1.0f, 2000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::PCF] //m_progDraw
- },
- { //SmImpl::VSM
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.006f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.02f, 0.0f, 0.1f, 0.00001f // m_customParam0
- , 300.0f, 1.0f, 1500.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::VSM] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::VSM] //m_progDraw
- },
- { //SmImpl::ESM
- 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 0.01f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0055f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 2500.0f, 1.0f, 5000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::ESM] //m_progDraw
- }
+ // Enable debug text.
+ bgfx::setDebug(m_debug);
- }
+ // Setup root path for binary shaders. Shader binaries are different
+ // for each renderer.
+ switch (bgfx::getRendererType() )
+ {
+ case bgfx::RendererType::Direct3D9:
+ s_texelHalf = 0.5f;
+ break;
- },
- { //LightType::Point
-
- { //DepthImpl::InvZ
-
- { //SmImpl::Hard
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.006f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 50.0f, 1.0f, 300.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
- , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::Hard] //m_progDraw
- },
- { //SmImpl::PCF
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 99.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 50.0f, 1.0f, 300.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.001f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::PCF] //m_progDraw
- },
- { //SmImpl::VSM
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 8.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.055f, 0.0f, 0.1f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
- , 450.0f, 1.0f, 900.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
- , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::VSM] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::VSM] //m_progDraw
- },
- { //SmImpl::ESM
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 3.0f, 1.0f, 10.0f, 0.01f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.035f, 0.0f, 0.1f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 9000.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
- , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::ESM] //m_progDraw
- }
+ case bgfx::RendererType::OpenGL:
+ case bgfx::RendererType::OpenGLES:
+ s_flipV = true;
+ break;
- },
- { //DepthImpl::Linear
-
- { //SmImpl::Hard
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.003f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 120.0f, 1.0f, 300.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
- , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::Hard] //m_progDraw
- },
- { //SmImpl::PCF
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 99.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0035f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 120.0f, 1.0f, 300.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.001f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::PCF] //m_progDraw
- },
- { //SmImpl::VSM
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.006f, 0.0f, 0.1f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.02f, 0.0f, 0.1f, 0.00001f // m_customParam0
- , 400.0f, 1.0f, 900.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
- , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::VSM] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::VSM] //m_progDraw
- },
- { //SmImpl::ESM
- 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 0.01f // m_near
- , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.007f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 8000.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
- , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::ESM] //m_progDraw
+ default:
+ break;
}
- }
+ // Imgui.
+ imguiCreate();
+
+ // Uniforms.
+ s_uniforms.init();
+ s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
+ s_shadowMap[0] = bgfx::createUniform("s_shadowMap0", bgfx::UniformType::Int1);
+ s_shadowMap[1] = bgfx::createUniform("s_shadowMap1", bgfx::UniformType::Int1);
+ s_shadowMap[2] = bgfx::createUniform("s_shadowMap2", bgfx::UniformType::Int1);
+ s_shadowMap[3] = bgfx::createUniform("s_shadowMap3", bgfx::UniformType::Int1);
+
+ // Programs.
+ s_programs.init();
+
+ // Vertex declarations.
+ bgfx::VertexDecl PosNormalTexcoordDecl;
+ PosNormalTexcoordDecl.begin()
+ .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
+ .add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true)
+ .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
+ .end();
- },
- { //LightType::Directional
-
- { //DepthImpl::InvZ
-
- { //SmImpl::Hard
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 200.0f, 1.0f, 400.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
- , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::Hard] //m_progDraw
- },
- { //SmImpl::PCF
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 99.0f, 1.0f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 200.0f, 1.0f, 400.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::PCF] //m_progDraw
- },
- { //SmImpl::VSM
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
- , 2500.0f, 1.0f, 5000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
- , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::VSM] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::VSM] //m_progDraw
- },
- { //SmImpl::ESM
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 0.01f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 9500.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
- , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::ESM] //m_progDraw
- }
+ m_posDecl.begin();
+ m_posDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
+ m_posDecl.end();
- },
- { //DepthImpl::Linear
-
- { //SmImpl::Hard
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
- , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::Hard] //m_progDraw
- },
- { //SmImpl::PCF
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 99.0f, 1.0f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 200.0f, 1.0f, 400.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
- , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
- , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::PCF] //m_progDraw
- },
- { //SmImpl::VSM
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 1.0f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
- , 2500.0f, 1.0f, 5000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
- , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::VSM] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::VSM] //m_progDraw
- },
- { //SmImpl::ESM
- 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
- , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
- , 1.0f, 1.0f, 10.0f, 0.01f // m_near
- , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
- , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
- , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
- , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
- , 9500.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
- , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
- , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
- , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
- , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
- , true // m_doBlur
- , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
- , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::ESM] //m_progDraw
- }
+ PosColorTexCoord0Vertex::init();
- }
- }
- };
+ // Textures.
+ m_texFigure = loadTexture("textures/figure-rgba.dds");
+ m_texFlare = loadTexture("textures/flare.dds");
+ m_texFieldstone = loadTexture("textures/fieldstone-rgba.dds");
- struct SceneSettings
- {
- LightType::Enum m_lightType;
- DepthImpl::Enum m_depthImpl;
- SmImpl::Enum m_smImpl;
- float m_spotOuterAngle;
- float m_spotInnerAngle;
- float m_fovXAdjust;
- float m_fovYAdjust;
- float m_coverageSpotL;
- float m_numSplitsf;
- float m_splitDistribution;
- uint8_t m_numSplits;
- bool m_updateLights;
- bool m_updateScene;
- bool m_drawDepthBuffer;
- bool m_showSmCoverage;
- bool m_stencilPack;
- bool m_stabilize;
- };
+ // Meshes.
+ m_bunnyMesh.load("meshes/bunny.bin");
+ m_treeMesh.load("meshes/tree.bin");
+ m_cubeMesh.load("meshes/cube.bin");
+ m_hollowcubeMesh.load("meshes/hollowcube.bin");
+ m_hplaneMesh.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordDecl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
+ m_vplaneMesh.load(s_vplaneVertices, BX_COUNTOF(s_vplaneVertices), PosNormalTexcoordDecl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
- SceneSettings settings;
- settings.m_lightType = LightType::SpotLight;
- settings.m_depthImpl = DepthImpl::InvZ;
- settings.m_smImpl = SmImpl::Hard;
- settings.m_spotOuterAngle = 45.0f;
- settings.m_spotInnerAngle = 30.0f;
- settings.m_fovXAdjust = 0.0f;
- settings.m_fovYAdjust = 0.0f;
- settings.m_coverageSpotL = 90.0f;
- settings.m_numSplitsf = 4.0f;
- settings.m_splitDistribution = 0.6f;
- settings.m_numSplits = uint8_t(settings.m_numSplitsf);
- settings.m_updateLights = true;
- settings.m_updateScene = true;
- settings.m_drawDepthBuffer = false;
- settings.m_showSmCoverage = false;
- settings.m_stencilPack = true;
- settings.m_stabilize = true;
-
- ShadowMapSettings* currentSmSettings = &smSettings[settings.m_lightType][settings.m_depthImpl][settings.m_smImpl];
-
- // Render targets.
- uint16_t shadowMapSize = 1 << uint32_t(currentSmSettings->m_sizePwrTwo);
- uint16_t currentShadowMapSize = shadowMapSize;
- float currentShadowMapSizef = float(int16_t(currentShadowMapSize) );
- s_uniforms.m_shadowMapTexelSize = 1.0f / currentShadowMapSizef;
- for (uint8_t ii = 0; ii < ShadowMapRenderTargets::Count; ++ii)
- {
- bgfx::TextureHandle fbtextures[] =
+ // Materials.
+ m_defaultMaterial =
{
- bgfx::createTexture2D(currentShadowMapSize, currentShadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT),
- bgfx::createTexture2D(currentShadowMapSize, currentShadowMapSize, false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT),
+ { { 1.0f, 1.0f, 1.0f, 0.0f } }, //ambient
+ { { 1.0f, 1.0f, 1.0f, 0.0f } }, //diffuse
+ { { 1.0f, 1.0f, 1.0f, 0.0f } }, //specular, exponent
};
- s_rtShadowMap[ii] = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
- }
- s_rtBlur = bgfx::createFrameBuffer(currentShadowMapSize, currentShadowMapSize, bgfx::TextureFormat::BGRA8);
-
- // Setup camera.
- float initialPos[3] = { 0.0f, 60.0f, -105.0f };
- cameraCreate();
- cameraSetPosition(initialPos);
- cameraSetVerticalAngle(-0.45f);
-
- // Set view and projection matrices.
- const float camFovy = 60.0f;
- const float camAspect = float(int32_t(viewState.m_width) ) / float(int32_t(viewState.m_height) );
- const float camNear = 0.1f;
- const float camFar = 2000.0f;
- const float projHeight = 1.0f/bx::ftan(bx::toRad(camFovy)*0.5f);
- const float projWidth = projHeight * camAspect;
- bx::mtxProj(viewState.m_proj, camFovy, camAspect, camNear, camFar, bgfx::getCaps()->homogeneousDepth);
- cameraGetViewMtx(viewState.m_view);
-
- float timeAccumulatorLight = 0.0f;
- float timeAccumulatorScene = 0.0f;
-
- entry::MouseState mouseState;
- uint32_t width;
- uint32_t height;
- while (!entry::processEvents(width, height, debug, reset, &mouseState) )
- {
- viewState.m_width = uint16_t(width);
- viewState.m_height = uint16_t(height);
- // Imgui.
- imguiBeginFrame(mouseState.m_mx
- , mouseState.m_my
- , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
- | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
- | (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
- , mouseState.m_mz
- , viewState.m_width
- , viewState.m_height
- );
-
- static int32_t rightScrollArea = 0;
- imguiBeginScrollArea("Settings", viewState.m_width - 256 - 10, 10, 256, 660, &rightScrollArea);
-
-#define IMGUI_FLOAT_SLIDER(_name, _val) \
- imguiSlider(_name \
- , _val \
- , *( ((float*)&_val)+1) \
- , *( ((float*)&_val)+2) \
- , *( ((float*)&_val)+3) \
- )
-
- imguiBool("Update lights", settings.m_updateLights);
- imguiBool("Update scene", settings.m_updateScene);
-
- imguiSeparatorLine();
- imguiLabel("Shadow map depth:");
- imguiEnum(settings.m_depthImpl);
- currentSmSettings = &smSettings[settings.m_lightType][settings.m_depthImpl][settings.m_smImpl];
-
- imguiSeparator();
- imguiBool("Draw depth buffer.", settings.m_drawDepthBuffer);
- if (settings.m_drawDepthBuffer)
+ // Lights.
+ m_pointLight =
{
- IMGUI_FLOAT_SLIDER("Depth value pow:", currentSmSettings->m_depthValuePow);
- }
-
- imguiSeparatorLine();
- imguiLabel("Shadow Map implementation:");
- imguiEnum(settings.m_smImpl);
- currentSmSettings = &smSettings[settings.m_lightType][settings.m_depthImpl][settings.m_smImpl];
+ { { 0.0f, 0.0f, 0.0f, 1.0f } }, //position
+ { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
+ { { 1.0f, 1.0f, 1.0f, 0.0f } }, //ambient
+ { { 1.0f, 1.0f, 1.0f, 850.0f } }, //diffuse
+ { { 1.0f, 1.0f, 1.0f, 0.0f } }, //specular
+ { { 0.0f,-0.4f,-0.6f, 0.0f } }, //spotdirection, spotexponent
+ { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
+ { { 1.0f, 0.0f, 1.0f, 91.0f } }, //attenuation, spotcutoff
+ };
- imguiSeparator();
- IMGUI_FLOAT_SLIDER("Bias:", currentSmSettings->m_bias);
- IMGUI_FLOAT_SLIDER("Normal offset:", currentSmSettings->m_normalOffset);
- imguiSeparator();
- if (LightType::DirectionalLight != settings.m_lightType)
+ m_directionalLight =
{
- IMGUI_FLOAT_SLIDER("Near plane:", currentSmSettings->m_near);
- }
- IMGUI_FLOAT_SLIDER("Far plane:", currentSmSettings->m_far);
+ { { 0.5f,-1.0f, 0.1f, 0.0f } }, //position
+ { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
+ { { 1.0f, 1.0f, 1.0f, 0.02f } }, //ambient
+ { { 1.0f, 1.0f, 1.0f, 0.4f } }, //diffuse
+ { { 1.0f, 1.0f, 1.0f, 0.0f } }, //specular
+ { { 0.0f, 0.0f, 0.0f, 1.0f } }, //spotdirection, spotexponent
+ { 0.0f, 0.0f, 0.0f, 0.0f }, //-ignore
+ { { 0.0f, 0.0f, 0.0f, 1.0f } }, //attenuation, spotcutoff
+ };
- imguiSeparator();
- switch(settings.m_smImpl)
+ // Setup uniforms.
+ m_color[0] = m_color[1] = m_color[2] = m_color[3] = 1.0f;
+ s_uniforms.setPtrs(&m_defaultMaterial
+ , &m_pointLight
+ , m_color
+ , m_lightMtx
+ , &m_shadowMapMtx[ShadowMapRenderTargets::First][0]
+ , &m_shadowMapMtx[ShadowMapRenderTargets::Second][0]
+ , &m_shadowMapMtx[ShadowMapRenderTargets::Third][0]
+ , &m_shadowMapMtx[ShadowMapRenderTargets::Fourth][0]
+ );
+ s_uniforms.submitConstUniforms();
+
+ // Settings.
+ ShadowMapSettings smSettings[LightType::Count][DepthImpl::Count][SmImpl::Count] =
{
- case SmImpl::Hard:
- //imguiLabel("Hard");
- break;
+ { //LightType::Spot
+
+ { //DepthImpl::InvZ
+
+ { //SmImpl::Hard
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0035f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.0012f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::Hard] //m_progDraw
+ },
+ { //SmImpl::PCF
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 99.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.007f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::PCF] //m_progDraw
+ },
+ { //SmImpl::VSM
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 8.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.045f, 0.0f, 0.1f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
+ , 450.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::VSM] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::VSM] //m_progDraw
+ },
+ { //SmImpl::ESM
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 3.0f, 1.0f, 10.0f, 0.01f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.02f, 0.0f, 0.3f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 9000.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::InvZ][SmImpl::ESM] //m_progDraw
+ }
- case SmImpl::PCF:
- imguiLabel("PCF");
- IMGUI_FLOAT_SLIDER("X Offset:", currentSmSettings->m_xOffset);
- IMGUI_FLOAT_SLIDER("Y Offset:", currentSmSettings->m_yOffset);
- break;
+ },
+ { //DepthImpl::Linear
+
+ { //SmImpl::Hard
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0025f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.0012f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::Hard] //m_progDraw
+ },
+ { //SmImpl::PCF
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 99.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0025f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 2000.0f, 1.0f, 2000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::PCF] //m_progDraw
+ },
+ { //SmImpl::VSM
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.006f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.02f, 0.0f, 0.1f, 0.00001f // m_customParam0
+ , 300.0f, 1.0f, 1500.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::VSM] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::VSM] //m_progDraw
+ },
+ { //SmImpl::ESM
+ 10.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 0.01f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0055f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 2500.0f, 1.0f, 5000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Single][DepthImpl::Linear][SmImpl::ESM] //m_progDraw
+ }
- case SmImpl::VSM:
- imguiLabel("VSM");
- IMGUI_FLOAT_SLIDER("Min variance", currentSmSettings->m_customParam0);
- IMGUI_FLOAT_SLIDER("Depth multiplier", currentSmSettings->m_customParam1);
- imguiBool("Blur shadow map", currentSmSettings->m_doBlur);
- if (currentSmSettings->m_doBlur)
- {
- IMGUI_FLOAT_SLIDER("Blur X Offset:", currentSmSettings->m_xOffset);
- IMGUI_FLOAT_SLIDER("Blur Y Offset:", currentSmSettings->m_yOffset);
}
- break;
- case SmImpl::ESM:
- imguiLabel("ESM");
- IMGUI_FLOAT_SLIDER("ESM Hardness", currentSmSettings->m_customParam0);
- IMGUI_FLOAT_SLIDER("Depth multiplier", currentSmSettings->m_customParam1);
- imguiBool("Blur shadow map", currentSmSettings->m_doBlur);
- if (currentSmSettings->m_doBlur)
- {
- IMGUI_FLOAT_SLIDER("Blur X Offset:", currentSmSettings->m_xOffset);
- IMGUI_FLOAT_SLIDER("Blur Y Offset:", currentSmSettings->m_yOffset);
+ },
+ { //LightType::Point
+
+ { //DepthImpl::InvZ
+
+ { //SmImpl::Hard
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.006f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 50.0f, 1.0f, 300.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::Hard] //m_progDraw
+ },
+ { //SmImpl::PCF
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 99.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 50.0f, 1.0f, 300.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.001f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::PCF] //m_progDraw
+ },
+ { //SmImpl::VSM
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 8.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.055f, 0.0f, 0.1f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
+ , 450.0f, 1.0f, 900.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::VSM] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::VSM] //m_progDraw
+ },
+ { //SmImpl::ESM
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 10.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 3.0f, 1.0f, 10.0f, 0.01f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.035f, 0.0f, 0.1f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 9000.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::InvZ][SmImpl::ESM] //m_progDraw
+ }
+
+ },
+ { //DepthImpl::Linear
+
+ { //SmImpl::Hard
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.003f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 120.0f, 1.0f, 300.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::Hard] //m_progDraw
+ },
+ { //SmImpl::PCF
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 99.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0035f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 120.0f, 1.0f, 300.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.001f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::PCF] //m_progDraw
+ },
+ { //SmImpl::VSM
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.006f, 0.0f, 0.1f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.02f, 0.0f, 0.1f, 0.00001f // m_customParam0
+ , 400.0f, 1.0f, 900.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::VSM] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::VSM] //m_progDraw
+ },
+ { //SmImpl::ESM
+ 12.0f, 9.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 0.01f // m_near
+ , 250.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.007f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.05f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 8000.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_xOffset
+ , 0.25f, 0.0f, 2.0f, 0.001f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Omni][DepthImpl::Linear][SmImpl::ESM] //m_progDraw
+ }
+
}
- break;
- default:
- break;
+ },
+ { //LightType::Directional
+
+ { //DepthImpl::InvZ
+
+ { //SmImpl::Hard
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 200.0f, 1.0f, 400.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::Hard] //m_progDraw
+ },
+ { //SmImpl::PCF
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 99.0f, 1.0f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 200.0f, 1.0f, 400.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::PCF] //m_progDraw
+ },
+ { //SmImpl::VSM
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
+ , 2500.0f, 1.0f, 5000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::VSM] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::VSM] //m_progDraw
+ },
+ { //SmImpl::ESM
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 0.01f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 9500.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::InvZ][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::InvZ][SmImpl::ESM] //m_progDraw
+ }
+
+ },
+ { //DepthImpl::Linear
+
+ { //SmImpl::Hard
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 500.0f, 1.0f, 1000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::Hard] //m_progDraw
+ },
+ { //SmImpl::PCF
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 99.0f, 1.0f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.0012f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 200.0f, 1.0f, 400.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 8.0f, 1.0f // m_yNum
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_xOffset
+ , 1.0f, 0.0f, 3.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::PCF] //m_progDraw
+ },
+ { //SmImpl::VSM
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 1.0f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.02f, 0.0f, 0.04f, 0.00001f // m_customParam0
+ , 2500.0f, 1.0f, 5000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::VSM] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::VSM] //m_progDraw
+ },
+ { //SmImpl::ESM
+ 11.0f, 7.0f, 12.0f, 1.0f // m_sizePwrTwo
+ , 1.0f, 1.0f, 20.0f, 1.0f // m_depthValuePow
+ , 1.0f, 1.0f, 10.0f, 0.01f // m_near
+ , 550.0f, 100.0f, 2000.0f, 50.0f // m_far
+ , 0.004f, 0.0f, 0.01f, 0.00001f // m_bias
+ , 0.001f, 0.0f, 0.04f, 0.00001f // m_normalOffset
+ , 0.7f, 0.0f, 1.0f, 0.01f // m_customParam0
+ , 9500.0f, 1.0f, 15000.0f, 1.0f // m_customParam1
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_xNum
+ , 2.0f, 0.0f, 4.0f, 1.0f // m_yNum
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_xOffset
+ , 0.2f, 0.0f, 1.0f, 0.01f // m_yOffset
+ , true // m_doBlur
+ , &s_programs.m_packDepth[DepthImpl::Linear][PackDepth::RGBA] //m_progPack
+ , &s_programs.m_colorLighting[SmType::Cascade][DepthImpl::Linear][SmImpl::ESM] //m_progDraw
+ }
+
+ }
+ }
};
+ bx::memCopy(m_smSettings, smSettings, sizeof(smSettings));
+
+ m_settings.m_lightType = LightType::SpotLight;
+ m_settings.m_depthImpl = DepthImpl::InvZ;
+ m_settings.m_smImpl = SmImpl::Hard;
+ m_settings.m_spotOuterAngle = 45.0f;
+ m_settings.m_spotInnerAngle = 30.0f;
+ m_settings.m_fovXAdjust = 0.0f;
+ m_settings.m_fovYAdjust = 0.0f;
+ m_settings.m_coverageSpotL = 90.0f;
+ m_settings.m_splitDistribution = 0.6f;
+ m_settings.m_numSplits = 4;
+ m_settings.m_updateLights = true;
+ m_settings.m_updateScene = true;
+ m_settings.m_drawDepthBuffer = false;
+ m_settings.m_showSmCoverage = false;
+ m_settings.m_stencilPack = true;
+ m_settings.m_stabilize = true;
+
+ ShadowMapSettings* currentSmSettings = &m_smSettings[m_settings.m_lightType][m_settings.m_depthImpl][m_settings.m_smImpl];
+
+ // Render targets.
+ uint16_t shadowMapSize = 1 << uint32_t(currentSmSettings->m_sizePwrTwo);
+ m_currentShadowMapSize = shadowMapSize;
+ float currentShadowMapSizef = float(int16_t(m_currentShadowMapSize) );
+ s_uniforms.m_shadowMapTexelSize = 1.0f / currentShadowMapSizef;
+ for (uint8_t ii = 0; ii < ShadowMapRenderTargets::Count; ++ii)
+ {
+ bgfx::TextureHandle fbtextures[] =
+ {
+ bgfx::createTexture2D(m_currentShadowMapSize, m_currentShadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT),
+ bgfx::createTexture2D(m_currentShadowMapSize, m_currentShadowMapSize, false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT),
+ };
+ s_rtShadowMap[ii] = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ }
+ s_rtBlur = bgfx::createFrameBuffer(m_currentShadowMapSize, m_currentShadowMapSize, bgfx::TextureFormat::BGRA8);
- imguiEndScrollArea();
+ // Setup camera.
+ float initialPos[3] = { 0.0f, 60.0f, -105.0f };
+ cameraCreate();
+ cameraSetPosition(initialPos);
+ cameraSetVerticalAngle(-0.45f);
- static int32_t leftScrollArea = 0;
- imguiBeginScrollArea("Light", 10, 70, 256, 334, &leftScrollArea);
+ m_timeAccumulatorLight = 0.0f;
+ m_timeAccumulatorScene = 0.0f;
+ }
- const LightType::Enum ltBefore = settings.m_lightType;
- imguiEnum(settings.m_lightType);
- const LightType::Enum ltAfter = settings.m_lightType;
- const bool bLtChanged = (ltAfter != ltBefore);
+ virtual int shutdown() override
+ {
+ m_bunnyMesh.unload();
+ m_treeMesh.unload();
+ m_cubeMesh.unload();
+ m_hollowcubeMesh.unload();
+ m_hplaneMesh.unload();
+ m_vplaneMesh.unload();
+
+ bgfx::destroy(m_texFigure);
+ bgfx::destroy(m_texFieldstone);
+ bgfx::destroy(m_texFlare);
+
+ for (uint8_t ii = 0; ii < ShadowMapRenderTargets::Count; ++ii)
+ {
+ bgfx::destroy(s_rtShadowMap[ii]);
+ }
+ bgfx::destroy(s_rtBlur);
- imguiSeparator();
- imguiBool("Show shadow map coverage.", settings.m_showSmCoverage);
+ s_programs.destroy();
- imguiSeparator();
- imguiLabel("Shadow map resolution: %ux%u", currentShadowMapSize, currentShadowMapSize);
- IMGUI_FLOAT_SLIDER(" ", currentSmSettings->m_sizePwrTwo);
+ bgfx::destroy(s_texColor);
+ bgfx::destroy(s_shadowMap[3]);
+ bgfx::destroy(s_shadowMap[2]);
+ bgfx::destroy(s_shadowMap[1]);
+ bgfx::destroy(s_shadowMap[0]);
- imguiSeparatorLine();
- if (LightType::SpotLight == settings.m_lightType)
- {
- imguiLabel("Spot light");
- imguiSlider("Shadow map area:", settings.m_coverageSpotL, 45.0f, 120.0f, 1.0f);
+ s_uniforms.destroy();
- imguiSeparator();
- imguiSlider("Spot outer cone:", settings.m_spotOuterAngle, 0.0f, 91.0f, 0.1f);
- imguiSlider("Spot inner cone:", settings.m_spotInnerAngle, 0.0f, 90.0f, 0.1f);
- }
- else if (LightType::PointLight == settings.m_lightType)
- {
- imguiLabel("Point light");
- imguiBool("Stencil pack", settings.m_stencilPack);
+ cameraDestroy();
+ imguiDestroy();
- imguiSlider("Fov X adjust:", settings.m_fovXAdjust, -20.0f, 20.0f, 0.0001f);
- imguiSlider("Fov Y adjust:", settings.m_fovYAdjust, -20.0f, 20.0f, 0.0001f);
- }
- else if (LightType::DirectionalLight == settings.m_lightType)
- {
- imguiLabel("Directional light");
- imguiBool("Stabilize cascades", settings.m_stabilize);
- imguiSlider("Cascade splits:", settings.m_numSplitsf, 1.0f, 4.0f, 1.0f);
- imguiSlider("Cascade distribution:", settings.m_splitDistribution, 0.0f, 1.0f, 0.001f);
- settings.m_numSplits = uint8_t(settings.m_numSplitsf);
- }
+ // Shutdown bgfx.
+ bgfx::shutdown();
-#undef IMGUI_FLOAT_SLIDER
+ return 0;
+ }
- imguiEndScrollArea();
- imguiEndFrame();
-
- // Update uniforms.
- s_uniforms.m_shadowMapBias = currentSmSettings->m_bias;
- s_uniforms.m_shadowMapOffset = currentSmSettings->m_normalOffset;
- s_uniforms.m_shadowMapParam0 = currentSmSettings->m_customParam0;
- s_uniforms.m_shadowMapParam1 = currentSmSettings->m_customParam1;
- s_uniforms.m_depthValuePow = currentSmSettings->m_depthValuePow;
- s_uniforms.m_XNum = currentSmSettings->m_xNum;
- s_uniforms.m_YNum = currentSmSettings->m_yNum;
- s_uniforms.m_XOffset = currentSmSettings->m_xOffset;
- s_uniforms.m_YOffset = currentSmSettings->m_yOffset;
- s_uniforms.m_showSmCoverage = float(settings.m_showSmCoverage);
- s_uniforms.m_lightPtr = (LightType::DirectionalLight == settings.m_lightType) ? &directionalLight : &pointLight;
-
- if (LightType::SpotLight == settings.m_lightType)
- {
- pointLight.m_attenuationSpotOuter.m_outer = settings.m_spotOuterAngle;
- pointLight.m_spotDirectionInner.m_inner = settings.m_spotInnerAngle;
- }
- else
+ bool update() override
+ {
+ if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
{
- pointLight.m_attenuationSpotOuter.m_outer = 91.0f; //above 90.0f means point light
- }
+ m_viewState.m_width = uint16_t(m_width);
+ m_viewState.m_height = uint16_t(m_height);
+
+ const bgfx::Caps* caps = bgfx::getCaps();
+
+ // Set view and projection matrices.
+ const float camFovy = 60.0f;
+ const float camAspect = float(int32_t(m_viewState.m_width) ) / float(int32_t(m_viewState.m_height) );
+ const float camNear = 0.1f;
+ const float camFar = 2000.0f;
+ const float projHeight = 1.0f/bx::ftan(bx::toRad(camFovy)*0.5f);
+ const float projWidth = projHeight * camAspect;
+ bx::mtxProj(m_viewState.m_proj, camFovy, camAspect, camNear, camFar, caps->homogeneousDepth);
+ cameraGetViewMtx(m_viewState.m_view);
+
+ float currentShadowMapSizef = float(int16_t(m_currentShadowMapSize) );
+ s_uniforms.m_shadowMapTexelSize = 1.0f / currentShadowMapSizef;
- s_uniforms.submitPerFrameUniforms();
-
- // Time.
- int64_t now = bx::getHPCounter();
- static int64_t last = now;
- const int64_t frameTime = now - last;
- last = now;
- const double freq = double(bx::getHPFrequency() );
- const double toMs = 1000.0/freq;
- const float deltaTime = float(frameTime/freq);
-
- // Use debug font to print information about this example.
- bgfx::dbgTextClear();
- bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/16-shadowmaps");
- bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow maps example.");
- bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
-
- // Update camera.
- cameraUpdate(deltaTime, mouseState);
-
- // Update view mtx.
- cameraGetViewMtx(viewState.m_view);
-
- // Update lights.
- pointLight.computeViewSpaceComponents(viewState.m_view);
- directionalLight.computeViewSpaceComponents(viewState.m_view);
-
- // Update time accumulators.
- if (settings.m_updateLights) { timeAccumulatorLight += deltaTime; }
- if (settings.m_updateScene) { timeAccumulatorScene += deltaTime; }
-
- // Setup lights.
- pointLight.m_position.m_x = bx::fcos(timeAccumulatorLight) * 20.0f;
- pointLight.m_position.m_y = 26.0f;
- pointLight.m_position.m_z = bx::fsin(timeAccumulatorLight) * 20.0f;
- pointLight.m_spotDirectionInner.m_x = -pointLight.m_position.m_x;
- pointLight.m_spotDirectionInner.m_y = -pointLight.m_position.m_y;
- pointLight.m_spotDirectionInner.m_z = -pointLight.m_position.m_z;
-
- directionalLight.m_position.m_x = -bx::fcos(timeAccumulatorLight);
- directionalLight.m_position.m_y = -1.0f;
- directionalLight.m_position.m_z = -bx::fsin(timeAccumulatorLight);
-
- // Setup instance matrices.
- float mtxFloor[16];
- const float floorScale = 550.0f;
- bx::mtxSRT(mtxFloor
- , floorScale //scaleX
- , floorScale //scaleY
- , floorScale //scaleZ
- , 0.0f //rotX
- , 0.0f //rotY
- , 0.0f //rotZ
- , 0.0f //translateX
- , 0.0f //translateY
- , 0.0f //translateZ
- );
-
- float mtxBunny[16];
- bx::mtxSRT(mtxBunny
- , 5.0f
- , 5.0f
- , 5.0f
- , 0.0f
- , 1.56f - timeAccumulatorScene
- , 0.0f
- , 15.0f
- , 5.0f
- , 0.0f
- );
+ s_uniforms.submitConstUniforms();
- float mtxHollowcube[16];
- bx::mtxSRT(mtxHollowcube
- , 2.5f
- , 2.5f
- , 2.5f
- , 0.0f
- , 1.56f - timeAccumulatorScene
- , 0.0f
- , 0.0f
- , 10.0f
- , 0.0f
- );
+ // s_uniforms.submitConstUniforms();
- float mtxCube[16];
- bx::mtxSRT(mtxCube
- , 2.5f
- , 2.5f
- , 2.5f
- , 0.0f
- , 1.56f - timeAccumulatorScene
- , 0.0f
- , -15.0f
- , 5.0f
- , 0.0f
- );
+ // Imgui.
+ imguiBeginFrame(m_mouseState.m_mx
+ , m_mouseState.m_my
+ , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
+ | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
+ | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
+ , m_mouseState.m_mz
+ , m_viewState.m_width
+ , m_viewState.m_height
+ );
- const uint8_t numTrees = 10;
- float mtxTrees[numTrees][16];
- for (uint8_t ii = 0; ii < numTrees; ++ii)
- {
- bx::mtxSRT(mtxTrees[ii]
- , 2.0f
- , 2.0f
- , 2.0f
- , 0.0f
- , float(ii)
- , 0.0f
- , bx::fsin(float(ii)*2.0f*bx::pi/float(numTrees) ) * 60.0f
- , 0.0f
- , bx::fcos(float(ii)*2.0f*bx::pi/float(numTrees) ) * 60.0f
+ showExampleDialog(this);
+
+ ImGui::SetNextWindowPos(
+ ImVec2(m_viewState.m_width - m_viewState.m_width / 5.0f - 10.0f, 10.0f)
+ , ImGuiSetCond_FirstUseEver
);
- }
+ ImGui::Begin("Settings"
+ , NULL
+ , ImVec2(m_viewState.m_width / 5.0f, m_viewState.m_height - 20.0f)
+ , ImGuiWindowFlags_AlwaysAutoResize
+ );
+
+#define IMGUI_FLOAT_SLIDER(_name, _val) \
+ ImGui::SliderFloat(_name \
+ , &_val \
+ , *( ((float*)&_val)+1) \
+ , *( ((float*)&_val)+2) \
+ )
+
+#define IMGUI_RADIO_BUTTON(_name, _var, _val) \
+ if (ImGui::RadioButton(_name, _var == _val) ) \
+ { \
+ _var = _val; \
+ }
- // Compute transform matrices.
- const uint8_t shadowMapPasses = ShadowMapRenderTargets::Count;
- float lightView[shadowMapPasses][16];
- float lightProj[shadowMapPasses][16];
- float mtxYpr[TetrahedronFaces::Count][16];
+ ImGui::Checkbox("Update lights", &m_settings.m_updateLights);
+ ImGui::Checkbox("Update scene", &m_settings.m_updateScene);
- float screenProj[16];
- float screenView[16];
- bx::mtxIdentity(screenView);
- bx::mtxOrtho(screenProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);
+ ImGui::Separator();
+ ImGui::Text("Shadow map depth:");
+ IMGUI_RADIO_BUTTON("InvZ", m_settings.m_depthImpl, DepthImpl::InvZ);
+ IMGUI_RADIO_BUTTON("Linear", m_settings.m_depthImpl, DepthImpl::Linear);
- if (LightType::SpotLight == settings.m_lightType)
- {
- const float fovy = settings.m_coverageSpotL;
- const float aspect = 1.0f;
- bx::mtxProj(lightProj[ProjType::Horizontal], fovy, aspect, currentSmSettings->m_near, currentSmSettings->m_far);
+ ShadowMapSettings* currentSmSettings = &m_smSettings[m_settings.m_lightType][m_settings.m_depthImpl][m_settings.m_smImpl];
- //For linear depth, prevent depth division by variable w-component in shaders and divide here by far plane
- if (DepthImpl::Linear == settings.m_depthImpl)
+ ImGui::Separator();
+ ImGui::Checkbox("Draw depth buffer", &m_settings.m_drawDepthBuffer);
+ if (m_settings.m_drawDepthBuffer)
{
- lightProj[ProjType::Horizontal][10] /= currentSmSettings->m_far;
- lightProj[ProjType::Horizontal][14] /= currentSmSettings->m_far;
+ IMGUI_FLOAT_SLIDER("Depth value pow", currentSmSettings->m_depthValuePow);
}
- float at[3];
- bx::vec3Add(at, pointLight.m_position.m_v, pointLight.m_spotDirectionInner.m_v);
- bx::mtxLookAt(lightView[TetrahedronFaces::Green], pointLight.m_position.m_v, at);
- }
- else if (LightType::PointLight == settings.m_lightType)
- {
- float ypr[TetrahedronFaces::Count][3] =
+ ImGui::Separator();
+ ImGui::Text("Shadow Map implementation");
+ IMGUI_RADIO_BUTTON("Hard", m_settings.m_smImpl, SmImpl::Hard);
+ IMGUI_RADIO_BUTTON("PCF", m_settings.m_smImpl, SmImpl::PCF);
+ IMGUI_RADIO_BUTTON("VSM", m_settings.m_smImpl, SmImpl::VSM);
+ IMGUI_RADIO_BUTTON("ESM", m_settings.m_smImpl, SmImpl::ESM);
+ currentSmSettings = &m_smSettings[m_settings.m_lightType][m_settings.m_depthImpl][m_settings.m_smImpl];
+
+ ImGui::Separator();
+ IMGUI_FLOAT_SLIDER("Bias", currentSmSettings->m_bias);
+ IMGUI_FLOAT_SLIDER("Normal offset", currentSmSettings->m_normalOffset);
+ ImGui::Separator();
+ if (LightType::DirectionalLight != m_settings.m_lightType)
{
- { bx::toRad( 0.0f), bx::toRad( 27.36780516f), bx::toRad(0.0f) },
- { bx::toRad(180.0f), bx::toRad( 27.36780516f), bx::toRad(0.0f) },
- { bx::toRad(-90.0f), bx::toRad(-27.36780516f), bx::toRad(0.0f) },
- { bx::toRad( 90.0f), bx::toRad(-27.36780516f), bx::toRad(0.0f) },
- };
-
+ IMGUI_FLOAT_SLIDER("Near plane", currentSmSettings->m_near);
+ }
+ IMGUI_FLOAT_SLIDER("Far plane", currentSmSettings->m_far);
- if (settings.m_stencilPack)
+ ImGui::Separator();
+ switch(m_settings.m_smImpl)
{
- const float fovx = 143.98570868f + 3.51f + settings.m_fovXAdjust;
- const float fovy = 125.26438968f + 9.85f + settings.m_fovYAdjust;
- const float aspect = bx::ftan(bx::toRad(fovx*0.5f) )/bx::ftan(bx::toRad(fovy*0.5f) );
-
- bx::mtxProj(lightProj[ProjType::Vertical]
- , fovx
- , aspect
- , currentSmSettings->m_near
- , currentSmSettings->m_far
- );
-
- //For linear depth, prevent depth division by variable w-component in shaders and divide here by far plane
- if (DepthImpl::Linear == settings.m_depthImpl)
- {
- lightProj[ProjType::Vertical][10] /= currentSmSettings->m_far;
- lightProj[ProjType::Vertical][14] /= currentSmSettings->m_far;
- }
+ case SmImpl::Hard:
+ //ImGui::Text("Hard");
+ break;
+
+ case SmImpl::PCF:
+ ImGui::Text("PCF");
+ IMGUI_FLOAT_SLIDER("X Offset", currentSmSettings->m_xOffset);
+ IMGUI_FLOAT_SLIDER("Y Offset", currentSmSettings->m_yOffset);
+ break;
+
+ case SmImpl::VSM:
+ ImGui::Text("VSM");
+ IMGUI_FLOAT_SLIDER("Min variance", currentSmSettings->m_customParam0);
+ IMGUI_FLOAT_SLIDER("Depth multiplier", currentSmSettings->m_customParam1);
+ ImGui::Checkbox("Blur shadow map", &currentSmSettings->m_doBlur);
+ if (currentSmSettings->m_doBlur)
+ {
+ IMGUI_FLOAT_SLIDER("Blur X Offset", currentSmSettings->m_xOffset);
+ IMGUI_FLOAT_SLIDER("Blur Y Offset", currentSmSettings->m_yOffset);
+ }
+ break;
+
+ case SmImpl::ESM:
+ ImGui::Text("ESM");
+ IMGUI_FLOAT_SLIDER("ESM Hardness", currentSmSettings->m_customParam0);
+ IMGUI_FLOAT_SLIDER("Depth multiplier", currentSmSettings->m_customParam1);
+ ImGui::Checkbox("Blur shadow map", &currentSmSettings->m_doBlur);
+ if (currentSmSettings->m_doBlur)
+ {
+ IMGUI_FLOAT_SLIDER("Blur X Offset", currentSmSettings->m_xOffset);
+ IMGUI_FLOAT_SLIDER("Blur Y Offset", currentSmSettings->m_yOffset);
+ }
+ break;
- ypr[TetrahedronFaces::Green ][2] = bx::toRad(180.0f);
- ypr[TetrahedronFaces::Yellow][2] = bx::toRad( 0.0f);
- ypr[TetrahedronFaces::Blue ][2] = bx::toRad( 90.0f);
- ypr[TetrahedronFaces::Red ][2] = bx::toRad(-90.0f);
- }
+ default:
+ break;
+ };
- const float fovx = 143.98570868f + 7.8f + settings.m_fovXAdjust;
- const float fovy = 125.26438968f + 3.0f + settings.m_fovYAdjust;
- const float aspect = bx::ftan(bx::toRad(fovx*0.5f) )/bx::ftan(bx::toRad(fovy*0.5f) );
+ ImGui::End();
+#undef IMGUI_RADIO_BUTTON
- bx::mtxProj(lightProj[ProjType::Horizontal], fovy, aspect, currentSmSettings->m_near, currentSmSettings->m_far);
+ ImGui::SetNextWindowPos(
+ ImVec2(10.0f, 260.0f)
+ , ImGuiSetCond_FirstUseEver
+ );
+ ImGui::Begin("Light"
+ , NULL
+ , ImVec2(m_viewState.m_width / 5.0f, 350.0f)
+ , ImGuiWindowFlags_AlwaysAutoResize
+ );
+ ImGui::PushItemWidth(185.0f);
- //For linear depth, prevent depth division by variable w component in shaders and divide here by far plane
- if (DepthImpl::Linear == settings.m_depthImpl)
+ bool bLtChanged = false;
+ if ( ImGui::RadioButton("Spot light", m_settings.m_lightType == LightType::SpotLight ))
+ {
+ m_settings.m_lightType = LightType::SpotLight; bLtChanged = true;
+ }
+ if ( ImGui::RadioButton("Point light", m_settings.m_lightType == LightType::PointLight ))
{
- lightProj[ProjType::Horizontal][10] /= currentSmSettings->m_far;
- lightProj[ProjType::Horizontal][14] /= currentSmSettings->m_far;
+ m_settings.m_lightType = LightType::PointLight; bLtChanged = true;
+ }
+ if ( ImGui::RadioButton("Directional light", m_settings.m_lightType == LightType::DirectionalLight ))
+ {
+ m_settings.m_lightType = LightType::DirectionalLight; bLtChanged = true;
}
+ ImGui::Separator();
+ ImGui::Checkbox("Show shadow map coverage.", &m_settings.m_showSmCoverage);
- for (uint8_t ii = 0; ii < TetrahedronFaces::Count; ++ii)
- {
- float mtxTmp[16];
- mtxYawPitchRoll(mtxTmp, ypr[ii][0], ypr[ii][1], ypr[ii][2]);
+ ImGui::Separator();
+ ImGui::Text("Shadow map resolution: %ux%u", m_currentShadowMapSize, m_currentShadowMapSize);
+ ImGui::SliderFloat("##SizePwrTwo", &currentSmSettings->m_sizePwrTwo,
+ currentSmSettings->m_sizePwrTwoMin,
+ currentSmSettings->m_sizePwrTwoMax, "%.0f");
- float tmp[3] =
- {
- -bx::vec3Dot(pointLight.m_position.m_v, &mtxTmp[0]),
- -bx::vec3Dot(pointLight.m_position.m_v, &mtxTmp[4]),
- -bx::vec3Dot(pointLight.m_position.m_v, &mtxTmp[8]),
- };
+ ImGui::Separator();
+ if (LightType::SpotLight == m_settings.m_lightType)
+ {
+ ImGui::Text("Spot light");
+ ImGui::SliderFloat("Shadow map area", &m_settings.m_coverageSpotL, 45.0f, 120.0f);
- bx::mtxTranspose(mtxYpr[ii], mtxTmp);
+ ImGui::Separator();
+ ImGui::SliderFloat("Spot outer cone", &m_settings.m_spotOuterAngle, 0.0f, 91.0f);
+ ImGui::SliderFloat("Spot inner cone", &m_settings.m_spotInnerAngle, 0.0f, 90.0f);
+ }
+ else if (LightType::PointLight == m_settings.m_lightType)
+ {
+ ImGui::Text("Point light");
+ ImGui::Checkbox("Stencil pack", &m_settings.m_stencilPack);
- bx::memCopy(lightView[ii], mtxYpr[ii], 12*sizeof(float) );
- lightView[ii][12] = tmp[0];
- lightView[ii][13] = tmp[1];
- lightView[ii][14] = tmp[2];
- lightView[ii][15] = 1.0f;
+ ImGui::SliderFloat("Fov X adjust", &m_settings.m_fovXAdjust, -20.0f, 20.0f);
+ ImGui::SliderFloat("Fov Y adjust", &m_settings.m_fovYAdjust, -20.0f, 20.0f);
}
- }
- else // LightType::DirectionalLight == settings.m_lightType
- {
- // Setup light view mtx.
- float eye[3] =
+ else if (LightType::DirectionalLight == m_settings.m_lightType)
{
- -directionalLight.m_position.m_x
- , -directionalLight.m_position.m_y
- , -directionalLight.m_position.m_z
- };
- float at[3] = { 0.0f, 0.0f, 0.0f };
- bx::mtxLookAt(lightView[0], eye, at);
+ ImGui::Text("Directional light");
+ ImGui::Checkbox("Stabilize cascades", &m_settings.m_stabilize);
+ ImGui::SliderInt("Cascade splits", &m_settings.m_numSplits, 1, 4);
+ ImGui::SliderFloat("Cascade distribution", &m_settings.m_splitDistribution, 0.0f, 1.0f);
+ }
- // Compute camera inverse view mtx.
- float mtxViewInv[16];
- bx::mtxInverse(mtxViewInv, viewState.m_view);
+#undef IMGUI_FLOAT_SLIDER
- // Compute split distances.
- const uint8_t maxNumSplits = 4;
- BX_CHECK(maxNumSplits >= settings.m_numSplits, "Error! Max num splits.");
+ ImGui::End();
- float splitSlices[maxNumSplits*2];
- splitFrustum(splitSlices, settings.m_numSplits, currentSmSettings->m_near, currentSmSettings->m_far, settings.m_splitDistribution);
+ imguiEndFrame();
// Update uniforms.
- for (uint8_t ii = 0, ff = 1; ii < settings.m_numSplits; ++ii, ff+=2)
+ s_uniforms.m_shadowMapBias = currentSmSettings->m_bias;
+ s_uniforms.m_shadowMapOffset = currentSmSettings->m_normalOffset;
+ s_uniforms.m_shadowMapParam0 = currentSmSettings->m_customParam0;
+ s_uniforms.m_shadowMapParam1 = currentSmSettings->m_customParam1;
+ s_uniforms.m_depthValuePow = currentSmSettings->m_depthValuePow;
+ s_uniforms.m_XNum = currentSmSettings->m_xNum;
+ s_uniforms.m_YNum = currentSmSettings->m_yNum;
+ s_uniforms.m_XOffset = currentSmSettings->m_xOffset;
+ s_uniforms.m_YOffset = currentSmSettings->m_yOffset;
+ s_uniforms.m_showSmCoverage = float(m_settings.m_showSmCoverage);
+ s_uniforms.m_lightPtr = (LightType::DirectionalLight == m_settings.m_lightType) ? &m_directionalLight : &m_pointLight;
+
+ if (LightType::SpotLight == m_settings.m_lightType)
{
- // This lags for 1 frame, but it's not a problem.
- s_uniforms.m_csmFarDistances[ii] = splitSlices[ff];
+ m_pointLight.m_attenuationSpotOuter.m_outer = m_settings.m_spotOuterAngle;
+ m_pointLight.m_spotDirectionInner.m_inner = m_settings.m_spotInnerAngle;
+ }
+ else
+ {
+ m_pointLight.m_attenuationSpotOuter.m_outer = 91.0f; //above 90.0f means point light
}
- float mtxProj[16];
- bx::mtxOrtho(mtxProj, 1.0f, -1.0f, 1.0f, -1.0f, -currentSmSettings->m_far, currentSmSettings->m_far);
-
- const uint8_t numCorners = 8;
- float frustumCorners[maxNumSplits][numCorners][3];
- for (uint8_t ii = 0, nn = 0, ff = 1; ii < settings.m_numSplits; ++ii, nn+=2, ff+=2)
+ s_uniforms.submitPerFrameUniforms();
+
+ // Time.
+ int64_t now = bx::getHPCounter();
+ static int64_t last = now;
+ const int64_t frameTime = now - last;
+ last = now;
+ const double freq = double(bx::getHPFrequency() );
+ const float deltaTime = float(frameTime/freq);
+
+ // Update camera.
+ cameraUpdate(deltaTime, m_mouseState);
+
+ // Update view mtx.
+ cameraGetViewMtx(m_viewState.m_view);
+
+ // Update lights.
+ m_pointLight.computeViewSpaceComponents(m_viewState.m_view);
+ m_directionalLight.computeViewSpaceComponents(m_viewState.m_view);
+
+ // Update time accumulators.
+ if (m_settings.m_updateLights) { m_timeAccumulatorLight += deltaTime; }
+ if (m_settings.m_updateScene) { m_timeAccumulatorScene += deltaTime; }
+
+ // Setup lights.
+ m_pointLight.m_position.m_x = bx::fcos(m_timeAccumulatorLight) * 20.0f;
+ m_pointLight.m_position.m_y = 26.0f;
+ m_pointLight.m_position.m_z = bx::fsin(m_timeAccumulatorLight) * 20.0f;
+ m_pointLight.m_spotDirectionInner.m_x = -m_pointLight.m_position.m_x;
+ m_pointLight.m_spotDirectionInner.m_y = -m_pointLight.m_position.m_y;
+ m_pointLight.m_spotDirectionInner.m_z = -m_pointLight.m_position.m_z;
+
+ m_directionalLight.m_position.m_x = -bx::fcos(m_timeAccumulatorLight);
+ m_directionalLight.m_position.m_y = -1.0f;
+ m_directionalLight.m_position.m_z = -bx::fsin(m_timeAccumulatorLight);
+
+ // Setup instance matrices.
+ float mtxFloor[16];
+ const float floorScale = 550.0f;
+ bx::mtxSRT(mtxFloor
+ , floorScale //scaleX
+ , floorScale //scaleY
+ , floorScale //scaleZ
+ , 0.0f //rotX
+ , 0.0f //rotY
+ , 0.0f //rotZ
+ , 0.0f //translateX
+ , 0.0f //translateY
+ , 0.0f //translateZ
+ );
+
+ float mtxBunny[16];
+ bx::mtxSRT(mtxBunny
+ , 5.0f
+ , 5.0f
+ , 5.0f
+ , 0.0f
+ , 1.56f - m_timeAccumulatorScene
+ , 0.0f
+ , 15.0f
+ , 5.0f
+ , 0.0f
+ );
+
+ float mtxHollowcube[16];
+ bx::mtxSRT(mtxHollowcube
+ , 2.5f
+ , 2.5f
+ , 2.5f
+ , 0.0f
+ , 1.56f - m_timeAccumulatorScene
+ , 0.0f
+ , 0.0f
+ , 10.0f
+ , 0.0f
+ );
+
+ float mtxCube[16];
+ bx::mtxSRT(mtxCube
+ , 2.5f
+ , 2.5f
+ , 2.5f
+ , 0.0f
+ , 1.56f - m_timeAccumulatorScene
+ , 0.0f
+ , -15.0f
+ , 5.0f
+ , 0.0f
+ );
+
+ const uint8_t numTrees = 10;
+ float mtxTrees[numTrees][16];
+ for (uint8_t ii = 0; ii < numTrees; ++ii)
{
- // Compute frustum corners for one split in world space.
- worldSpaceFrustumCorners( (float*)frustumCorners[ii], splitSlices[nn], splitSlices[ff], projWidth, projHeight, mtxViewInv);
+ bx::mtxSRT(mtxTrees[ii]
+ , 2.0f
+ , 2.0f
+ , 2.0f
+ , 0.0f
+ , float(ii)
+ , 0.0f
+ , bx::fsin(float(ii)*2.0f*bx::kPi/float(numTrees) ) * 60.0f
+ , 0.0f
+ , bx::fcos(float(ii)*2.0f*bx::kPi/float(numTrees) ) * 60.0f
+ );
+ }
- float min[3] = { 9000.0f, 9000.0f, 9000.0f };
- float max[3] = { -9000.0f, -9000.0f, -9000.0f };
+ // Compute transform matrices.
+ const uint8_t shadowMapPasses = ShadowMapRenderTargets::Count;
+ float lightView[shadowMapPasses][16];
+ float lightProj[shadowMapPasses][16];
+ float mtxYpr[TetrahedronFaces::Count][16];
+
+ float screenProj[16];
+ float screenView[16];
+ bx::mtxIdentity(screenView);
+
+ bx::mtxOrtho(
+ screenProj
+ , 0.0f
+ , 1.0f
+ , 1.0f
+ , 0.0f
+ , 0.0f
+ , 100.0f
+ , 0.0f
+ , caps->homogeneousDepth
+ );
+
+ if (LightType::SpotLight == m_settings.m_lightType)
+ {
+ const float fovy = m_settings.m_coverageSpotL;
+ const float aspect = 1.0f;
+ bx::mtxProj(
+ lightProj[ProjType::Horizontal]
+ , fovy
+ , aspect
+ , currentSmSettings->m_near
+ , currentSmSettings->m_far
+ , false
+ );
- for (uint8_t jj = 0; jj < numCorners; ++jj)
+ //For linear depth, prevent depth division by variable w-component in shaders and divide here by far plane
+ if (DepthImpl::Linear == m_settings.m_depthImpl)
{
- // Transform to light space.
- float lightSpaceFrustumCorner[3];
- bx::vec3MulMtx(lightSpaceFrustumCorner, frustumCorners[ii][jj], lightView[0]);
-
- // Update bounding box.
- min[0] = bx::fmin(min[0], lightSpaceFrustumCorner[0]);
- max[0] = bx::fmax(max[0], lightSpaceFrustumCorner[0]);
- min[1] = bx::fmin(min[1], lightSpaceFrustumCorner[1]);
- max[1] = bx::fmax(max[1], lightSpaceFrustumCorner[1]);
- min[2] = bx::fmin(min[2], lightSpaceFrustumCorner[2]);
- max[2] = bx::fmax(max[2], lightSpaceFrustumCorner[2]);
+ lightProj[ProjType::Horizontal][10] /= currentSmSettings->m_far;
+ lightProj[ProjType::Horizontal][14] /= currentSmSettings->m_far;
}
- float minproj[3];
- float maxproj[3];
- bx::vec3MulMtxH(minproj, min, mtxProj);
- bx::vec3MulMtxH(maxproj, max, mtxProj);
-
- float offsetx, offsety;
- float scalex, scaley;
+ float at[3];
+ bx::vec3Add(at, m_pointLight.m_position.m_v, m_pointLight.m_spotDirectionInner.m_v);
+ bx::mtxLookAt(lightView[TetrahedronFaces::Green], m_pointLight.m_position.m_v, at);
+ }
+ else if (LightType::PointLight == m_settings.m_lightType)
+ {
+ float ypr[TetrahedronFaces::Count][3] =
+ {
+ { bx::toRad( 0.0f), bx::toRad( 27.36780516f), bx::toRad(0.0f) },
+ { bx::toRad(180.0f), bx::toRad( 27.36780516f), bx::toRad(0.0f) },
+ { bx::toRad(-90.0f), bx::toRad(-27.36780516f), bx::toRad(0.0f) },
+ { bx::toRad( 90.0f), bx::toRad(-27.36780516f), bx::toRad(0.0f) },
+ };
- scalex = 2.0f / (maxproj[0] - minproj[0]);
- scaley = 2.0f / (maxproj[1] - minproj[1]);
- if (settings.m_stabilize)
+ if (m_settings.m_stencilPack)
{
- const float quantizer = 64.0f;
- scalex = quantizer / bx::fceil(quantizer / scalex);
- scaley = quantizer / bx::fceil(quantizer / scaley);
+ const float fovx = 143.98570868f + 3.51f + m_settings.m_fovXAdjust;
+ const float fovy = 125.26438968f + 9.85f + m_settings.m_fovYAdjust;
+ const float aspect = bx::ftan(bx::toRad(fovx*0.5f) )/bx::ftan(bx::toRad(fovy*0.5f) );
+
+ bx::mtxProj(
+ lightProj[ProjType::Vertical]
+ , fovx
+ , aspect
+ , currentSmSettings->m_near
+ , currentSmSettings->m_far
+ , false
+ );
+
+ //For linear depth, prevent depth division by variable w-component in shaders and divide here by far plane
+ if (DepthImpl::Linear == m_settings.m_depthImpl)
+ {
+ lightProj[ProjType::Vertical][10] /= currentSmSettings->m_far;
+ lightProj[ProjType::Vertical][14] /= currentSmSettings->m_far;
+ }
+
+ ypr[TetrahedronFaces::Green ][2] = bx::toRad(180.0f);
+ ypr[TetrahedronFaces::Yellow][2] = bx::toRad( 0.0f);
+ ypr[TetrahedronFaces::Blue ][2] = bx::toRad( 90.0f);
+ ypr[TetrahedronFaces::Red ][2] = bx::toRad(-90.0f);
}
- offsetx = 0.5f * (maxproj[0] + minproj[0]) * scalex;
- offsety = 0.5f * (maxproj[1] + minproj[1]) * scaley;
+ const float fovx = 143.98570868f + 7.8f + m_settings.m_fovXAdjust;
+ const float fovy = 125.26438968f + 3.0f + m_settings.m_fovYAdjust;
+ const float aspect = bx::ftan(bx::toRad(fovx*0.5f) )/bx::ftan(bx::toRad(fovy*0.5f) );
- if (settings.m_stabilize)
+ bx::mtxProj(
+ lightProj[ProjType::Horizontal]
+ , fovy
+ , aspect
+ , currentSmSettings->m_near
+ , currentSmSettings->m_far
+ , caps->homogeneousDepth
+ );
+
+ //For linear depth, prevent depth division by variable w component in shaders and divide here by far plane
+ if (DepthImpl::Linear == m_settings.m_depthImpl)
{
- const float halfSize = currentShadowMapSizef * 0.5f;
- offsetx = bx::fceil(offsetx * halfSize) / halfSize;
- offsety = bx::fceil(offsety * halfSize) / halfSize;
+ lightProj[ProjType::Horizontal][10] /= currentSmSettings->m_far;
+ lightProj[ProjType::Horizontal][14] /= currentSmSettings->m_far;
}
- float mtxCrop[16];
- bx::mtxIdentity(mtxCrop);
- mtxCrop[ 0] = scalex;
- mtxCrop[ 5] = scaley;
- mtxCrop[12] = offsetx;
- mtxCrop[13] = offsety;
-
- bx::mtxMul(lightProj[ii], mtxCrop, mtxProj);
- }
- }
- // Reset render targets.
- const bgfx::FrameBufferHandle invalidRt = BGFX_INVALID_HANDLE;
- for (uint8_t ii = 0; ii < RENDERVIEW_DRAWDEPTH_3_ID+1; ++ii)
- {
- bgfx::setViewFrameBuffer(ii, invalidRt);
- }
+ for (uint8_t ii = 0; ii < TetrahedronFaces::Count; ++ii)
+ {
+ float mtxTmp[16];
+ mtxYawPitchRoll(mtxTmp, ypr[ii][0], ypr[ii][1], ypr[ii][2]);
- // Determine on-screen rectangle size where depth buffer will be drawn.
- uint16_t depthRectHeight = uint16_t(float(viewState.m_height) / 2.5f);
- uint16_t depthRectWidth = depthRectHeight;
- uint16_t depthRectX = 0;
- uint16_t depthRectY = viewState.m_height - depthRectHeight;
+ float tmp[3] =
+ {
+ -bx::vec3Dot(m_pointLight.m_position.m_v, &mtxTmp[0]),
+ -bx::vec3Dot(m_pointLight.m_position.m_v, &mtxTmp[4]),
+ -bx::vec3Dot(m_pointLight.m_position.m_v, &mtxTmp[8]),
+ };
- // Setup views and render targets.
- bgfx::setViewRect(0, 0, 0, viewState.m_width, viewState.m_height);
- bgfx::setViewTransform(0, viewState.m_view, viewState.m_proj);
+ bx::mtxTranspose(mtxYpr[ii], mtxTmp);
- if (LightType::SpotLight == settings.m_lightType)
- {
- /**
- * RENDERVIEW_SHADOWMAP_0_ID - Clear shadow map. (used as convenience, otherwise render_pass_1 could be cleared)
- * RENDERVIEW_SHADOWMAP_1_ID - Craft shadow map.
- * RENDERVIEW_VBLUR_0_ID - Vertical blur.
- * RENDERVIEW_HBLUR_0_ID - Horizontal blur.
- * RENDERVIEW_DRAWSCENE_0_ID - Draw scene.
- * RENDERVIEW_DRAWSCENE_1_ID - Draw floor bottom.
- * RENDERVIEW_DRAWDEPTH_0_ID - Draw depth buffer.
- */
-
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_VBLUR_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_HBLUR_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_DRAWSCENE_0_ID, 0, 0, viewState.m_width, viewState.m_height);
- bgfx::setViewRect(RENDERVIEW_DRAWSCENE_1_ID, 0, 0, viewState.m_width, viewState.m_height);
- bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_0_ID, depthRectX, depthRectY, depthRectWidth, depthRectHeight);
-
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_1_ID, lightView[0], lightProj[ProjType::Horizontal]);
- bgfx::setViewTransform(RENDERVIEW_VBLUR_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_HBLUR_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_0_ID, viewState.m_view, viewState.m_proj);
- bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_1_ID, viewState.m_view, viewState.m_proj);
- bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_0_ID, screenView, screenProj);
-
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_0_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_1_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_0_ID, s_rtBlur);
- bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_0_ID, s_rtShadowMap[0]);
- }
- else if (LightType::PointLight == settings.m_lightType)
- {
- /**
- * RENDERVIEW_SHADOWMAP_0_ID - Clear entire shadow map.
- * RENDERVIEW_SHADOWMAP_1_ID - Craft green tetrahedron shadow face.
- * RENDERVIEW_SHADOWMAP_2_ID - Craft yellow tetrahedron shadow face.
- * RENDERVIEW_SHADOWMAP_3_ID - Craft blue tetrahedron shadow face.
- * RENDERVIEW_SHADOWMAP_4_ID - Craft red tetrahedron shadow face.
- * RENDERVIEW_VBLUR_0_ID - Vertical blur.
- * RENDERVIEW_HBLUR_0_ID - Horizontal blur.
- * RENDERVIEW_DRAWSCENE_0_ID - Draw scene.
- * RENDERVIEW_DRAWSCENE_1_ID - Draw floor bottom.
- * RENDERVIEW_DRAWDEPTH_0_ID - Draw depth buffer.
- */
-
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- if (settings.m_stencilPack)
- {
- const uint16_t f = currentShadowMapSize; //full size
- const uint16_t h = currentShadowMapSize/2; //half size
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, f, h);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_2_ID, 0, h, f, h);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_3_ID, 0, 0, h, f);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_4_ID, h, 0, h, f);
- }
- else
- {
- const uint16_t h = currentShadowMapSize/2; //half size
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, h, h);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_2_ID, h, 0, h, h);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_3_ID, 0, h, h, h);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_4_ID, h, h, h, h);
- }
- bgfx::setViewRect(RENDERVIEW_VBLUR_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_HBLUR_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_DRAWSCENE_0_ID, 0, 0, viewState.m_width, viewState.m_height);
- bgfx::setViewRect(RENDERVIEW_DRAWSCENE_1_ID, 0, 0, viewState.m_width, viewState.m_height);
- bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_0_ID, depthRectX, depthRectY, depthRectWidth, depthRectHeight);
-
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_1_ID, lightView[TetrahedronFaces::Green], lightProj[ProjType::Horizontal]);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_2_ID, lightView[TetrahedronFaces::Yellow], lightProj[ProjType::Horizontal]);
- if(settings.m_stencilPack)
- {
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_3_ID, lightView[TetrahedronFaces::Blue], lightProj[ProjType::Vertical]);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_4_ID, lightView[TetrahedronFaces::Red], lightProj[ProjType::Vertical]);
+ bx::memCopy(lightView[ii], mtxYpr[ii], 12*sizeof(float) );
+ lightView[ii][12] = tmp[0];
+ lightView[ii][13] = tmp[1];
+ lightView[ii][14] = tmp[2];
+ lightView[ii][15] = 1.0f;
+ }
}
- else
+ else // LightType::DirectionalLight == settings.m_lightType
{
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_3_ID, lightView[TetrahedronFaces::Blue], lightProj[ProjType::Horizontal]);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_4_ID, lightView[TetrahedronFaces::Red], lightProj[ProjType::Horizontal]);
- }
- bgfx::setViewTransform(RENDERVIEW_VBLUR_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_HBLUR_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_0_ID, viewState.m_view, viewState.m_proj);
- bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_1_ID, viewState.m_view, viewState.m_proj);
- bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_0_ID, screenView, screenProj);
-
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_0_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_1_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_2_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_3_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_4_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_0_ID, s_rtBlur);
- bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_0_ID, s_rtShadowMap[0]);
- }
- else // LightType::DirectionalLight == settings.m_lightType
- {
- /**
- * RENDERVIEW_SHADOWMAP_1_ID - Craft shadow map for first split.
- * RENDERVIEW_SHADOWMAP_2_ID - Craft shadow map for second split.
- * RENDERVIEW_SHADOWMAP_3_ID - Craft shadow map for third split.
- * RENDERVIEW_SHADOWMAP_4_ID - Craft shadow map for fourth split.
- * RENDERVIEW_VBLUR_0_ID - Vertical blur for first split.
- * RENDERVIEW_HBLUR_0_ID - Horizontal blur for first split.
- * RENDERVIEW_VBLUR_1_ID - Vertical blur for second split.
- * RENDERVIEW_HBLUR_1_ID - Horizontal blur for second split.
- * RENDERVIEW_VBLUR_2_ID - Vertical blur for third split.
- * RENDERVIEW_HBLUR_2_ID - Horizontal blur for third split.
- * RENDERVIEW_VBLUR_3_ID - Vertical blur for fourth split.
- * RENDERVIEW_HBLUR_3_ID - Horizontal blur for fourth split.
- * RENDERVIEW_DRAWSCENE_0_ID - Draw scene.
- * RENDERVIEW_DRAWSCENE_1_ID - Draw floor bottom.
- * RENDERVIEW_DRAWDEPTH_0_ID - Draw depth buffer for first split.
- * RENDERVIEW_DRAWDEPTH_1_ID - Draw depth buffer for second split.
- * RENDERVIEW_DRAWDEPTH_2_ID - Draw depth buffer for third split.
- * RENDERVIEW_DRAWDEPTH_3_ID - Draw depth buffer for fourth split.
- */
-
- depthRectHeight = viewState.m_height / 3;
- depthRectWidth = depthRectHeight;
- depthRectX = 0;
- depthRectY = viewState.m_height - depthRectHeight;
-
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_2_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_3_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_SHADOWMAP_4_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_VBLUR_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_HBLUR_0_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_VBLUR_1_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_HBLUR_1_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_VBLUR_2_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_HBLUR_2_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_VBLUR_3_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_HBLUR_3_ID, 0, 0, currentShadowMapSize, currentShadowMapSize);
- bgfx::setViewRect(RENDERVIEW_DRAWSCENE_0_ID, 0, 0, viewState.m_width, viewState.m_height);
- bgfx::setViewRect(RENDERVIEW_DRAWSCENE_1_ID, 0, 0, viewState.m_width, viewState.m_height);
- bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_0_ID, depthRectX+(0*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
- bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_1_ID, depthRectX+(1*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
- bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_2_ID, depthRectX+(2*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
- bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_3_ID, depthRectX+(3*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
-
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_1_ID, lightView[0], lightProj[0]);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_2_ID, lightView[0], lightProj[1]);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_3_ID, lightView[0], lightProj[2]);
- bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_4_ID, lightView[0], lightProj[3]);
- bgfx::setViewTransform(RENDERVIEW_VBLUR_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_HBLUR_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_VBLUR_1_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_HBLUR_1_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_VBLUR_2_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_HBLUR_2_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_VBLUR_3_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_HBLUR_3_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_0_ID, viewState.m_view, viewState.m_proj);
- bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_1_ID, viewState.m_view, viewState.m_proj);
- bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_0_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_1_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_2_ID, screenView, screenProj);
- bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_3_ID, screenView, screenProj);
-
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_1_ID, s_rtShadowMap[0]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_2_ID, s_rtShadowMap[1]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_3_ID, s_rtShadowMap[2]);
- bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_4_ID, s_rtShadowMap[3]);
- bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_0_ID, s_rtBlur); //vblur
- bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_0_ID, s_rtShadowMap[0]); //hblur
- bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_1_ID, s_rtBlur); //vblur
- bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_1_ID, s_rtShadowMap[1]); //hblur
- bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_2_ID, s_rtBlur); //vblur
- bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_2_ID, s_rtShadowMap[2]); //hblur
- bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_3_ID, s_rtBlur); //vblur
- bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_3_ID, s_rtShadowMap[3]); //hblur
- }
+ // Setup light view mtx.
+ float eye[3] =
+ {
+ -m_directionalLight.m_position.m_x
+ , -m_directionalLight.m_position.m_y
+ , -m_directionalLight.m_position.m_z
+ };
+ float at[3] = { 0.0f, 0.0f, 0.0f };
+ bx::mtxLookAt(lightView[0], eye, at);
+
+ // Compute camera inverse view mtx.
+ float mtxViewInv[16];
+ bx::mtxInverse(mtxViewInv, m_viewState.m_view);
+
+ // Compute split distances.
+ const uint8_t maxNumSplits = 4;
+ BX_CHECK(maxNumSplits >= settings.m_numSplits, "Error! Max num splits.");
+
+ float splitSlices[maxNumSplits*2];
+ splitFrustum(splitSlices
+ , uint8_t(m_settings.m_numSplits)
+ , currentSmSettings->m_near
+ , currentSmSettings->m_far
+ , m_settings.m_splitDistribution
+ );
- // Clear backbuffer at beginning.
- bgfx::setViewClear(0
- , BGFX_CLEAR_COLOR
- | BGFX_CLEAR_DEPTH
- , clearValues.m_clearRgba
- , clearValues.m_clearDepth
- , clearValues.m_clearStencil
- );
- bgfx::touch(0);
-
- // Clear shadowmap rendertarget at beginning.
- const uint8_t flags0 = (LightType::DirectionalLight == settings.m_lightType)
- ? 0
- : BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL
- ;
-
- bgfx::setViewClear(RENDERVIEW_SHADOWMAP_0_ID
- , flags0
- , 0xfefefefe //blur fails on completely white regions
- , clearValues.m_clearDepth
- , clearValues.m_clearStencil
- );
- bgfx::touch(RENDERVIEW_SHADOWMAP_0_ID);
+ // Update uniforms.
+ for (uint8_t ii = 0, ff = 1; ii < m_settings.m_numSplits; ++ii, ff+=2)
+ {
+ // This lags for 1 frame, but it's not a problem.
+ s_uniforms.m_csmFarDistances[ii] = splitSlices[ff];
+ }
- const uint8_t flags1 = (LightType::DirectionalLight == settings.m_lightType)
- ? BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
- : 0
- ;
+ float mtxProj[16];
+ bx::mtxOrtho(
+ mtxProj
+ , 1.0f
+ , -1.0f
+ , 1.0f
+ , -1.0f
+ , -currentSmSettings->m_far
+ , currentSmSettings->m_far
+ , 0.0f
+ , caps->homogeneousDepth
+ );
+
+ const uint8_t numCorners = 8;
+ float frustumCorners[maxNumSplits][numCorners][3];
+ for (uint8_t ii = 0, nn = 0, ff = 1; ii < m_settings.m_numSplits; ++ii, nn+=2, ff+=2)
+ {
+ // Compute frustum corners for one split in world space.
+ worldSpaceFrustumCorners( (float*)frustumCorners[ii], splitSlices[nn], splitSlices[ff], projWidth, projHeight, mtxViewInv);
- for (uint8_t ii = 0; ii < 4; ++ii)
- {
- bgfx::setViewClear(RENDERVIEW_SHADOWMAP_1_ID+ii
- , flags1
- , 0xfefefefe //blur fails on completely white regions
- , clearValues.m_clearDepth
- , clearValues.m_clearStencil
- );
- bgfx::touch(RENDERVIEW_SHADOWMAP_1_ID+ii);
- }
+ float min[3] = { 9000.0f, 9000.0f, 9000.0f };
+ float max[3] = { -9000.0f, -9000.0f, -9000.0f };
+
+ for (uint8_t jj = 0; jj < numCorners; ++jj)
+ {
+ // Transform to light space.
+ float lightSpaceFrustumCorner[3];
+ bx::vec3MulMtx(lightSpaceFrustumCorner, frustumCorners[ii][jj], lightView[0]);
+
+ // Update bounding box.
+ min[0] = bx::fmin(min[0], lightSpaceFrustumCorner[0]);
+ max[0] = bx::fmax(max[0], lightSpaceFrustumCorner[0]);
+ min[1] = bx::fmin(min[1], lightSpaceFrustumCorner[1]);
+ max[1] = bx::fmax(max[1], lightSpaceFrustumCorner[1]);
+ min[2] = bx::fmin(min[2], lightSpaceFrustumCorner[2]);
+ max[2] = bx::fmax(max[2], lightSpaceFrustumCorner[2]);
+ }
- // Render.
+ float minproj[3];
+ float maxproj[3];
+ bx::vec3MulMtxH(minproj, min, mtxProj);
+ bx::vec3MulMtxH(maxproj, max, mtxProj);
- // Craft shadow map.
- {
- // Craft stencil mask for point light shadow map packing.
- if(LightType::PointLight == settings.m_lightType && settings.m_stencilPack)
- {
- if (6 == bgfx::getAvailTransientVertexBuffer(6, posDecl) )
- {
- struct Pos
+ float offsetx, offsety;
+ float scalex, scaley;
+
+ scalex = 2.0f / (maxproj[0] - minproj[0]);
+ scaley = 2.0f / (maxproj[1] - minproj[1]);
+
+ if (m_settings.m_stabilize)
{
- float m_x, m_y, m_z;
- };
+ const float quantizer = 64.0f;
+ scalex = quantizer / bx::fceil(quantizer / scalex);
+ scaley = quantizer / bx::fceil(quantizer / scaley);
+ }
- bgfx::TransientVertexBuffer vb;
- bgfx::allocTransientVertexBuffer(&vb, 6, posDecl);
- Pos* vertex = (Pos*)vb.data;
-
- const float min = 0.0f;
- const float max = 1.0f;
- const float center = 0.5f;
- const float zz = 0.0f;
-
- vertex[0].m_x = min;
- vertex[0].m_y = min;
- vertex[0].m_z = zz;
-
- vertex[1].m_x = max;
- vertex[1].m_y = min;
- vertex[1].m_z = zz;
-
- vertex[2].m_x = center;
- vertex[2].m_y = center;
- vertex[2].m_z = zz;
-
- vertex[3].m_x = center;
- vertex[3].m_y = center;
- vertex[3].m_z = zz;
-
- vertex[4].m_x = max;
- vertex[4].m_y = max;
- vertex[4].m_z = zz;
-
- vertex[5].m_x = min;
- vertex[5].m_y = max;
- vertex[5].m_z = zz;
-
- bgfx::setState(0);
- bgfx::setStencil(BGFX_STENCIL_TEST_ALWAYS
- | BGFX_STENCIL_FUNC_REF(1)
- | BGFX_STENCIL_FUNC_RMASK(0xff)
- | BGFX_STENCIL_OP_FAIL_S_REPLACE
- | BGFX_STENCIL_OP_FAIL_Z_REPLACE
- | BGFX_STENCIL_OP_PASS_Z_REPLACE
- );
- bgfx::setVertexBuffer(&vb);
- bgfx::submit(RENDERVIEW_SHADOWMAP_0_ID, s_programs.m_black);
+ offsetx = 0.5f * (maxproj[0] + minproj[0]) * scalex;
+ offsety = 0.5f * (maxproj[1] + minproj[1]) * scaley;
+
+ if (m_settings.m_stabilize)
+ {
+ const float halfSize = currentShadowMapSizef * 0.5f;
+ offsetx = bx::fceil(offsetx * halfSize) / halfSize;
+ offsety = bx::fceil(offsety * halfSize) / halfSize;
+ }
+
+ float mtxCrop[16];
+ bx::mtxIdentity(mtxCrop);
+ mtxCrop[ 0] = scalex;
+ mtxCrop[ 5] = scaley;
+ mtxCrop[12] = offsetx;
+ mtxCrop[13] = offsety;
+
+ bx::mtxMul(lightProj[ii], mtxCrop, mtxProj);
}
}
- // Draw scene into shadowmap.
- uint8_t drawNum;
- if (LightType::SpotLight == settings.m_lightType)
+ // Reset render targets.
+ const bgfx::FrameBufferHandle invalidRt = BGFX_INVALID_HANDLE;
+ for (uint8_t ii = 0; ii < RENDERVIEW_DRAWDEPTH_3_ID+1; ++ii)
{
- drawNum = 1;
+ bgfx::setViewFrameBuffer(ii, invalidRt);
}
- else if (LightType::PointLight == settings.m_lightType)
+
+ // Determine on-screen rectangle size where depth buffer will be drawn.
+ uint16_t depthRectHeight = uint16_t(float(m_viewState.m_height) / 2.5f);
+ uint16_t depthRectWidth = depthRectHeight;
+ uint16_t depthRectX = 0;
+ uint16_t depthRectY = m_viewState.m_height - depthRectHeight;
+
+ // Setup views and render targets.
+ bgfx::setViewRect(0, 0, 0, m_viewState.m_width, m_viewState.m_height);
+ bgfx::setViewTransform(0, m_viewState.m_view, m_viewState.m_proj);
+
+ if (LightType::SpotLight == m_settings.m_lightType)
{
- drawNum = 4;
+ /**
+ * RENDERVIEW_SHADOWMAP_0_ID - Clear shadow map. (used as convenience, otherwise render_pass_1 could be cleared)
+ * RENDERVIEW_SHADOWMAP_1_ID - Craft shadow map.
+ * RENDERVIEW_VBLUR_0_ID - Vertical blur.
+ * RENDERVIEW_HBLUR_0_ID - Horizontal blur.
+ * RENDERVIEW_DRAWSCENE_0_ID - Draw scene.
+ * RENDERVIEW_DRAWSCENE_1_ID - Draw floor bottom.
+ * RENDERVIEW_DRAWDEPTH_0_ID - Draw depth buffer.
+ */
+
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_VBLUR_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_HBLUR_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_DRAWSCENE_0_ID, 0, 0, m_viewState.m_width, m_viewState.m_height);
+ bgfx::setViewRect(RENDERVIEW_DRAWSCENE_1_ID, 0, 0, m_viewState.m_width, m_viewState.m_height);
+ bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_0_ID, depthRectX, depthRectY, depthRectWidth, depthRectHeight);
+
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_1_ID, lightView[0], lightProj[ProjType::Horizontal]);
+ bgfx::setViewTransform(RENDERVIEW_VBLUR_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_HBLUR_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_0_ID, m_viewState.m_view, m_viewState.m_proj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_1_ID, m_viewState.m_view, m_viewState.m_proj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_0_ID, screenView, screenProj);
+
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_0_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_1_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_0_ID, s_rtBlur);
+ bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_0_ID, s_rtShadowMap[0]);
+ }
+ else if (LightType::PointLight == m_settings.m_lightType)
+ {
+ /**
+ * RENDERVIEW_SHADOWMAP_0_ID - Clear entire shadow map.
+ * RENDERVIEW_SHADOWMAP_1_ID - Craft green tetrahedron shadow face.
+ * RENDERVIEW_SHADOWMAP_2_ID - Craft yellow tetrahedron shadow face.
+ * RENDERVIEW_SHADOWMAP_3_ID - Craft blue tetrahedron shadow face.
+ * RENDERVIEW_SHADOWMAP_4_ID - Craft red tetrahedron shadow face.
+ * RENDERVIEW_VBLUR_0_ID - Vertical blur.
+ * RENDERVIEW_HBLUR_0_ID - Horizontal blur.
+ * RENDERVIEW_DRAWSCENE_0_ID - Draw scene.
+ * RENDERVIEW_DRAWSCENE_1_ID - Draw floor bottom.
+ * RENDERVIEW_DRAWDEPTH_0_ID - Draw depth buffer.
+ */
+
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ if (m_settings.m_stencilPack)
+ {
+ const uint16_t f = m_currentShadowMapSize; //full size
+ const uint16_t h = m_currentShadowMapSize/2; //half size
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, f, h);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_2_ID, 0, h, f, h);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_3_ID, 0, 0, h, f);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_4_ID, h, 0, h, f);
+ }
+ else
+ {
+ const uint16_t h = m_currentShadowMapSize/2; //half size
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, h, h);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_2_ID, h, 0, h, h);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_3_ID, 0, h, h, h);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_4_ID, h, h, h, h);
+ }
+ bgfx::setViewRect(RENDERVIEW_VBLUR_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_HBLUR_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_DRAWSCENE_0_ID, 0, 0, m_viewState.m_width, m_viewState.m_height);
+ bgfx::setViewRect(RENDERVIEW_DRAWSCENE_1_ID, 0, 0, m_viewState.m_width, m_viewState.m_height);
+ bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_0_ID, depthRectX, depthRectY, depthRectWidth, depthRectHeight);
+
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_1_ID, lightView[TetrahedronFaces::Green], lightProj[ProjType::Horizontal]);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_2_ID, lightView[TetrahedronFaces::Yellow], lightProj[ProjType::Horizontal]);
+ if(m_settings.m_stencilPack)
+ {
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_3_ID, lightView[TetrahedronFaces::Blue], lightProj[ProjType::Vertical]);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_4_ID, lightView[TetrahedronFaces::Red], lightProj[ProjType::Vertical]);
+ }
+ else
+ {
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_3_ID, lightView[TetrahedronFaces::Blue], lightProj[ProjType::Horizontal]);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_4_ID, lightView[TetrahedronFaces::Red], lightProj[ProjType::Horizontal]);
+ }
+ bgfx::setViewTransform(RENDERVIEW_VBLUR_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_HBLUR_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_0_ID, m_viewState.m_view, m_viewState.m_proj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_1_ID, m_viewState.m_view, m_viewState.m_proj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_0_ID, screenView, screenProj);
+
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_0_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_1_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_2_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_3_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_4_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_0_ID, s_rtBlur);
+ bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_0_ID, s_rtShadowMap[0]);
}
- else //LightType::DirectionalLight == settings.m_lightType)
+ else // LightType::DirectionalLight == settings.m_lightType
{
- drawNum = settings.m_numSplits;
+ /**
+ * RENDERVIEW_SHADOWMAP_1_ID - Craft shadow map for first split.
+ * RENDERVIEW_SHADOWMAP_2_ID - Craft shadow map for second split.
+ * RENDERVIEW_SHADOWMAP_3_ID - Craft shadow map for third split.
+ * RENDERVIEW_SHADOWMAP_4_ID - Craft shadow map for fourth split.
+ * RENDERVIEW_VBLUR_0_ID - Vertical blur for first split.
+ * RENDERVIEW_HBLUR_0_ID - Horizontal blur for first split.
+ * RENDERVIEW_VBLUR_1_ID - Vertical blur for second split.
+ * RENDERVIEW_HBLUR_1_ID - Horizontal blur for second split.
+ * RENDERVIEW_VBLUR_2_ID - Vertical blur for third split.
+ * RENDERVIEW_HBLUR_2_ID - Horizontal blur for third split.
+ * RENDERVIEW_VBLUR_3_ID - Vertical blur for fourth split.
+ * RENDERVIEW_HBLUR_3_ID - Horizontal blur for fourth split.
+ * RENDERVIEW_DRAWSCENE_0_ID - Draw scene.
+ * RENDERVIEW_DRAWSCENE_1_ID - Draw floor bottom.
+ * RENDERVIEW_DRAWDEPTH_0_ID - Draw depth buffer for first split.
+ * RENDERVIEW_DRAWDEPTH_1_ID - Draw depth buffer for second split.
+ * RENDERVIEW_DRAWDEPTH_2_ID - Draw depth buffer for third split.
+ * RENDERVIEW_DRAWDEPTH_3_ID - Draw depth buffer for fourth split.
+ */
+
+ depthRectHeight = m_viewState.m_height / 3;
+ depthRectWidth = depthRectHeight;
+ depthRectX = 0;
+ depthRectY = m_viewState.m_height - depthRectHeight;
+
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_1_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_2_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_3_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_SHADOWMAP_4_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_VBLUR_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_HBLUR_0_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_VBLUR_1_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_HBLUR_1_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_VBLUR_2_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_HBLUR_2_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_VBLUR_3_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_HBLUR_3_ID, 0, 0, m_currentShadowMapSize, m_currentShadowMapSize);
+ bgfx::setViewRect(RENDERVIEW_DRAWSCENE_0_ID, 0, 0, m_viewState.m_width, m_viewState.m_height);
+ bgfx::setViewRect(RENDERVIEW_DRAWSCENE_1_ID, 0, 0, m_viewState.m_width, m_viewState.m_height);
+ bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_0_ID, depthRectX+(0*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
+ bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_1_ID, depthRectX+(1*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
+ bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_2_ID, depthRectX+(2*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
+ bgfx::setViewRect(RENDERVIEW_DRAWDEPTH_3_ID, depthRectX+(3*depthRectWidth), depthRectY, depthRectWidth, depthRectHeight);
+
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_1_ID, lightView[0], lightProj[0]);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_2_ID, lightView[0], lightProj[1]);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_3_ID, lightView[0], lightProj[2]);
+ bgfx::setViewTransform(RENDERVIEW_SHADOWMAP_4_ID, lightView[0], lightProj[3]);
+ bgfx::setViewTransform(RENDERVIEW_VBLUR_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_HBLUR_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_VBLUR_1_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_HBLUR_1_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_VBLUR_2_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_HBLUR_2_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_VBLUR_3_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_HBLUR_3_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_0_ID, m_viewState.m_view, m_viewState.m_proj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWSCENE_1_ID, m_viewState.m_view, m_viewState.m_proj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_0_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_1_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_2_ID, screenView, screenProj);
+ bgfx::setViewTransform(RENDERVIEW_DRAWDEPTH_3_ID, screenView, screenProj);
+
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_1_ID, s_rtShadowMap[0]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_2_ID, s_rtShadowMap[1]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_3_ID, s_rtShadowMap[2]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_SHADOWMAP_4_ID, s_rtShadowMap[3]);
+ bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_0_ID, s_rtBlur); //vblur
+ bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_0_ID, s_rtShadowMap[0]); //hblur
+ bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_1_ID, s_rtBlur); //vblur
+ bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_1_ID, s_rtShadowMap[1]); //hblur
+ bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_2_ID, s_rtBlur); //vblur
+ bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_2_ID, s_rtShadowMap[2]); //hblur
+ bgfx::setViewFrameBuffer(RENDERVIEW_VBLUR_3_ID, s_rtBlur); //vblur
+ bgfx::setViewFrameBuffer(RENDERVIEW_HBLUR_3_ID, s_rtShadowMap[3]); //hblur
}
- for (uint8_t ii = 0; ii < drawNum; ++ii)
+ // Clear backbuffer at beginning.
+ bgfx::setViewClear(0
+ , BGFX_CLEAR_COLOR
+ | BGFX_CLEAR_DEPTH
+ , m_clearValues.m_clearRgba
+ , m_clearValues.m_clearDepth
+ , m_clearValues.m_clearStencil
+ );
+ bgfx::touch(0);
+
+ // Clear shadowmap rendertarget at beginning.
+ const uint8_t flags0 = (LightType::DirectionalLight == m_settings.m_lightType)
+ ? 0
+ : BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL
+ ;
+
+ bgfx::setViewClear(RENDERVIEW_SHADOWMAP_0_ID
+ , flags0
+ , 0xfefefefe //blur fails on completely white regions
+ , m_clearValues.m_clearDepth
+ , m_clearValues.m_clearStencil
+ );
+ bgfx::touch(RENDERVIEW_SHADOWMAP_0_ID);
+
+ const uint8_t flags1 = (LightType::DirectionalLight == m_settings.m_lightType)
+ ? BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
+ : 0
+ ;
+
+ for (uint8_t ii = 0; ii < 4; ++ii)
{
- const uint8_t viewId = RENDERVIEW_SHADOWMAP_1_ID + ii;
+ bgfx::setViewClear(RENDERVIEW_SHADOWMAP_1_ID+ii
+ , flags1
+ , 0xfefefefe //blur fails on completely white regions
+ , m_clearValues.m_clearDepth
+ , m_clearValues.m_clearStencil
+ );
+ bgfx::touch(RENDERVIEW_SHADOWMAP_1_ID+ii);
+ }
- uint8_t renderStateIndex = RenderState::ShadowMap_PackDepth;
- if(LightType::PointLight == settings.m_lightType && settings.m_stencilPack)
+ // Render.
+
+ // Craft shadow map.
+ {
+ // Craft stencil mask for point light shadow map packing.
+ if(LightType::PointLight == m_settings.m_lightType && m_settings.m_stencilPack)
{
- renderStateIndex = uint8_t( (ii < 2) ? RenderState::ShadowMap_PackDepthHoriz : RenderState::ShadowMap_PackDepthVert);
- }
+ if (6 == bgfx::getAvailTransientVertexBuffer(6, m_posDecl) )
+ {
+ struct Pos
+ {
+ float m_x, m_y, m_z;
+ };
- // Floor.
- hplaneMesh.submit(viewId
- , mtxFloor
- , *currentSmSettings->m_progPack
- , s_renderStates[renderStateIndex]
- );
+ bgfx::TransientVertexBuffer vb;
+ bgfx::allocTransientVertexBuffer(&vb, 6, m_posDecl);
+ Pos* vertex = (Pos*)vb.data;
+
+ const float min = 0.0f;
+ const float max = 1.0f;
+ const float center = 0.5f;
+ const float zz = 0.0f;
+
+ vertex[0].m_x = min;
+ vertex[0].m_y = min;
+ vertex[0].m_z = zz;
+
+ vertex[1].m_x = max;
+ vertex[1].m_y = min;
+ vertex[1].m_z = zz;
+
+ vertex[2].m_x = center;
+ vertex[2].m_y = center;
+ vertex[2].m_z = zz;
+
+ vertex[3].m_x = center;
+ vertex[3].m_y = center;
+ vertex[3].m_z = zz;
+
+ vertex[4].m_x = max;
+ vertex[4].m_y = max;
+ vertex[4].m_z = zz;
+
+ vertex[5].m_x = min;
+ vertex[5].m_y = max;
+ vertex[5].m_z = zz;
+
+ bgfx::setState(0);
+ bgfx::setStencil(BGFX_STENCIL_TEST_ALWAYS
+ | BGFX_STENCIL_FUNC_REF(1)
+ | BGFX_STENCIL_FUNC_RMASK(0xff)
+ | BGFX_STENCIL_OP_FAIL_S_REPLACE
+ | BGFX_STENCIL_OP_FAIL_Z_REPLACE
+ | BGFX_STENCIL_OP_PASS_Z_REPLACE
+ );
+ bgfx::setVertexBuffer(0, &vb);
+ bgfx::submit(RENDERVIEW_SHADOWMAP_0_ID, s_programs.m_black);
+ }
+ }
- // Bunny.
- bunnyMesh.submit(viewId
- , mtxBunny
- , *currentSmSettings->m_progPack
- , s_renderStates[renderStateIndex]
- );
+ // Draw scene into shadowmap.
+ uint8_t drawNum;
+ if (LightType::SpotLight == m_settings.m_lightType)
+ {
+ drawNum = 1;
+ }
+ else if (LightType::PointLight == m_settings.m_lightType)
+ {
+ drawNum = 4;
+ }
+ else //LightType::DirectionalLight == settings.m_lightType)
+ {
+ drawNum = uint8_t(m_settings.m_numSplits);
+ }
- // Hollow cube.
- hollowcubeMesh.submit(viewId
- , mtxHollowcube
- , *currentSmSettings->m_progPack
- , s_renderStates[renderStateIndex]
- );
+ for (uint8_t ii = 0; ii < drawNum; ++ii)
+ {
+ const uint8_t viewId = RENDERVIEW_SHADOWMAP_1_ID + ii;
- // Cube.
- cubeMesh.submit(viewId
- , mtxCube
- , *currentSmSettings->m_progPack
- , s_renderStates[renderStateIndex]
- );
+ uint8_t renderStateIndex = RenderState::ShadowMap_PackDepth;
+ if(LightType::PointLight == m_settings.m_lightType && m_settings.m_stencilPack)
+ {
+ renderStateIndex = uint8_t( (ii < 2) ? RenderState::ShadowMap_PackDepthHoriz : RenderState::ShadowMap_PackDepthVert);
+ }
- // Trees.
- for (uint8_t jj = 0; jj < numTrees; ++jj)
- {
- treeMesh.submit(viewId
- , mtxTrees[jj]
- , *currentSmSettings->m_progPack
- , s_renderStates[renderStateIndex]
- );
+ // Floor.
+ m_hplaneMesh.submit(viewId
+ , mtxFloor
+ , *currentSmSettings->m_progPack
+ , s_renderStates[renderStateIndex]
+ );
+
+ // Bunny.
+ m_bunnyMesh.submit(viewId
+ , mtxBunny
+ , *currentSmSettings->m_progPack
+ , s_renderStates[renderStateIndex]
+ );
+
+ // Hollow cube.
+ m_hollowcubeMesh.submit(viewId
+ , mtxHollowcube
+ , *currentSmSettings->m_progPack
+ , s_renderStates[renderStateIndex]
+ );
+
+ // Cube.
+ m_cubeMesh.submit(viewId
+ , mtxCube
+ , *currentSmSettings->m_progPack
+ , s_renderStates[renderStateIndex]
+ );
+
+ // Trees.
+ for (uint8_t jj = 0; jj < numTrees; ++jj)
+ {
+ m_treeMesh.submit(viewId
+ , mtxTrees[jj]
+ , *currentSmSettings->m_progPack
+ , s_renderStates[renderStateIndex]
+ );
+ }
}
}
- }
- PackDepth::Enum depthType = (SmImpl::VSM == settings.m_smImpl) ? PackDepth::VSM : PackDepth::RGBA;
- bool bVsmOrEsm = (SmImpl::VSM == settings.m_smImpl) || (SmImpl::ESM == settings.m_smImpl);
+ PackDepth::Enum depthType = (SmImpl::VSM == m_settings.m_smImpl) ? PackDepth::VSM : PackDepth::RGBA;
+ bool bVsmOrEsm = (SmImpl::VSM == m_settings.m_smImpl) || (SmImpl::ESM == m_settings.m_smImpl);
- // Blur shadow map.
- if (bVsmOrEsm
- && currentSmSettings->m_doBlur)
- {
- bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[0]) );
- bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
- bgfx::submit(RENDERVIEW_VBLUR_0_ID, s_programs.m_vBlur[depthType]);
+ // Blur shadow map.
+ if (bVsmOrEsm
+ && currentSmSettings->m_doBlur)
+ {
+ bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[0]) );
+ bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
+ screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
+ bgfx::submit(RENDERVIEW_VBLUR_0_ID, s_programs.m_vBlur[depthType]);
- bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtBlur) );
- bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
- bgfx::submit(RENDERVIEW_HBLUR_0_ID, s_programs.m_hBlur[depthType]);
+ bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtBlur) );
+ bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
+ screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
+ bgfx::submit(RENDERVIEW_HBLUR_0_ID, s_programs.m_hBlur[depthType]);
- if (LightType::DirectionalLight == settings.m_lightType)
- {
- for (uint8_t ii = 1, jj = 2; ii < settings.m_numSplits; ++ii, jj+=2)
+ if (LightType::DirectionalLight == m_settings.m_lightType)
{
- const uint8_t viewId = RENDERVIEW_VBLUR_0_ID + jj;
+ for (uint8_t ii = 1, jj = 2; ii < m_settings.m_numSplits; ++ii, jj+=2)
+ {
+ const uint8_t viewId = RENDERVIEW_VBLUR_0_ID + jj;
- bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[ii]) );
- bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
- bgfx::submit(viewId, s_programs.m_vBlur[depthType]);
+ bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[ii]) );
+ bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
+ screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
+ bgfx::submit(viewId, s_programs.m_vBlur[depthType]);
- bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtBlur) );
- bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
- bgfx::submit(viewId+1, s_programs.m_hBlur[depthType]);
+ bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtBlur) );
+ bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
+ screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
+ bgfx::submit(viewId+1, s_programs.m_hBlur[depthType]);
+ }
}
}
- }
-
- // Draw scene.
- {
- // Setup shadow mtx.
- float mtxShadow[16];
-
- const float ymul = (s_flipV) ? 0.5f : -0.5f;
- float zadd = (DepthImpl::Linear == settings.m_depthImpl) ? 0.0f : 0.5f;
- const float mtxBias[16] =
+ // Draw scene.
{
- 0.5f, 0.0f, 0.0f, 0.0f,
- 0.0f, ymul, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.5f, 0.0f,
- 0.5f, 0.5f, zadd, 1.0f,
- };
+ // Setup shadow mtx.
+ float mtxShadow[16];
- if (LightType::SpotLight == settings.m_lightType)
- {
- float mtxTmp[16];
- bx::mtxMul(mtxTmp, lightProj[ProjType::Horizontal], mtxBias);
- bx::mtxMul(mtxShadow, lightView[0], mtxTmp); //lightViewProjBias
- }
- else if (LightType::PointLight == settings.m_lightType)
- {
- const float s = (s_flipV) ? 1.0f : -1.0f; //sign
- zadd = (DepthImpl::Linear == settings.m_depthImpl) ? 0.0f : 0.5f;
+ const float ymul = (s_flipV) ? 0.5f : -0.5f;
+ float zadd = (DepthImpl::Linear == m_settings.m_depthImpl) ? 0.0f : 0.5f;
- const float mtxCropBias[2][TetrahedronFaces::Count][16] =
+ const float mtxBias[16] =
{
- { // settings.m_stencilPack == false
+ 0.5f, 0.0f, 0.0f, 0.0f,
+ 0.0f, ymul, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ 0.5f, 0.5f, zadd, 1.0f,
+ };
- { // D3D: Green, OGL: Blue
- 0.25f, 0.0f, 0.0f, 0.0f,
+ if (LightType::SpotLight == m_settings.m_lightType)
+ {
+ float mtxTmp[16];
+ bx::mtxMul(mtxTmp, lightProj[ProjType::Horizontal], mtxBias);
+ bx::mtxMul(mtxShadow, lightView[0], mtxTmp); //lightViewProjBias
+ }
+ else if (LightType::PointLight == m_settings.m_lightType)
+ {
+ const float s = (s_flipV) ? 1.0f : -1.0f; //sign
+ zadd = (DepthImpl::Linear == m_settings.m_depthImpl) ? 0.0f : 0.5f;
+
+ const float mtxCropBias[2][TetrahedronFaces::Count][16] =
+ {
+ { // settings.m_stencilPack == false
+
+ { // D3D: Green, OGL: Blue
+ 0.25f, 0.0f, 0.0f, 0.0f,
0.0f, s*0.25f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
- 0.25f, 0.25f, zadd, 1.0f,
- },
- { // D3D: Yellow, OGL: Red
- 0.25f, 0.0f, 0.0f, 0.0f,
+ 0.25f, 0.25f, zadd, 1.0f,
+ },
+ { // D3D: Yellow, OGL: Red
+ 0.25f, 0.0f, 0.0f, 0.0f,
0.0f, s*0.25f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
- 0.75f, 0.25f, zadd, 1.0f,
- },
- { // D3D: Blue, OGL: Green
- 0.25f, 0.0f, 0.0f, 0.0f,
+ 0.75f, 0.25f, zadd, 1.0f,
+ },
+ { // D3D: Blue, OGL: Green
+ 0.25f, 0.0f, 0.0f, 0.0f,
0.0f, s*0.25f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
- 0.25f, 0.75f, zadd, 1.0f,
- },
- { // D3D: Red, OGL: Yellow
- 0.25f, 0.0f, 0.0f, 0.0f,
+ 0.25f, 0.75f, zadd, 1.0f,
+ },
+ { // D3D: Red, OGL: Yellow
+ 0.25f, 0.0f, 0.0f, 0.0f,
0.0f, s*0.25f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
- 0.75f, 0.75f, zadd, 1.0f,
+ 0.75f, 0.75f, zadd, 1.0f,
+ },
},
- },
- { // settings.m_stencilPack == true
+ { // settings.m_stencilPack == true
- { // D3D: Red, OGL: Blue
- 0.25f, 0.0f, 0.0f, 0.0f,
+ { // D3D: Red, OGL: Blue
+ 0.25f, 0.0f, 0.0f, 0.0f,
0.0f, s*0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
- 0.25f, 0.5f, zadd, 1.0f,
- },
- { // D3D: Blue, OGL: Red
- 0.25f, 0.0f, 0.0f, 0.0f,
+ 0.25f, 0.5f, zadd, 1.0f,
+ },
+ { // D3D: Blue, OGL: Red
+ 0.25f, 0.0f, 0.0f, 0.0f,
0.0f, s*0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
- 0.75f, 0.5f, zadd, 1.0f,
- },
- { // D3D: Green, OGL: Green
- 0.5f, 0.0f, 0.0f, 0.0f,
- 0.0f, s*0.25f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.5f, 0.0f,
- 0.5f, 0.75f, zadd, 1.0f,
+ 0.75f, 0.5f, zadd, 1.0f,
+ },
+ { // D3D: Green, OGL: Green
+ 0.5f, 0.0f, 0.0f, 0.0f,
+ 0.0f, s*0.25f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ 0.5f, 0.75f, zadd, 1.0f,
+ },
+ { // D3D: Yellow, OGL: Yellow
+ 0.5f, 0.0f, 0.0f, 0.0f,
+ 0.0f, s*0.25f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.5f, 0.0f,
+ 0.5f, 0.25f, zadd, 1.0f,
+ },
+ }
+ };
+
+ //Use as: [stencilPack][flipV][tetrahedronFace]
+ static const uint8_t cropBiasIndices[2][2][4] =
+ {
+ { // settings.m_stencilPack == false
+ { 0, 1, 2, 3 }, //flipV == false
+ { 2, 3, 0, 1 }, //flipV == true
},
- { // D3D: Yellow, OGL: Yellow
- 0.5f, 0.0f, 0.0f, 0.0f,
- 0.0f, s*0.25f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.5f, 0.0f,
- 0.5f, 0.25f, zadd, 1.0f,
+ { // settings.m_stencilPack == true
+ { 3, 2, 0, 1 }, //flipV == false
+ { 2, 3, 0, 1 }, //flipV == true
},
- }
- };
+ };
- //Use as: [stencilPack][flipV][tetrahedronFace]
- static const uint8_t cropBiasIndices[2][2][4] =
- {
- { // settings.m_stencilPack == false
- { 0, 1, 2, 3 }, //flipV == false
- { 2, 3, 0, 1 }, //flipV == true
- },
- { // settings.m_stencilPack == true
- { 3, 2, 0, 1 }, //flipV == false
- { 2, 3, 0, 1 }, //flipV == true
- },
- };
+ for (uint8_t ii = 0; ii < TetrahedronFaces::Count; ++ii)
+ {
+ ProjType::Enum projType = (m_settings.m_stencilPack) ? ProjType::Enum(ii>1) : ProjType::Horizontal;
+ uint8_t biasIndex = cropBiasIndices[m_settings.m_stencilPack][uint8_t(s_flipV)][ii];
- for (uint8_t ii = 0; ii < TetrahedronFaces::Count; ++ii)
+ float mtxTmp[16];
+ bx::mtxMul(mtxTmp, mtxYpr[ii], lightProj[projType]);
+ bx::mtxMul(m_shadowMapMtx[ii], mtxTmp, mtxCropBias[m_settings.m_stencilPack][biasIndex]); //mtxYprProjBias
+ }
+
+ bx::mtxTranslate(mtxShadow //lightInvTranslate
+ , -m_pointLight.m_position.m_v[0]
+ , -m_pointLight.m_position.m_v[1]
+ , -m_pointLight.m_position.m_v[2]
+ );
+ }
+ else //LightType::DirectionalLight == settings.m_lightType
{
- ProjType::Enum projType = (settings.m_stencilPack) ? ProjType::Enum(ii>1) : ProjType::Horizontal;
- uint8_t biasIndex = cropBiasIndices[settings.m_stencilPack][uint8_t(s_flipV)][ii];
+ for (uint8_t ii = 0; ii < m_settings.m_numSplits; ++ii)
+ {
+ float mtxTmp[16];
- float mtxTmp[16];
- bx::mtxMul(mtxTmp, mtxYpr[ii], lightProj[projType]);
- bx::mtxMul(shadowMapMtx[ii], mtxTmp, mtxCropBias[settings.m_stencilPack][biasIndex]); //mtxYprProjBias
+ bx::mtxMul(mtxTmp, lightProj[ii], mtxBias);
+ bx::mtxMul(m_shadowMapMtx[ii], lightView[0], mtxTmp); //lViewProjCropBias
+ }
}
- bx::mtxTranslate(mtxShadow //lightInvTranslate
- , -pointLight.m_position.m_v[0]
- , -pointLight.m_position.m_v[1]
- , -pointLight.m_position.m_v[2]
- );
- }
- else //LightType::DirectionalLight == settings.m_lightType
- {
- for (uint8_t ii = 0; ii < settings.m_numSplits; ++ii)
+ // Floor.
+ if (LightType::DirectionalLight != m_settings.m_lightType)
{
- float mtxTmp[16];
-
- bx::mtxMul(mtxTmp, lightProj[ii], mtxBias);
- bx::mtxMul(shadowMapMtx[ii], lightView[0], mtxTmp); //lViewProjCropBias
+ bx::mtxMul(m_lightMtx, mtxFloor, mtxShadow); //not needed for directional light
}
- }
+ m_hplaneMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
+ , mtxFloor
+ , *currentSmSettings->m_progDraw
+ , s_renderStates[RenderState::Default]
+ , true
+ );
- // Floor.
- if (LightType::DirectionalLight != settings.m_lightType)
- {
- bx::mtxMul(lightMtx, mtxFloor, mtxShadow); //not needed for directional light
- }
- hplaneMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
- , mtxFloor
- , *currentSmSettings->m_progDraw
- , s_renderStates[RenderState::Default]
- , true
- );
+ // Bunny.
+ if (LightType::DirectionalLight != m_settings.m_lightType)
+ {
+ bx::mtxMul(m_lightMtx, mtxBunny, mtxShadow);
+ }
+ m_bunnyMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
+ , mtxBunny
+ , *currentSmSettings->m_progDraw
+ , s_renderStates[RenderState::Default]
+ , true
+ );
- // Bunny.
- if (LightType::DirectionalLight != settings.m_lightType)
- {
- bx::mtxMul(lightMtx, mtxBunny, mtxShadow);
- }
- bunnyMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
- , mtxBunny
- , *currentSmSettings->m_progDraw
- , s_renderStates[RenderState::Default]
- , true
- );
+ // Hollow cube.
+ if (LightType::DirectionalLight != m_settings.m_lightType)
+ {
+ bx::mtxMul(m_lightMtx, mtxHollowcube, mtxShadow);
+ }
+ m_hollowcubeMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
+ , mtxHollowcube
+ , *currentSmSettings->m_progDraw
+ , s_renderStates[RenderState::Default]
+ , true
+ );
- // Hollow cube.
- if (LightType::DirectionalLight != settings.m_lightType)
- {
- bx::mtxMul(lightMtx, mtxHollowcube, mtxShadow);
- }
- hollowcubeMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
- , mtxHollowcube
- , *currentSmSettings->m_progDraw
- , s_renderStates[RenderState::Default]
- , true
- );
+ // Cube.
+ if (LightType::DirectionalLight != m_settings.m_lightType)
+ {
+ bx::mtxMul(m_lightMtx, mtxCube, mtxShadow);
+ }
+ m_cubeMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
+ , mtxCube
+ , *currentSmSettings->m_progDraw
+ , s_renderStates[RenderState::Default]
+ , true
+ );
- // Cube.
- if (LightType::DirectionalLight != settings.m_lightType)
- {
- bx::mtxMul(lightMtx, mtxCube, mtxShadow);
- }
- cubeMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
- , mtxCube
- , *currentSmSettings->m_progDraw
- , s_renderStates[RenderState::Default]
- , true
- );
+ // Trees.
+ for (uint8_t ii = 0; ii < numTrees; ++ii)
+ {
+ if (LightType::DirectionalLight != m_settings.m_lightType)
+ {
+ bx::mtxMul(m_lightMtx, mtxTrees[ii], mtxShadow);
+ }
+ m_treeMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
+ , mtxTrees[ii]
+ , *currentSmSettings->m_progDraw
+ , s_renderStates[RenderState::Default]
+ , true
+ );
+ }
- // Trees.
- for (uint8_t ii = 0; ii < numTrees; ++ii)
- {
- if (LightType::DirectionalLight != settings.m_lightType)
+ // Lights.
+ if (LightType::SpotLight == m_settings.m_lightType || LightType::PointLight == m_settings.m_lightType)
{
- bx::mtxMul(lightMtx, mtxTrees[ii], mtxShadow);
+ const float lightScale[3] = { 1.5f, 1.5f, 1.5f };
+ float mtx[16];
+ mtxBillboard(mtx, m_viewState.m_view, m_pointLight.m_position.m_v, lightScale);
+ m_vplaneMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
+ , mtx
+ , s_programs.m_colorTexture
+ , s_renderStates[RenderState::Custom_BlendLightTexture]
+ , m_texFlare
+ );
}
- treeMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
- , mtxTrees[ii]
- , *currentSmSettings->m_progDraw
- , s_renderStates[RenderState::Default]
- , true
- );
- }
- // Lights.
- if (LightType::SpotLight == settings.m_lightType || LightType::PointLight == settings.m_lightType)
- {
- const float lightScale[3] = { 1.5f, 1.5f, 1.5f };
- float mtx[16];
- mtxBillboard(mtx, viewState.m_view, pointLight.m_position.m_v, lightScale);
- vplaneMesh.submit(RENDERVIEW_DRAWSCENE_0_ID
- , mtx
- , s_programs.m_colorTexture
- , s_renderStates[RenderState::Custom_BlendLightTexture]
- , texFlare
- );
+ // Draw floor bottom.
+ float floorBottomMtx[16];
+ bx::mtxSRT(floorBottomMtx
+ , floorScale //scaleX
+ , floorScale //scaleY
+ , floorScale //scaleZ
+ , 0.0f //rotX
+ , 0.0f //rotY
+ , 0.0f //rotZ
+ , 0.0f //translateX
+ , -0.1f //translateY
+ , 0.0f //translateZ
+ );
+
+ m_hplaneMesh.submit(RENDERVIEW_DRAWSCENE_1_ID
+ , floorBottomMtx
+ , s_programs.m_texture
+ , s_renderStates[RenderState::Custom_DrawPlaneBottom]
+ , m_texFigure
+ );
}
- // Draw floor bottom.
- float floorBottomMtx[16];
- bx::mtxSRT(floorBottomMtx
- , floorScale //scaleX
- , floorScale //scaleY
- , floorScale //scaleZ
- , 0.0f //rotX
- , 0.0f //rotY
- , 0.0f //rotZ
- , 0.0f //translateX
- , -0.1f //translateY
- , 0.0f //translateZ
- );
-
- hplaneMesh.submit(RENDERVIEW_DRAWSCENE_1_ID
- , floorBottomMtx
- , s_programs.m_texture
- , s_renderStates[RenderState::Custom_DrawPlaneBottom]
- , texFigure
- );
- }
-
- // Draw depth rect.
- if (settings.m_drawDepthBuffer)
- {
- bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[0]) );
- bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
- bgfx::submit(RENDERVIEW_DRAWDEPTH_0_ID, s_programs.m_drawDepth[depthType]);
-
- if (LightType::DirectionalLight == settings.m_lightType)
+ // Draw depth rect.
+ if (m_settings.m_drawDepthBuffer)
{
- for (uint8_t ii = 1; ii < settings.m_numSplits; ++ii)
+ bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[0]) );
+ bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
+ screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
+ bgfx::submit(RENDERVIEW_DRAWDEPTH_0_ID, s_programs.m_drawDepth[depthType]);
+
+ if (LightType::DirectionalLight == m_settings.m_lightType)
{
- bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[ii]) );
- bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
- bgfx::submit(RENDERVIEW_DRAWDEPTH_0_ID+ii, s_programs.m_drawDepth[depthType]);
+ for (uint8_t ii = 1; ii < m_settings.m_numSplits; ++ii)
+ {
+ bgfx::setTexture(4, s_shadowMap[0], bgfx::getTexture(s_rtShadowMap[ii]) );
+ bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
+ screenSpaceQuad(currentShadowMapSizef, currentShadowMapSizef, s_flipV);
+ bgfx::submit(RENDERVIEW_DRAWDEPTH_0_ID+ii, s_programs.m_drawDepth[depthType]);
+ }
}
}
- }
-
- // Update render target size.
- shadowMapSize = 1 << uint32_t(currentSmSettings->m_sizePwrTwo);
- if (bLtChanged || currentShadowMapSize != shadowMapSize)
- {
- currentShadowMapSize = shadowMapSize;
- currentShadowMapSizef = float(int16_t(currentShadowMapSize) );
- s_uniforms.m_shadowMapTexelSize = 1.0f / currentShadowMapSizef;
+ // Update render target size.
+ uint16_t shadowMapSize = 1 << uint32_t(currentSmSettings->m_sizePwrTwo);
+ if (bLtChanged || m_currentShadowMapSize != shadowMapSize)
{
- bgfx::destroyFrameBuffer(s_rtShadowMap[0]);
+ m_currentShadowMapSize = shadowMapSize;
+ s_uniforms.m_shadowMapTexelSize = 1.0f / currentShadowMapSizef;
- bgfx::TextureHandle fbtextures[] =
{
- bgfx::createTexture2D(currentShadowMapSize, currentShadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT),
- bgfx::createTexture2D(currentShadowMapSize, currentShadowMapSize, false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT),
- };
- s_rtShadowMap[0] = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
- }
+ bgfx::destroy(s_rtShadowMap[0]);
- if (LightType::DirectionalLight == settings.m_lightType)
- {
- for (uint8_t ii = 1; ii < ShadowMapRenderTargets::Count; ++ii)
- {
+ bgfx::TextureHandle fbtextures[] =
{
- bgfx::destroyFrameBuffer(s_rtShadowMap[ii]);
+ bgfx::createTexture2D(m_currentShadowMapSize, m_currentShadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT),
+ bgfx::createTexture2D(m_currentShadowMapSize, m_currentShadowMapSize, false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT),
+ };
+ s_rtShadowMap[0] = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ }
- bgfx::TextureHandle fbtextures[] =
+ if (LightType::DirectionalLight == m_settings.m_lightType)
+ {
+ for (uint8_t ii = 1; ii < ShadowMapRenderTargets::Count; ++ii)
+ {
{
- bgfx::createTexture2D(currentShadowMapSize, currentShadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT),
- bgfx::createTexture2D(currentShadowMapSize, currentShadowMapSize, false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT),
- };
- s_rtShadowMap[ii] = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ bgfx::destroy(s_rtShadowMap[ii]);
+
+ bgfx::TextureHandle fbtextures[] =
+ {
+ bgfx::createTexture2D(m_currentShadowMapSize, m_currentShadowMapSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT),
+ bgfx::createTexture2D(m_currentShadowMapSize, m_currentShadowMapSize, false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT),
+ };
+ s_rtShadowMap[ii] = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
+ }
}
}
+
+ bgfx::destroy(s_rtBlur);
+ s_rtBlur = bgfx::createFrameBuffer(m_currentShadowMapSize, m_currentShadowMapSize, bgfx::TextureFormat::BGRA8);
}
- bgfx::destroyFrameBuffer(s_rtBlur);
- s_rtBlur = bgfx::createFrameBuffer(currentShadowMapSize, currentShadowMapSize, bgfx::TextureFormat::BGRA8);
- }
+ // Advance to next frame. Rendering thread will be kicked to
+ // process submitted rendering primitives.
+ bgfx::frame();
- // Advance to next frame. Rendering thread will be kicked to
- // process submitted rendering primitives.
- bgfx::frame();
+ return true;
+ }
+ return false;
}
- bunnyMesh.unload();
- treeMesh.unload();
- cubeMesh.unload();
- hollowcubeMesh.unload();
- hplaneMesh.unload();
- vplaneMesh.unload();
+ entry::MouseState m_mouseState;
+ uint32_t m_width;
+ uint32_t m_height;
+ uint32_t m_debug;
+ uint32_t m_reset;
- bgfx::destroyTexture(texFigure);
- bgfx::destroyTexture(texFieldstone);
- bgfx::destroyTexture(texFlare);
+ ViewState m_viewState;
+ ClearValues m_clearValues;
- for (uint8_t ii = 0; ii < ShadowMapRenderTargets::Count; ++ii)
- {
- bgfx::destroyFrameBuffer(s_rtShadowMap[ii]);
- }
- bgfx::destroyFrameBuffer(s_rtBlur);
+ bgfx::VertexDecl m_posDecl;
- s_programs.destroy();
+ bgfx::TextureHandle m_texFigure;
+ bgfx::TextureHandle m_texFlare;
+ bgfx::TextureHandle m_texFieldstone;
- bgfx::destroyUniform(s_texColor);
- bgfx::destroyUniform(s_shadowMap[3]);
- bgfx::destroyUniform(s_shadowMap[2]);
- bgfx::destroyUniform(s_shadowMap[1]);
- bgfx::destroyUniform(s_shadowMap[0]);
+ Mesh m_bunnyMesh;
+ Mesh m_treeMesh;
+ Mesh m_cubeMesh;
+ Mesh m_hollowcubeMesh;
+ Mesh m_hplaneMesh;
+ Mesh m_vplaneMesh;
- s_uniforms.destroy();
+ float m_color[4];
+ Material m_defaultMaterial;
+ Light m_pointLight;
+ Light m_directionalLight;
- cameraDestroy();
- imguiDestroy();
+ float m_lightMtx[16];
+ float m_shadowMapMtx[ShadowMapRenderTargets::Count][16];
- // Shutdown bgfx.
- bgfx::shutdown();
+ ShadowMapSettings m_smSettings[LightType::Count][DepthImpl::Count][SmImpl::Count];
+ SceneSettings m_settings;
- return 0;
-}
+ uint16_t m_currentShadowMapSize;
+
+ float m_timeAccumulatorLight;
+ float m_timeAccumulatorScene;
+};
+
+} // namespace
+
+ENTRY_IMPLEMENT_MAIN(ExampleShadowmaps, "16-shadowmaps", "Shadow maps example.");