source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/RenderingRuns/OgreDepthShadowMapRenderingRun.cpp @ 2321

Revision 2321, 13.3 KB checked in by szirmay, 17 years ago (diff)
RevLine 
[790]1#include "OgreDepthShadowMapRenderingRun.h"
[1055]2#include "OgreIlluminationManager.h"
[790]3
4
5OgreDepthShadowMapRenderingRun::OgreDepthShadowMapRenderingRun(OgreSharedRuns* sharedRuns,
6                                                                                                                                String name,
7                                                                                                                                Light* light,
8                                                                                                                                unsigned int resolutionX,
9                                                                                                                                unsigned int resolutionY,
10                                                                                                                                String materialName
11                                                                                                                   )
12                                                                                                                   :DepthShadowMapRenderingRun(resolutionX, resolutionY)
[874]13                                                                                                                   , OgreRenderingRun(1, 1)
14                                                                                                                   , RenderingRun(1, 1)
[790]15{
16        this->light = light;
17        this->sharedRuns = sharedRuns;
[1120]18        this->name = name;     
[1130]19        this->blurredname = name + "blurred";
[1120]20       
[790]21        this->materialName = materialName;
[1670]22        lightFarPlane = 0;
[790]23        createDepthMap();       
24}
25
26void OgreDepthShadowMapRenderingRun::createDepthMap()
27{
[1120]28       
29                TexturePtr texPtr = Ogre::TextureManager::getSingleton().createManual(name,
[1055]30                                                                                                                                                        "default",
31                                                                                                                                                        TEX_TYPE_2D,
32                                                                                                                                                        resolutionX,
33                                                                                                                                                        resolutionY,
34                                                                                                                                                        0,
35                                                                                                                                                        0,
36                                                                                                                                                        PF_FLOAT16_RGBA,
[1130]37                                                                                                                                                        TU_RENDERTARGET);               
[1120]38                depthMapTexture = texPtr.getPointer();
39                depthMapCamera = Root::getSingleton()._getCurrentSceneManager()->createCamera(name + "_CAMERA");
[1055]40                //add viewport to rendertarget
[1120]41                HardwarePixelBuffer* hpb = (depthMapTexture->getBuffer()).getPointer();
[1055]42                RenderTarget* rt = hpb->getRenderTarget();
[1120]43                Viewport* v = rt->addViewport(depthMapCamera);
[1628]44                v->setBackgroundColour(ColourValue::White);
[1055]45                v->setOverlaysEnabled(false);
[1130]46                rt->setAutoUpdated(false);
[1628]47               
48                if(OgreIlluminationManager::getSingleton().getBlurShadowMap())
49                {
50                        texPtr = Ogre::TextureManager::getSingleton().createManual(blurredname,
51                                                                                                                                                                "default",
52                                                                                                                                                                TEX_TYPE_2D,
53                                                                                                                                                                resolutionX,
54                                                                                                                                                                resolutionY,
55                                                                                                                                                                0,
[2297]56                                                                                                                                                                0,
[1628]57                                                                                                                                                                PF_FLOAT16_RGBA,
58                                                                                                                                                                TU_RENDERTARGET);
59                        blurredDepthMapTexture = texPtr.getPointer();
60                        hpb = (blurredDepthMapTexture->getBuffer()).getPointer();
61                        rt = hpb->getRenderTarget();
62                        v = rt->addViewport(depthMapCamera);
63                        v->setOverlaysEnabled(false);
64                        rt->setAutoUpdated(false);
65                }
[790]66}
67
68void OgreDepthShadowMapRenderingRun::updateFrame(unsigned long frameNum)
69{
[1103]70        refreshLight(frameNum);
[790]71
72        if(light->getType() == Light::LT_POINT)
73        {
74                updateDepthMap();
75        }
76        else
77        {
78                updateDepthMap();
[1130]79        }       
[790]80}
81
82void OgreDepthShadowMapRenderingRun::updateDepthCubeFace(int facenum)
83{
84}
85
86void OgreDepthShadowMapRenderingRun::updateDepthMap()
87{
[1120]88        setMaterialForVisibles(materialName, depthMapCamera, false);   
89        RenderTarget* rt = depthMapTexture->getBuffer().getPointer()->getRenderTarget();       
90        Viewport* vp = rt->getViewport(0);
91       
[1055]92        rt->update();
93        restoreMaterials();
[1130]94       
[1628]95        if(OgreIlluminationManager::getSingleton().getBlurShadowMap())
96        {
97                rt = blurredDepthMapTexture->getBuffer().getPointer()->getRenderTarget();
98                Material*  mat = (Material*) MaterialManager::getSingleton().getByName("GameTools/Blur").getPointer();
99                mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(depthMapTexture->getName());
100                renderFullscreenQuad("GameTools/Blur", rt);
101        }       
[1130]102       
[2182]103        //rt->writeContentsToFile("shadowmap1.dds");
[1130]104
105        //depthMapTexture->();
[1055]106}
[1688]107
108const String& OgreDepthShadowMapRenderingRun::getDepthMapTextureName()
[1055]109{
[1628]110                if(OgreIlluminationManager::getSingleton().getBlurShadowMap())
111                        return blurredname;
[790]112
[1628]113                return name;
[790]114}
115
[1103]116void OgreDepthShadowMapRenderingRun::refreshLight(unsigned long frameNum)
[790]117{
118       
119        if(light!= 0)
120        {
[1628]121                bool uselispsm = OgreIlluminationManager::getSingleton().getUseLISPSM();
[1639]122                bool usefocusing = OgreIlluminationManager::getSingleton().getFocusingShadowMap();
[790]123                if(light->getType() == Light::LT_DIRECTIONAL)
124                {
[1125]125                        Camera* viewcam = OgreIlluminationManager::getSingleton().getMainCamera();                     
[1055]126                       
[1103]127                        OgreFocusingMapRenderingRun* frun = (OgreFocusingMapRenderingRun*)
[1125]128                                OgreIlluminationManager::getSingleton().getGlobalRun(ILLUMRUN_FOCUSING_MAP)->asOgreRenderingRun();
129                        frun->setCameraMatrices(viewcam->getViewMatrix(), viewcam->getProjectionMatrix());
[1055]130
[1628]131                        Vector3 lightpos = light->getParentSceneNode()->getWorldPosition();
[1103]132                        Vector3 lightdir = light->getDirection();
[1125]133                        lightdir.normalise();           
134                       
135                        Vector3 min;
136                        Vector3 max;                   
[1055]137
[1628]138                       
[1125]139                        if(uselispsm)
140                        {
141                                Camera* maincam = OgreIlluminationManager::getSingleton().getMainCamera();
142                                Vector3 viewdir = maincam->getDirection();
143                                viewdir.normalise();
144                                Vector3 campos = maincam->getPosition();
145                                float nearclip = maincam->getNearClipDistance();
[1055]146
[1125]147                                float dotprod = viewdir.dotProduct(lightdir);
148                                float sinGamma = sqrt(1.0 - dotprod * dotprod);
149                               
150                                Vector3 left = lightdir.crossProduct(viewdir);
[1628]151                                left.normalise();
[1125]152                                Vector3 up = left.crossProduct(lightdir);
153                                up.normalise();
154                                //left = lightdir.crossProduct(up);
155                                left.normalise();                               
156                                Matrix4 viewMatrix( left.x,      left.y,      left.z,            0,
157                                                                        up.x,            up.y,            up.z,                  0,
158                                                                        lightdir.x,  lightdir.y,  lightdir.z,    0,
159                                                                        0,           0,           0,             1);                           
160                               
161                                frun->setLightMatrix(viewMatrix);                               
162                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
163                                                                                                                                                        frameNum);                     
164                                frun->getMinMax(min, max);
165
166                                float n;
167                                float f;
168                                float d = abs(max.y - min.y);
169                                       
170                                float z_n = nearclip / sinGamma;
171                                float one_min_singamma = (1 - sinGamma);
172                                float fact = d * pow(one_min_singamma, 2);
173                                float z_f = z_n + d * sinGamma * fact;
174                                n = (z_n + sqrt(z_f * z_n)) / sinGamma;
175                                ///n = 100000;
176                                f = n + d;
177
178                                Vector3 pos = campos - up * (n - nearclip);
179                                Matrix4 newViewMatrix(  left.x,      left.y,      left.z,                -left.dotProduct(pos),
180                                                                                up.x,            up.y,            up.z,                  -up.dotProduct(pos),
[1628]181                                                                                -lightdir.x,  -lightdir.y,  -lightdir.z,    lightdir.dotProduct(pos),
[1125]182                                                                                0,           0,           0,             1);
183
[1130]184                                Matrix4 lispMat = Matrix4::IDENTITY;
[1125]185                               
[1130]186                                lispMat[1][1] = f / (f - n);
187                                lispMat[1][3] = f * n / (f - n);
188                                lispMat[3][1] = 1;
189                                lispMat[3][3] = 0;
190                               
191                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
192                                depthMapCamera->setCustomViewMatrix(true, lispMat * newViewMatrix);
[1125]193                        }
194                        else
195                        {
[1130]196                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
[1125]197                                depthMapCamera->setCustomViewMatrix(false);
198                                depthMapCamera->setPosition(lightpos);
[1130]199                                depthMapCamera->setDirection(lightdir);                         
[1125]200                        }
201
202
[1130]203                        Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
[1125]204                        frun->setLightMatrix(lightMatrix);
[1120]205                       
[1125]206                        OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
207                                                                                                                                                frameNum);
208
209                        frun->getMinMax(min, max);                     
210
211                                               
[1120]212                        Vector3 scale = (max - min);
[1125]213                        scale *= 1.5; // just for safety
[1628]214                        if(uselispsm)
215                                scale.z += 1;
216                        else
217                                scale.z += 1000; //TODO: get scene bounding box to set z scale 
[1125]218                        Matrix4 projection = Matrix4::IDENTITY;
[1628]219                        Matrix4 trans = Matrix4::IDENTITY;
220                        trans.setTrans(Vector3(-(max.x + min.x) / 2.0,
221                                                                   -(max.y + min.y) / 2.0,
222                                                                   -(max.z + min.z) / 2.0));
223                        Matrix4 scaleM = Matrix4::IDENTITY;
224                        scaleM.setScale(Vector3(2.0 / scale.x, 2.0 / scale.y, -2.0 / scale.z));
225                        projection = scaleM * trans;                   
[1130]226                        depthMapCamera->setCustomProjectionMatrix(true, projection);                   
[790]227                }
228                else if(light->getType() == Light::LT_SPOTLIGHT)
229                {
[1628]230                        Camera* viewcam = OgreIlluminationManager::getSingleton().getMainCamera();                     
231                       
232                        OgreFocusingMapRenderingRun* frun = (OgreFocusingMapRenderingRun*)
233                                OgreIlluminationManager::getSingleton().getGlobalRun(ILLUMRUN_FOCUSING_MAP)->asOgreRenderingRun();
234                        frun->setCameraMatrices(viewcam->getViewMatrix(), viewcam->getProjectionMatrix());
235
236                        Vector3 lightpos = light->getParentSceneNode()->getWorldPosition ();
237                        Vector3 lightdir = light->getDirection();
238                        lightdir.normalise();           
239                        Radian lightangle = light->getSpotlightOuterAngle();
240                               
241                        Vector3 min;
242                        Vector3 max;
243                       
244                        if(uselispsm)
245                        {
246                                Camera* maincam = OgreIlluminationManager::getSingleton().getMainCamera();
247                                Vector3 viewdir = maincam->getDirection();
248                                viewdir.normalise();
249                                Vector3 campos = maincam->getPosition();
250                                float nearclip = maincam->getNearClipDistance();
251
252                                float dotprod = viewdir.dotProduct(lightdir);
253                                float sinGamma = sqrt(1.0 - dotprod * dotprod);
254                               
255                                Vector3 left = lightdir.crossProduct(viewdir);
256                                Vector3 up = left.crossProduct(lightdir);
257                                up.normalise();
258                                //left = lightdir.crossProduct(up);
259                                left.normalise();
260                               
261                                depthMapCamera->setCustomProjectionMatrix(false);
262                                depthMapCamera->setProjectionType(PT_PERSPECTIVE);
263                                depthMapCamera->setFOVy(lightangle);
264                                depthMapCamera->setAspectRatio(1);
265                                depthMapCamera->setNearClipDistance(0.1);
266                                depthMapCamera->setFarClipDistance(1.0);
267
268                                Matrix4 projMatrix = depthMapCamera->getProjectionMatrixWithRSDepth();
269
270                                Matrix4 viewMatrix( left.x,      left.y,      left.z,            0,
271                                                                        up.x,            up.y,            up.z,                  0,
272                                                                        -lightdir.x,  -lightdir.y,  -lightdir.z,    0,
273                                                                        0,           0,           0,             1);                           
274                               
275                                frun->setLightMatrix(projMatrix * viewMatrix);                         
276                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
277                                                                                                                                                        frameNum);                     
278                                frun->getMinMax(min, max);
279
280                                float n;
281                                float f;
282                                float d = abs(max.y - min.y);
283                                       
284                                float z_n = nearclip / sinGamma;
285                                float one_min_singamma = (1 - sinGamma);
286                                float fact = d * pow(one_min_singamma, 2);
287                                float z_f = z_n + d * sinGamma * fact;
288                                n = (z_n + sqrt(z_f * z_n)) / sinGamma;
289                                ///n = 100000;
290                                f = n + d;
291
292                                Vector3 pos = campos - up * (n - nearclip);
293                                Matrix4 newViewMatrix(  left.x,      left.y,      left.z,                -left.dotProduct(pos),
294                                                                                up.x,            up.y,            up.z,                  -up.dotProduct(pos),
295                                                                                -lightdir.x,  -lightdir.y,  -lightdir.z,    lightdir.dotProduct(pos),
296                                                                                0,           0,           0,             1);
297
298                                Matrix4 lispMat = Matrix4::IDENTITY;
299                               
300                                lispMat[1][1] = f / (f - n);
301                                lispMat[1][3] = f * n / (f - n);
302                                lispMat[3][1] = 1;
303                                lispMat[3][3] = 0;
304                               
305                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
306                                depthMapCamera->setCustomViewMatrix(true, lispMat * projMatrix * newViewMatrix);
307                        }
308                        else
309                        {
310                                depthMapCamera->setCustomProjectionMatrix(false);
311                                depthMapCamera->setCustomViewMatrix(false);
312                                depthMapCamera->setPosition(lightpos);
313                                depthMapCamera->setDirection(lightdir);
314                                depthMapCamera->setProjectionType(PT_PERSPECTIVE);
315                                depthMapCamera->setFOVy(lightangle);
316                                depthMapCamera->setAspectRatio(1);
[2189]317                                depthMapCamera->setNearClipDistance(OgreIlluminationManager::getSingleton().getAreaLightRadius());
[1628]318                                depthMapCamera->setFarClipDistance(1.0);
319                        }
320                       
[1639]321                        if(!usefocusing)
[1628]322                        {
[1670]323                                lightFarPlane = light->getAttenuationRange();
324                                depthMapCamera->setFarClipDistance(lightFarPlane);
325                               
[1639]326                        }
327                        else
328                        {
329                                Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
330                                frun->setLightMatrix(lightMatrix);
331                               
332                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
333                                                                                                                                                        frameNum);
[1628]334
[1639]335                                frun->getMinMax(min, max);                     
[1628]336                               
[1639]337                                if(min.z < 0)
338                                {
339                                        float farP= -1.5 * min.z;
340                                        if(farP < 0.2) farP = 0.2;
[1670]341                                                depthMapCamera->setFarClipDistance(farP);
342                                        lightFarPlane = farP;
343                               
[1639]344                                        Vector3 scale = (max - min);
345                                        scale *= 1.5; // just for safety
346                                       
347                                        Matrix4 projection = Matrix4::IDENTITY;
348                                        Matrix4 trans = Matrix4::IDENTITY;
349                                        trans.setTrans(Vector3(-(max.x + min.x) / 2.0,
350                                                                        -(max.y + min.y) / 2.0,
351                                                                                0));
352                                        Matrix4 scaleM = Matrix4::IDENTITY;
353                                        scaleM.setScale(Vector3(2.0 / scale.x, 2.0 / scale.y, 1));
354                                        projection = scaleM * trans;                   
355                                        depthMapCamera->setCustomProjectionMatrix(true, projection * depthMapCamera->getProjectionMatrix());                                           
356                                }
[1628]357                        }
[790]358                }
359                else//point light
360                {
[1055]361        /*              Vector3 pos = light->getParentNode()->getWorldPosition();
[790]362                        Vector3 dir = -pos;
363                        depthMapCamera->setDirection( dir );
364                        depthMapCamera->setPosition(pos);
365                        depthMapCamera->setProjectionType(PT_PERSPECTIVE);
366                        depthMapCamera->setFOVy(Radian(Degree(140)));
367                        depthMapCamera->setNearClipDistance(1);
368                        // depthMapCamera->setFarClipDistance(200);
369       
370                        //OGRE_EXCEPT(0, "NOT implemented for Pointlight", "OgreDepthShadowMapRenderingRun::refreshLight");
[1055]371                */     
[790]372                        /*Vector3 pos = light->getParentNode()->getWorldPosition();
373                        Vector3 dir = -pos;
374                        depthMapCamera->setDirection( dir );
375                        depthMapCamera->setPosition(pos);
376                        depthMapCamera->setProjectionType(PT_ORTHOGRAPHIC);
377                        depthMapCamera->*/
378                       
379                }
380        }
381}
382
[1120]383Matrix4 OgreDepthShadowMapRenderingRun::getLightViewMatrix()
[790]384{
[1120]385        return depthMapCamera->getViewMatrix();
[790]386}
387
[1120]388Matrix4 OgreDepthShadowMapRenderingRun::getLightViewProjMatrix()
[790]389{
[1120]390        return depthMapCamera->getProjectionMatrixWithRSDepth() * depthMapCamera->getViewMatrix();
[790]391}
392
[2320]393void OgreDepthShadowMapRenderingRun::freeAllResources()
394{
[2321]395        this->blurredDepthMapTexture = 0;
396        this->depthMapTexture = 0;
[2320]397        TextureManager::getSingleton().remove(name);
398        TextureManager::getSingleton().remove(blurredname);
399        Root::getSingleton()._getCurrentSceneManager()->destroyCamera(name + "_CAMERA");       
400}
Note: See TracBrowser for help on using the repository browser.