forked from OGRECave/ogre
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RTSS: implement GBuffer output SubRenderState
supporting any two of DEPTH, DEPTH_NORMAL, DIFFUSE_SPECULAR outputs
- Loading branch information
Showing
13 changed files
with
380 additions
and
553 deletions.
There are no files selected for viewing
133 changes: 133 additions & 0 deletions
133
Components/RTShaderSystem/include/OgreShaderExGBuffer.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
----------------------------------------------------------------------------- | ||
This source file is part of OGRE | ||
(Object-oriented Graphics Rendering Engine) | ||
For the latest info, see http://www.ogre3d.org | ||
Copyright (c) 2000-2014 Torus Knot Software Ltd | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
----------------------------------------------------------------------------- | ||
*/ | ||
#ifndef _ShaderGBuffer_ | ||
#define _ShaderGBuffer_ | ||
|
||
#include "OgreShaderPrerequisites.h" | ||
#ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS | ||
#include "OgreShaderParameter.h" | ||
#include "OgreShaderSubRenderState.h" | ||
|
||
namespace Ogre | ||
{ | ||
namespace RTShader | ||
{ | ||
|
||
/** \addtogroup Optional | ||
* @{ | ||
*/ | ||
/** \addtogroup RTShader | ||
* @{ | ||
*/ | ||
|
||
/** Transform sub render state implementation of writing to GBuffers | ||
*/ | ||
class _OgreRTSSExport GBuffer : public SubRenderState | ||
{ | ||
|
||
// Interface. | ||
public: | ||
enum TargetLayout | ||
{ | ||
TL_DEPTH, | ||
TL_DEPTH_NORMAL, | ||
TL_DIFFUSE_SPECULAR, | ||
}; | ||
typedef std::vector<TargetLayout> TargetBuffers; | ||
|
||
/** | ||
@see SubRenderState::getType. | ||
*/ | ||
virtual const String& getType() const; | ||
|
||
/** | ||
@see SubRenderState::getExecutionOrder. | ||
*/ | ||
virtual int getExecutionOrder() const; | ||
|
||
/** | ||
@see SubRenderState::copyFrom. | ||
*/ | ||
virtual void copyFrom(const SubRenderState& rhs); | ||
|
||
/** | ||
@see SubRenderState::createCpuSubPrograms. | ||
*/ | ||
virtual bool createCpuSubPrograms(ProgramSet* programSet); | ||
|
||
bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); | ||
|
||
void setOutBuffers(const TargetBuffers& buffers) { mOutBuffers = buffers; } | ||
|
||
static String Type; | ||
|
||
private: | ||
void addDepthInvocations(ProgramSet* programSet, const ParameterPtr& out) const; | ||
void addNormalInvocations(ProgramSet* programSet, const ParameterPtr& out) const ; | ||
void addDiffuseSpecularInvocations(ProgramSet* programSet, const ParameterPtr& out) const; | ||
|
||
TargetBuffers mOutBuffers; | ||
}; | ||
|
||
/** | ||
A factory that enables creation of GBuffer instances. | ||
@remarks Sub class of SubRenderStateFactory | ||
*/ | ||
class _OgreRTSSExport GBufferFactory : public SubRenderStateFactory | ||
{ | ||
public: | ||
/** | ||
@see SubRenderStateFactory::getType. | ||
*/ | ||
virtual const String& getType() const; | ||
|
||
/** | ||
@see SubRenderStateFactory::createInstance. | ||
*/ | ||
virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, | ||
SGScriptTranslator* translator); | ||
|
||
/** | ||
@see SubRenderStateFactory::writeInstance. | ||
*/ | ||
virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); | ||
|
||
protected: | ||
/** | ||
@see SubRenderStateFactory::createInstanceImpl. | ||
*/ | ||
virtual SubRenderState* createInstanceImpl(); | ||
}; | ||
|
||
/** @} */ | ||
/** @} */ | ||
|
||
} // namespace RTShader | ||
} // namespace Ogre | ||
|
||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
/* | ||
----------------------------------------------------------------------------- | ||
This source file is part of OGRE | ||
(Object-oriented Graphics Rendering Engine) | ||
For the latest info, see http://www.ogre3d.org | ||
Copyright (c) 2000-2014 Torus Knot Software Ltd | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
----------------------------------------------------------------------------- | ||
*/ | ||
#include "OgreShaderPrecompiledHeaders.h" | ||
#ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS | ||
|
||
namespace Ogre | ||
{ | ||
namespace RTShader | ||
{ | ||
|
||
/************************************************************************/ | ||
/* */ | ||
/************************************************************************/ | ||
String GBuffer::Type = "GBuffer"; | ||
|
||
//----------------------------------------------------------------------- | ||
const String& GBuffer::getType() const { return Type; } | ||
|
||
//----------------------------------------------------------------------- | ||
int GBuffer::getExecutionOrder() const { return FFP_LIGHTING; } | ||
|
||
bool GBuffer::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) | ||
{ | ||
srcPass->setLightingEnabled(false); // disable receiving shadows | ||
return true; | ||
} | ||
|
||
//----------------------------------------------------------------------- | ||
bool GBuffer::createCpuSubPrograms(ProgramSet* programSet) | ||
{ | ||
Function* psMain = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM)->getMain(); | ||
|
||
for(size_t i = 0; i < mOutBuffers.size(); i++) | ||
{ | ||
auto out = | ||
psMain->resolveOutputParameter(i == 0 ? Parameter::SPC_COLOR_DIFFUSE : Parameter::SPC_COLOR_SPECULAR); | ||
|
||
switch(mOutBuffers[i]) | ||
{ | ||
case TL_DEPTH_NORMAL: | ||
addNormalInvocations(programSet, out); | ||
OGRE_FALLTHROUGH; | ||
case TL_DEPTH: | ||
addDepthInvocations(programSet, out); | ||
break; | ||
case TL_DIFFUSE_SPECULAR: | ||
addDiffuseSpecularInvocations(programSet, out); | ||
break; | ||
default: | ||
OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "unsupported TargetLayout"); | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
void GBuffer::addDepthInvocations(ProgramSet* programSet, const ParameterPtr& out) const | ||
{ | ||
Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM); | ||
Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM); | ||
Function* vsMain = vsProgram->getMain(); | ||
Function* psMain = psProgram->getMain(); | ||
|
||
// vertex shader | ||
auto vsOutPos = vsMain->resolveOutputParameter(Parameter::SPC_POSITION_PROJECTIVE_SPACE); | ||
|
||
bool isD3D9 = ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl" && | ||
!GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1"); | ||
|
||
if (isD3D9) | ||
{ | ||
auto vstage = vsMain->getStage(FFP_VS_POST_PROCESS); | ||
auto vsPos = vsMain->resolveOutputParameter(Parameter::SPC_UNKNOWN, GCT_FLOAT4); | ||
vstage.assign(vsOutPos, vsPos); | ||
std::swap(vsOutPos, vsPos); | ||
} | ||
|
||
// fragment shader | ||
auto fstage = psMain->getStage(FFP_PS_COLOUR_END); | ||
auto viewPos = psMain->resolveInputParameter(vsOutPos); | ||
|
||
fstage.assign(In(viewPos).z(), Out(out).x()); | ||
|
||
if (isD3D9) | ||
{ | ||
fstage.div(In(out).x(), In(viewPos).w(), Out(out).x()); | ||
} | ||
} | ||
|
||
void GBuffer::addNormalInvocations(ProgramSet* programSet, const ParameterPtr& out) const | ||
{ | ||
Program* vsProgram = programSet->getCpuProgram(GPT_VERTEX_PROGRAM); | ||
Function* vsMain = vsProgram->getMain(); | ||
Function* psMain = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM)->getMain(); | ||
|
||
// compute vertex shader normal | ||
auto vstage = vsMain->getStage(FFP_VS_LIGHTING); | ||
auto vsInNormal = vsMain->resolveInputParameter(Parameter::SPC_NORMAL_OBJECT_SPACE); | ||
auto vsOutNormal = vsMain->resolveOutputParameter(Parameter::SPC_NORMAL_VIEW_SPACE); | ||
auto worldViewITMatrix = vsProgram->resolveParameter(GpuProgramParameters::ACT_NORMAL_MATRIX); | ||
vstage.callFunction(FFP_FUNC_TRANSFORM, worldViewITMatrix, vsInNormal, vsOutNormal); | ||
|
||
// pass through | ||
auto fstage = psMain->getStage(FFP_PS_COLOUR_END); | ||
fstage.assign(psMain->resolveInputParameter(vsOutNormal), Out(out).mask(Operand::OPM_YZW)); | ||
} | ||
|
||
void GBuffer::addDiffuseSpecularInvocations(ProgramSet* programSet, const ParameterPtr& out) const | ||
{ | ||
Program* psProgram = programSet->getCpuProgram(GPT_FRAGMENT_PROGRAM); | ||
Function* psMain = psProgram->getMain(); | ||
|
||
// set diffuse - TODO vertex color tracking | ||
auto diffuse = psProgram->resolveParameter(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR); | ||
psMain->getStage(FFP_PS_COLOUR_BEGIN + 1).assign(diffuse, out); | ||
|
||
// set shininess | ||
auto surfaceShininess = psProgram->resolveParameter(GpuProgramParameters::ACT_SURFACE_SHININESS); | ||
psMain->getStage(FFP_PS_COLOUR_END).assign(surfaceShininess, Out(out).w()); | ||
} | ||
|
||
//----------------------------------------------------------------------- | ||
void GBuffer::copyFrom(const SubRenderState& rhs) | ||
{ | ||
const GBuffer& rhsTransform = static_cast<const GBuffer&>(rhs); | ||
mOutBuffers = rhsTransform.mOutBuffers; | ||
} | ||
|
||
//----------------------------------------------------------------------- | ||
const String& GBufferFactory::getType() const { return GBuffer::Type; } | ||
|
||
static GBuffer::TargetLayout translate(const String& val) | ||
{ | ||
if(val == "depth") | ||
return GBuffer::TL_DEPTH; | ||
if(val == "depth_normal") | ||
return GBuffer::TL_DEPTH_NORMAL; | ||
return GBuffer::TL_DIFFUSE_SPECULAR; | ||
} | ||
|
||
//----------------------------------------------------------------------- | ||
SubRenderState* GBufferFactory::createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, | ||
SGScriptTranslator* translator) | ||
{ | ||
if (prop->name != "lighting_stage" || prop->values.size() < 2) | ||
return NULL; | ||
|
||
auto it = prop->values.begin(); | ||
String val; | ||
|
||
if(!SGScriptTranslator::getString(*it++, &val)) | ||
{ | ||
compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); | ||
return NULL; | ||
} | ||
|
||
if (val != "gbuffer") | ||
return NULL; | ||
|
||
GBuffer::TargetBuffers targets; | ||
|
||
if(!SGScriptTranslator::getString(*it++, &val)) | ||
{ | ||
compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); | ||
return NULL; | ||
} | ||
targets.push_back(translate(val)); | ||
|
||
if(it != prop->values.end()) | ||
{ | ||
if(!SGScriptTranslator::getString(*it++, &val)) | ||
{ | ||
compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); | ||
return NULL; | ||
} | ||
|
||
targets.push_back(translate(val)); | ||
} | ||
|
||
auto ret = static_cast<GBuffer*>(createOrRetrieveInstance(translator)); | ||
ret->setOutBuffers(targets); | ||
return ret; | ||
} | ||
|
||
//----------------------------------------------------------------------- | ||
void GBufferFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, | ||
Pass* dstPass) | ||
{ | ||
ser->writeAttribute(4, "lighting_stage"); | ||
ser->writeValue("gbuffer"); | ||
ser->writeValue("depth"); | ||
} | ||
|
||
//----------------------------------------------------------------------- | ||
SubRenderState* GBufferFactory::createInstanceImpl() { return OGRE_NEW GBuffer; } | ||
|
||
} // namespace RTShader | ||
} // namespace Ogre | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.