Re: xml based postprocessing framework
Posted: Fri Nov 02, 2012 6:28 pm
the shaders would have to be optimised but the framework is quite well done
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
is a little bit general I think....these things really have to be optimized
See, what did I say?930 fps in mode 0 (no antialiasing)
730 fps in mde 1 (fxaa aplied)
450 in mode 2 (four cascading effects with about 30 passes)
Code: Select all
void CPostProcessManager::renderDepth(const video::SColor& defaultDepth)
{
if (DepthPassNodes.size())
{
// animate and render the camera to ensure correct depth and normal information
scene::ICameraSceneNode* camera = Device->getSceneManager()->getActiveCamera();
if (camera)
{
camera->OnRegisterSceneNode();
camera->OnAnimate(Device->getTimer()->getTime());
camera->render();
DepthMaterial->setPixelShaderConstant("MaxDistance", camera->getFarValue());
}
// set depth and normal render target texture
// as multi render target
core::array<video::IRenderTarget> mrt;
mrt.push_back(video::IRenderTarget(RenderTargetMap["rttDepth"]));
mrt.push_back(video::IRenderTarget(RenderTargetMap["rttNormal"]));
Device->getVideoDriver()->setRenderTarget(mrt, true, true, defaultDepth);
// render all nodes that are stored in the depth pass array
for(u32 i=0; i<DepthPassNodes.size(); i++)
{
// get the scene node from the array
scene::ISceneNode* node = DepthPassNodes[i];
if (node->isVisible())
{
// save the scene node materials
core::array<video::E_MATERIAL_TYPE> bufferMaterialList(node->getMaterialCount());
bufferMaterialList.set_used(0);
for(u32 j=0; j<node->getMaterialCount(); j++)
bufferMaterialList.push_back(node->getMaterial(j).MaterialType);
// apply the depth material
node->setMaterialType(DepthMaterial->getMaterialType());
// animate the node
node->OnAnimate(Device->getTimer()->getTime());
// render the node
node->render();
// reset the scene node to the original material
for(u32 j=0; j<node->getMaterialCount(); j++)
node->getMaterial(j).MaterialType = bufferMaterialList[j];
}
}
}
}
Code: Select all
//Matrices
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 ProjMatrix;
struct VS_INPUT
{
float4 Pos : POSITION0;
float3 Normal : NORMAL0;
float2 Tex : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Pos : POSITION; // Vertexposition
float4 WorldPos : TEXCOORD0; // World Position
float4 WorldNormal : TEXCOORD1; // World Normal
float Depth : TEXCOORD2; // Depth
};
VS_OUTPUT main (VS_INPUT input)
{
VS_OUTPUT output;
// default positions
output.Pos = mul(mul(mul(input.Pos, WorldMatrix), ViewMatrix), ProjMatrix);
// world positions
output.WorldPos = mul(input.Pos, WorldMatrix);
// world normal
output.WorldNormal = 0.5*mul(input.Normal, WorldMatrix)+0.5;
// depth
output.Depth = output.Pos.z;
return output;
}
Code: Select all
niform float MaxDistance;
struct MRT_OUT
{
float4 rt0 : COLOR0;
float4 rt1 : COLOR1;
};
MRT_OUT main(float4 worldPos : TEXCOORD0,
float4 worldNormal : TEXCOORD1,
float depth : TEXCOORD2)
{
MRT_OUT output;
// put the worldpos, calculated in vertex shader, into rgb of the first rt
output.rt0.rgb = worldPos.xyz;
// put the depth, calculated in vertex shader, into alpha of the first rt
output.rt0.a = depth/MaxDistance;
// put normal into the second rt
output.rt1 = worldNormal;
return output;
}
Code: Select all
core::array<video::IRenderTarget> AuxBuffer[2];
// additional render target textures (defined in rtt.xml)
core::map<core::stringw, core::array<video::IRenderTarget>> RenderTargetMap;
Code: Select all
void CPostProcessManager::SwapAuxBuffers()
{
// swap the in and out buffers
core::array<video::IRenderTarget> tmp = RenderTargetMap["auxIn"];
RenderTargetMap["auxIn"] = RenderTargetMap["auxOut"];
RenderTargetMap["auxOut"] = tmp;
}
Code: Select all
void CPostProcessManager::render(E_POSTPROCESS_EFFECT effect)
{
if (effect<EPPE_COUNT)
{
// first swap the in and out buffers
SwapAuxBuffers();
// run through the effect chain
for (u32 i=0; i<EffectChain[effect].size(); i++)
{
// retrieve the post process
IPostProcess* postProcess = EffectChain[effect][i];
// bind input buffer
if( !postProcess->getRenderSource().empty())
{
core::array<video::IRenderTarget> a = RenderTargetMap[postProcess->getRenderSource()];
for (int i =0; i< a.size();i++)
{
postProcess->getMaterial().setTexture(i, a[i].RenderTexture);
}
}
// bind output buffer
if( !postProcess->getRenderTarget().empty())
Device->getVideoDriver()->setRenderTarget(RenderTargetMap[postProcess->getRenderTarget()],true,true,video::SColor(40,255,255,255));
// render the post process
postProcess->render();
}
}
}
Code: Select all
void CPostProcessManager::update()
{
// render the scene into the framebuffer after postprocessing
core::array<video::IRenderTarget> a = RenderTargetMap["auxOut"];
RenderToScreen->getMaterial().setTexture(0, a[0].RenderTexture);
Device->getVideoDriver()->setRenderTarget(video::ERT_FRAME_BUFFER, true, true);
RenderToScreen->render();
}
Code: Select all
void CPostProcessManager::loadRTTConfig()
{
// create a xml reader
io::IrrXMLReader* xmlReader = io::createIrrXMLReader("config/rtt.xml");
// we'll be looking for the rendertarget tag in the xml
const core::stringw renderTargetTag(L"RenderTarget");
while(xmlReader && xmlReader->read())
{
switch(xmlReader->getNodeType())
{
case io::EXN_ELEMENT:
{
// we are in the setup section and we find a rendertarget to parse
if (renderTargetTag.equals_ignore_case(xmlReader->getNodeName()))
{
// get the rtt parameters
core::stringw id = xmlReader->getAttributeValueSafe("id");
u32 width = (u32) xmlReader->getAttributeValueAsInt("width");
u32 height = (u32) xmlReader->getAttributeValueAsInt("height");
f32 scale = (f32) xmlReader->getAttributeValueAsFloat("scale");
video::ECOLOR_FORMAT colorFormat[4];
u32 count = (u32) xmlReader->getAttributeValueAsInt("MRT");
colorFormat[0] = (video::ECOLOR_FORMAT) xmlReader->getAttributeValueAsInt("colorFormat");
colorFormat[1] = (video::ECOLOR_FORMAT) xmlReader->getAttributeValueAsInt("colorFormat1");
colorFormat[2] = (video::ECOLOR_FORMAT) xmlReader->getAttributeValueAsInt("colorFormat2");
colorFormat[3] = (video::ECOLOR_FORMAT) xmlReader->getAttributeValueAsInt("colorFormat3");
// set width and height of the rtt
if (scale > 0.0f)
{
width = (u32) (scale * Device->getVideoDriver()->getScreenSize().Width);
height = (u32) (scale * Device->getVideoDriver()->getScreenSize().Height);
}
if (width==0 || height==0)
{
width=Device->getVideoDriver()->getScreenSize().Width;
height=Device->getVideoDriver()->getScreenSize().Height;
}
core::array<video::IRenderTarget> a;
// add the rendertarget with its properties and store it in the render target map
if (count >1)
for(u32 i=0; i<count; i++)
{
core::stringw lid = id;
lid+=i;
video::ITexture* texture = Device->getVideoDriver()->addRenderTargetTexture(core::dimension2d<u32>(width, height), lid, colorFormat[i]);
a.push_back( video::IRenderTarget(texture));
}
else
{
video::ITexture* texture = Device->getVideoDriver()->addRenderTargetTexture(core::dimension2d<u32>(width, height), id, colorFormat[0]);
a.push_back( video::IRenderTarget(texture));
}
RenderTargetMap[id] =a;
}
}
break;
}
}
delete xmlReader;
}
Code: Select all
void CPostProcessManager::RollbackRTT()
{
Device->getVideoDriver()->setRenderTarget(RenderTargetMap["auxOut"]);
}
Code: Select all
<RenderTarget id="auxIn" colorFormat="3" scale="1.0" MRT="2" colorFormat1="9"/>
<RenderTarget id="auxOut" colorFormat="3" scale="1.0" MRT="2"colorFormat1="9"/>
<RenderTarget id="coulds" colorFormat="3" scale="1.0" MRT="2"colorFormat1="6"/>
Code: Select all
irrlicht-1.8/include/irrMap.h: In member function ‘irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass& irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass::operator=(const irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass&)’:
irrlicht-1.8/include/irrMap.h:635:8: error: non-static reference member ‘irr::core::map<const irr::core::string<char>, irr::video::ITexture*>& irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass::Tree’, can’t use default assignment operator
irrlicht-1.8/include/irrMap.h:635:8: error: non-static reference member ‘const irr::core::string<char>& irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass::Key’, can’t use default assignment operator
PostProcessManager.cpp: In member function ‘void CPostProcessManager::SwapAuxBuffers()’:
PostProcessManager.cpp:53:53: note: synthesized method ‘irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass& irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass::operator=(const irr::core::map<const irr::core::string<char>, irr::video::ITexture*>::AccessClass&)’ first required here
It seems gcc 4.2 doesn't like the default operator and passes the AccessClass into the = operator, instead of the pointer in the SwapAuxBuffers() function. You can get around this by changing the SwapAuxBuffers in PostProcessManager.cpp like so:Justei wrote:I'm unsure about if this is my fault or well, what it could be...
Anyhow, the problem I am having is that whenever I try to include this into my project I get the following error:
Unsure of why this could be :/ I am trying to run this on mingw on Code::Blocks... Any ideas?Code: Select all
C:\Users\Kristoffer\Desktop\ChannelIrrlicht\include\irrMap.h|488|error: non-static reference member 'irr::core::map<irr::core::string<wchar_t, irr::core::irrAllocator<wchar_t> >, irr::video::ITexture*>& irr::core::map<irr::core::string<wchar_t, irr::core::irrAllocator<wchar_t> >, irr::video::ITexture*>::AccessClass::Tree', can't use default assignment operator|
Code: Select all
void CPostProcessManager::SwapAuxBuffers()
{
video::ITexture* texin = RenderTargetMap["auxIn"];
video::ITexture* texout = RenderTargetMap["auxOut"];
RenderTargetMap["auxIn"] = texout;
RenderTargetMap["auxOut"] = texin;
}
Like other people in this thread I've ran into some problems with the OpenGL shaders, as I'm using an embedded graphics processor too. I've fixed the following shaders as they have minor issues with them (incorrect casts etc:)ACE247 wrote:Yes that certainly works. However, some of the shaders also do not want to work correctly, but thats be due to something else. I'll look into it.