From efc4406b472f537ec2732aa6d0de21830de691df Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 12 Sep 2016 19:46:18 -0700 Subject: [PATCH] Debugging the grid content --- libraries/gpu/src/gpu/Buffer.h | 7 +- libraries/gpu/src/gpu/Format.cpp | 3 +- libraries/gpu/src/gpu/Format.h | 1 + .../render-utils/src/LightClusterGrid.slh | 9 + .../src/LightClusterGrid_shared.slh | 32 ++- libraries/render-utils/src/LightClusters.cpp | 219 +++++++++++++++++- libraries/render-utils/src/LightClusters.h | 22 +- libraries/render-utils/src/LightPayload.cpp | 1 + libraries/render-utils/src/LightStage.cpp | 10 +- .../render-utils/src/RenderDeferredTask.cpp | 4 +- .../src/lightClusters_drawClusterContent.slf | 19 ++ .../src/lightClusters_drawClusterContent.slv | 74 ++++++ 12 files changed, 379 insertions(+), 22 deletions(-) create mode 100644 libraries/render-utils/src/lightClusters_drawClusterContent.slf create mode 100644 libraries/render-utils/src/lightClusters_drawClusterContent.slv diff --git a/libraries/gpu/src/gpu/Buffer.h b/libraries/gpu/src/gpu/Buffer.h index e8e04f471a..2079c60605 100644 --- a/libraries/gpu/src/gpu/Buffer.h +++ b/libraries/gpu/src/gpu/Buffer.h @@ -391,11 +391,14 @@ public: ~StructBuffer() {}; StructBuffer() : gpu::BufferView(makeBuffer()) {} - const T* operator ->() const { return &get(); } + T& edit() { return BufferView::edit(0); } - + const T& get() const { + return BufferView::get(0); + } + const T* operator ->() const { return &get(); } }; }; diff --git a/libraries/gpu/src/gpu/Format.cpp b/libraries/gpu/src/gpu/Format.cpp index 83b2a59a73..2a8185bf94 100644 --- a/libraries/gpu/src/gpu/Format.cpp +++ b/libraries/gpu/src/gpu/Format.cpp @@ -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 }; diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index ad630e8e43..13809a41e6 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -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: diff --git a/libraries/render-utils/src/LightClusterGrid.slh b/libraries/render-utils/src/LightClusterGrid.slh index 004339ff34..5b1b765e0f 100644 --- a/libraries/render-utils/src/LightClusterGrid.slh +++ b/libraries/render-utils/src/LightClusterGrid.slh @@ -46,4 +46,13 @@ float projection_getFar(mat4 projection) { // end of hybrid include + +uniform clusterGridBuffer { + int _clusterGridTable[10000]; +}; + +uniform clusterContentBuffer { + int _clusterGridContent[10000]; +}; + <@endif@> diff --git a/libraries/render-utils/src/LightClusterGrid_shared.slh b/libraries/render-utils/src/LightClusterGrid_shared.slh index 5ccba9a786..5577b2e612 100644 --- a/libraries/render-utils/src/LightClusterGrid_shared.slh +++ b/libraries/render-utils/src/LightClusterGrid_shared.slh @@ -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); diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp index 97f91657df..ff9362eb3e 100644 --- a/libraries/render-utils/src/LightClusters.cpp +++ b/libraries/render-utils/src/LightClusters.cpp @@ -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()) { + _lightIndicesBuffer(std::make_shared()), + _clusterGridBuffer(std::make_shared(), gpu::Element::INDEX_INT32), + _clusterContentBuffer(std::make_shared(), 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(); + + 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 diff --git a/libraries/render-utils/src/LightClusters.h b/libraries/render-utils/src/LightClusters.h index 60b4d50ced..9930eda731 100644 --- a/libraries/render-utils/src/LightClusters.h +++ b/libraries/render-utils/src/LightClusters.h @@ -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 _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 _clusterGrid; + std::vector _clusterContent; + gpu::BufferView _clusterGridBuffer; + gpu::BufferView _clusterContentBuffer; }; using LightClustersPointer = std::shared_ptr; @@ -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 diff --git a/libraries/render-utils/src/LightPayload.cpp b/libraries/render-utils/src/LightPayload.cpp index e8d9e0d5bd..8f7b893f6a 100644 --- a/libraries/render-utils/src/LightPayload.cpp +++ b/libraries/render-utils/src/LightPayload.cpp @@ -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) { diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index 8c8c9406e0..357e7f46f7 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -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(); - _lightArrayBuffer->setSubData(lightId, lightSchema); + auto light = _lights._elements[lightId]; + if (light) { + auto lightSchema = light->getSchemaBuffer().get(); + _lightArrayBuffer->setSubData(lightId, lightSchema); + } else { + // this should not happen ? + } } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index c959743b57..d8f3b325f1 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -192,7 +192,9 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer)); addJob("DebugDeferredBuffer", debugFramebuffers); - addJob("DebugScattering", deferredLightingInputs); + const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, + surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).hasVarying(); + addJob("DebugScattering", debugSubsurfaceScatteringInputs); const auto debugAmbientOcclusionInputs = DebugAmbientOcclusion::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget, ambientOcclusionUniforms).hasVarying(); addJob("DebugAmbientOcclusion", debugAmbientOcclusionInputs); diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slf b/libraries/render-utils/src/lightClusters_drawClusterContent.slf new file mode 100644 index 0000000000..b31479554f --- /dev/null +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slf @@ -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; +} diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slv b/libraries/render-utils/src/lightClusters_drawClusterContent.slv new file mode 100644 index 0000000000..1e4246da1c --- /dev/null +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slv @@ -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); +} \ No newline at end of file