Skip to content
Draft
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
2 changes: 2 additions & 0 deletions Components/RTShaderSystem/include/OgreShaderParameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,8 @@ class _OgreRTSSExport ParameterFactory
static ParameterPtr createConstParam(const Vector4& val);
static ParameterPtr createConstParam(float val);

static ParameterPtr createSharedParam(const GpuSharedParametersPtr& parent, const String& name);

static UniformParameterPtr createSampler(GpuConstantType type, int index);
static UniformParameterPtr createSampler1D(int index);
static UniformParameterPtr createSampler2D(int index);
Expand Down
5 changes: 5 additions & 0 deletions Components/RTShaderSystem/include/OgreShaderProgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ class _OgreRTSSExport Program : public RTShaderSystemAlloc
void setUseLinearColours(bool useLinear) { mUseLinearColours = useLinear; }
bool getUseLinearColours() const { return mUseLinearColours; }

void addSharedParameters(GpuSharedParametersPtr sharedParams) { mSharedParameters.push_back(sharedParams); }
const std::vector<GpuSharedParametersPtr>& getSharedParameters() const { return mSharedParameters; }

/** Class destructor */
~Program();
// Protected methods.
Expand Down Expand Up @@ -213,6 +216,8 @@ class _OgreRTSSExport Program : public RTShaderSystemAlloc
StringVector mDependencies;
/// preprocessor definitions
String mPreprocessorDefines;
/// Shared parameter sets referenced by this program
std::vector<GpuSharedParametersPtr> mSharedParameters;
// Skeletal animation calculation
bool mSkeletalAnimation;
// Whether to pass matrices as column-major.
Expand Down
2 changes: 2 additions & 0 deletions Components/RTShaderSystem/include/OgreShaderSubRenderState.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ _OgreRTSSExport extern const String SRS_TRIPLANAR_TEXTURING;
_OgreRTSSExport extern const String SRS_LAYERED_BLENDING;
/// Include skinning calculations for Skeletal Animation in the shader to move computations to the GPU
_OgreRTSSExport extern const String SRS_HARDWARE_SKINNING;
/// Enable clustered light culling and per-fragment light list generation
_OgreRTSSExport extern const String SRS_CLUSTERED_LIGHT_CULLING;

/** This class is the base interface of sub part from a shader based rendering pipeline.
* All sub parts implementations should derive from it and implement the needed methods.
Expand Down
27 changes: 27 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderCGProgramWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,30 @@ void CGProgramWriter::initializeStringMaps()
mParamSemanticMap[Parameter::SPS_LAYER] = "SV_RenderTargetArrayIndex";
}

void CGProgramWriter::writeSharedParams(std::ostream& os, const String& name, int registerIdx, const GpuSharedParametersPtr& params)
{
// In HLSL/D3D11 constant buffers are bound to register(bN).
// Only SM4+ (ps_4_0 and up) understands cbuffer/register(b#).
bool useRegister = GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0");

os << "cbuffer " << name;
if (useRegister)
os << " : register(b" << registerIdx << ")";
os << " {\n";

for (const auto& e : params->getConstantDefinitionsSorted())
{
const GpuConstantDefinition& def = e.second;

os << "\t" << mGpuConstTypeMap[def.constType] << " " << e.first;
if (def.arraySize > 1)
os << "[" << def.arraySize << "]";
os << ";\n";
}

os << "};\n";
}

//-----------------------------------------------------------------------
void CGProgramWriter::writeSourceCode(std::ostream& os, Program* program)
{
Expand All @@ -108,6 +132,9 @@ void CGProgramWriter::writeSourceCode(std::ostream& os, Program* program)
}
os << std::endl;

int sharedRegister = 1;
for (const auto& shared : program->getSharedParameters())
writeSharedParams(os, shared->getName(), sharedRegister++, shared);

Function* curFunction = program->getMain();

Expand Down
1 change: 1 addition & 0 deletions Components/RTShaderSystem/src/OgreShaderCGProgramWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class CGProgramWriter : public ProgramWriter

// Protected methods.
protected:
void writeSharedParams(std::ostream& os, const String& name, int registerIdx, const GpuSharedParametersPtr& params);

/** Initialize string maps. */
void initializeStringMaps();
Expand Down
132 changes: 132 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderClusteredLightCulling.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "OgreLogManager.h"
#include "OgreShaderPrecompiledHeaders.h"
#ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS

namespace Ogre {
namespace RTShader {

const String SRS_CLUSTERED_LIGHT_CULLING = "SGX_FroxelClustered";

//-----------------------------------------------------------------------
const String& ClusteredLightCulling::getType() const { return SRS_CLUSTERED_LIGHT_CULLING; }

//-----------------------------------------------------------------------
void ClusteredLightCulling::copyFrom(const SubRenderState& rhs)
{
const auto& rhsFroxel = static_cast<const ClusteredLightCulling&>(rhs);
mDebugVisualisation = rhsFroxel.mDebugVisualisation;
}

//-----------------------------------------------------------------------
bool ClusteredLightCulling::setParameter(const String& name, const String& value)
{
if (name == "debug")
return StringConverter::parse(value, mDebugVisualisation);

return false;
}

//-----------------------------------------------------------------------
bool ClusteredLightCulling::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass)
{
if (!srcPass->getLightingEnabled())
return false;

// must match the light count used by the lighting SRS, so the
// ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY parameter is shared instead of duplicated
mLightCount = renderState->getLightCount();

if (srcPass->getIteratePerLight())
{
mLightCount = srcPass->getLightCountPerIteration();
}

if(srcPass->getMaxSimultaneousLights() == 0)
{
mLightCount = 0;
}

return mLightCount > 0;
}

bool ClusteredLightCulling::createCpuSubPrograms(ProgramSet* programSet)
{
Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM);
Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);

psProgram->addDependency("RTSLib_Froxels");

if(mDebugVisualisation)
psProgram->addPreprocessorDefines("DEBUG_FROXELS");

Function* vsMain = vsProgram->getEntryPointFunction();
Function* psMain = psProgram->getEntryPointFunction();

// make sure the shared parameter block exists before we reference it
auto aps = ShaderGenerator::getSingleton().getActiveSceneManager()->_getAutoParamDataSource();
const_cast<AutoParamDataSource*>(aps)->updateFroxelData();

auto froxelData = GpuProgramManager::getSingleton().getSharedParameters("OgreFroxels");
psProgram->addSharedParameters(froxelData);

auto froxelGrid = ParameterFactory::createSharedParam(froxelData, "froxelGrid");
auto froxelRecords = ParameterFactory::createSharedParam(froxelData, "froxelRecords");

auto tileParams = psProgram->resolveParameter(GpuProgramParameters::ACT_FROXEL_TILE_PARAMS);
auto depthParams = psProgram->resolveParameter(GpuProgramParameters::ACT_FROXEL_DEPTH_PARAMS);
auto lightPositions =
psProgram->resolveParameter(GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY, mLightCount);

// fragment position in projective space (provided by SRS_TRANSFORM)
auto vsOutPos = vsMain->getOutputParameter(Parameter::SPC_POSITION_PROJECTIVE_SPACE);
auto fragCoord = psMain->resolveInputParameter(vsOutPos);

auto lightList = psMain->resolveLocalStructParameter("FroxelLights", "lights");

// runs before the lighting stage (FFP_PS_COLOUR_BEGIN + 1)
auto stage = psMain->getStage(FFP_PS_COLOUR_BEGIN);

std::vector<Operand> args = {In(fragCoord).xyz(), In(tileParams), In(depthParams), In(lightPositions),
At(0), In(froxelGrid), Out(lightList)};
if(mDebugVisualisation)
args.push_back(InOut(psProgram->resolveParameter(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR)).xyz());
stage.callFunction("getFroxelLights", args);
return true;
}

//-----------------------------------------------------------------------
const String& ClusteredLightCullingFactory::getType() const { return SRS_CLUSTERED_LIGHT_CULLING; }

//-----------------------------------------------------------------------
SubRenderState* ClusteredLightCullingFactory::createInstance(const ScriptProperty& prop, Pass* pass,
SGScriptTranslator* translator)
{
if (prop.name != "light_clustering" || prop.values.empty())
return NULL;

if (prop.values[0] != "froxel")
return NULL;

auto ret = createOrRetrieveInstance(translator);

for (auto it = prop.values.begin() + 1; it != prop.values.end(); ++it)
{
if (!ret->setParameter(*it, "true"))
translator->emitError(*it);
}

return ret;
}

//-----------------------------------------------------------------------
void ClusteredLightCullingFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState,
Pass* srcPass, Pass* dstPass)
{
ser->writeAttribute(4, "light_clustering");
ser->writeValue("froxel");
}

}
}

#endif
71 changes: 71 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderClusteredLightCulling.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef _ShaderExFroxelClustered_
#define _ShaderExFroxelClustered_

#include "OgreShaderPrerequisites.h"
#ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS
#include "OgreShaderSubRenderState.h"
#include "OgreShaderFFPRenderState.h"
#include "OgreShaderParameter.h"

namespace Ogre {
namespace RTShader {

/** \addtogroup Optional
* @{
*/
/** \addtogroup RTShader
* @{
*/

/** Clustered (froxel) light culling.

Culls the global light list against the froxel grid and publishes the resulting
per-fragment light list as the local parameter @c lights of type @c FroxelLights.
Lighting sub render states
*/
class ClusteredLightCulling : public SubRenderState
{
public:
const String& getType() const override;
/// must run before any lighting SRS so the light list local exists
int getExecutionOrder() const override { return FFP_LIGHTING - 1; }

void copyFrom(const SubRenderState& rhs) override;
bool setParameter(const String& name, const String& value) override;
bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) override;

protected:
void updateGpuProgramsParams(Renderable*, const Pass*, const AutoParamDataSource* source,
const LightList*) override
{
const_cast<AutoParamDataSource*>(source)->updateFroxelData();
}

bool createCpuSubPrograms(ProgramSet* programSet) override;

int mLightCount = 0;
bool mDebugVisualisation = false;
};

/// A factory that enables creation of ClusteredLightCulling instances.
class ClusteredLightCullingFactory : public SubRenderStateFactory
{
public:
const String& getType() const override;
SubRenderState* createInstance(const ScriptProperty& prop, Pass* pass,
SGScriptTranslator* translator) override;
void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass,
Pass* dstPass) override;

protected:
SubRenderState* createInstanceImpl() override { return OGRE_NEW ClusteredLightCulling; }
};

/** @} */
/** @} */

}
}

#endif
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ bool CookTorranceLighting::createCpuSubPrograms(ProgramSet* programSet)
In(lightDiffuse), In(pointParams), In(lightDirView), In(spotParams),
In(pixelParams), InOut(outDiffuse).xyz()};

if(auto lights = psMain->getLocalParameter("lights"))
{
auto froxelData = GpuProgramManager::getSingleton().getSharedParameters("OgreFroxels");
auto froxelRecords = ParameterFactory::createSharedParam(froxelData, "froxelRecords");
params.insert(params.begin(), {In(lights), In(froxelRecords)});
}

if(mLtcLUT1SamplerIndex > -1)
{
auto ltcLUT1 = psProgram->resolveParameter(GCT_SAMPLER2D, "ltcLUT1Sampler", mLtcLUT1SamplerIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ bool PerPixelLighting::addFunctionInvocations(ProgramSet* programSet)

mShadowFactor = psMain->getLocalParameter("lShadowFactor");

addIlluminationInvocation(stage);
addIlluminationInvocation(stage, psMain->getLocalParameter("lights"));

// Assign back temporary variables
stage.assign(mOutDiffuse, mInDiffuse);
Expand Down
11 changes: 9 additions & 2 deletions Components/RTShaderSystem/src/OgreShaderFFPLighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ bool FFPLighting::addFunctionInvocations(ProgramSet* programSet)
addGlobalIlluminationInvocation(stage);

// Add per light functions.
addIlluminationInvocation(stage);
addIlluminationInvocation(stage, nullptr);

auto psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
auto psMain = psProgram->getMain();
Expand Down Expand Up @@ -258,7 +258,7 @@ void FFPLighting::addGlobalIlluminationInvocation(const FunctionStageRef& stage)
}

//-----------------------------------------------------------------------
void FFPLighting::addIlluminationInvocation(const FunctionStageRef& stage)
void FFPLighting::addIlluminationInvocation(const FunctionStageRef& stage, const ParameterPtr& lights)
{
if(mLightCount == 0)
return;
Expand All @@ -282,6 +282,13 @@ void FFPLighting::addIlluminationInvocation(const FunctionStageRef& stage)
args.insert(args.end(),
{In(mSpecularColours), In(mSurfaceShininess), InOut(mOutSpecular).xyz()});

if(lights)
{
auto froxelData = GpuProgramManager::getSingleton().getSharedParameters("OgreFroxels");
auto froxelRecords = ParameterFactory::createSharedParam(froxelData, "froxelRecords");
args.insert(args.end(), {In(lights), In(froxelRecords)});
}

stage.callFunction("FFP_Lights", args);
}

Expand Down
2 changes: 1 addition & 1 deletion Components/RTShaderSystem/src/OgreShaderFFPLighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class FFPLighting : public SubRenderState
/**
Internal method that adds illumination component functions invocations.
*/
void addIlluminationInvocation(const FunctionStageRef& stage);
void addIlluminationInvocation(const FunctionStageRef& stage, const ParameterPtr& lights);


// Track per vertex colour type.
Expand Down
Loading
Loading