INtroducing a true stage for updating the light cluster and ui to debug

This commit is contained in:
samcake 2016-09-11 00:17:34 -07:00
parent 3bcea4310d
commit 7a7a60a5c4
11 changed files with 292 additions and 89 deletions

View file

@ -634,7 +634,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
}
RenderDeferredLocals::RenderDeferredLocals() :
_localLightsBuffer(std::make_shared<gpu::Buffer>()) {
_localLightsBuffer(std::make_shared<gpu::Buffer>()) {
}
@ -642,7 +642,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
const DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer) {
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const LightClustersPointer& lightClusters) {
bool points = lightingModel->isPointLightEnabled();
bool spots = lightingModel->isSpotLightEnabled();
@ -676,18 +676,17 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), viewport);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewTransform, true);
// batch.setProjectionTransform(projMat);
// batch.setViewTransform(viewTransform, true);
// gather lights
auto& srcPointLights = deferredLightingEffect->_pointLights;
/* auto& srcPointLights = deferredLightingEffect->_pointLights;
auto& srcSpotLights = deferredLightingEffect->_spotLights;
int numPointLights = (int) srcPointLights.size();
int offsetPointLights = 0;
int numSpotLights = (int) srcSpotLights.size();
int offsetSpotLights = numPointLights;
auto lightClusters = deferredLightingEffect->_lightClusters;
std::vector<int> lightIndices(numPointLights + numSpotLights + 1);
lightIndices[0] = 0;
@ -699,28 +698,21 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
if (spots && !srcSpotLights.empty()) {
memcpy(lightIndices.data() + (lightIndices[0] + 1), srcSpotLights.data(), srcSpotLights.size() * sizeof(int));
lightIndices[0] += (int)srcSpotLights.size();
}
if (lightIndices[0] > 0) {
static int frame = 0;
frame++;
if (frame % 1000 == 0) {
lightClusters->updateFrustum(viewFrustum);
lightClusters->updateVisibleLights(lightIndices);
}
_localLightsBuffer._buffer->setData(lightIndices.size() * sizeof(int), (const gpu::Byte*) lightIndices.data());
_localLightsBuffer._size = lightIndices.size() * sizeof(int);
}*/
//auto lightClusters = deferredLightingEffect->_lightClusters;
auto& lightIndices = lightClusters->_visibleLightIndices;
if (!lightIndices.empty() && lightIndices[0] > 0) {
// _localLightsBuffer._buffer->setData(lightIndices.size() * sizeof(int), (const gpu::Byte*) lightIndices.data());
// _localLightsBuffer._size = lightIndices.size() * sizeof(int);
// Bind the global list of lights and the visible lights this frame
batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightBufferUnit, deferredLightingEffect->getLightStage()->_lightArrayBuffer);
batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightIndexBufferUnit, _localLightsBuffer);
batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightBufferUnit, lightClusters->_lightStage->_lightArrayBuffer);
batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightIndexBufferUnit, lightClusters->_lightIndicesBuffer);
// before we get to the real lighting, let s try to cull down the number of pixels
if (false) {
if (false) {/*
if (numPointLights > 0) {
auto mesh = deferredLightingEffect->getPointLightMesh();
batch.setIndexBuffer(mesh->getIndexBuffer());
@ -753,7 +745,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
batch.setPipeline(deferredLightingEffect->_spotLightFront);
batch.drawIndexedInstanced(numSpotLights, model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex, offsetSpotLights);
}
}*/
}
// Local light pipeline
@ -815,6 +807,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
auto surfaceGeometryFramebuffer = inputs.get3();
auto ssaoFramebuffer = inputs.get4();
auto subsurfaceScatteringResource = inputs.get5();
auto lightClusters = inputs.get6();
auto args = renderContext->args;
if (!_gpuTimer) {
@ -828,7 +821,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource);
lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer);
lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters);
cleanupJob.run(sceneContext, renderContext);

View file

@ -117,7 +117,7 @@ private:
std::vector<int> _pointLights;
std::vector<int> _spotLights;
friend class LightClusteringPass;
friend class RenderDeferredSetup;
friend class RenderDeferredLocals;
friend class RenderDeferredCleanup;
@ -167,7 +167,8 @@ public:
const DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer);
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const LightClustersPointer& lightClusters);
gpu::BufferView _localLightsBuffer;
@ -187,7 +188,7 @@ using RenderDeferredConfig = render::GPUJobConfig;
class RenderDeferred {
public:
using Inputs = render::VaryingSet6 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer>;
using Inputs = render::VaryingSet7 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer>;
using Config = RenderDeferredConfig;
using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>;

View file

@ -1,10 +1,5 @@
// glsl / C++ compatible source as interface for FrustrumGrid
int frustumGrid_numClusters() {
return frustumGrid.dims.x * frustumGrid.dims.y * frustumGrid.dims.z;
}
float frustumGrid_depthRamp(float linear) {
// return linear;
return linear * linear;
@ -60,6 +55,11 @@ vec3 frustumGrid_eyeToVolume(vec3 epos, mat4 projection, float rangeNear, float
}
int frustumGrid_numClusters() {
return frustumGrid.dims.x * frustumGrid.dims.y * (frustumGrid.dims.z);
}
vec3 frustumGrid_clusterPosToEye(ivec3 clusterPos, vec3 offset) {
vec3 cvpos = vec3(clusterPos) + offset;
@ -78,9 +78,17 @@ ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) {
return ivec3(-1);
}
if (eyePos.z > -frustumGrid.rangeNear) {
return ivec3(0,0,-1);
}
vec3 volumePos = frustumGrid_eyeToVolume(eyePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar);
vec3 gridPos = frustumGrid_volumeToGrid(volumePos, frustumGrid.dims);
if (gridPos.z >= frustumGrid.dims.z) {
gridPos.z = frustumGrid.dims.z;
}
return ivec3(gridPos);

View file

@ -35,7 +35,8 @@ enum LightClusterGridShader_BufferSlot {
#include "DeferredLightingEffect.h"
LightClusters::LightClusters() {
LightClusters::LightClusters() :
_lightIndicesBuffer(std::make_shared<gpu::Buffer>()) {
}
void LightClusters::updateFrustum(const ViewFrustum& frustum) {
@ -49,12 +50,77 @@ void LightClusters::updateLightStage(const LightStagePointer& lightStage) {
}
void LightClusters::updateVisibleLights(const LightStage::LightIndices& visibleLights) {
_visibleLightIndices.clear();
// _lightClusters->_visibleLightIndices.push_back(0);
_visibleLightIndices = visibleLights;
_lightIndicesBuffer._buffer->setData(_visibleLightIndices.size() * sizeof(int), (const gpu::Byte*) _visibleLightIndices.data());
_lightIndicesBuffer._size = _visibleLightIndices.size() * sizeof(int);
}
LightClusteringPass::LightClusteringPass() {
}
void LightClusteringPass::configure(const Config& config) {
if (_lightClusters) {
if (_lightClusters->_frustumGridBuffer->rangeNear != config.rangeNear) {
_lightClusters->_frustumGridBuffer.edit().rangeNear = config.rangeNear;
}
if (_lightClusters->_frustumGridBuffer->rangeFar != config.rangeFar) {
_lightClusters->_frustumGridBuffer.edit().rangeFar = config.rangeFar;
}
}
_freeze = config.freeze;
}
void LightClusteringPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) {
auto args = renderContext->args;
auto deferredTransform = inputs.get0();
auto lightingModel = inputs.get1();
auto surfaceGeometryFramebuffer = inputs.get2();
bool points = lightingModel->isPointLightEnabled();
bool spots = lightingModel->isSpotLightEnabled();
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
if (!_lightClusters) {
_lightClusters = deferredLightingEffect->getLightClusters();
}
// first update the Grid with the new frustum
if (!_freeze) {
_lightClusters->updateFrustum(args->getViewFrustum());
}
// Now gather the lights
// gather lights
auto& srcPointLights = deferredLightingEffect->_pointLights;
auto& srcSpotLights = deferredLightingEffect->_spotLights;
int numPointLights = (int) srcPointLights.size();
int offsetPointLights = 0;
int numSpotLights = (int) srcSpotLights.size();
int offsetSpotLights = numPointLights;
std::vector<int> lightIndices(numPointLights + numSpotLights + 1);
lightIndices[0] = 0;
if (points && !srcPointLights.empty()) {
memcpy(lightIndices.data() + (lightIndices[0] + 1), srcPointLights.data(), srcPointLights.size() * sizeof(int));
lightIndices[0] += (int)srcPointLights.size();
}
if (spots && !srcSpotLights.empty()) {
memcpy(lightIndices.data() + (lightIndices[0] + 1), srcSpotLights.data(), srcSpotLights.size() * sizeof(int));
lightIndices[0] += (int)srcSpotLights.size();
}
_lightClusters->updateVisibleLights(lightIndices);
output = _lightClusters;
}
DebugLightClusters::DebugLightClusters() {
@ -62,6 +128,9 @@ DebugLightClusters::DebugLightClusters() {
void DebugLightClusters::configure(const Config& config) {
doDrawGrid = config.doDrawGrid;
doDrawClusterFromDepth = config.doDrawClusterFromDepth;
}
const gpu::PipelinePointer DebugLightClusters::getDrawClusterGridPipeline() {
@ -119,15 +188,12 @@ const gpu::PipelinePointer DebugLightClusters::getDrawClusterFromDepthPipeline()
}
void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs) {
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
auto lightClusters = deferredLightingEffect->getLightClusters();
auto deferredTransform = inputs.get0();
auto deferredFramebuffer = inputs.get1();
auto lightingModel = inputs.get2();
auto linearDepthTarget = inputs.get3();
auto lightClusters = inputs.get4();
auto args = renderContext->args;
gpu::Batch batch;
@ -148,10 +214,7 @@ void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, co
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, lightClusters->_frustumGridBuffer);
if (true) {
if (doDrawClusterFromDepth) {
batch.setPipeline(getDrawClusterFromDepthPipeline());
batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, deferredTransform->getFrameTransformBuffer());
@ -166,7 +229,8 @@ 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 (true) {
if (doDrawGrid) {
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawClusterGridPipeline());

View file

@ -72,43 +72,84 @@ public:
gpu::StructBuffer<FrustumGrid> _frustumGridBuffer;
gpu::BufferPointer _lightIndicesBuffer;
LightStage::LightIndices _visibleLightIndices;
gpu::BufferView _lightIndicesBuffer;
};
using LightClustersPointer = std::shared_ptr<LightClusters>;
class DebugLightClustersConfig : public render::Job::Config {
class LightClusteringPassConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
Q_PROPERTY(float rangeNear MEMBER rangeNear NOTIFY dirty)
Q_PROPERTY(float rangeFar MEMBER rangeFar NOTIFY dirty)
Q_PROPERTY(bool freeze MEMBER freeze NOTIFY dirty)
public:
DebugLightClustersConfig() : render::Job::Config(true){}
int getNumDrawn() { return numDrawn; }
void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
int maxDrawn { -1 };
LightClusteringPassConfig() : render::Job::Config(true){}
float rangeNear{ 1.0f };
float rangeFar{ 512.0f };
bool freeze{ false };
signals:
void numDrawnChanged();
void dirty();
protected:
int numDrawn { 0 };
};
#include "DeferredFrameTransform.h"
#include "DeferredFramebuffer.h"
#include "LightingModel.h"
#include "SurfaceGeometryPass.h"
class LightClusteringPass {
public:
using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, LightingModelPointer, LinearDepthFramebufferPointer>;
using Outputs = LightClustersPointer;
using Config = LightClusteringPassConfig;
using JobModel = render::Job::ModelIO<LightClusteringPass, Inputs, Outputs, Config>;
LightClusteringPass();
void configure(const Config& config);
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output);
protected:
LightClustersPointer _lightClusters;
bool _freeze;
};
class DebugLightClustersConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(bool doDrawGrid MEMBER doDrawGrid NOTIFY dirty)
Q_PROPERTY(bool doDrawClusterFromDepth MEMBER doDrawClusterFromDepth NOTIFY dirty)
public:
DebugLightClustersConfig() : render::Job::Config(true){}
bool doDrawGrid{ false };
bool doDrawClusterFromDepth{ false };
signals:
void dirty();
protected:
};
#include "DeferredFramebuffer.h"
class DebugLightClusters {
public:
using Inputs = render::VaryingSet4 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, LinearDepthFramebufferPointer>;
using Inputs = render::VaryingSet5 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, LinearDepthFramebufferPointer, LightClustersPointer>;
using Config = DebugLightClustersConfig;
using JobModel = render::Job::ModelI<DebugLightClusters, Inputs, Config>;
@ -124,6 +165,8 @@ protected:
gpu::PipelinePointer _drawClusterFromDepth;
const gpu::PipelinePointer getDrawClusterGridPipeline();
const gpu::PipelinePointer getDrawClusterFromDepthPipeline();
bool doDrawGrid{ false };
bool doDrawClusterFromDepth{ false };
};
#endif

View file

@ -142,29 +142,37 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
const auto ambientOcclusionFramebuffer = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(0);
const auto ambientOcclusionUniforms = ambientOcclusionOutputs.getN<AmbientOcclusionEffect::Outputs>(1);
// Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now.
addJob<DrawLight>("DrawLight", lights);
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).hasVarying();
// Light Clustering
// Create the cluster grid of lights, cpu job for now
const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).hasVarying();
const auto lightClusters = addJob<LightClusteringPass>("LightClustering", lightClusteringPassInputs);
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).hasVarying();
addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);
// Use Stencil and draw background in Lighting buffer to complete filling in the opaque
const auto backgroundInputs = DrawBackgroundDeferred::Inputs(background, lightingModel).hasVarying();
addJob<DrawBackgroundDeferred>("DrawBackgroundDeferred", backgroundInputs);
// LIght Cluster Grid Debuging job
{
const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget).hasVarying();
addJob<DebugLightClusters>("DebugLightClusters", debugLightClustersInputs);
}
// Render transparent objects forward in LightingBuffer
const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).hasVarying();
addJob<DrawDeferred>("DrawTransparentDeferred", transparentsInputs, shapePlumber);
// LIght Cluster Grid Debuging job
{
const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget, lightClusters).hasVarying();
addJob<DebugLightClusters>("DebugLightClusters", debugLightClustersInputs);
}
const auto toneAndPostRangeTimer = addJob<BeginGPURangeTimer>("BeginToneAndPostRangeTimer", "PostToneOverlaysAntialiasing");
// Lighting Buffer ready for tone mapping
@ -196,8 +204,6 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
addJob<DrawItemSelection>("DrawItemSelection", spatialSelection);
}
// Status icon rendering job
{
// Grab a texture map representing the different status icons and assign that to the drawStatsuJob

View file

@ -29,27 +29,15 @@ void main(void) {
// Grab the fragment data from the uv
vec2 texCoord = varTexCoord0.st;
float Zeye = texture(linearZeyeMap, texCoord).x;
if (Zeye <= 0.1) {
return;
}
// _fragColor = vec4(colorWheel(fract(0.1 * Zeye)),.5);
// return;
vec4 fragPosition = unpackDeferredPositionFromZeye(texCoord);
// Frag pos in world
vec4 fragWorldPos = getViewInverse() * fragPosition;
vec4 fragEyePos = unpackDeferredPositionFromZeye(texCoord);
vec4 fragWorldPos = getViewInverse() * fragEyePos;
// From frag world pos find the cluster
//vec3 fragEyePos = fragPosition.xyz;
// vec4 worldPos = frustumGrid_eyeToWorld(vec4(eyePos.xyz, 1.0));
vec4 clusterEyePos = frustumGrid_worldToEye(fragWorldPos);
ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz);
ivec3 dims = frustumGrid.dims.xyz;
dims.z +=1;
ivec3 summedDims = ivec3(dims.x * dims.y, dims.x, 1);
if (clusterPos.x < 0 || clusterPos.x >= dims.x) {
@ -61,7 +49,7 @@ void main(void) {
_fragColor = vec4(0.0);
return;
}
if (clusterPos.z < 0 || clusterPos.z >= dims.z) {
if (clusterPos.z < 0 || clusterPos.z > dims.z) {
_fragColor = vec4(0.0);
return;
}

View file

@ -19,9 +19,9 @@
// Everything about light
<@include model/Light.slh@>
<$declareLightBuffer(32)$>
<$declareLightBuffer(128)$>
uniform lightIndexBuffer {
int lightIndex[32];
int lightIndex[128];
};
<@include LightingModel.slh@>

View file

@ -254,6 +254,40 @@ public:
Varying hasVarying() const { return Varying((*this)); }
};
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
class VaryingSet7 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying>{
public:
using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying>;
VaryingSet7() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6())) {}
VaryingSet7(const VaryingSet7& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src)) {}
VaryingSet7(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh) : Parent(first, second, third, fourth, fifth, sixth, seventh) {}
const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
Varying hasVarying() const { return Varying((*this)); }
};
template < class T, int NUM >
class VaryingArray : public std::array<Varying, NUM> {
public:

View file

@ -0,0 +1,21 @@
//
// lightClustering.js
// examples/utilities/tools/render
//
// Sam Gateau, created on 9/9/2016.
// Copyright 2016 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
//
// Set up the qml ui
var qml = Script.resolvePath('lightClustering.qml');
var window = new OverlayWindow({
title: 'Light Clustering',
source: qml,
width: 400,
height: 200
});
window.setPosition(Window.innerWidth - 420, 50 + 250 + 50);
window.closed.connect(function() { Script.stop(); });

View file

@ -0,0 +1,45 @@
//
// lightClustering.qml
//
// Created by Sam Gateau on 9/9/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import "configSlider"
Column {
spacing: 8
Column {
id: lightClustering
spacing: 10
Column{
ConfigSlider {
label: qsTr("Range Near [m]")
integral: false
config: Render.getConfig("LightClustering")
property: "rangeNear"
max: 20.0
min: 0.1
}
ConfigSlider {
label: qsTr("Range Far [m]")
integral: false
config: Render.getConfig("LightClustering")
property: "rangeFar"
max: 500.0
min: 100.0
}
CheckBox {
text: "Freeze"
checked: Render.getConfig("LightClustering")["freeze"]
onCheckedChanged: { Render.getConfig("LightClustering")["freeze"] = checked }
}
}
}
}