Fixing the vizualisation shader for world to cluster space

This commit is contained in:
samcake 2016-09-10 10:14:31 -07:00
parent 108910052a
commit a0d09e3316
8 changed files with 162 additions and 132 deletions

View file

@ -705,7 +705,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
static int frame = 0;
frame++;
if (frame % 2000 == 0) {
if (frame % 1000 == 0) {
lightClusters->updateFrustum(viewFrustum);
lightClusters->updateVisibleLights(lightIndices);

View file

@ -1,91 +1,98 @@
// glsl / C++ compatible source as interface for FrustrumGrid
// glsl / C++ compatible source as interface for FrustrumGrid
int frustumGrid_numClusters() {
return frustumGrid.dims.x * frustumGrid.dims.y * frustumGrid.dims.z;
int frustumGrid_numClusters() {
return frustumGrid.dims.x * frustumGrid.dims.y * frustumGrid.dims.z;
}
float frustumGrid_depthRamp(float linear) {
// return linear;
return linear * linear;
}
float frustumGrid_depthRampInverse(float volume) {
// return volume;
return sqrt(volume);
}
vec3 frustumGrid_gridToVolume(vec3 pos, ivec3 dims) {
vec3 gridScale = vec3(1.0, 1.0, 1.0) / vec3(dims);
vec3 volumePos = pos * gridScale;
volumePos.z = frustumGrid_depthRamp(volumePos.z);
return volumePos;
}
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);
vec4 clipPos = vec4(ndcPos.x * depth, ndcPos.y * depth, 1.0, depth);
return clipPos;
}
vec3 frustumGrid_clipToEye(vec4 clipPos, mat4 projection) {
return vec3(
(clipPos.x + projection[2][0] * clipPos.w) / projection[0][0],
(clipPos.y + projection[2][1] * clipPos.w) / projection[1][1],
-clipPos.w
//, (clipPos.z - projection[3][3] * clipPos.w) / projection[3][2]
);
}
vec3 frustumGrid_volumeToEye(vec3 vpos, mat4 projection, float rangeNear, float rangeFar) {
return frustumGrid_clipToEye(frustumGrid_volumeToClip(vpos, rangeNear, rangeFar), projection);
}
vec3 frustumGrid_eyeToVolume(vec3 epos, mat4 projection, float rangeNear, float rangeFar) {
vec4 clipPos = vec4(epos.x * projection[0][0] + epos.z * projection[2][0],
epos.y * projection[1][1] + epos.z * projection[2][1],
epos.z * projection[2][2] + projection[2][3],
-epos.z);
vec4 ndcPos = clipPos / clipPos.w;
vec3 volumePos = vec3(0.5 * (ndcPos.x + 1.0), 0.5 * (ndcPos.y + 1.0), (clipPos.w - rangeNear) / (rangeFar - rangeNear));
return volumePos;
}
vec3 frustumGrid_clusterPosToEye(ivec3 clusterPos, vec3 offset) {
vec3 cvpos = vec3(clusterPos) + offset;
vec3 volumePos = frustumGrid_gridToVolume(cvpos, frustumGrid.dims);
vec3 eyePos = frustumGrid_volumeToEye(volumePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar);
return eyePos;
}
ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) {
if ((eyePos.z > -frustumGrid.frustumNear) || (eyePos.z < -frustumGrid.frustumFar)) {
return ivec3(-1);
}
vec3 volumePos = frustumGrid_eyeToVolume(eyePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar);
vec3 gridPos = frustumGrid_volumeToGrid(volumePos, frustumGrid.dims);
float frustumGrid_depthRamp(float linear) {
// return linear;
return linear * linear;
}
float frustumGrid_depthRampInverse(float volume) {
// return volume;
return sqrt(volume);
}
return ivec3(gridPos);
}
vec3 frustumGrid_gridToVolume(vec3 pos, ivec3 dims) {
vec3 gridScale = vec3(1.0, 1.0, 1.0) / vec3(dims);
vec3 volumePos = pos * gridScale;
volumePos.z = frustumGrid_depthRamp(volumePos.z);
return volumePos;
}
vec4 frustumGrid_eyeToWorld(vec4 eyePos) {
return frustumGrid.eyeToWorldMat * eyePos;
}
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);
vec4 clipPos = vec4(ndcPos.x * depth, ndcPos.y * depth, 1.0, depth);
return clipPos;
}
vec3 frustumGrid_clipToEye(vec4 clipPos, mat4 projection) {
return vec3(
(clipPos.x + projection[2][0] * clipPos.w) / projection[0][0],
(clipPos.y + projection[2][1] * clipPos.w) / projection[1][1],
-clipPos.w
//, (clipPos.z - projection[3][3] * clipPos.w) / projection[3][2]
);
}
vec3 frustumGrid_volumeToEye(vec3 vpos, mat4 projection, float rangeNear, float rangeFar) {
return frustumGrid_clipToEye(frustumGrid_volumeToClip(vpos, rangeNear, rangeFar), projection);
}
vec3 frustumGrid_eyeToVolume(vec3 epos, mat4 projection, float rangeNear, float rangeFar) {
vec4 clipPos = vec4(epos.x * projection[0][0] + epos.z * projection[2][0],
epos.y * projection[1][1] + epos.z * projection[2][1],
epos.z * projection[2][2] + projection[2][3],
-epos.z);
vec4 ndcPos = clipPos / clipPos.w;
vec3 volumePos = vec3(0.5 * (ndcPos.x + 1.0), 0.5 * (ndcPos.y + 1.0), (clipPos.w - rangeNear) / (rangeFar - rangeNear));
return volumePos;
}
vec3 frustumGrid_clusterPosToEye(ivec3 clusterPos, vec3 offset = vec3(0.5)) {
vec3 cvpos = vec3(clusterPos) + offset;
vec3 volumePos = frustumGrid_gridToVolume(cvpos, frustumGrid.dims);
vec3 eyePos = frustumGrid_volumeToEye(volumePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar);
return eyePos;
}
ivec3 frustumGrid_eyeToClusterPos(vec3 eyePos) {
vec3 volumePos = frustumGrid_eyeToVolume(eyePos, frustumGrid.eyeToGridProj, frustumGrid.rangeNear, frustumGrid.rangeFar);
vec3 gridPos = frustumGrid_volumeToGrid(volumePos, frustumGrid.dims);
return ivec3(gridPos);
}
vec4 frustumGrid_eyeToWorld(vec4 eyePos) {
return frustumGrid.eyeToWorldMat * eyePos;
}
vec4 frustumGrid_worldToEye(vec4 worldPos) {
return frustumGrid.worldToEyeMat * worldPos;
}
// <@if 1@>
// Trigger Scribe include

View file

@ -22,7 +22,7 @@
#include "lightClusters_drawClusterFromDepth_frag.h"
enum LightClusterGridShader_MapSlot {
DEFERRED_BUFFER_LINEAR_DEPTH_UNIT = 7,
DEFERRED_BUFFER_LINEAR_DEPTH_UNIT = 0,
};
enum LightClusterGridShader_BufferSlot {
@ -126,7 +126,7 @@ void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, co
auto deferredTransform = inputs.get0();
auto deferredFramebuffer = inputs.get1();
auto lightingModel = inputs.get2();
auto surfaceGeometryFramebuffer = inputs.get3();
auto linearDepthTarget = inputs.get3();
auto args = renderContext->args;
@ -149,21 +149,14 @@ void DebugLightClusters::run(const render::SceneContextPointer& sceneContext, co
if (true) {
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawClusterGridPipeline());
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 (true) {
batch.setPipeline(getDrawClusterFromDepthPipeline());
batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, deferredTransform->getFrameTransformBuffer());
if (surfaceGeometryFramebuffer) {
batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, surfaceGeometryFramebuffer->getLinearDepthTexture());
if (linearDepthTarget) {
batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, linearDepthTarget->getLinearDepthTexture());
}
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
@ -173,7 +166,14 @@ 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) {
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawClusterGridPipeline());
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);
}
args->_context->appendFrameBatch(batch);
}

View file

@ -19,25 +19,28 @@
class FrustumGrid {
public:
float _near { 0.1f };
float frustumNear { 0.1f };
float rangeNear { 1.0f };
float rangeFar { 100.0f };
float _far { 10000.0f };
float frustumFar { 10000.0f };
glm::ivec3 dims { 8, 8, 8 };
float spare;
glm::mat4 eyeToGridProj;
glm::mat4 _worldToEyeMat;
glm::mat4 worldToEyeMat;
glm::mat4 eyeToWorldMat;
void updateFrustum(const ViewFrustum& frustum) {
frustumNear = frustum.getNearClip();
frustumFar = frustum.getFarClip();
eyeToGridProj = frustum.evalProjectionMatrixRange(rangeNear, rangeFar);
Transform view;
frustum.evalViewTransform(view);
eyeToWorldMat = view.getMatrix();
_worldToEyeMat = view.getInverseMatrix();
worldToEyeMat = view.getInverseMatrix();
}
// Copy paste of the slh functions
@ -105,7 +108,7 @@ protected:
class DebugLightClusters {
public:
using Inputs = render::VaryingSet4 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer>;
using Inputs = render::VaryingSet4 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, LinearDepthFramebufferPointer>;
using Config = DebugLightClustersConfig;
using JobModel = render::Job::ModelI<DebugLightClusters, Inputs, Config>;

View file

@ -154,7 +154,13 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
// 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);
@ -190,11 +196,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
addJob<DrawItemSelection>("DrawItemSelection", spatialSelection);
}
// LIght Cluster Grid Debuging job
{
const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget).hasVarying();
addJob<DebugLightClusters>("DebugLightClusters", debugLightClustersInputs);
}
// Status icon rendering job
{

View file

@ -21,7 +21,7 @@
<$declareColorWheel()$>
in vec4 varTexCoord0;
in vec2 varTexCoord0;
out vec4 _fragColor;
void main(void) {
@ -30,32 +30,50 @@ void main(void) {
vec2 texCoord = varTexCoord0.st;
float Zeye = texture(linearZeyeMap, texCoord).x;
_fragColor = vec4(vec3(0.1 * (10 - Zeye)), 1.0);
// return;
if (Zeye <= 0.1) {
return;
}
// _fragColor = vec4(colorWheel(fract(0.1 * Zeye)),.5);
// return;
vec4 fragPosition = unpackDeferredPositionFromZeye(texCoord);
// return;
ivec3 dims = frustumGrid.dims.xyz;
ivec3 summedDims = ivec3(dims.x * dims.y, dims.x, 1);
vec3 eyePos = fragPosition.xyz;
// Frag pos in world
vec4 fragWorldPos = getViewInverse() * fragPosition;
// 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 clusterPos = frustumGrid_eyeToClusterPos(eyePos);
// standard transform
// TransformCamera cam = getTransformCamera();
// <$transformWorldToClipPos(cam, worldPos, gl_Position)$>
_fragColor = vec4(colorWheel(fract(float(clusterPos.z * summedDims.x + clusterPos.y * summedDims.y + clusterPos.x) / float(frustumGrid_numClusters()))), 0.9);
_fragColor = vec4(abs(fract(eyePos * 0.5)), 0.9);
ivec3 dims = frustumGrid.dims.xyz;
ivec3 summedDims = ivec3(dims.x * dims.y, dims.x, 1);
if (clusterPos.x < 0 || clusterPos.x >= dims.x) {
_fragColor = vec4(0.0);
return;
}
if (clusterPos.y < 0 || clusterPos.y >= dims.y) {
_fragColor = vec4(0.0);
return;
}
if (clusterPos.z < 0 || clusterPos.z >= dims.z) {
_fragColor = vec4(0.0);
return;
}
float relClusterId = float(clusterPos.z * summedDims.x + clusterPos.y * summedDims.y + clusterPos.x) / float(frustumGrid_numClusters());
if (relClusterId < 0.0) {
_fragColor = vec4(0.0);
} else if (relClusterId >= 1.0) {
_fragColor = vec4(vec3(1.0), 0.5);
} else {
_fragColor = vec4(colorWheel(fract(relClusterId)), 0.9);
}
}

View file

@ -30,7 +30,7 @@ uniform lightIndexBuffer {
<@include LightSpot.slh@>
<$declareLightingSpot(supportScattering)$>
in vec4 _texCoord0;
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {

View file

@ -117,10 +117,10 @@ namespace indexed_container {
Index newElement(const ElementPtr& e) {
Index index = _allocator.allocateIndex();
if (index != INVALID_INDEX) {
if (index < _elements.size()) {
if (index < (Index) _elements.size()) {
_elements.emplace(_elements.begin() + index, e);
} else {
assert(index == _elements.size());
assert(index == (Index) _elements.size());
_elements.emplace_back(e);
}
}