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
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
13 changes: 13 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderExIntegratedPSSM3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void IntegratedPSSM3::updateGpuProgramsParams(Renderable* rend, const Pass* pass
const AutoParamDataSource* source,
const LightList* pLightList)
{
const_cast<AutoParamDataSource*>(source)->updateFroxelData();
if (mMultiLightCount > 1)
return;

Expand Down Expand Up @@ -274,6 +275,7 @@ bool IntegratedPSSM3::resolveDependencies(ProgramSet* programSet)
{
Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM);
psProgram->addDependency(SGX_LIB_INTEGRATEDPSSM);
psProgram->addDependency("RTSLib_Froxels");

psProgram->addPreprocessorDefines(StringUtil::format("PSSM_NUM_SPLITS=%zu,PCF_XSAMPLES=%.1f,SHADOWLIGHT_COUNT=%d",
mShadowTextureParamsList.size(), mPCFxSamples, mMultiLightCount));
Expand Down Expand Up @@ -377,6 +379,17 @@ bool IntegratedPSSM3::addPSInvocation(Program* psProgram, const int groupOrder)
stage.callFunction("SGX_ComputeShadowFactor_PSSM3", params);
}

auto aps = ShaderGenerator::getSingleton().getActiveSceneManager()->_getAutoParamDataSource();
const_cast<AutoParamDataSource*>(aps)->updateFroxelData();
auto froxelData = GpuProgramManager::getSingleton().getSharedParameters("OgreFroxels");
psProgram->addSharedParameters(froxelData);

auto sceneCol = psProgram->resolveParameter(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR);
auto froxelTP = psProgram->resolveParameter(GpuProgramParameters::ACT_FROXEL_TILE_PARAMS);
auto froxelDP = psProgram->resolveParameter(GpuProgramParameters::ACT_FROXEL_DEPTH_PARAMS);
auto froxelGrid = ParameterFactory::createSharedParam(froxelData, "froxelGrid");
stage.callFunction("debugFroxelOccupancy", {In(mPSInDepth).xyz(), In(froxelTP), In(froxelDP), In(froxelGrid), InOut(sceneCol)});

// shadow factor is applied by lighting stages
return true;
}
Expand Down
31 changes: 31 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderGLSLProgramWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,33 @@ void GLSLProgramWriter::writeUniformBlock(std::ostream& os, const String& name,
os << "};\n";
}

void GLSLProgramWriter::writeUniformBlock(std::ostream& os, const String& name, int binding,
const GpuSharedParametersPtr& params)
{
// Explicit binding needs GLSL 420 / SPIR-V; otherwise the RS assigns it by block name.
bool explicitBinding = mIsVulkan || mGLSLVersion >= 420;

os << "layout(";
if (explicitBinding)
os << "binding = " << binding << ", ";
os << "std140, row_major) uniform " << name << " {\n";

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

if (def.constType == GCT_MATRIX_3X4 || def.constType == GCT_MATRIX_2X4)
os << "layout(column_major) ";

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

os << "};\n";
}

void GLSLProgramWriter::writeMainSourceCode(std::ostream& os, Program* program)
{
GpuProgramType gpuType = program->getType();
Expand Down Expand Up @@ -188,6 +215,10 @@ void GLSLProgramWriter::writeMainSourceCode(std::ostream& os, Program* program)
uniforms.clear();
}

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

int uniformLoc = 0;
for (const auto& uparam : uniforms)
{
Expand Down
2 changes: 2 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderGLSLProgramWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class GLSLProgramWriter : public ProgramWriter

void writeUniformBlock(std::ostream& os, const String& name, int binding, const UniformParameterList& uniforms);

void writeUniformBlock(std::ostream& os, const String& name, int binding, const GpuSharedParametersPtr& params);

protected:
typedef std::map<Parameter::Semantic, const char*> ParamSemanticToStringMap;

Expand Down
6 changes: 6 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderParameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,12 @@ ParameterPtr ParameterFactory::createConstParam(float val)
Parameter::SPC_UNKNOWN));
}

ParameterPtr ParameterFactory::createSharedParam(const GpuSharedParametersPtr& parent, const String& name)
{
auto p = parent->getConstantDefinition(name);
return std::make_shared<Parameter>(p.constType, name, Parameter::SPS_UNKNOWN, 0, p.arraySize);
}

//-----------------------------------------------------------------------
UniformParameterPtr ParameterFactory::createUniform(GpuConstantType type,
int index, uint16 variability,
Expand Down
4 changes: 4 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderProgramProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ void ProgramProcessor::bindAutoParameters(Program* pCpuProgram, GpuProgramPtr pG
{
GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters();

// Forward shared parameter sets to the concrete GpuProgramParameters,
for (const auto& sharedParams : pCpuProgram->getSharedParameters())
pGpuParams->addSharedParameters(sharedParams);

pGpuParams->setUseLinearColours(pCpuProgram->getUseLinearColours());
for (const auto& p : pCpuProgram->getParameters())
{
Expand Down
104 changes: 104 additions & 0 deletions Media/RTShaderLib/RTSLib_Froxels.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#define FROXEL_GRID_VEC4_COUNT 1024 // 4096 froxels / 4 per uvec4
#define FROXEL_RECORD_VEC4_COUNT 1024 // 16384 light indices / 16 per uvec4
#if 0
layout(std140) uniform OgreFroxels {
uvec4 froxelGrid[FROXEL_GRID_VEC4_COUNT]; // (offset << 8) | count
uvec4 froxelRecords[FROXEL_RECORD_VEC4_COUNT];
};
#endif

void debugFroxel(inout vec3 color, int index)
{
const vec3 debugColors[17] = vec3[](
vec3(0.0, 0.0, 0.0), // black
vec3(0.0, 0.0, 0.1647), // darkest blue
vec3(0.0, 0.0, 0.3647), // darker blue
vec3(0.0, 0.0, 0.6647), // dark blue
vec3(0.0, 0.0, 0.9647), // blue
vec3(0.0, 0.9255, 0.9255), // cyan
vec3(0.0, 0.5647, 0.0), // dark green
vec3(0.0, 0.7843, 0.0), // green
vec3(1.0, 1.0, 0.0), // yellow
vec3(0.90588, 0.75294, 0.0), // yellow-orange
vec3(1.0, 0.5647, 0.0), // orange
vec3(1.0, 0.0, 0.0), // bright red
vec3(0.8392, 0.0, 0.0), // red
vec3(1.0, 0.0, 1.0), // magenta
vec3(0.6, 0.3333, 0.7882), // purple
vec3(1.0, 1.0, 1.0), // white
vec3(1.0, 1.0, 1.0) // white
);
color = mix(color, debugColors[clamp(index, 0, 16)], 0.8);
}

#define DEBUG_FROXELS 1

// fragCoord = gl_FragCoord.xyz: .xy in pixels, .z = screen depth
// froxel_params = (countX, countY, countZ, tileSizePx)
// froxel_z_params = (scaleZ, biasZ, linZ, sliceCount)
uint getFroxelIndex(in vec3 fragCoord, in vec4 froxel_params, in vec4 froxel_z_params
#if DEBUG_FROXELS
, inout vec4 color
#endif
) {
uint x = min(uint(fragCoord.x / froxel_params.w), uint(froxel_params.x) - 1u);
uint y = min(uint(fragCoord.y / froxel_params.w), uint(froxel_params.y) - 1u);

#if DEBUG_FROXELS == 1
uint tile = y * uint(froxel_params.x) + x;
int idx = int(tile % 16);

debugFroxel(color.rgb, idx);
#endif

float depth = fragCoord.z;
#if OGRE_REVERSED_Z
depth = 1.0 - depth; // reversed-z is exactly 1 - standard depth for perspective
#endif

// screen depth -> reciprocal normalized view-Z (linear in depth)
float recipViewZ = froxel_z_params.x * depth + froxel_z_params.y;
recipViewZ = max(recipViewZ, 1e-6); // guard: far plane -> log2(0)
float sliceCount = froxel_z_params.w;
float sliceZ = log2(recipViewZ) * froxel_z_params.z; // linearizerNeg is negative
uint z = uint(clamp(sliceZ + sliceCount, 0.0, sliceCount - 1.0));

#if DEBUG_FROXELS == 2
debugFroxel(color.rgb, int(z));
#endif

return (z * uint(froxel_params.y) + y) * uint(froxel_params.x) + x;
}

#define FROXEL_MAX_OCCUPANCY 2
void debugFroxelOccupancy(vec3 fragCoord, in vec4 froxel_params, in vec4 froxel_z_params,in uvec4 froxelGrid[FROXEL_GRID_VEC4_COUNT], inout vec4 color)
{
vec4 dummy = vec4(0.0);
uint f = getFroxelIndex(fragCoord, froxel_params, froxel_z_params, dummy);
uint grid = froxelGrid[f >> 2][f & 3u];
uint count = grid & 0xFFu;

if (count == 0u)
return;

float t = saturate(float(count) / FROXEL_MAX_OCCUPANCY);
color = mix(color, vec4(1.0, 0.0, 0.0, 0.0), t);
}

uint getLightIndex(uint record, in uvec4 froxelRecords[FROXEL_RECORD_VEC4_COUNT]) {
uint word = froxelRecords[record >> 4][(record >> 2) & 3u]; // which uint
return (word >> ((record & 3u) * 8u)) & 0xFFu; // which byte
}

#if !DEBUG_FROXELS
void shadeClustered(vec3 fragCoord, in uvec4 froxelGrid[FROXEL_GRID_VEC4_COUNT], in uvec4 froxelRecords[FROXEL_RECORD_VEC4_COUNT], in vec4 froxel_params, in vec4 froxel_z_params) {
uint f = getFroxelIndex(fragCoord, froxel_params, froxel_z_params);
uint grid = froxelGrid[f >> 2][f & 3u];
uint offset = grid >> 8;
uint count = grid & 0xFFu;

for (uint i = 0u; i < count; ++i) {
uint lightIndex = getLightIndex(offset + i, froxelRecords);
}
}
#endif
10 changes: 10 additions & 0 deletions OgreMain/include/OgreAutoParamDataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace Ogre {

// forward decls
struct VisibleObjectsBoundsInfo;
struct Froxelizer;

/** \addtogroup Core
* @{
Expand Down Expand Up @@ -120,7 +121,10 @@ namespace Ogre {
mutable bool mSceneDepthRangeDirty;
mutable bool mLodCameraPositionDirty;
mutable bool mLodCameraPositionObjectSpaceDirty;
mutable bool mFroxelStructureDirty;

std::unique_ptr<Froxelizer> mFroxelizer;
GpuSharedParametersPtr mFroxelParams;
const Renderable* mCurrentRenderable;
const Camera* mCurrentCamera;
std::vector<const Camera*> mCameraArray;
Expand All @@ -144,6 +148,7 @@ namespace Ogre {
bool mCurrentUseIdentityProj;
public:
AutoParamDataSource();
~AutoParamDataSource();
/** Updates the current renderable */
void setCurrentRenderable(const Renderable* rend);
/** Sets the world matrices, avoid query from renderable again */
Expand Down Expand Up @@ -298,6 +303,11 @@ namespace Ogre {
uint16 getGpuParamsDirty() const { return mGpuParamsDirty; }
void resetGpuParamsDirty() { mGpuParamsDirty = 0; }
void updateLightCustomGpuParameter(const GpuProgramParameters::AutoConstantEntry& constantEntry, GpuProgramParameters *params) const;

const Vector4f& getFroxelTileParams() const;
const Vector4f& getFroxelDepthParams() const;
// Updates the froxel data in the shared parameters
void updateFroxelData();
};
/** @} */
/** @} */
Expand Down
9 changes: 9 additions & 0 deletions OgreMain/include/OgreGpuProgramParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,9 @@ namespace Ogre {
*/
const GpuNamedConstants& getConstantDefinitions() const;

/// Get the constant definitions ordered by their physical index.
std::vector<std::pair<String, GpuConstantDefinition>> getConstantDefinitionsSorted() const;

/** @copydoc GpuProgramParameters::setNamedConstant(const String&, Real) */
template <typename T> void setNamedConstant(const String& name, T val)
{
Expand Down Expand Up @@ -1143,6 +1146,12 @@ namespace Ogre {
ACT_POINT_PARAMS,
/// the LOD index as selected by the active LodStrategy
ACT_MATERIAL_LOD_INDEX,
/// Clustered (froxel) lighting grid size parameters
/// packed as `(countX, countY, yFix, tileSizePx)`
ACT_FROXEL_TILE_PARAMS,
/// Clustered (froxel) lighting depth parameters
/// packed as `(scaleZ, biasZ, linZ, sliceCount)`
ACT_FROXEL_DEPTH_PARAMS,
};

/** Defines the type of the extra data item used by the auto constant.
Expand Down
Loading
Loading