mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 13:12:52 +02:00
Debugging the grid content
This commit is contained in:
parent
821072bb76
commit
efc4406b47
12 changed files with 379 additions and 22 deletions
|
@ -391,11 +391,14 @@ public:
|
|||
~StructBuffer<T>() {};
|
||||
StructBuffer<T>() : gpu::BufferView(makeBuffer()) {}
|
||||
|
||||
const T* operator ->() const { return &get<T>(); }
|
||||
|
||||
T& edit() {
|
||||
return BufferView::edit<T>(0);
|
||||
}
|
||||
|
||||
const T& get() const {
|
||||
return BufferView::get<T>(0);
|
||||
}
|
||||
const T* operator ->() const { return &get(); }
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ const Element Element::VEC2F_UV{ VEC2, FLOAT, UV };
|
|||
const Element Element::VEC2F_XY{ VEC2, FLOAT, XY };
|
||||
const Element Element::VEC3F_XYZ{ VEC3, FLOAT, XYZ };
|
||||
const Element Element::VEC4F_XYZW{ VEC4, FLOAT, XYZW };
|
||||
const Element Element::INDEX_UINT16{ SCALAR, UINT16, INDEX };
|
||||
const Element Element::INDEX_UINT16 { SCALAR, UINT16, INDEX };
|
||||
const Element Element::INDEX_INT32 { SCALAR, INT32, INDEX };
|
||||
const Element Element::PART_DRAWCALL{ VEC4, UINT32, PART };
|
||||
|
||||
|
|
|
@ -236,6 +236,7 @@ public:
|
|||
static const Element VEC3F_XYZ;
|
||||
static const Element VEC4F_XYZW;
|
||||
static const Element INDEX_UINT16;
|
||||
static const Element INDEX_INT32;
|
||||
static const Element PART_DRAWCALL;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -46,4 +46,13 @@ float projection_getFar(mat4 projection) {
|
|||
|
||||
// end of hybrid include
|
||||
|
||||
|
||||
uniform clusterGridBuffer {
|
||||
int _clusterGridTable[10000];
|
||||
};
|
||||
|
||||
uniform clusterContentBuffer {
|
||||
int _clusterGridContent[10000];
|
||||
};
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -17,11 +17,16 @@ vec3 frustumGrid_gridToVolume(vec3 pos, ivec3 dims) {
|
|||
}
|
||||
|
||||
|
||||
float frustumGrid_volumeToGridDepth(float vposZ, ivec3 dims) {
|
||||
return frustumGrid_depthRampInverse(vposZ) * float(dims.z);
|
||||
}
|
||||
|
||||
vec3 frustumGrid_volumeToGrid(vec3 vpos, ivec3 dims) {
|
||||
vec3 gridPos = vec3(vpos.x, vpos.y, frustumGrid_depthRampInverse(vpos.z)) * vec3(dims);
|
||||
return gridPos;
|
||||
}
|
||||
|
||||
|
||||
vec4 frustumGrid_volumeToClip(vec3 vpos, float rangeNear, float rangeFar) {
|
||||
vec3 ndcPos = vec3(-1.0 + 2.0 * vpos.x, -1.0 + 2.0 * vpos.y, vpos.z);
|
||||
float depth = rangeNear * (1 - ndcPos.z) + rangeFar * (ndcPos.z);
|
||||
|
@ -42,6 +47,10 @@ vec3 frustumGrid_volumeToEye(vec3 vpos, mat4 projection, float rangeNear, float
|
|||
return frustumGrid_clipToEye(frustumGrid_volumeToClip(vpos, rangeNear, rangeFar), projection);
|
||||
}
|
||||
|
||||
float frustumGrid_eyeToVolumeDepth(float eposZ, float rangeNear, float rangeFar) {
|
||||
return (-eposZ - rangeNear) / (rangeFar - rangeNear);
|
||||
}
|
||||
|
||||
|
||||
vec3 frustumGrid_eyeToVolume(vec3 epos, mat4 projection, float rangeNear, float rangeFar) {
|
||||
vec4 clipPos = vec4(epos.x * projection[0][0] + epos.z * projection[2][0],
|
||||
|
@ -57,7 +66,7 @@ vec3 frustumGrid_eyeToVolume(vec3 epos, mat4 projection, float rangeNear, float
|
|||
|
||||
|
||||
int frustumGrid_numClusters() {
|
||||
return frustumGrid.dims.x * frustumGrid.dims.y * (frustumGrid.dims.z);
|
||||
return frustumGrid.dims.x * frustumGrid.dims.y * (frustumGrid.dims.z + 1);
|
||||
}
|
||||
|
||||
vec3 frustumGrid_clusterPosToEye(ivec3 clusterPos, vec3 offset) {
|
||||
|
@ -73,6 +82,27 @@ vec3 frustumGrid_clusterPosToEye(ivec3 clusterPos, vec3 offset) {
|
|||
}
|
||||
|
||||
|
||||
int frustumGrid_eyeDepthToClusterLayer(float eyeZ) {
|
||||
if ((eyeZ > -frustumGrid.frustumNear) || (eyeZ < -frustumGrid.frustumFar)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eyeZ > -frustumGrid.rangeNear) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float volumeZ = frustumGrid_eyeToVolumeDepth(eyeZ, frustumGrid.rangeNear, frustumGrid.rangeFar);
|
||||
|
||||
float gridZ = frustumGrid_volumeToGridDepth(volumeZ, frustumGrid.dims);
|
||||
|
||||
if (gridZ >= frustumGrid.dims.z) {
|
||||
gridZ = frustumGrid.dims.z;
|
||||
}
|
||||
|
||||
|
||||
return int(gridZ);
|
||||
}
|
||||
|
||||
ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) {
|
||||
if ((eyePos.z > -frustumGrid.frustumNear) || (eyePos.z < -frustumGrid.frustumFar)) {
|
||||
return ivec3(-1);
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
//#include "lightClusters_drawClusterFromDepth_vert.h"
|
||||
#include "lightClusters_drawClusterFromDepth_frag.h"
|
||||
|
||||
|
||||
#include "lightClusters_drawClusterContent_vert.h"
|
||||
#include "lightClusters_drawClusterContent_frag.h"
|
||||
|
||||
enum LightClusterGridShader_MapSlot {
|
||||
DEFERRED_BUFFER_LINEAR_DEPTH_UNIT = 0,
|
||||
};
|
||||
|
@ -31,14 +35,32 @@ enum LightClusterGridShader_BufferSlot {
|
|||
CAMERA_CORRECTION_BUFFER_SLOT,
|
||||
LIGHT_GPU_SLOT = render::ShapePipeline::Slot::LIGHT,
|
||||
LIGHT_INDEX_GPU_SLOT,
|
||||
|
||||
LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
|
||||
LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
|
||||
};
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
LightClusters::LightClusters() :
|
||||
_lightIndicesBuffer(std::make_shared<gpu::Buffer>()) {
|
||||
_lightIndicesBuffer(std::make_shared<gpu::Buffer>()),
|
||||
_clusterGridBuffer(std::make_shared<gpu::Buffer>(), gpu::Element::INDEX_INT32),
|
||||
_clusterContentBuffer(std::make_shared<gpu::Buffer>(), gpu::Element::INDEX_INT32) {
|
||||
setDimensions(_frustumGridBuffer->dims, 10000);
|
||||
}
|
||||
|
||||
void LightClusters::setDimensions(glm::uvec3 gridDims, uint32_t listBudget) {
|
||||
_frustumGridBuffer.edit().dims = gridDims;
|
||||
|
||||
_numClusters = _frustumGridBuffer.edit().frustumGrid_numClusters();
|
||||
|
||||
_clusterGridBuffer._size = _clusterGridBuffer._buffer->resize(_numClusters * sizeof(uint32_t));
|
||||
_clusterContentBuffer._size = _clusterContentBuffer._buffer->resize(listBudget * sizeof(uint32_t));
|
||||
_clusterGrid.resize(_numClusters, EMPTY_CLUSTER);
|
||||
_clusterContent.resize(listBudget, INVALID_LIGHT);
|
||||
}
|
||||
|
||||
|
||||
void LightClusters::updateFrustum(const ViewFrustum& frustum) {
|
||||
_frustum = frustum;
|
||||
|
||||
|
@ -51,23 +73,23 @@ void LightClusters::updateLightStage(const LightStagePointer& lightStage) {
|
|||
}
|
||||
|
||||
void LightClusters::updateLightFrame(const LightStage::Frame& lightFrame, bool points, bool spots) {
|
||||
|
||||
|
||||
// start fresh
|
||||
_visibleLightIndices.clear();
|
||||
|
||||
|
||||
// Now gather the lights
|
||||
// gather lights
|
||||
auto& srcPointLights = lightFrame._pointLights;
|
||||
auto& srcSpotLights = lightFrame._spotLights;
|
||||
int numPointLights = (int) srcPointLights.size();
|
||||
// int offsetPointLights = 0;
|
||||
int numSpotLights = (int) srcSpotLights.size();
|
||||
// int offsetSpotLights = numPointLights;
|
||||
|
||||
int numPointLights = (int)srcPointLights.size();
|
||||
// int offsetPointLights = 0;
|
||||
int numSpotLights = (int)srcSpotLights.size();
|
||||
// int offsetSpotLights = numPointLights;
|
||||
|
||||
_visibleLightIndices.resize(numPointLights + numSpotLights + 1);
|
||||
|
||||
|
||||
_visibleLightIndices[0] = 0;
|
||||
|
||||
|
||||
if (points && !srcPointLights.empty()) {
|
||||
memcpy(_visibleLightIndices.data() + (_visibleLightIndices[0] + 1), srcPointLights.data(), srcPointLights.size() * sizeof(int));
|
||||
_visibleLightIndices[0] += (int)srcPointLights.size();
|
||||
|
@ -76,11 +98,144 @@ void LightClusters::updateLightFrame(const LightStage::Frame& lightFrame, bool p
|
|||
memcpy(_visibleLightIndices.data() + (_visibleLightIndices[0] + 1), srcSpotLights.data(), srcSpotLights.size() * sizeof(int));
|
||||
_visibleLightIndices[0] += (int)srcSpotLights.size();
|
||||
}
|
||||
|
||||
|
||||
_lightIndicesBuffer._buffer->setData(_visibleLightIndices.size() * sizeof(int), (const gpu::Byte*) _visibleLightIndices.data());
|
||||
_lightIndicesBuffer._size = _visibleLightIndices.size() * sizeof(int);
|
||||
}
|
||||
|
||||
void LightClusters::updateClusters() {
|
||||
// Clean up last info
|
||||
std::vector< std::vector< uint32_t > > clusterGrid(_numClusters);
|
||||
|
||||
_clusterGrid.resize(_numClusters, EMPTY_CLUSTER);
|
||||
uint32_t maxNumIndices = _clusterContent.size();
|
||||
_clusterContent.resize(maxNumIndices, INVALID_LIGHT);
|
||||
|
||||
auto theFrustumGrid(_frustumGridBuffer.get());
|
||||
|
||||
glm::ivec3 gridPosToOffset(1, theFrustumGrid.dims.x, theFrustumGrid.dims.x * theFrustumGrid.dims.y);
|
||||
|
||||
uint32_t numClusterTouched = 0;
|
||||
for (size_t lightNum = 1; lightNum < _visibleLightIndices.size(); ++lightNum) {
|
||||
auto lightId = _visibleLightIndices[lightNum];
|
||||
auto light = _lightStage->getLight(lightId);
|
||||
if (!light)
|
||||
continue;
|
||||
|
||||
auto worldOri = light->getPosition();
|
||||
auto radius = light->getMaximumRadius();
|
||||
|
||||
// Bring into frustum eye space
|
||||
auto eyeOri = theFrustumGrid.frustumGrid_worldToEye(glm::vec4(worldOri, 1.0f));
|
||||
|
||||
// Remove light that slipped through and is not in the z range
|
||||
float eyeZMax = eyeOri.z - radius;
|
||||
if (eyeZMax > -theFrustumGrid.rangeNear) {
|
||||
continue;
|
||||
}
|
||||
float eyeZMin = eyeOri.z + radius;
|
||||
if (eyeZMin < -theFrustumGrid.rangeFar) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get z slices
|
||||
int zMin = theFrustumGrid.frustumGrid_eyeDepthToClusterLayer(eyeZMin);
|
||||
int zMax = theFrustumGrid.frustumGrid_eyeDepthToClusterLayer(eyeZMax);
|
||||
// That should never happen
|
||||
if (zMin == -1 && zMax == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
float eyeOriLen2 = glm::length2(eyeOri);
|
||||
|
||||
// CLamp the z range
|
||||
zMin = std::max(0, zMin);
|
||||
|
||||
|
||||
|
||||
// find 2D corners of the sphere in grid
|
||||
int xMin { 0 };
|
||||
int xMax { theFrustumGrid.dims.x - 1 };
|
||||
int yMin { 0 };
|
||||
int yMax { theFrustumGrid.dims.y - 1 };
|
||||
|
||||
float radius2 = radius * radius;
|
||||
auto eyeOriH = eyeOri;
|
||||
auto eyeOriV = eyeOri;
|
||||
|
||||
eyeOriH.y = 0.0f;
|
||||
eyeOriV.x = 0.0f;
|
||||
|
||||
float eyeOriLen2H = glm::length2(eyeOriH);
|
||||
float eyeOriLen2V = glm::length2(eyeOriV);
|
||||
|
||||
if ((eyeOriLen2H > radius2) && (eyeOriLen2V > radius2)) {
|
||||
float eyeOriLenH = sqrt(eyeOriLen2H);
|
||||
float eyeOriLenV = sqrt(eyeOriLen2V);
|
||||
|
||||
auto eyeOriDirH = glm::vec3(eyeOriH) / eyeOriLenH;
|
||||
auto eyeOriDirV = glm::vec3(eyeOriV) / eyeOriLenV;
|
||||
|
||||
|
||||
|
||||
float eyeToTangentCircleLenH = sqrt(eyeOriLen2H - radius2);
|
||||
float eyeToTangentCircleLenV = sqrt(eyeOriLen2V - radius2);
|
||||
|
||||
float eyeToTangentCircleTanH = radius / eyeToTangentCircleLenH;
|
||||
float eyeToTangentCircleTanV = radius / eyeToTangentCircleLenV;
|
||||
|
||||
float eyeToTangentCircleCosH = eyeToTangentCircleLenH / eyeOriLenH;
|
||||
float eyeToTangentCircleCosV = eyeToTangentCircleLenV / eyeOriLenV;
|
||||
|
||||
float eyeToTangentCircleSinH = radius / eyeOriLenH;
|
||||
float eyeToTangentCircleSinV = radius / eyeOriLenV;
|
||||
|
||||
|
||||
// rotate the eyeToOriDir (H & V) in both directions
|
||||
glm::vec3 leftDir(eyeOriDirH.x * eyeToTangentCircleCosH - eyeOriDirH.z * eyeToTangentCircleSinH, 0.0f, eyeOriDirH.x * eyeToTangentCircleSinH + eyeOriDirH.z * eyeToTangentCircleCosH);
|
||||
glm::vec3 rightDir(eyeOriDirH.x * eyeToTangentCircleCosH + eyeOriDirH.z * eyeToTangentCircleSinH, 0.0f, eyeOriDirH.x * -eyeToTangentCircleSinH + eyeOriDirH.z * eyeToTangentCircleCosH);
|
||||
glm::vec3 bottomDir(0.0f, eyeOriDirV.y * eyeToTangentCircleCosV - eyeOriDirV.z * eyeToTangentCircleSinV, eyeOriDirV.y * eyeToTangentCircleSinV + eyeOriDirV.z * eyeToTangentCircleCosV);
|
||||
glm::vec3 topDir(0.0f, eyeOriDirV.y * eyeToTangentCircleCosV + eyeOriDirV.z * eyeToTangentCircleSinV, eyeOriDirV.y * -eyeToTangentCircleSinV + eyeOriDirV.z * eyeToTangentCircleCosV);
|
||||
|
||||
}
|
||||
|
||||
// now voxelize
|
||||
for (auto z = zMin; z <= zMax; z++) {
|
||||
for (auto y = yMin; y <= yMax; y++) {
|
||||
for (auto x = xMin; x <= xMax; x++) {
|
||||
auto index = x + gridPosToOffset.y * y + gridPosToOffset.z * z;
|
||||
clusterGrid[index].emplace_back(lightId);
|
||||
numClusterTouched++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lights have been gathered now reexpress in terms of 2 sequential buffers
|
||||
|
||||
uint16_t indexOffset = 0;
|
||||
for (int i = 0; i < clusterGrid.size(); i++) {
|
||||
auto& cluster = clusterGrid[i];
|
||||
uint16_t numLights = ((uint16_t)cluster.size());
|
||||
uint16_t offset = indexOffset;
|
||||
|
||||
_clusterGrid[i] = (uint32_t)((numLights << 16) | offset);
|
||||
|
||||
if (numLights) {
|
||||
memcpy(_clusterContent.data() + indexOffset, cluster.data(), numLights * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
indexOffset += numLights;
|
||||
}
|
||||
|
||||
// update the buffers
|
||||
_clusterGridBuffer._buffer->setData(_clusterGridBuffer._size, (gpu::Byte*) _clusterGrid.data());
|
||||
_clusterContentBuffer._buffer->setSubData(0, indexOffset * sizeof(uint32_t), (gpu::Byte*) _clusterContent.data());
|
||||
}
|
||||
|
||||
|
||||
|
||||
LightClusteringPass::LightClusteringPass() {
|
||||
}
|
||||
|
@ -122,6 +277,8 @@ void LightClusteringPass::run(const render::SceneContextPointer& sceneContext, c
|
|||
_lightClusters->updateLightStage(lightStage);
|
||||
_lightClusters->updateLightFrame(lightStage->_currentFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled());
|
||||
|
||||
_lightClusters->updateClusters();
|
||||
|
||||
output = _lightClusters;
|
||||
}
|
||||
|
||||
|
@ -190,6 +347,35 @@ const gpu::PipelinePointer DebugLightClusters::getDrawClusterFromDepthPipeline()
|
|||
return _drawClusterFromDepth;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer DebugLightClusters::getDrawClusterContentPipeline() {
|
||||
if (!_drawClusterContent) {
|
||||
auto vs = gpu::Shader::createVertex(std::string(lightClusters_drawClusterContent_vert));
|
||||
auto ps = gpu::Shader::createPixel(std::string(lightClusters_drawClusterContent_frag));
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("frustumGridBuffer"), LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("clusterGridBuffer"), LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("clusterContentBuffer"), LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT));
|
||||
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
|
||||
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
||||
|
||||
// Blend on transparent
|
||||
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_drawClusterContent = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
return _drawClusterContent;
|
||||
}
|
||||
|
||||
|
||||
void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
auto deferredTransform = inputs.get0();
|
||||
auto deferredFramebuffer = inputs.get1();
|
||||
|
@ -232,6 +418,17 @@ void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, co
|
|||
batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, nullptr);
|
||||
batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, nullptr);
|
||||
}
|
||||
|
||||
if (doDrawContent) {
|
||||
// bind the one gpu::Pipeline we need
|
||||
batch.setPipeline(getDrawClusterContentPipeline());
|
||||
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, lightClusters->_clusterGridBuffer);
|
||||
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, lightClusters->_clusterContentBuffer);
|
||||
|
||||
auto dims = lightClusters->_frustumGridBuffer->dims;
|
||||
glm::ivec3 summedDims(dims.x*dims.y * dims.z, dims.x*dims.y, dims.x);
|
||||
batch.drawInstanced(summedDims.x, gpu::LINES, 24, 0);
|
||||
}
|
||||
|
||||
if (doDrawGrid) {
|
||||
// bind the one gpu::Pipeline we need
|
||||
|
|
|
@ -57,12 +57,16 @@ public:
|
|||
|
||||
LightClusters();
|
||||
|
||||
void setDimensions(glm::uvec3 gridDims, uint32_t listBudget);
|
||||
|
||||
void updateFrustum(const ViewFrustum& frustum);
|
||||
|
||||
void updateLightStage(const LightStagePointer& lightStage);
|
||||
|
||||
void updateLightFrame(const LightStage::Frame& lightFrame, bool points = true, bool spots = true);
|
||||
|
||||
|
||||
void updateClusters();
|
||||
|
||||
ViewFrustum _frustum;
|
||||
|
||||
LightStagePointer _lightStage;
|
||||
|
@ -72,8 +76,17 @@ public:
|
|||
gpu::StructBuffer<FrustumGrid> _frustumGridBuffer;
|
||||
|
||||
LightStage::LightIndices _visibleLightIndices;
|
||||
|
||||
gpu::BufferView _lightIndicesBuffer;
|
||||
|
||||
uint32_t _numClusters { 0 };
|
||||
|
||||
const uint32_t EMPTY_CLUSTER { 0x0000FFFF };
|
||||
const uint32_t INVALID_LIGHT { 0xFFFFFFFF };
|
||||
|
||||
std::vector<uint32_t> _clusterGrid;
|
||||
std::vector<uint32_t> _clusterContent;
|
||||
gpu::BufferView _clusterGridBuffer;
|
||||
gpu::BufferView _clusterContentBuffer;
|
||||
};
|
||||
|
||||
using LightClustersPointer = std::shared_ptr<LightClusters>;
|
||||
|
@ -162,10 +175,13 @@ protected:
|
|||
gpu::BufferPointer _gridBuffer;
|
||||
gpu::PipelinePointer _drawClusterGrid;
|
||||
gpu::PipelinePointer _drawClusterFromDepth;
|
||||
gpu::PipelinePointer _drawClusterContent;
|
||||
const gpu::PipelinePointer getDrawClusterGridPipeline();
|
||||
const gpu::PipelinePointer getDrawClusterFromDepthPipeline();
|
||||
const gpu::PipelinePointer getDrawClusterContentPipeline();
|
||||
bool doDrawGrid{ false };
|
||||
bool doDrawClusterFromDepth{ false };
|
||||
bool doDrawClusterFromDepth { false };
|
||||
bool doDrawContent { true };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -55,6 +55,7 @@ void LightPayload::render(RenderArgs* args) {
|
|||
// Do we need to allocate the light in the stage ?
|
||||
if (LightStage::isIndexInvalid(_index)) {
|
||||
_index = _stage->addLight(_light);
|
||||
_needUpdate = false;
|
||||
}
|
||||
// Need an update ?
|
||||
if (_needUpdate) {
|
||||
|
|
|
@ -146,8 +146,12 @@ void LightStage::updateLightArrayBuffer(Index lightId) {
|
|||
}
|
||||
|
||||
// lightArray is big enough so we can remap
|
||||
auto& light = _lights._elements[lightId];
|
||||
auto lightSchema = light->getSchemaBuffer().get<model::Light::Schema>();
|
||||
_lightArrayBuffer->setSubData<model::Light::Schema>(lightId, lightSchema);
|
||||
auto light = _lights._elements[lightId];
|
||||
if (light) {
|
||||
auto lightSchema = light->getSchemaBuffer().get<model::Light::Schema>();
|
||||
_lightArrayBuffer->setSubData<model::Light::Schema>(lightId, lightSchema);
|
||||
} else {
|
||||
// this should not happen ?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -192,7 +192,9 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
|
|||
const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer));
|
||||
addJob<DebugDeferredBuffer>("DebugDeferredBuffer", debugFramebuffers);
|
||||
|
||||
addJob<DebugSubsurfaceScattering>("DebugScattering", deferredLightingInputs);
|
||||
const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).hasVarying();
|
||||
addJob<DebugSubsurfaceScattering>("DebugScattering", debugSubsurfaceScatteringInputs);
|
||||
|
||||
const auto debugAmbientOcclusionInputs = DebugAmbientOcclusion::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget, ambientOcclusionUniforms).hasVarying();
|
||||
addJob<DebugAmbientOcclusion>("DebugAmbientOcclusion", debugAmbientOcclusionInputs);
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// lightClusters_drawClusterContent.slf
|
||||
//
|
||||
// Created by Sam Gateau on 9/8/2016.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
in vec4 varColor;
|
||||
out vec4 outFragColor;
|
||||
|
||||
|
||||
void main(void) {
|
||||
outFragColor = varColor;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// lightClusters_drawClusterContent.slv
|
||||
// Vertex shader
|
||||
//
|
||||
// Created by Sam Gateau on 9/8/2016
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include LightClusterGrid.slh@>
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
<$declareColorWheel()$>
|
||||
|
||||
|
||||
|
||||
|
||||
out vec4 varColor;
|
||||
|
||||
|
||||
void main(void) {
|
||||
const vec4 UNIT_BOX[8] = vec4[8](
|
||||
vec4(0.0, 0.0, 0.0, 1.0),
|
||||
vec4(1.0, 0.0, 0.0, 1.0),
|
||||
vec4(0.0, 1.0, 0.0, 1.0),
|
||||
vec4(1.0, 1.0, 0.0, 1.0),
|
||||
vec4(0.0, 0.0, 1.0, 1.0),
|
||||
vec4(1.0, 0.0, 1.0, 1.0),
|
||||
vec4(0.0, 1.0, 1.0, 1.0),
|
||||
vec4(1.0, 1.0, 1.0, 1.0)
|
||||
);
|
||||
const int UNIT_BOX_LINE_INDICES[24] = int[24](
|
||||
0, 1,
|
||||
1, 3,
|
||||
3, 2,
|
||||
2, 0,
|
||||
4, 5,
|
||||
5, 7,
|
||||
7, 6,
|
||||
6, 4,
|
||||
2, 6,
|
||||
3, 7,
|
||||
0, 4,
|
||||
1, 5
|
||||
);
|
||||
vec4 pos = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]];
|
||||
|
||||
ivec3 dims = frustumGrid.dims.xyz;
|
||||
|
||||
ivec3 summedDims = ivec3(dims.x * dims.y, dims.x, 1);
|
||||
|
||||
int layer = gl_InstanceID / summedDims.x;
|
||||
int offsetInLayer = gl_InstanceID % summedDims.x;
|
||||
ivec3 clusterPos = ivec3(offsetInLayer % summedDims.y, offsetInLayer / summedDims.y, layer);
|
||||
|
||||
|
||||
vec3 eyePos = frustumGrid_clusterPosToEye(clusterPos, vec3(0.05) + 0.9 * pos.xyz);
|
||||
vec4 worldPos = frustumGrid_eyeToWorld(vec4(eyePos.xyz, 1.0));
|
||||
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
<$transformWorldToClipPos(cam, worldPos, gl_Position)$>
|
||||
|
||||
varColor = vec4(colorWheel(fract(float(gl_InstanceID) / float(frustumGrid_numClusters()))), 0.9);
|
||||
}
|
Loading…
Reference in a new issue