Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 91 additions & 1 deletion game/graphics/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,14 @@ bool Renderer::requiresTlas() const {
return false;
}

bool Renderer::requiresLightsTree() const {
if(!Shaders::isLightsTreeSupported())
return false;
if(settings.giMethod==GiMethod::IrrC || settings.pathTraceEnabled)
return true;
return true;
}

StorageImage& Renderer::usesImage3d(Tempest::StorageImage& ret, Tempest::TextureFormat frm, uint32_t w, uint32_t h, uint32_t d, bool mips) {
if(ret.format()==frm && uint32_t(ret.w())==w && uint32_t(ret.h())==h && uint32_t(ret.d())==d && bool(ret.mipCount()>1)==mips)
return ret;
Expand Down Expand Up @@ -634,6 +642,9 @@ void Renderer::draw(Tempest::Attachment& result, Encoder<CommandBuffer>& cmd, ui
wview->updateRtScene();
wview->updateLights();

if(requiresLightsTree())
prepareLightsBvh(cmd, *wview);

updateCamera(*camera);

static bool updFr = true;
Expand Down Expand Up @@ -693,6 +704,7 @@ void Renderer::draw(Tempest::Attachment& result, Encoder<CommandBuffer>& cmd, ui
drawAmbient(cmd,*wview);
drawLights(cmd,*wview);
drawSky(cmd,*wview);
drawLightTreeDbg(sceneLinear, cmd, *wview);

stashSceneAux(cmd);

Expand Down Expand Up @@ -1049,6 +1061,30 @@ void Renderer::drawHashDbg(Attachment& result, Tempest::Encoder<Tempest::Command
cmd.draw(nullptr, 0, 3);
}

void Renderer::drawLightTreeDbg(Attachment& result, Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview) {
static bool enable = false;
if(!enable)
return;

auto& scene = wview.sceneGlobals();

struct Push {
Vec3 originLwc;
} push;
push.originLwc = scene.originLwc;

cmd.setDebugMarker("LightTree-dbg");
cmd.setPushData(push);
cmd.setBinding(0, scene.uboGlobal[SceneGlobals::V_Main]);
cmd.setBinding(1, gbufNormal);
cmd.setBinding(2, zbuffer);
cmd.setBinding(3, lightsTree.bvh);

cmd.setFramebuffer({{result, Tempest::Preserve, Tempest::Preserve}});
cmd.setPipeline(shaders.lightsTreeDbg);
cmd.draw(nullptr, 0, 3);
}

void Renderer::drawHiZ(Encoder<CommandBuffer>& cmd, WorldView& view) {
cmd.setDebugMarker("HiZ-occluders");
cmd.setFramebuffer({}, {zbuffer, 1.f, Tempest::Preserve});
Expand Down Expand Up @@ -1954,6 +1990,59 @@ void Renderer::prepareEpipolar(Tempest::Encoder<Tempest::CommandBuffer>& cmd, Wo
cmd.dispatch(uint32_t(epTrace.h()));
}

void Renderer::prepareLightsBvh(Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview) {
if(!Shaders::isLightsTreeSupported())
return;

struct Push {
uint32_t numLightsPot;
uint32_t numLights;
} push = {};
const uint32_t numLights = uint32_t(wview.lights().size());
push.numLightsPot = nextPot(numLights);
push.numLights = numLights;

auto& lightsSsbo = wview.lights().lightsSsbo();
auto& bvhMorton = usesSsbo(lightsTree.bvhMorton, shaders.lightsBvh.sizeofBuffer(1, push.numLightsPot));
auto& bvhAlux = usesSsbo(lightsTree.bvhAlux, shaders.lightsBvh.sizeofBuffer(3, numLights * 2));
auto& ctrl = usesSsboInit(lightsTree.bvhCtrl, shaders.lightsBvh.sizeofBuffer(4, (numLights + 31 )/32));

const bool ltree = settings.pathTraceEnabled;
const bool lbvh = (settings.giMethod==GiMethod::IrrC);

cmd.setDebugMarker("LightsTree");
cmd.setFramebuffer({});
cmd.setPushData(push);
cmd.setBinding(0, lightsSsbo);
cmd.setBinding(1, bvhMorton);
//
cmd.setBinding(3, bvhAlux);
cmd.setBinding(4, ctrl);

cmd.setPipeline(shaders.lightsMorton);
cmd.dispatch(1); // single pass, for simplicity

if(ltree) {
auto& tree = usesSsbo(lightsTree.tree, shaders.lightsBvh.sizeofBuffer(2, numLights * 2));
cmd.setBinding(2, tree);
cmd.setPipeline(shaders.lightsTopology);
cmd.dispatchThreads(numLights);

cmd.setPipeline(shaders.lightsTree);
cmd.dispatchThreads(numLights);
}

if(lbvh) {
auto& bvh = usesSsbo(lightsTree.bvh, shaders.lightsBvh.sizeofBuffer(2, numLights * 2));
cmd.setBinding(2, bvh);
cmd.setPipeline(shaders.lightsTopology);
cmd.dispatchThreads(numLights);

cmd.setPipeline(shaders.lightsBvh);
cmd.dispatchThreads(numLights);
}
}

void Renderer::prepareSurfels(Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview) {
static bool enable = true;
if(!enable)
Expand Down Expand Up @@ -2184,6 +2273,7 @@ void Renderer::surfelsTrace(Tempest::Encoder<Tempest::CommandBuffer>& cmd, World
cmd.setBinding(10,scene.rtScene.ibo);
cmd.setBinding(11,scene.rtScene.rtDesc);
cmd.setBinding(12,shadowMap[1]);
cmd.setBinding(13,lightsTree.bvh);

cmd.setPipeline(*pso);
const uint32_t offset = postPass ? sizeof(uint32_t) : 0;
Expand Down Expand Up @@ -2423,7 +2513,7 @@ void Renderer::drawPathtrace(Tempest::Encoder<Tempest::CommandBuffer>& cmd, Worl
cmd.setBinding(3, sky.viewCldLut, sky.sampler);
//cmd.setBinding(4, shadowMap[1], Sampler::bilinear());
cmd.setBinding(4, Resources::fallbackBlack(), Sampler::bilinear());
//
cmd.setBinding(5, lightsTree.tree);
cmd.setBinding(6, scene.rtScene.tlas);
cmd.setBinding(7, Sampler::trillinear());
cmd.setBinding(8, scene.rtScene.tex);
Expand Down
11 changes: 10 additions & 1 deletion game/graphics/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Renderer final {

void updateCamera(const Camera &camera);
bool requiresTlas() const;
bool requiresLightsTree() const;

Tempest::StorageImage& usesImage2d(Tempest::StorageImage& ret, Tempest::TextureFormat frm, uint32_t w, uint32_t h, bool mips = false);
Tempest::StorageImage& usesImage2d(Tempest::StorageImage& ret, Tempest::TextureFormat frm, Tempest::Size sz, bool mips = false);
Expand All @@ -67,6 +68,8 @@ class Renderer final {
void prepareExposure (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview);
void prepareEpipolar (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview);

void prepareLightsBvh (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview);

void prepareSurfels (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview);
void surfelsApply (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview, int32_t tileSize, bool postPass);
void surfelsBinning (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview, int32_t tileSize, bool postPass);
Expand Down Expand Up @@ -107,6 +110,7 @@ class Renderer final {
void drawSwrDbg (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
void drawRtsmDbg (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
void drawHashDbg (Tempest::Attachment& result, Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
void drawLightTreeDbg (Tempest::Attachment& result, Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);

void setupSettings();
void toggleGi();
Expand Down Expand Up @@ -166,6 +170,11 @@ class Renderer final {
Tempest::RenderPipeline* directLightPso = nullptr;
} lights;

struct {
Tempest::StorageBuffer bvh, tree;
Tempest::StorageBuffer bvhMorton, bvhAlux, bvhCtrl;
} lightsTree;

struct Sky {
Quality quality = Quality::None;

Expand Down Expand Up @@ -215,7 +224,7 @@ class Renderer final {
} gi;

struct {
const Tempest::IVec2 gbufTile = {8, 8};
const Tempest::IVec2 gbufTile = {8};
const uint32_t gbufTilesX = 256;
const uint32_t gbufTilesY = 256;
const uint32_t maxSurfels = gbufTilesX*gbufTilesY;
Expand Down
2 changes: 2 additions & 0 deletions game/graphics/rtscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ void RtScene::addInstance(const Matrix4x4& pos, const AccelerationStructure& bla
ix.flags = RtInstanceFlags::Opaque;
ix.flags = ix.flags | RtInstanceFlags::CullFlip;

#if 1
if(mat.alpha==Material::Solid)
ix.flags = ix.flags | RtInstanceFlags::CullDisable;
#endif

if(mat.alpha==Material::Solid)
ix.mask = CullMask::CM_Opaque;
Expand Down
16 changes: 16 additions & 0 deletions game/graphics/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ void Shaders::compileShaders() {
surLighting = computeShader("surf_lighting.comp.sprv");
}

if(Shaders::isLightsTreeSupported()) {
lightsMorton = computeShader("lights_morton.comp.sprv");
lightsTopology = computeShader("lights_topology.comp.sprv");
lightsTree = computeShader("lights_tree.comp.sprv");
lightsBvh = computeShader("lights_bvh.comp.sprv");

lightsTreeDbg = postEffect("triangle_uv", "lightstree_dbg");
}

if(Shaders::isVsmSupported()) {
fogEpipolarOcclusion = computeShader("fog_epipolar_occlusion.comp.sprv");
fogEpipolarVsm = computeShader("fog_epipolar_vsm.comp.sprv");
Expand Down Expand Up @@ -388,6 +397,13 @@ bool Shaders::isRtsmSupported() {
return true;
}

bool Shaders::isLightsTreeSupported() {
auto& gpu = Resources::device().properties();
if(gpu.compute.maxInvocations<512 || gpu.compute.maxSharedMemory<16*1024)
return false;
return true;
}

bool Shaders::isGi1Supported() {
auto& gpu = Resources::device().properties();
if(!gpu.raytracing.rayQuery)
Expand Down
5 changes: 5 additions & 0 deletions game/graphics/shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Shaders {
static Shaders& inst();
static bool isVsmSupported();
static bool isRtsmSupported();
static bool isLightsTreeSupported();
static bool isGi1Supported();
static bool isGi2Supported();

Expand Down Expand Up @@ -95,6 +96,10 @@ class Shaders {

Tempest::ComputePipeline surfPathtrace, surfRaycast, surLighting;

// Lights tree
Tempest::ComputePipeline lightsMorton, lightsTopology, lightsTree, lightsBvh;
Tempest::RenderPipeline lightsTreeDbg;

// Epipolar
Tempest::ComputePipeline fogEpipolarVsm;
Tempest::ComputePipeline fogEpipolarOcclusion;
Expand Down
4 changes: 2 additions & 2 deletions game/world/objects/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,11 @@ void Item::setPhysicsEnable(const MeshObjects::Mesh& view) {
}

void Item::setPhysicsEnable(const ProtoMesh* mesh) {
if(bBox()==nullptr)
if(mesh==nullptr)
return;
auto& p = *world.physic();
Bounds b;
b.assign(bBox());
b.assign(mesh->bboxMesh);
physic = p.dynamicObj(transform(),b,zenkit::MaterialGroup(hitem->material));
physic.setItem(this);
}
Expand Down
5 changes: 5 additions & 0 deletions game/world/worldlight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

WorldLight::WorldLight(Vob* parent, World& world, const zenkit::VLight& vob, Flags flags)
: Vob(parent,world,vob,flags) {
#if 0
if(!(flags&Startup))
return;
#endif

light = world.addLight(vob);
if(!vob.is_static && !vob.on) {
light.setEnabled(false);
Expand Down
9 changes: 8 additions & 1 deletion shader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,14 @@ add_shader(surf_raycast.comp lighting/surfels/surf_raycast.comp)
add_shader(surf_lighting.comp lighting/surfels/surf_lighting.comp)

# Pathtracing
add_shader(pathtrace.frag lighting/pt/pathtrace.frag -DRAY_QUERY -DRAY_QUERY_AT)
add_shader(pathtrace.frag lighting/pt/pathtrace.frag -DRAY_QUERY -DRAY_QUERY_AT)

add_shader(lights_morton.comp lighting/lightstree/lights_morton.comp)
add_shader(lights_topology.comp lighting/lightstree/lights_topology.comp)
add_shader(lights_tree.comp lighting/lightstree/lights_tree.comp)
add_shader(lights_bvh.comp lighting/lightstree/lights_bvh.comp)

add_shader(lightstree_dbg.frag lighting/lightstree/lightstree_dbg.frag)

# CMAA2
add_shader(cmaa2_edges_color2x2_quality_0.comp antialiasing/cmaa2/edge_color2x2.comp -DCMAA2_STATIC_QUALITY_PRESET=0)
Expand Down
37 changes: 37 additions & 0 deletions shader/common.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,43 @@ vec3 i_octahedral_32( uint data ) {
return normalize(nor);
}

uint floatToOrderedUint(float value) {
uint uvalue = floatBitsToUint(value);
uint mask = -int(uvalue >> 31) | 0x80000000;
return uvalue ^ mask;
}

uvec4 floatToOrderedUint(vec4 value) {
uvec4 r;
r.x = floatToOrderedUint(value.x);
r.y = floatToOrderedUint(value.y);
r.z = floatToOrderedUint(value.z);
r.w = floatToOrderedUint(value.w);
return r;
}

float orderedUintToFloat(uint value) {
uint mask = ((value >> 31) - 1) | 0x80000000;
return uintBitsToFloat(value ^ mask);
}

vec3 orderedUintToFloat(uvec3 value) {
vec3 r;
r.x = orderedUintToFloat(value.x);
r.y = orderedUintToFloat(value.y);
r.z = orderedUintToFloat(value.z);
return r;
}

vec4 orderedUintToFloat(uvec4 value) {
vec4 r;
r.x = orderedUintToFloat(value.x);
r.y = orderedUintToFloat(value.y);
r.z = orderedUintToFloat(value.z);
r.w = orderedUintToFloat(value.w);
return r;
}

// the next packing/unpacking methods are taken from
// https://github.com/Microsoft/DirectX-Graphics-Samples/blob/master/MiniEngine/Core/Shaders/PixelPacking_R11G11B10.hlsli
uint packR11G11B10F(vec3 rgb) {
Expand Down
2 changes: 1 addition & 1 deletion shader/lighting/light.vert
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ layout(binding = 0, std140) uniform UboScene {
SceneDesc scene;
};

layout(binding = 4, std140) readonly buffer SsboLighting {
layout(binding = 4, std430) readonly buffer SsboLighting {
LightSource lights[];
};

Expand Down
18 changes: 18 additions & 0 deletions shader/lighting/lightstree/bvh_build_common.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef BVH_BUILD_COMMON_GLSL
#define BVH_BUILD_COMMON_GLSL

struct MortonHeader {
uint numActiveLights;
uint padd0, padd1, padd2;
};

struct MortonPair {
uint key;
uint id;
};

struct BVHAlux {
uint parent;
};

#endif
Loading
Loading