#pragma once #include #include #include #include #include #include #include /** @brief Implements a hierarchical particle system. A hierarchical particle system is a particle system made out of a smaller particle systems. First an image of the smaller particle system should be rendered, than this image can be multiplied and be used as sprite images to form the bigger system. To avoid incorrect depth culling caused by the simplifications made by considering a group of particles as a single quad we have to take into acount some additional depth information too. We also render the the closest and the furthest depth values of the smaller system in the view camera's space. During display this depth information can be used to estimate the length of the light ray segment travelled in the medium and alter the opacity of the particles respectively. This particle system implementation also deals with light scattering inside the medium. It builds a layered light absorption texture which stores the amount of absorped light in different depths from lightsource. With the use of the illumination texture we can approximate self shadowing of the medium. This implementation uses four layers and stores it in the four channels of a texture. This way no 3D textures are needed, and the light absorption (illumination) texture can be generated in a single render pass. During rendering a mie scattering model is used to compute the amount of scattered light. To speed up calculations phase function values are read back from a 2D look-up texture (phase texture). */ class AdvancedParticleSystem { public: AdvancedParticleSystem(void); ~AdvancedParticleSystem(void); private: //!Impostor to display Impostor m_DisplayImpostor; //!Impostor for illumination calculation Impostor m_IllumImpostor; //not used RenderTexture m_DisplayTexture; //!Illumination texture RenderTexture m_IllumTexture; //! Stores nearest and furthest distances of the particles from the camera and also the opacity RenderTexture m_FrontDepthTexture; //not used RenderTexture m_BackDepthTexture; //! Stores nearest distances of the scene objects from the camera RenderTexture m_ObjectsTexture; //! A motion blurred version of the illumination texture to avoid abrupt changes RenderTexture m_ScatteredIlumTexture; //cg programs CgProgram m_IllumProgram; CgProgram m_FrontDepthProgram; CgProgram m_DensityOnlyProgram; CgProgram m_DisplayProgram; CgProgram m_Psys_Depth_Multiple_Forward_Program; CgProgram m_TempProg;CgProgram m_TempProg2; CgProgram m_ObjDepthProg; CgProgram m_ScatterIllumProgram; CgProgram m_Psys_Multiple_Forward_Program; CgProgram m_Psys_Single_Phase_Program; CgProgram m_Psys_Depth_Single_Phase_Program; CgProgram m_Psys_Depth_Default_Program; CgProgram m_Psys_Default_Program; //Camera m_LightCamera; ThirdPersonCamera m_LightCamera; float* m_SceneTransformMatrix; public: bool m_HasSceneTransformMatrix; Scene* theScene; bool object_shadows; bool depthcalc; int m_PSys_RenderMode; //! albedo of the particles float albedo; //! scattering symmetry of the scattering (used in phase function calculation) float symmetry; //only helper attribute float symmetry2; //! transparency of the particles float transparency; unsigned int PhaseTexID; unsigned int AngleTexID; Vector m_LightColor; Vector m_LightPosition; //! particle system made ot of a smaller system ParticleSystem m_ParticleSystem; //! smaller particle system ParticleSystem m_LittleParticleSystem; //Billboard display texture Texture m_BillboardTexture; Texture m_BbBackDepthTexture; Texture m_BbFrontDepthTexture; //! renders the particle system from the given camera using the given light position void Display(Camera* cam,Vector LightPos); //! refreshes the particle system void Refresh(Camera* cam, Vector LightPos, unsigned int Dt, unsigned int TimefromSecond); //! generates front and back depth textures od the smaller particle system void RefreshDepths(Camera* cam); //not used void RefreshDepthswithSpheres(Camera* cam); //! initialize textures and gpu programs void Initialize(); //! initialize the two particle systems void InitSystems(); //! generates scene depth texture void RenderObjectDepths(Camera* cam); //for debug void displayillum(Camera* cam); void displayLittle(Camera* cam); void displaytexture(int tex); /** @brief refreshes the illumination texture The illumination texture is a four layered texture, each layer stored in the separate color channels. */ void RefreshIllumTextures(Vector LightPos); void DecreaseAlbedo(){albedo-=0.01;if(albedo<0)albedo=0;} void IncreaseAlbedo(){albedo+=0.01;if(albedo>1)albedo=1;} void DecreaseTransparency(){transparency-=0.05;if(transparency<0)transparency=0;} void IncreaseTransparency(){transparency+=0.05;if(transparency>1)transparency=1;} void DecreaseSymmetry(){symmetry-=0.01;if(symmetry<-1)symmetry=-1;} void IncreaseSymmetry(){symmetry+=0.01;if(symmetry>1)symmetry=1;} void setSceneTransformMatrix(float* matr){m_HasSceneTransformMatrix=true;m_SceneTransformMatrix=matr;} };