Skip to content

Commit 31eefcb

Browse files
committed
Load lights from buffer
1 parent 8f4f357 commit 31eefcb

28 files changed

Lines changed: 425 additions & 186 deletions

.editorconfig

118 Bytes
Binary file not shown.

src/CMakeLists.txt

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,87 @@
11
set(SOURCES
2-
main.cpp
3-
Cluster.h
4-
Cluster.cpp
5-
Config.h
6-
Config.cpp
7-
UI.h
8-
UI.cpp
9-
Scene/Scene.h
10-
Scene/Scene.cpp
11-
Scene/Camera.h
12-
Scene/Camera.cpp
13-
Scene/Mesh.h
14-
Scene/Mesh.cpp
15-
Scene/Material.h
16-
Scene/Light.h
17-
Renderer/Renderer.h
18-
Renderer/Renderer.cpp
19-
Renderer/ForwardRenderer.h
20-
Renderer/ForwardRenderer.cpp
21-
Renderer/DeferredRenderer.h
22-
Renderer/DeferredRenderer.cpp
23-
Renderer/ClusteredRenderer.h
24-
Renderer/ClusteredRenderer.cpp
25-
Renderer/PBRShader.h
26-
Renderer/PBRShader.cpp
27-
Log/Log.h
28-
Log/Log.cpp
29-
Log/UISink.h
30-
Log/AssimpSource.h
31-
vs_forward.sc
32-
fs_forward.sc
33-
vs_tonemap.sc
34-
fs_tonemap.sc
35-
tonemapping.sh
36-
pbr_shader.sh
37-
varying.def.sc
2+
main.cpp
3+
Cluster.h
4+
Cluster.cpp
5+
Config.h
6+
Config.cpp
7+
UI.h
8+
UI.cpp
9+
10+
Log/Log.h
11+
Log/Log.cpp
12+
Log/UISink.h
13+
Log/AssimpSource.h
14+
15+
Renderer/Renderer.h
16+
Renderer/Renderer.cpp
17+
Renderer/ForwardRenderer.h
18+
Renderer/ForwardRenderer.cpp
19+
Renderer/DeferredRenderer.h
20+
Renderer/DeferredRenderer.cpp
21+
Renderer/ClusteredRenderer.h
22+
Renderer/ClusteredRenderer.cpp
23+
Renderer/PBRShader.h
24+
Renderer/PBRShader.cpp
25+
Renderer/LightShader.h
26+
Renderer/LightShader.cpp
27+
28+
Scene/Scene.h
29+
Scene/Scene.cpp
30+
Scene/Camera.h
31+
Scene/Camera.cpp
32+
Scene/Mesh.h
33+
Scene/Mesh.cpp
34+
Scene/Material.h
35+
Scene/Light.h
36+
)
37+
38+
set(SHADERS
39+
Renderer/Shaders/varying.def.sc
40+
Renderer/Shaders/vs_forward.sc
41+
Renderer/Shaders/fs_forward.sc
42+
Renderer/Shaders/vs_tonemap.sc
43+
Renderer/Shaders/fs_tonemap.sc
44+
Renderer/Shaders/tonemapping.sh
45+
Renderer/Shaders/pbr.sh
46+
Renderer/Shaders/lights.sh
3847
)
3948

40-
add_executable(Cluster ${SOURCES})
49+
add_executable(Cluster ${SOURCES} ${SHADERS})
4150
target_include_directories(Cluster PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
4251
target_link_libraries(Cluster PRIVATE bigg IconFontCppHeaders assimp spdlog)
4352
target_compile_definitions(Cluster PRIVATE GLM_FORCE_LEFT_HANDED)
4453

4554
set_target_properties(Cluster PROPERTIES
46-
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
55+
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
4756
)
4857

4958
configure_debugging(Cluster WORKING_DIR ${PROJECT_BINARY_DIR})
5059

5160
if(MSVC)
52-
# disable macro redefinition warning
53-
# ideally 3rd party include folders were marked as SYSTEM so we wouldn't get these warnings
54-
target_compile_options(Cluster PRIVATE "/wd4005")
55-
# hide console window
56-
target_link_options(Cluster PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
61+
# disable macro redefinition warning
62+
# ideally 3rd party include folders were marked as SYSTEM so we wouldn't get these warnings
63+
target_compile_options(Cluster PRIVATE "/wd4005")
64+
# hide console window
65+
target_link_options(Cluster PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
5766
endif()
5867

5968
set(SHADER_DIR "${PROJECT_BINARY_DIR}/shaders")
6069
set(ASSETS_DIR "${PROJECT_BINARY_DIR}/assets")
6170

62-
add_shader(vs_forward.sc VERTEX OUTPUT ${SHADER_DIR} DX11_MODEL 5_0 GLSL_VERSION 130)
63-
add_shader(fs_forward.sc FRAGMENT OUTPUT ${SHADER_DIR} DX11_MODEL 5_0 GLSL_VERSION 130)
64-
add_shader(vs_tonemap.sc VERTEX OUTPUT ${SHADER_DIR} DX11_MODEL 5_0 GLSL_VERSION 130)
65-
add_shader(fs_tonemap.sc FRAGMENT OUTPUT ${SHADER_DIR} DX11_MODEL 5_0 GLSL_VERSION 130)
71+
foreach(SHADER ${SHADERS})
72+
get_filename_component(SHADER_NAME "${SHADER}" NAME)
73+
get_filename_component(SHADER_FILE "${SHADER}" ABSOLUTE)
74+
if(SHADER_NAME MATCHES "^vs_")
75+
add_shader("${SHADER_FILE}" VERTEX OUTPUT "${SHADER_DIR}" PLATFORMS dx11 glsl)
76+
elseif(SHADER_NAME MATCHES "^fs_")
77+
add_shader("${SHADER_FILE}" FRAGMENT OUTPUT "${SHADER_DIR}" PLATFORMS dx11 glsl)
78+
elseif(SHADER_NAME MATCHES "^cs_")
79+
add_shader("${SHADER_FILE}" COMPUTE OUTPUT "${SHADER_DIR}" PLATFORMS dx11 glsl)
80+
else()
81+
# add_shader does this, do it manually for includes/varying.def.sc
82+
source_group("Shader Files" FILES ${SHADERS})
83+
endif()
84+
endforeach()
6685

6786
file(COPY ../assets/ DESTINATION ${ASSETS_DIR})
6887

src/Cluster.cpp

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ void Cluster::initialize(int _argc, char* _argv[])
6060
spdlog::flush_every(std::chrono::seconds(2));
6161
// TODO remove sink during shutdown
6262

63-
// TODO read from config
64-
reset(/*BGFX_RESET_VSYNC | */ BGFX_RESET_MAXANISOTROPY);
65-
//bgfx::setDebug(BGFX_DEBUG_TEXT);
63+
uint32_t resetFlags = BGFX_RESET_MAXANISOTROPY;
64+
if(config->vsync)
65+
resetFlags |= BGFX_RESET_VSYNC;
66+
reset(resetFlags);
6667

6768
if(config->fullscreen)
6869
toggleFullscreen();
@@ -79,14 +80,11 @@ void Cluster::initialize(int _argc, char* _argv[])
7980

8081
Scene::init();
8182
// TODO multithreaded
82-
if(scene->load(config->sceneFile))
83+
// textures still have to be loaded from main thread
84+
// keep list and load one texture every X frames
85+
if(!scene->load(config->sceneFile))
8386
{
84-
scene->skyColor = glm::make_vec3(&config->skyColor[0]);
85-
scene->ambientLight = { glm::vec3(0.04f, 0.04f, 0.04f) };
86-
}
87-
else
88-
{
89-
Log->error("Loading model failed");
87+
Log->error("Loading scene model failed");
9088
close();
9189
return;
9290
}
@@ -296,24 +294,6 @@ void Cluster::toggleFullscreen()
296294
}
297295
}
298296

299-
void Cluster::createLights(unsigned int num)
300-
{
301-
size_t curNum = scene->pointLights.size();
302-
if(num < curNum)
303-
{
304-
scene->pointLights.resize(num);
305-
}
306-
else if(num > curNum)
307-
{
308-
std::generate_n(std::back_inserter(scene->pointLights), num - curNum, []() -> PointLight {
309-
return {
310-
glm::linearRand(glm::vec3(0.0f), glm::vec3(2.0f)),
311-
glm::vec4(glm::linearRand(glm::vec3(0.0f), glm::vec3(1.0f)), 1.0f)
312-
};
313-
});
314-
}
315-
}
316-
317297
void Cluster::setRenderPath(RenderPath path)
318298
{
319299
if(renderer && path == config->renderPath)

src/Cluster.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ class Cluster : public bigg::Application
3636
void close();
3737
void toggleFullscreen();
3838

39-
void createLights(unsigned int num);
40-
4139
enum RenderPath : int
4240
{
4341
Forward,

src/Config.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ Config::Config() :
55
logFile("Cluster.log"),
66
renderer(bgfx::RendererType::Count),
77
renderPath(Cluster::Forward),
8+
vsync(false),
89
//sceneFile("assets/models/duck/Duck.gltf"),
910
sceneFile("assets/models/Sponza/glTF/Sponza.gltf"),
10-
//skyColor{ 0.53f, 0.81f, 0.98f }, // https://en.wikipedia.org/wiki/Sky_blue#Light_sky_blue
11-
//skyColor{ 0.1f, 0.1f, 0.44f }, // https://en.wikipedia.org/wiki/Midnight_blue#X11
12-
skyColor{ 0.0f, 0.0f, 0.0f },
1311
lights(1),
1412
fullscreen(false),
1513
showUI(true),
@@ -29,7 +27,12 @@ void Config::readArgv(int argc, char* argv[])
2927
// somehow this also makes it the only usable renderer
3028
// passing D3D11 as renderer will still use OpenGL with that define
3129

32-
// D3D9 doesn't seem to work, device gets lost
30+
// DX 9.0c (shader model 3.0) doesn't allow indexing into the light buffer
31+
// so shaders for DX9 aren't even compiled anymore
32+
33+
// DX11, DX12, OpenGL all work
34+
// Vulkan doesn't support framebuffer textures
35+
3336
renderer = bgfx::RendererType::Direct3D11;
3437

3538
showStatsOverlay = false;

src/Config.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ class Config
1818
bgfx::RendererType::Enum renderer; // not exposed to UI
1919
Cluster::RenderPath renderPath;
2020

21+
bool vsync; // not exposed to UI
22+
2123
// Scene
2224

2325
const char* sceneFile; // not exposed to UI
24-
float skyColor[3]; // RGB, not exposed to UI
2526
int lights;
2627

2728
// UI

src/Renderer/ForwardRenderer.cpp

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
#include "Scene/Scene.h"
44
#include <bigg.hpp>
55
#include <bx/string.h>
6-
#include <bx/math.h>
7-
#include <glm/gtc/matrix_transform.hpp>
6+
#include <glm/matrix.hpp>
87

98
ForwardRenderer::ForwardRenderer(const Scene* scene) :
109
Renderer(scene),
@@ -27,8 +26,6 @@ bool ForwardRenderer::supported()
2726

2827
void ForwardRenderer::onInitialize()
2928
{
30-
normalMatrixUniform = bgfx::createUniform("u_normalMatrix", bgfx::UniformType::Mat4);
31-
3229
char vsName[128], fsName[128];
3330
bx::snprintf(vsName, BX_COUNTOF(vsName), "%s%s", shaderDir(), "vs_forward.bin");
3431
bx::snprintf(fsName, BX_COUNTOF(fsName), "%s%s", shaderDir(), "fs_forward.bin");
@@ -49,39 +46,28 @@ void ForwardRenderer::onRender(float dt)
4946
if(!scene->loaded)
5047
return;
5148

52-
// view matrix
53-
glm::mat4 view = scene->camera.matrix();
54-
// projection matrix
55-
glm::mat4 proj;
56-
bx::mtxProj(&proj[0][0], scene->camera.fov, float(width) / height,
57-
scene->camera.zNear, scene->camera.zFar, bgfx::getCaps()->homogeneousDepth);
49+
setViewProjection(vDefault);
50+
51+
uint64_t state = BGFX_STATE_DEFAULT & ~BGFX_STATE_CULL_MASK;
5852

59-
glm::mat4 scaleM = glm::scale(glm::mat4(), glm::vec3(scale));
60-
view = scaleM * view;
61-
bgfx::setViewTransform(vDefault, &view[0][0], &proj[0][0]);
6253

6354
for(const Mesh& mesh : scene->meshes)
6455
{
6556
glm::mat4 model = glm::mat4();
6657
bgfx::setTransform(&model[0][0]);
67-
glm::mat4 modelView = view * model;
68-
// if we don't do non-uniform scaling, the normal matrix is the same as the model-view matrix
69-
//glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelView));
70-
glm::mat4 normalMatrix = modelView;
71-
bgfx::setUniform(normalMatrixUniform, &normalMatrix[0][0]);
72-
58+
setNormalMatrix(model);
7359
bgfx::setVertexBuffer(0, mesh.vertexBuffer);
7460
bgfx::setIndexBuffer(mesh.indexBuffer);
7561
const Material& mat = scene->materials[mesh.material];
7662
uint64_t materialState = pbr.bindMaterial(mat);
77-
uint64_t state = BGFX_STATE_DEFAULT & ~BGFX_STATE_CULL_MASK;
78-
bgfx::setState(state | materialState);
63+
uint64_t lightState = lights.bindLights();
64+
bgfx::setState(state | lightState | materialState);
7965
bgfx::submit(vDefault, program);
8066
}
8167
}
8268

8369
void ForwardRenderer::onShutdown()
8470
{
85-
bgfx::destroy(normalMatrixUniform);
8671
bgfx::destroy(program);
72+
program = BGFX_INVALID_HANDLE;
8773
}

src/Renderer/ForwardRenderer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,4 @@ class ForwardRenderer : public Renderer
1616

1717
private:
1818
bgfx::ProgramHandle program;
19-
bgfx::UniformHandle normalMatrixUniform;
2019
};

src/Renderer/LightShader.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include "LightShader.h"
2+
3+
bgfx::VertexDecl LightShader::VertexVec3::decl;
4+
5+
LightShader::LightShader() :
6+
numLights(3),
7+
lightCountVecUniform(BGFX_INVALID_HANDLE),
8+
lightPosBuffer(BGFX_INVALID_HANDLE),
9+
lightFluxBuffer(BGFX_INVALID_HANDLE),
10+
lightPositions(nullptr),
11+
lightFluxs(nullptr)
12+
{
13+
}
14+
15+
void LightShader::initialize()
16+
{
17+
VertexVec3::init();
18+
19+
lightCountVecUniform = bgfx::createUniform("u_lightCountVec", bgfx::UniformType::Vec4);
20+
21+
lightPositions = new VertexVec3[numLights];
22+
lightFluxs = new VertexVec3[numLights];
23+
24+
lightPosBuffer = bgfx::createDynamicVertexBuffer(numLights, VertexVec3::decl, BGFX_BUFFER_COMPUTE_READ);
25+
lightFluxBuffer = bgfx::createDynamicVertexBuffer(numLights, VertexVec3::decl, BGFX_BUFFER_COMPUTE_READ);
26+
27+
lightPositions[0] = { -5.0f, 1.1f, 0.0f };
28+
lightPositions[1] = { 0.0f, 1.1f, 0.0f };
29+
lightPositions[2] = { 5.0f, 1.1f, 0.0f };
30+
31+
lightFluxs[1] = { 1.0f, 0.0f, 1.0f };
32+
lightFluxs[0] = { 0.0f, 1.0f, 1.0f };
33+
lightFluxs[2] = { 1.0f, 1.0f, 0.0f };
34+
35+
//uint32_t structsize = sizeof(VertexVec3);
36+
//uint32_t declsize = VertexVec3::decl.getStride();
37+
38+
bgfx::update(lightPosBuffer, 0, bgfx::makeRef(lightPositions, sizeof(VertexVec3) * numLights));
39+
bgfx::update(lightFluxBuffer, 0, bgfx::makeRef(lightFluxs, sizeof(VertexVec3) * numLights));
40+
}
41+
42+
void LightShader::shutdown()
43+
{
44+
bgfx::destroy(lightCountVecUniform);
45+
bgfx::destroy(lightPosBuffer);
46+
bgfx::destroy(lightFluxBuffer);
47+
48+
lightPosBuffer = lightFluxBuffer = BGFX_INVALID_HANDLE;
49+
lightCountVecUniform = BGFX_INVALID_HANDLE;
50+
51+
delete[] lightPositions;
52+
delete[] lightFluxs;
53+
lightPositions = lightFluxs = nullptr;
54+
}
55+
56+
uint64_t LightShader::bindLights()
57+
{
58+
// a 32-bit IEEE 754 float can represent all integers up to 2^24 (~16.7 million) correctly
59+
// should be enough for this use case (comparison in for loop)
60+
float lightCountVec[4] = { (float)numLights };
61+
bgfx::setUniform(lightCountVecUniform, lightCountVec);
62+
63+
bgfx::setBuffer(SAMPLER_START, lightPosBuffer, bgfx::Access::Read);
64+
bgfx::setBuffer(SAMPLER_START + 1, lightFluxBuffer, bgfx::Access::Read);
65+
66+
return 0;
67+
}

0 commit comments

Comments
 (0)