After saying that - start working on the project, tutorials are nice - but we need to get to work here.

I haven't seen real progress since the quoted post, I am sorry to say that I don't see myself giving you a passing grade - as no real work has been done.Assaf Raman wrote:Well, the mid-term evaluations are in July 9, by that time - I will need to see real progress, else we will have a problem here.
According to your new schedule - you will have less then two weeks to program, I don't like it.
What would you do if you were in my place? Tell me how this is going to work out.
Code: Select all
/*
-----------------------------------------------------------------------------
Filename: OffScreenParticles.cpp
-----------------------------------------------------------------------------
*/
#include "OffScreenParticles.h"
#include <OgreMath.h>
#include <OgreVector4.h>
#include <OgreColourValue.h>
#include <OgreSubEntity.h>
Ogre::Viewport* mViewport;
Ogre::SceneNode* headNode;
Ogre::SceneNode* barrelsNode;
Ogre::SceneNode* launcherNode;
Ogre::SceneNode* penguinTravelPathNode;
Ogre::SceneNode* penguinNode;
Ogre::SceneNode* fogNode;
Ogre::SceneNode* houseNode;
unsigned long period = 3000;
float headStartingPhase = 1.5f;
float barrelsPhaseDelay = 0.60f;
float headAmplitude = 30.0f;
float headAverageAngle = 2.5f;
float barrelsAmplitude = 25.0f;
float barrelsAverageAngle = 0.0f;
float previousPenguinHeigth = 0.0f;
float previousPenguinHeigthDelta = 0.0f;
float previousTravelAngle = 0.0f;
float previousPenguinAngle = 0.0f;
float previousHeadAngle = headStartingPhase*Ogre::Math::PI;
float previousBarrelsAngle = previousHeadAngle - barrelsPhaseDelay*Ogre::Math::PI;
float penguinAngle;
float headAngle;
float barrelsAngle;
int pushUpsBetweenTravelling = 5;
int loopsPerTravelling = 2;
unsigned int pushUpsCount = 0;
bool isPenguinTravelling=false;
//-------------------------------------------------------------------------------------
OffScreenParticles::OffScreenParticles(void)
{
}
//-------------------------------------------------------------------------------------
OffScreenParticles::~OffScreenParticles(void)
{
}
Ogre::String GetShaderFileNameSuffix(){
Ogre::String shaderFileNameSuffix;
// Use GLSL ES in case of OpenGL ES 2 render system.
if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") != Ogre::String::npos)
{
shaderFileNameSuffix = "glsles";
}
// Use GLSL in case of OpenGL render system.
else if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL") != Ogre::String::npos)
{
shaderFileNameSuffix = "glsl";
}
// Use HLSL, Multiple Render Target in case of D3D9 render system.
else if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("Direct3D9") != Ogre::String::npos)
{
shaderFileNameSuffix = "hlsl";
}
// Use HLSL, in case of D3D10 or D3D11 render system.
else if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("Direct3D1") != Ogre::String::npos)
{
shaderFileNameSuffix = "hlsl4";
}
// If none of above render systems fit, use cg
else{
shaderFileNameSuffix = "cg";
}
return shaderFileNameSuffix;
}
bool OffScreenParticles::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
float headPhase = mRoot->getTimer()->getMilliseconds() * Ogre::Math::PI / period + headStartingPhase*Ogre::Math::TWO_PI;
float barrelsPhase = headPhase - barrelsPhaseDelay*Ogre::Math::PI;
headAngle = (Ogre::Math::Sin(headPhase)) * headAmplitude + headAverageAngle;
barrelsAngle = (Ogre::Math::Sin(barrelsPhase)) * barrelsAmplitude + barrelsAverageAngle;
headNode->pitch(Ogre::Degree(headAngle-previousHeadAngle));
barrelsNode->pitch(Ogre::Degree(barrelsAngle-previousBarrelsAngle));
float penguinHeigth = (sin(mRoot->getTimer()->getMilliseconds() / 500.0)+1.0f) * 50.0f;
penguinNode->setPosition(0.0f, penguinHeigth, 0.0f);
float penguinHeigthDelta = penguinHeigth - previousPenguinHeigth;
if(!isPenguinTravelling){
float penguinRocketOscilation = mRoot->getTimer()->getMilliseconds() / 270.0;
// spin the head around and make it float up and down
launcherNode->setPosition(sin(penguinRocketOscilation) * 10.0f - 50.0f, 0.0f, -100.0f);
penguinAngle = -cos(penguinRocketOscilation) * 10.0f;
penguinNode->roll(Ogre::Degree(penguinAngle-previousPenguinAngle));
//checking if penguin has made next push-up
if(previousPenguinHeigthDelta>=0 && penguinHeigthDelta<0){
pushUpsCount = (pushUpsCount+1) % pushUpsBetweenTravelling;
if(pushUpsCount==0){
/*start travelling*/
isPenguinTravelling = true;
launcherNode->pitch(Ogre::Degree(30));
}
}
previousPenguinHeigth = penguinHeigth;
previousPenguinHeigthDelta = penguinHeigthDelta;
previousPenguinAngle = penguinAngle;
}
else{
float angleDelta = evt.timeSinceLastFrame*50;
//checking if penguin has made a loop;
if(previousTravelAngle + angleDelta > 360*loopsPerTravelling){
isPenguinTravelling = false;
angleDelta = 360*loopsPerTravelling - previousTravelAngle;
launcherNode->pitch(Ogre::Degree(-30));
previousTravelAngle = 0.0f;
}
else{
previousTravelAngle += angleDelta;
}
penguinTravelPathNode->yaw(Ogre::Degree(angleDelta));
}
previousHeadAngle = headAngle;
previousBarrelsAngle = barrelsAngle;
fogNode->yaw(Ogre::Degree(evt.timeSinceLastFrame * 200));
return BaseApplication::frameRenderingQueued(evt);
}
/*void BloomCompositorListener::notifyCompositor( Ogre::CompositorInstance * instance )
{
CompositorListener::notifyCompositor( instance );
// Get some RTT dimensions for later calculations
Ogre::CompositionTechnique::TextureDefinitionIterator defIter = instance->getTechnique()->getTextureDefinitionIterator();
while ( defIter.hasMoreElements() )
{
Ogre::CompositionTechnique::TextureDefinition * def = defIter.getNext();
if ( def->name == TTEXT("renderTarget1") || def->name == TTEXT("renderTarget2") )
{
def->width = mVpWidth / 2;
def->height = mVpHeight / 2;
}
}
}*/
enum ShaderParam { SP_SHININESS = 1, SP_DIFFUSE, SP_SPECULAR };
//-------------------------------------------------------------------------------------
void OffScreenParticles::createScene(void)
{
mViewport=mWindow->getViewport(0);
mViewport->setBackgroundColour(Ogre::ColourValue::ColourValue(0.2f,0.2f,0.2f,1));
Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "OSP_SolidMaterialsBuffer");
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "OSP_SolidMaterialsBuffer", true);
Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "OSP_ShowDepth");//"SSAO/Volumetric");//"SSAO/ShowNormals");
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "OSP_ShowDepth", true);//"SSAO/Volumetric", true);//"SSAO/ShowNormals", true);
Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "OSP_PostFilter");
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "OSP_PostFilter", true);
/*Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "Bloom");
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Bloom", true);*/
//Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "BlackWhite2");
//Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "BlackWhite2", true);
//Ogre::CompositorChain *chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mViewport);
//Ogre::Compositor newCompositor = Ogre::CompositorManager::getSingleton().create("MyCompositor","MyGroup",true);
//Ogre::CompositionTechnique::TextureDefinitionIterator defIter = Ogre::CompositorManager::instance->get
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.75f, 0.75f, 0.25f));
Ogre::Light* light = mSceneMgr->createLight("MainLight");
light->setPosition(200.0f, 80.0f, -50.0f);
// create your scene here :)
Ogre::SceneNode* root = mSceneMgr->getRootSceneNode();
//Ogre's head
headNode = root->createChildSceneNode("HeadNode");
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
headNode->attachObject(ogreHead);
headNode->setPosition(50.0f, 0.0f, -100.0f);
headNode->pitch(Ogre::Degree(previousHeadAngle));
//ogreHead->setMaterialName("SSAO/ShowDepth");//"Examples/CelShading");
/*Ogre::SubEntity* sub;
sub = ogreHead->getSubEntity(0); // eyes
sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(35, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(1, 0.3, 0.3, 1));
sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(1, 0.6, 0.6, 1));
sub = ogreHead->getSubEntity(1); // skin
sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(10, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(0, 0.5, 0, 1));
sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(0.3, 0.5, 0.3, 1));
sub = ogreHead->getSubEntity(2); // earring
sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(25, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(1, 1, 0, 1));
sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(1, 1, 0.7, 1));
sub = ogreHead->getSubEntity(3); // teeth
sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(20, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(1, 1, 0.7, 1));
sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(1, 1, 1, 1));*/
//Barrels on Ogre's tusks
barrelsNode = headNode->createChildSceneNode("BarrelsNode");
barrelsNode->setPosition(0.0f, 5.0f, -2.0f);
barrelsNode->pitch(Ogre::Degree(previousBarrelsAngle));
//Right tusk Barrel
Ogre::SceneNode* barrel1Node = barrelsNode->createChildSceneNode("Barrel1Node");
Ogre::Entity* barrel1 = mSceneMgr->createEntity("Barrel1", "Barrel.mesh");
barrel1Node->attachObject(barrel1);
barrel1Node->setPosition(-21.0f, 2.0f, 0.0f);
barrel1Node->scale(1.25f, 1.25f, 1.25f);
//Right Barrel's smoke
Ogre::SceneNode* smoke1Node = barrel1Node->createChildSceneNode("Smoke1Node");
Ogre::ParticleSystem* smoke1 = mSceneMgr->createParticleSystem("Smoke1", "Examples/Smoke2");
//smoke1->setMaterialName("Examples/CelShading");
smoke1Node->attachObject(smoke1);
//Left tusk Barrel
Ogre::SceneNode* barrel2Node = barrelsNode->createChildSceneNode("Barrel2Node");
Ogre::Entity* barrel2 = mSceneMgr->createEntity("Barrel2", "Barrel.mesh");
barrel2Node->attachObject(barrel2);
barrel2Node->setPosition(21.0f, 2.0f, 0.0f);
barrel2Node->scale(1.25f, 1.25f, 1.25f);
//Left Barrel's smoke
Ogre::SceneNode* smoke2Node = barrel2Node->createChildSceneNode("Smoke2Node");
Ogre::ParticleSystem* smoke2 = mSceneMgr->createParticleSystem("Smoke2", "Examples/Smoke2");
smoke2Node->attachObject(smoke2);
//Penguin Travel Path
penguinTravelPathNode = root->createChildSceneNode("PenguinTravelPath");
penguinTravelPathNode->setPosition(25.0f, 0.0f, -100.0f);
//Penguin Launcher
launcherNode = penguinTravelPathNode->createChildSceneNode("LauncherNode");
launcherNode->setPosition(-75.0f, 0.0f, 0.0f);
//Penguin Rocket
penguinNode = launcherNode->createChildSceneNode("PenguinNode");
Ogre::Entity* penguin = mSceneMgr->createEntity("Penguin","penguin.mesh");
//penguin->setMaterialName("shader/orange_"+GetShaderFileNameSuffix());//"shader/smooth_add");//"Examples/CelShading");//"shader/depth_cg");//"PlainTexture");//"TextureModColor");
penguinNode->attachObject(penguin);
penguinNode->setPosition(0.0f, 50.0f, 0.0f);
//Penguin Rocket's jet
Ogre::SceneNode* penguinJetNode = penguinNode->createChildSceneNode("PenguinJetNode");
Ogre::ParticleSystem* penguinJet = mSceneMgr->createParticleSystem("PenguinJet", "Examples/JetEngine1");
penguinJetNode->attachObject(penguinJet);
//Fog
fogNode = launcherNode->createChildSceneNode("FogNode");
Ogre::ParticleSystem* fog = mSceneMgr->createParticleSystem("Fog", "Examples/Fog");
fogNode->attachObject(fog);
//fog->setMaterialName("ShowDepth");//"TextureModColor");//"PlainTexture");
//Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "SSAO/Post/CrossBilateralFilter");//"DOF");//"DeferredShading/ShowDepthSpecular");//"Sharpen Edges");//"B&W");
//Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "SSAO/Post/CrossBilateralFilter", true);//"DOF", true);//"DeferredShading/ShowDepthSpecular", true);//"Sharpen Edges", true);//"B&W", true);
ogreHead->setMaterialName("OSP_SolidMaterialsBuffer");
barrel1->setMaterialName("OSP_SolidMaterialsBuffer");
barrel2->setMaterialName("OSP_SolidMaterialsBuffer");
penguin->setMaterialName("OSP_SolidMaterialsBuffer");
//smoke1->setMaterialName("SSAO/GBuffer");
//smoke2->setMaterialName("SSAO/GBuffer");
//penguinJet->setMaterialName("SSAO/GBuffer");
//fog->setMaterialName("SSAO/GBuffer");
}
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char *argv[])
#endif
{
// Create application object
OffScreenParticles app;
try {
app.go();
} catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
std::cerr << "An exception has occured: " <<
e.getFullDescription().c_str() << std::endl;
#endif
}
return 0;
}
#ifdef __cplusplus
}
#endif
Code: Select all
/*
-----------------------------------------------------------------------------
Filename: OffScreenParticles.h
-----------------------------------------------------------------------------
*/
#ifndef __TutorialApplication_h_
#define __TutorialApplication_h_
#include "BaseApplication.h"
class OffScreenParticles : public BaseApplication
{
public:
OffScreenParticles(void);
virtual ~OffScreenParticles(void);
virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
protected:
virtual void createScene(void);
};
#endif // #ifndef __OffScreenParticles_h_
Code: Select all
texture mrt target_width target_height PF_FLOAT32_RGBA PF_FLOAT32_RGBA PF_FLOAT32_RGBA chain_scope
Code: Select all
texture depthInAlpha target_width target_height PF_FLOAT32_RGBA chain_scope
Code: Select all
compositor OSP_SolidMaterialsBuffer
{
technique
{
texture depthInAlpha target_width target_height PF_FLOAT32_RGBA chain_scope
texture occlusion target_width target_height PF_FLOAT32_RGBA chain_scope
target depthInAlpha
{
input none
shadows off
pass clear
{
buffers colour depth stencil
depth_value 1.0
}
pass render_scene {}
}
}
}
Code: Select all
compositor OSP_ShowDepth
{
technique
{
texture_ref occlusion OSP_SolidMaterialsBuffer occlusion
target occlusion
{
input none
pass render_quad
{
// Renders a fullscreen quad with a material
material OSP_ShowDepth
}
}
}
}
Code: Select all
compositor OSP_PostFilter
{
technique
{
target_output
{
input none
pass render_quad
{
material OSP_PostFilter
}
}
}
}
Code: Select all
/*fragment_program OSP_ShowDepth_fp_hlsl hlsl
{
source OSP.cg
entry_point OSP_ShowDepth_fp
target ps_3_0
}*/
fragment_program OSP_ShowDepth_fp_cg cg
{
source OSP.cg
entry_point OSP_ShowDepth_fp
profiles ps_2_x arbfp1
}
fragment_program OSP_ShowDepth_fp unified
{
//delegate OSP_ShowDepth_fp_hlsl
delegate OSP_ShowDepth_fp_cg
}
material OSP_ShowDepth
{
technique
{
pass
{
depth_check off
vertex_program_ref Ogre/Compositor/StdQuad_vp {}
fragment_program_ref OSP_ShowDepth_fp {}
texture_unit
{
content_type compositor OSP_SolidMaterialsBuffer depthInAlpha
tex_address_mode clamp
filtering none
}
texture_unit
{
texture gray256.png
tex_address_mode wrap
filtering none
}
}
}
}
//---------------------------------------------------
// Gbuffer Material
/*vertex_program OSP_SolidMaterialsBuffer_vp_hlsl hlsl
{
source OSP.cg
entry_point OSP_SolidMaterialsBuffer_vp
target vs_3_0
}
fragment_program OSP_SolidMaterialsBuffer_fp_hlsl hlsl
{
source OSP.cg
entry_point OSP_SolidMaterialsBuffer_fp
target ps_3_0
}*/
vertex_program OSP_SolidMaterialsBuffer_vp_cg cg
{
source OSP.cg
entry_point OSP_SolidMaterialsBuffer_vp
profiles vs_2_x arbvp1
default_params
{
}
}
fragment_program OSP_SolidMaterialsBuffer_fp_cg cg
{
source OSP.cg
entry_point OSP_SolidMaterialsBuffer_fp
profiles ps_3_0 arbfp1
default_params
{
}
}
vertex_program OSP_SolidMaterialsBuffer_vp unified
{
//delegate OSP_SolidMaterialsBuffer_vp_hlsl
delegate OSP_SolidMaterialsBuffer_vp_cg
}
fragment_program OSP_SolidMaterialsBuffer_fp unified
{
//delegate OSP_SolidMaterialsBuffer_fp_hlsl
delegate OSP_SolidMaterialsBuffer_fp_cg
}
material OSP_SolidMaterialsBuffer
{
technique
{
pass
{
//scene_blend alpha_blend
vertex_program_ref OSP_SolidMaterialsBuffer_vp
{
param_named_auto worldViewProj worldviewproj_matrix
param_named_auto texelOffsets texel_offsets
param_named_auto depthRange scene_depth_range
}
fragment_program_ref OSP_SolidMaterialsBuffer_fp
{
param_named_auto depthRange scene_depth_range
}
texture_unit
{
texture Ten.png 2d
}
}
}
}
//------------------------------------------------
/*fragment_program OSP_PostFilter_fp_hlsl hlsl
{
source OSP.cg
entry_point OSP_PostFilter_fp
target ps_3_0
}*/
fragment_program OSP_PostFilter_fp_cg cg
{
source OSP.cg
entry_point OSP_PostFilter_fp
profiles ps_3_0 ps_2_x arbfp1
}
fragment_program OSP_PostFilter_fp unified
{
// delegate OSP_PostFilter_fp_hlsl
delegate OSP_PostFilter_fp_cg
}
material OSP_PostFilter
{
technique
{
pass
{
cull_hardware none
cull_software none
depth_check off
vertex_program_ref Ogre/Compositor/StdQuad_vp {}
fragment_program_ref OSP_PostFilter_fp {}
texture_unit
{
content_type compositor OSP_SolidMaterialsBuffer occlusion
tex_address_mode clamp
filtering none
}
}
}
}
Code: Select all
void OSP_SolidMaterialsBuffer_vp(
float4 inputPosition : POSITION,
out float4 outputPosition : POSITION,
out float2 outputDepth : TEXCOORD0,
uniform float4x4 worldViewProj,
uniform float4 texelOffsets,
uniform float4 depthRange
)
{
outputPosition = mul(worldViewProj, inputPosition);
outputPosition.xy += texelOffsets.zw * outputPosition.w; //solution presented by cyanbeck
outputDepth.x = smoothstep(depthRange.x,depthRange.y,outputPosition.z);
outputDepth.y = outputPosition.w;
}
void OSP_SolidMaterialsBuffer_fp(
float2 inputDepth : TEXCOORD0,
//float2 diffuse : TEXCOORD1,
out float4 outputColorAndDepth : COLOR,
uniform sampler2D texture
)
{
outputColorAndDepth = tex2D(texture, diffuse);
float finalDepth = inputDepth.x;
outputColorAndDepth.w = finalDepth;
}
void OSP_ShowDepth_fp
(
in float2 iTexCoord: TEXCOORD0,
out float4 oColor0 : COLOR0,
uniform sampler depthInAlpha: register(s0),
uniform sampler tex : register(s1)
)
{
float4 colorAndDepth = tex2D(depthInAlpha, iTexCoord);
float depth = colorAndDepth.a;
float3 color = colorAndDepth*depth;
//oColor0 = float4(tex2D(tex, float2((255-depth*200), 0)).rgb, 1);
//oColor0 = float4(color.rgb, 1);
oColor0 = float4(depth, depth, depth, 1);
}
void OSP_PostFilter_fp (
in float2 uv : TEXCOORD0,
out float4 oColor0 : COLOR0,
uniform sampler sOcclusion : register(s0)
)
{
oColor0 = float4(tex2D(sOcclusion, uv).xyz, 1);
}
Code: Select all
-float2 offset = //(x,y) position of texture (0,0) point from camera view
-oututPosition = multiplication of woldViewProj and inputPosition.
-outputPosition.x = (outputPosition.x-offset.x)*scaleInWidth + offset.x
-outputPosition.y = (outputPosition.y-offset.y)*scaleInHeight + offset.y
To check how application looks right now, comment sompositors in *.cpp file and comment substitution of solid objects material.Karol Badowski 1989 wrote:I've just added depth acquisition with depth passed by alfa channel of a texture.
My material equivalnet to "g-buffer" is still attached manually to objects that are supposed to be rendered as non-particle. There are some more differences since last time. All calculations of depth are done in the first compositor vertex shader.
Right now I am debugging it. I think I'll be finished in several hours with that task.
It does not change however strategy of choosing materials for objects on scene. That is why I can already ask a question based on older version.
There is a difference between running applocation under openGl and DirectX9 that causes strange thing (I'll explain it on old version, nearly the same as SSAO):
Particle effects are unvisible in DirectX (GOOD)
Particle effects are visible, but with a very strange material in OpenGL (WRONG).
In application:In DirectX only solid objects are rendered.Code: Select all
(...) Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "OSP_SolidMaterialsBuffer"); Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "OSP_SolidMaterialsBuffer", true); Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "OSP_ShowDepth");//"SSAO/Volumetric");//"SSAO/ShowNormals"); Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "OSP_ShowDepth", true);//"SSAO/Volumetric", true);//"SSAO/ShowNormals", true); Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "OSP_PostFilter"); Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "OSP_PostFilter", true); (...) //material of the G-buffer quivalence is attached manually only to solid objects ogreHead->setMaterialName("OSP_SolidMaterialsBuffer"); barrel1->setMaterialName("OSP_SolidMaterialsBuffer"); barrel2->setMaterialName("OSP_SolidMaterialsBuffer"); penguin->setMaterialName("OSP_SolidMaterialsBuffer"); //It is not attached to particle effects //smoke1->setMaterialName("SSAO/GBuffer"); //smoke2->setMaterialName("SSAO/GBuffer"); //penguinJet->setMaterialName("SSAO/GBuffer"); //fog->setMaterialName("SSAO/GBuffer"); (...)
In OpenGL particle effects are rendered too by the compositor. They have a really strange material. I suppose that in SSAO occlusion is based on fact that compositors in chain can't work unless object has a special buffer with data that is requested. In OpenGl it seems that it is still displayed.
This is old version of compositor chain, nearly same as SSAO:
OSP.cg file:OSP.compositorCode: Select all
void OSP_SolidMaterialsBuffer_vp( float4 iPosition : POSITION, float3 iNormal : NORMAL, out float4 oPosition : POSITION, out float3 oViewPos : TEXCOORD0, out float3 oNormal : TEXCOORD1, uniform float4x4 cWorldViewProj, uniform float4x4 cWorldView ) { oPosition = mul(cWorldViewProj, iPosition); // transform the vertex position to the projection space oViewPos = mul(cWorldView, iPosition).xyz; // transform the vertex position to the view space oNormal = mul(cWorldView, float4(iNormal,0)).xyz; // transform the vertex normal to view space } void OSP_SolidMaterialsBuffer_fp( float3 iViewPos : TEXCOORD0, float3 iNormal : TEXCOORD1, out float4 oColor0 : COLOR0, // rgb color out float4 oNormalDepth : COLOR1, // normal + linear depth [0, 1] out float4 oViewPos : COLOR2, // view space position uniform float cNearClipDistance, uniform float cFarClipDistance // !!! might be 0 for infinite view projection. ) { oColor0 = float4(1, 1, 1, 1); //...and a least little touch of the titanium white... float clipDistance = cFarClipDistance - cNearClipDistance; oNormalDepth = float4(normalize(iNormal).xyz, (length(iViewPos) - cNearClipDistance) / clipDistance); oViewPos = float4(iViewPos, 0); } void OSP_ShowDepth_fp ( in float2 iTexCoord: TEXCOORD0, out float4 oColor0 : COLOR0, uniform sampler mrt1: register(s0), uniform sampler tex : register(s1) ) { float depth = tex2D(mrt1, iTexCoord).w; oColor0 = float4(tex2D(tex, float2((255-depth*200), 0)).rgb, 1); } void OSP_PostFilter_fp ( in float2 uv : TEXCOORD0, out float4 oColor0 : COLOR0, uniform sampler sOcclusion : register(s0) ) { oColor0 = float4(tex2D(sOcclusion, uv).xyz, 1); }
OSP.materialCode: Select all
compositor OSP_SolidMaterialsBuffer { technique { // GBuffer enconding: -------------------------------------------------- // mrt0: rgba --> unused in this sample (plain white, (1, 1, 1, 1)) // mrt1: xyz --> normals, w --> normalized linear depth [0, 1] // mrt2: xyz --> position in view space // // use a better packing of variables in the mrt to (possibly) increase // performance! // --------------------------------------------------------------------- texture mrt target_width target_height PF_FLOAT32_RGBA PF_FLOAT32_RGBA PF_FLOAT32_RGBA chain_scope texture occlusion target_width target_height PF_FLOAT32_RGBA chain_scope target mrt { input none shadows off pass clear { buffers colour depth stencil depth_value 1.0 } pass render_scene {} } } } compositor OSP_ShowDepth { technique { texture_ref occlusion OSP_SolidMaterialsBuffer occlusion target occlusion { input none pass render_quad { // Renders a fullscreen quad with a material material OSP_ShowDepth } } } } compositor OSP_PostFilter { technique { target_output { input none pass render_quad { material OSP_PostFilter } } } }
I wonder how to make particle effects be skipped by the compositor chain also in OpenGL in more appropriate way. For sure there is a simple solution for this kind of occlusion?Code: Select all
/*fragment_program OSP_ShowDepth_fp_hlsl hlsl { source OSP.cg entry_point OSP_ShowDepth_fp target ps_3_0 }*/ fragment_program OSP_ShowDepth_fp_cg cg { source OSP.cg entry_point OSP_ShowDepth_fp profiles ps_2_x arbfp1 } fragment_program OSP_ShowDepth_fp unified { //delegate OSP_ShowDepth_fp_hlsl delegate OSP_ShowDepth_fp_cg } material OSP_ShowDepth { technique { pass { depth_check off vertex_program_ref Ogre/Compositor/StdQuad_vp {} fragment_program_ref OSP_ShowDepth_fp {} texture_unit { content_type compositor OSP_SolidMaterialsBuffer mrt 1 tex_address_mode clamp filtering none } texture_unit { texture gray256.png tex_address_mode wrap filtering none } } } } //--------------------------------------------------- // Gbuffer Material /*vertex_program OSP_SolidMaterialsBuffer_vp_hlsl hlsl { source OSP.cg entry_point OSP_SolidMaterialsBuffer_vp target vs_3_0 } fragment_program OSP_SolidMaterialsBuffer_fp_hlsl hlsl { source OSP.cg entry_point OSP_SolidMaterialsBuffer_fp target ps_3_0 }*/ vertex_program OSP_SolidMaterialsBuffer_vp_cg cg { source OSP.cg entry_point OSP_SolidMaterialsBuffer_vp profiles vs_2_x arbvp1 } fragment_program OSP_SolidMaterialsBuffer_fp_cg cg { source OSP.cg entry_point OSP_SolidMaterialsBuffer_fp profiles ps_3_0 arbfp1 } vertex_program OSP_SolidMaterialsBuffer_vp unified { //delegate OSP_SolidMaterialsBuffer_vp_hlsl delegate OSP_SolidMaterialsBuffer_vp_cg } fragment_program OSP_SolidMaterialsBuffer_fp unified { //delegate OSP_SolidMaterialsBuffer_fp_hlsl delegate OSP_SolidMaterialsBuffer_fp_cg } material OSP_SolidMaterialsBuffer { technique { pass { vertex_program_ref OSP_SolidMaterialsBuffer_vp { param_named_auto cWorldViewProj worldviewproj_matrix param_named_auto cWorldView worldview_matrix } fragment_program_ref OSP_SolidMaterialsBuffer_fp { param_named_auto cNearClipDistance near_clip_distance param_named_auto cFarClipDistance far_clip_distance } } } } //------------------------------------------------ /*fragment_program OSP_PostFilter_fp_hlsl hlsl { source OSP.cg entry_point OSP_PostFilter_fp target ps_3_0 }*/ fragment_program OSP_PostFilter_fp_cg cg { source OSP.cg entry_point OSP_PostFilter_fp profiles ps_3_0 ps_2_x arbfp1 } fragment_program OSP_PostFilter_fp unified { // delegate OSP_PostFilter_fp_hlsl delegate OSP_PostFilter_fp_cg } material OSP_PostFilter { technique { pass { cull_hardware none cull_software none depth_check off vertex_program_ref Ogre/Compositor/StdQuad_vp {} fragment_program_ref OSP_PostFilter_fp {} texture_unit { content_type compositor OSP_SolidMaterialsBuffer occlusion tex_address_mode clamp filtering none } } } }
Separate viewports? rendering queue? Some possibility to give a command inside of Compositor "do not render object if(something... )"? It is not obvious for me yet, but I am sure that solution is easy when you have a right hint.
Question about downsampling:
I've seen advice to use target_width_scaled <parameter> and target_height_scaled <parameter>
to define size of new texture.
Is it better if I do several fixed scales <parameter>=0.5/0.25/0.125, or is it possible to use non-constant parameter in this syntax? (I'd like to use a variable, set from the level of application by setCustomParameter() function if non-constant is allowed)?
PS:
Today I have modified previous compositor according to advices from
http://www.ogre3d.org/forums/viewtopic.php?f=2&t=38354
proposed by cyanbeck in ordet to create lighter G-buffer.
Calculated depth there is a little bit unconventional
(i wonder whether this line is needed:
outPos.xy += texelOffsets.zw * outPos.w;
),
however it gets all needed data in vertex shader instead of separate compositor (much easier than it was in Deferred shading and in SSAO).
I've written saving depth to alpha channel based on depth acquired this way.
It can be easily modified back to mrt.
Code: Select all
material Examples/Fog
{
technique
{
pass
{
lighting off
scene_blend alpha_blend
depth_write off
diffuse vertexcolour
texture_unit
{
texture fog.png
tex_address_mode clamp
}
}
}
}
Code: Select all
// smoke2
particle_system Examples/Smoke2
{
material Examples/Smoke
particle_width 10
particle_height 10
cull_each true
quota 400
billboard_type point
sorted true
// Area emitter
emitter Point
{
position 0 5 0
angle 35
emission_rate 20
time_to_live 3
direction 0 1 0
velocity_min 20
velocity_max 50
}
affector ColourImage
{
image smokecolors2.png
}
affector Rotator
{
rotation_range_start 0
rotation_range_end 360
rotation_speed_range_start -60
rotation_speed_range_end 200
}
affector Scaler
{
rate 20
}
}
// smoke2
particle_system Examples/Fog
{
material Examples/Fog
particle_width 1
particle_height 1
cull_each true
quota 700
billboard_type point
sorted true
// Area emitter
emitter Point
{
position 0 -50 0
angle 10
emission_rate 70
time_to_live 12
direction 1 0 0
velocity_min 10
velocity_max 20
}
affector ColourImage
{
image fogcolors.png
}
affector Rotator
{
rotation_range_start 360
rotation_range_end 0
rotation_speed_range_start -60
rotation_speed_range_end 10
}
affector Scaler
{
rate 10
}
affector DirectionRandomiser
{
randomness 20
}
}
Code: Select all
// A jet engine (of sorts)
particle_system Examples/JetEngine1
{
material Examples/Flare
particle_width 20
particle_height 20
cull_each true
quota 200
billboard_type point
sorted true
emitter Point
{
angle 5
emission_rate 100
time_to_live 0.75
direction 0 -1 0
velocity_min 175
velocity_max 250
colour_range_start 1 1 0.5
colour_range_end 1 0.8 0.3
}
affector ColourFader
{
red -0.25
green -1
blue -1
}
}
Code: Select all
compositor BlackWhite2
{
technique
{
// Temporary textures:
// Keeps colour texture of solid objects
texture solidObjectsTexture target_width target_height PF_A8R8G8B8
//texture depth target_width target_height PF_FLOAT32_RGBA
target solidObjectsTexture
{
input previous
}
target_output
{
// Start with clear output
input none
// Draw a fullscreen quad
pass render_quad
{
// Renders a fullscreen quad with a material
material BlackWhite2
input 0 solidObjectsTexture
}
}
}
}
Code: Select all
fragment_program BlackWhite2_Cg_FP cg
{
source BlackWhite2.cg
entry_point GrayScale_ps
profiles ps_3_0 ps_2_x ps_4_0 ps_2_0 arbfp1
}
fragment_program BlackWhite2_FP unified
{
delegate BlackWhite2_Cg_FP
}
//-------------------------------------------------
vertex_program BlackWhite2_Cg_vp cg
{
source BlackWhite2.cg
entry_point StdQuad_vp
profiles vs_2_x vs_4_0 vs_2_0 vs_1_1 arbvp1
default_params
{
//param_named_auto cWorldViewProj worldviewproj_matrix
//param_named_auto cWorldView worldview_matrix
}
}
vertex_program BlackWhite2_vp unified
{
delegate BlackWhite2_Cg_vp
}
//-----------------------------------------------------
material BlackWhite2
{
technique
{
pass
{
//depth_check off
vertex_program_ref BlackWhite2_vp
{
param_named_auto cWorldViewProj worldviewproj_matrix
param_named_auto cWorldView worldview_matrix
}
fragment_program_ref BlackWhite2_FP
{
//param_named_auto depthRange scene_depth_range
param_named_auto near near_clip_distance
param_named_auto far far_clip_distance
}
texture_unit
{
texture RT
tex_coord_set 0
//tex_coord_set 1
tex_address_mode clamp
filtering linear linear linear
}
}
}
}
Code: Select all
void StdQuad_vp
(
in float4 inputPosition : POSITION,
out float4 outputPosition : POSITION,
out float3 outputViewPosition : TEXCOORD0,
out float2 uv0 : TEXCOORD1,
uniform float4x4 cWorldViewProj,
uniform float4x4 cWorldView
)
{
// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
outputPosition = mul(cWorldViewProj, inputPosition);
outputViewPosition = mul(cWorldView, inputPosition).xyz;
// The input positions adjusted by texel offsets, so clean up inaccuracies
//inputPosition.xy = sign(inputPosition.xy);
// Convert to image-space
uv0 = (float2(inputPosition.x, -inputPosition.y) + 1.0f) * 0.5f;
/*outputDepth = uv0;*/
}
sampler2D RT : register(s0);
float4 GrayScale_ps(
float4 pos : POSITION,
float3 inputViewPosition : TEXCOORD0,
float2 iTexCoord : TEXCOORD1,
uniform float near,
uniform float far
) : COLOR
{
float3 color = tex2D(RT, iTexCoord).rgb;
float xPosition = inputViewPosition.x;
float yPosition = inputViewPosition.y;
float zPosition = length(inputViewPosition);
float depth = (zPosition-near)/(far-near);
float4 outputColorDepth;
return float4(depth*255, color.gb, 1.0);
}
So - as I see it:The basic algorithm is this:
1. Render all solid objects in the scene as normal, with depth-writes.
2. Downsample the resulting depth buffer.
3. Render the particles to the off-screen render target, testing against the small depth buffer.
4. Composite the particle render target back onto the main frame buffer, upsampling.