Skip to content

Commit

Permalink
Add DDGI for global illumination (#243)
Browse files Browse the repository at this point in the history
* Continue work on DDGI

* Move sample counts to globals in shader to allow for setting up the probe buffers CPU side

* Continued DDGI work

* DDGI volume deletion

Selection tool scales with size of item, even if not a model
Fixed error in component inspection that would recreate an item indefinitely when a uint value was defined

* Split ddgi debug to own shader

* Continued DDGI work. Initial probe update close to finished.

* Fix ratio calculation and add range adjustment for texture preview

* Start working on step 2 of DDGI, finalizing the light contributions

* Continued work on finalization shader

* Continue work on probe finalize

* More work on probe finalization

* More DDGI stuff, feeding the blending shader and syncing resources.

* Minor fixes

* Add DDGI to clustering system

* Add color masking to Imgui shader

* Add more DDGI settings

* Add switch to enable/disable terrain shadows

* Continued DDGI work and added script to convert old surface definitions to new.

* Add mode for converting an entire folder to the surface updater

* Make DDGI buffers full precision when working

* Raytracing fixes

* Fix resource server not picking the correct loader

* Fix bugs in material parsing

* Make area lights cull in view space in shader, but passed in world space

* Add texture channel masking to resource browser

* Fixed typo

* Bind ray tracing pipeline before binding resources to ensure the layout change doesn't invalidate the bindings

* Fix lights not showing in raytracing.

Also fix surface updater correctly setting the value in tags instead of putting it as XML content.

* Broken, but trying to fix probe direction being wrong in finalize.

* DDGI almost working

* Many DDGI fixes

* Got DDGI running!

* Initial implementation of probe relocation feature

* Add blending between GI volumes and continue work on extra DDGI features like infinite scrolling, classification, etc.

* Merge together the different DDGI volume structs to one.

Fix debug rendering of DDGI probes

* Fix ddgi probe relocation

* Add probe classification function.

* Use new raytracing payload.

Use true random rotation transform for DDGI instead of just rotating the current one.

* Add missing attributes to GI volume component

* Move graphicsfeature settings to levelsettings and projectsettings

* Remove old graphics feature flatbuffer schemas

* Make DDGI use project settings

* Use level settings to load the terrain and vegetation stuff

* Fix materials and frame scripts not detecting when a recompile is necessary

* Fix validation error for shader resource access now when we do the lighting in the hit shader

* Fix raytracing test pass so it doesn't flicker.

Also fixes incorrect GLTF emissive calculation

* Add tbui to graphics feature

* Fix DDGI partial update

* Fix incorrect GLTF shader implementations

* Area lights were missing diffuse...

* Allow interactions with viewport without explicit focus.

Allows hovering to get 'focus' for picking and manipulating gadgets.

* Fix materials not getting updated in the raytracing material system

* Comments

* -128 is 0x80, +127 is 0x7F...

* Add names to resource tables

* Minor fixes

* Options fixes

* Ensure we can't have less than the lowest required amount of rays per probe

* More fixes for lowest amount of allowed rays per probe

* Fix build

* More build fixes

* Fix test apps with new API for setting up globallight (w/o backlight garbage)

* Add base level and fix include of old terrain settings.

Fix DDGI compile issue

* Working on fixing a raytracing bug and fixing some stupid decisions with mesh exporting

* Fix physics with the new nvx format

* Use uint64 for GPU offsets and sizes

Also limit uniform buffer binding to size min(MaxUniformSize, buffer.size)

* Fix graphics manager not triggering DDGI if raytracing is off

* Some raytracing fixes

* Revert max vertex count

* Working on fixing what appears to be incorrect material assignment when raytracing.

* Fix raytracing issues where a model with multiple primitive groups wouldn't render correctly.

* Fix mesh unload double delete

* Improve DDGI debugging and safe guard against negative energy

* Material template generator spits out 16 bit aligned material types when used as pointers.

* Remove StackAlloc in favor of ArrayAllocStack, which is a thread local linear buffer.

* Fix some export issues

* Material asset editor allows for copy-paste of textures using right click (copy) and middle click (paste)

* Correctly scale selection boxes based on object scale

* Minor fixes in material loader, mainly renaming the global state to materialLoaderState to not confuse debuggers (didn't work)

* Disable point sampling for mip mapped normal maps. Technically normal maps "can't" be mipped but whatever...

* Add DDGI update frequency to project settings

* New syswork export with the changes done to the content

* Fix bug with light grid where lights didn't have enough cells to be culled into. Miracle it ever worked.

I think this could be solved in a better way, but it will work for now.

* Turn on raytracing by default on models. Only does something if raytracing is enabled anyways.
  • Loading branch information
Duttenheim authored Jan 27, 2025
1 parent 016c7ad commit d8e45fb
Show file tree
Hide file tree
Showing 131 changed files with 4,552 additions and 1,064 deletions.
3 changes: 2 additions & 1 deletion code/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ add_subdirectory(physics)
add_subdirectory(application)
add_subdirectory(addons)
add_subdirectory(audio)
add_subdirectory(input)
add_subdirectory(input)
add_subdirectory(options)
47 changes: 38 additions & 9 deletions code/addons/dynui/imgui/shaders/imgui.fx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
#include "lib/shared.fxh"
#include "lib/defaultsamplers.fxh"


// put variables in push-constant block
push constant ImGUI [ string Visibility = "PS|VS"; ]
{
mat4 TextProjectionModel;
uint ColorMask;
uint PackedTextureInfo;
float RangeMin;
float RangeMax;
};

group(BATCH_GROUP) sampler_state TextureSampler
Expand All @@ -37,13 +41,31 @@ render_state TextState
//------------------------------------------------------------------------------
/**
*/
void UnpackTexture(uint val, out uint id, out uint type, out uint mip, out uint layer, out uint useAlpha)
void
UnpackTexture(uint val, out uint id, out uint type, out uint mip, out uint layer, out uint useRange, out uint useAlpha)
{
const uint TEXTURE_TYPE_MASK = 0xF;
const uint TEXTURE_LAYER_MASK = 0xFF;
const uint TEXTURE_MIP_MASK = 0xF;
const uint TEXTURE_USE_RANGE_MASK = 0x1;
const uint TEXTURE_USE_ALPHA_MASK = 0x1;
const uint TEXTURE_ID_MASK = 0xFFF;

type = val & TEXTURE_TYPE_MASK;
layer = (val >> 4) & TEXTURE_LAYER_MASK;
mip = (val >> 12) & TEXTURE_MIP_MASK;
useRange = (val >> 16) & TEXTURE_USE_RANGE_MASK;
useAlpha = (val >> 17) & TEXTURE_USE_ALPHA_MASK;
id = (val >> 18) & TEXTURE_ID_MASK;
}

//------------------------------------------------------------------------------
/**
*/
vec4
UnpackMask(uint val)
{
type = val & 0xF;
layer = (val >> 4) & 0xFF;
mip = (val >> 12) & 0xFF;
useAlpha = (val >> 20) & 0x1;
id = (val >> 21) & 0xFFF;
return vec4(val & 0x1, (val >> 1) & 0x1, (val >> 2) & 0x1, (val >> 3) & 0x1);
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -75,8 +97,8 @@ psMain(
[color0] out vec4 FinalColor)
{
vec4 texColor;
uint id, type, layer, mip, useAlpha;
UnpackTexture(ImGUI.PackedTextureInfo, id, type, mip, layer, useAlpha);
uint id, type, layer, mip, useAlpha, useRange;
UnpackTexture(ImGUI.PackedTextureInfo, id, type, mip, layer, useRange, useAlpha);
if (type == 0)
texColor = sample2DLod(id, TextureSampler, UV, mip);
else if (type == 1)
Expand All @@ -86,12 +108,19 @@ psMain(
ivec3 size = textureSize(make_sampler3D(id, TextureSampler), int(mip));
texColor = sample3DLod(id, TextureSampler, vec3(UV, layer / float(size.z)), mip);
}

if (useRange != 0)
{
texColor.rgb = (texColor.rgb - ImGUI.RangeMin) / (ImGUI.RangeMax - ImGUI.RangeMin);
}

if (useAlpha == 0)
texColor.a = 1;

vec4 mask = UnpackMask(ImGUI.ColorMask);

// Since we are using sRGB output, remember to degamma
FinalColor = Color * texColor;
FinalColor = Color * texColor * mask;
}


Expand Down
59 changes: 53 additions & 6 deletions code/addons/dynui/imguicontext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,24 @@ ImguiDrawFunction(const CoreGraphics::CmdBufferId cmdBuf, const Math::rectangle<

struct TextureInfo
{
uint32 type : 4;
uint32 layer : 8;
uint32 mip : 8;
uint32 useAlpha : 1;
uint32 id : 11;
uint type : 4;
uint layer : 8;
uint mip : 4;
uint useRange : 1;
uint useAlpha : 1;
uint id : 11;
};

union ColorMask
{
struct
{
uint red: 1;
uint green: 1;
uint blue: 1;
uint alpha: 1;
};
uint bits = 0xF;
};

IndexT vertexOffset = 0;
Expand Down Expand Up @@ -175,6 +188,7 @@ ImguiDrawFunction(const CoreGraphics::CmdBufferId cmdBuf, const Math::rectangle<

TextureInfo texInfo;
texInfo.type = 0;
texInfo.useRange = tex.useRange;
texInfo.useAlpha = tex.useAlpha;

// set texture in shader, we shouldn't have to put it into ImGui
Expand All @@ -199,7 +213,19 @@ ImguiDrawFunction(const CoreGraphics::CmdBufferId cmdBuf, const Math::rectangle<
texInfo.mip = tex.mip;
texInfo.id = CoreGraphics::TextureGetBindlessHandle(texture);

ColorMask colorMask;
colorMask.red = tex.red;
colorMask.green = tex.green;
colorMask.blue = tex.blue;
colorMask.alpha = tex.alpha;

CoreGraphics::CmdPushConstants(cmdBuf, CoreGraphics::GraphicsPipeline, ImguiContext::state.packedTextureInfo, sizeof(TextureInfo), (byte*)& texInfo);
CoreGraphics::CmdPushConstants(cmdBuf, CoreGraphics::GraphicsPipeline, ImguiContext::state.colorMaskConstant, sizeof(ColorMask), (byte*)&colorMask);
if (texInfo.useRange)
{
CoreGraphics::CmdPushConstants(cmdBuf, CoreGraphics::GraphicsPipeline, ImguiContext::state.rangeMinConstant, sizeof(float), &tex.rangeMin);
CoreGraphics::CmdPushConstants(cmdBuf, CoreGraphics::GraphicsPipeline, ImguiContext::state.rangeMaxConstant, sizeof(float), &tex.rangeMax);
}

// setup primitive
CoreGraphics::PrimitiveGroup primitive;
Expand Down Expand Up @@ -343,6 +369,9 @@ ImguiContext::Create()

state.textProjectionConstant = CoreGraphics::ShaderGetConstantBinding(state.uiShader, "TextProjectionModel");
state.packedTextureInfo = CoreGraphics::ShaderGetConstantBinding(state.uiShader, "PackedTextureInfo");
state.rangeMinConstant = CoreGraphics::ShaderGetConstantBinding(state.uiShader, "RangeMin");
state.rangeMaxConstant = CoreGraphics::ShaderGetConstantBinding(state.uiShader, "RangeMax");
state.colorMaskConstant = CoreGraphics::ShaderGetConstantBinding(state.uiShader, "ColorMask");

state.inputHandler = ImguiInputHandler::Create();
Input::InputServer::Instance()->AttachInputHandler(Input::InputPriority::DynUi, state.inputHandler.upcast<Input::InputHandler>());
Expand All @@ -353,7 +382,7 @@ ImguiContext::Create()
components.Append(VertexComponent(1, VertexComponent::Float2, 0));
components.Append(VertexComponent(2, VertexComponent::UByte4N, 0));
state.vlo = CoreGraphics::CreateVertexLayout({ .name = "ImGui"_atm, .comps = components });

#if WITH_NEBULA_EDITOR
if (App::GameApplication::IsEditorEnabled())
{
Expand Down Expand Up @@ -394,6 +423,24 @@ ImguiContext::Create()
});
}

FrameScript_default::RegisterSubgraphPipelines_ImGUI_Pass([](const CoreGraphics::PassId pass, uint subpass)
{
CoreGraphics::InputAssemblyKey inputAssembly{ CoreGraphics::PrimitiveTopology::TriangleList, false };
if (state.editorPipeline != CoreGraphics::InvalidPipelineId)
CoreGraphics::DestroyGraphicsPipeline(state.editorPipeline);
state.pipeline = CoreGraphics::CreateGraphicsPipeline({ state.prog, pass, subpass, inputAssembly });
});

FrameScript_default::RegisterSubgraph_ImGUI_Pass([](const CoreGraphics::CmdBufferId cmdBuf, const Math::rectangle<int>& viewport, const IndexT frame, const IndexT bufferIndex)
{
#ifdef NEBULA_NO_DYNUI_ASSERTS
ImguiContext::RecoverImGuiContextErrors();
#endif
//ImGui::Render();
//ImguiDrawFunction(cmdBuf, viewport, false);
});


SizeT numBuffers = CoreGraphics::GetNumBufferedFrames();

CoreGraphics::BufferCreateInfo vboInfo;
Expand Down
10 changes: 10 additions & 0 deletions code/addons/dynui/imguicontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ struct ImguiTextureId
uint layer : 8 = 0;
uint mip : 4 = 0;
uint useAlpha : 1 = 0;
uint useRange : 1 = 0;
float rangeMin, rangeMax;
uint red : 1 = 1;
uint green : 1 = 1;
uint blue : 1 = 1;
uint alpha : 1 = 1;

};

class ImguiContext : public Graphics::GraphicsContext
Expand Down Expand Up @@ -79,6 +86,9 @@ class ImguiContext : public Graphics::GraphicsContext

IndexT textProjectionConstant;
IndexT packedTextureInfo;
IndexT rangeMinConstant;
IndexT rangeMaxConstant;
IndexT colorMaskConstant;
CoreGraphics::ResourceTableId resourceTable;
//Ptr<CoreGraphics::BufferLock> vboBufferLock;
//Ptr<CoreGraphics::BufferLock> iboBufferLock;
Expand Down
2 changes: 1 addition & 1 deletion code/addons/graphicsfeature/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
nebula_begin_module(graphicsfeature)
nebula_flatc(SYSTEM graphicsfeature/graphicsfeatureschema.fbs graphicsfeature/terrainschema.fbs graphicsfeature/vegetationschema.fbs)
fips_deps(render application dynui tbui nflatbuffer)
target_precompile_headers(graphicsfeature PRIVATE <application/stdneb.h>)
fips_ide_group(features)
Expand All @@ -20,6 +19,7 @@ fips_dir(components)
decal.json
lighting.json
model.json
gi.json
)
nebula_end_module()

81 changes: 81 additions & 0 deletions code/addons/graphicsfeature/components/gi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"namespace": "GraphicsFeature",
"components": {
"DDGIVolume": {
"graphicsEntityId": {
"type": "uint",
"default": -1,
"hideInInspector": true
},
"numProbesX": {
"type": "uint",
"default": 8
},
"numProbesY": {
"type": "uint",
"default": 8
},
"numProbesZ": {
"type": "uint",
"default": 8
},
"numRaysPerProbe": {
"type": "uint",
"default": 188
},
"relocate": {
"type": "bool",
"default": false,
"description": "Relocate probes if they are inside geometry"
},
"scrolling": {
"type": "bool",
"default": false,
"description": "Scroll probes infinitely based on camera position"
},
"updateBudget": {
"type": "float",
"default": 1.0,
"description": "Percentage of probes to update per frame, 1.0 means 100%"
},
"classify": {
"type": "bool",
"default": false,
"description": "Automatically disable probes that hit no geometry. This is to save performance. Said probes shoot a minimal set of rays to check if they should invalidate their status"
},
"irradianceScale": {
"type": "float",
"default": 1,
"description": "Energy of output irradiance"
},
"normalBias": {
"type": "float",
"default": 0.1,
"description": "Adds distance on surface along normal direction to avoid aliasing"
},
"viewBias": {
"type": "float",
"default": 0.1,
"description": "Adds distance on surface along camera view direction to avoid aliasing"
},
"distanceExponent": {
"type": "float",
"default": 50
},
"hysteresis": {
"type": "float",
"default": 0.97
},
"borderBlendCutoff": {
"type": "float",
"default": 0.0,
"description": "Percentage distance from the volume edge where blending should start"
},
"borderBlend": {
"type": "float",
"default": 0.0,
"description": "Blend gradient factor based on cutoff point and outer edge of volume"
}
}
}
}
5 changes: 4 additions & 1 deletion code/addons/graphicsfeature/components/model.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
"default": -1,
"hideInInspector": true
},
"raytracing": "bool",
"raytracing": {
"type": "bool",
"default": true
},
"anim": {
"type": "resource",
"default": ""
Expand Down
Loading

0 comments on commit d8e45fb

Please sign in to comment.