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

Revision 2410, 15.9 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{
[2333]28        if(light->getType() == Light::LT_POINT)
29        {
30                depthMapTexture = createCubeRenderTexture(name, light->getPosition(), resolutionX,PF_FLOAT16_RGBA,0,ColourValue::White);
[2410]31                for(int i = 0; i < 6; i++)
32                        depthMapTexture->getBuffer(i, 0).getPointer()->getRenderTarget()->getViewport(0)->setSkiesEnabled(false);
33               
[2333]34                if(OgreIlluminationManager::getSingleton().getBlurShadowMap(light->getType()))
35                blurredDepthMapTexture = createCubeRenderTexture(blurredname, light->getPosition(), resolutionX,PF_FLOAT16_RGBA,0,ColourValue::White);
36        }
37        else
38        {
[1120]39       
40                TexturePtr texPtr = Ogre::TextureManager::getSingleton().createManual(name,
[1055]41                                                                                                                                                        "default",
42                                                                                                                                                        TEX_TYPE_2D,
43                                                                                                                                                        resolutionX,
44                                                                                                                                                        resolutionY,
45                                                                                                                                                        0,
46                                                                                                                                                        0,
47                                                                                                                                                        PF_FLOAT16_RGBA,
[1130]48                                                                                                                                                        TU_RENDERTARGET);               
[1120]49                depthMapTexture = texPtr.getPointer();
50                depthMapCamera = Root::getSingleton()._getCurrentSceneManager()->createCamera(name + "_CAMERA");
[1055]51                //add viewport to rendertarget
[1120]52                HardwarePixelBuffer* hpb = (depthMapTexture->getBuffer()).getPointer();
[1055]53                RenderTarget* rt = hpb->getRenderTarget();
[1120]54                Viewport* v = rt->addViewport(depthMapCamera);
[1628]55                v->setBackgroundColour(ColourValue::White);
[1055]56                v->setOverlaysEnabled(false);
[2406]57                v->setSkiesEnabled(false);
[1130]58                rt->setAutoUpdated(false);
[1628]59               
[2333]60                if(OgreIlluminationManager::getSingleton().getBlurShadowMap(light->getType()))
[1628]61                {
62                        texPtr = Ogre::TextureManager::getSingleton().createManual(blurredname,
63                                                                                                                                                                "default",
64                                                                                                                                                                TEX_TYPE_2D,
65                                                                                                                                                                resolutionX,
66                                                                                                                                                                resolutionY,
67                                                                                                                                                                0,
[2297]68                                                                                                                                                                0,
[1628]69                                                                                                                                                                PF_FLOAT16_RGBA,
70                                                                                                                                                                TU_RENDERTARGET);
71                        blurredDepthMapTexture = texPtr.getPointer();
72                        hpb = (blurredDepthMapTexture->getBuffer()).getPointer();
73                        rt = hpb->getRenderTarget();
74                        v = rt->addViewport(depthMapCamera);
75                        v->setOverlaysEnabled(false);
76                        rt->setAutoUpdated(false);
77                }
[2333]78        }
[790]79}
80
[2379]81bool  OgreDepthShadowMapRenderingRun::renderableQueued (Renderable *rend, uint8 groupID, ushort priority, Technique **ppTech)
82{
[2406]83        if((*ppTech)->isTransparent())
84                return false;
85
86        String materialToSet = materialName;
[2379]87        OgreTechniqueGroup* TG = (OgreTechniqueGroup*) rend->getRenderTechniqueGroup();
88        if(TG)
89        {
90                String triggeredMaterial = TG->getMaterialNameForTrigger(triggerName);
91                if(triggeredMaterial != "")//a trigger is associated
92                        materialToSet = triggeredMaterial;
[2410]93       
94        }       
95       
[2406]96        Technique* techn = ((Material*)MaterialManager::getSingleton().getByName(       materialToSet ).getPointer())->getTechnique(0);
97        *ppTech = techn;       
[2379]98        return true;
99}
100
[790]101void OgreDepthShadowMapRenderingRun::updateFrame(unsigned long frameNum)
102{
[1103]103        refreshLight(frameNum);
[2410]104       
[790]105        if(light->getType() == Light::LT_POINT)
[2379]106        {               
[2375]107               
[2333]108                for(int i = 0; i < 6 ; i++)
[2379]109                        updateDepthCubeFace(i);         
[2375]110
[2379]111                //restoreMaterials();
[790]112        }
113        else
114        {
115                updateDepthMap();
[1130]116        }       
[2379]117
[2410]118       
[790]119}
120
121void OgreDepthShadowMapRenderingRun::updateDepthCubeFace(int facenum)
[2375]122{       
123        Vector3 lightpos = light->getDerivedPosition();                 
124               
[2333]125        RenderTarget* rt = depthMapTexture->getBuffer(facenum, 0).getPointer()->getRenderTarget();     
126        Camera*  cam =  rt->getViewport(0)->getCamera();
127        cam->setFarClipDistance(lightFarPlane);
[2375]128        cam->setPosition(lightpos);
129       
130       
[2379]131        //setMaterialForVisibles(materialName, cam, true, false, triggerName);
[2410]132        RenderQueue* rq = Root::getSingleton()._getCurrentSceneManager()->getRenderQueue();             
133        rq->setRenderableListener(this);
134
[2333]135        rt->update();
136
[2375]137//      restoreMaterials();
138       
[2333]139        //rt->writeContentsToFile("shadowmap_" + StringConverter::toString(facenum) + ".dds");
140
[2410]141        rq->setRenderableListener(0);
142
[2333]143        if(OgreIlluminationManager::getSingleton().getBlurShadowMap(light->getType()))
144        {
145                rt = blurredDepthMapTexture->getBuffer(facenum, 0).getPointer()->getRenderTarget();
146                Material*  mat = (Material*) MaterialManager::getSingleton().getByName("GameTools/BlurCubeFace").getPointer();
147                mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(depthMapTexture->getName());
148                mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("face", facenum);
149                renderFullscreenQuad("GameTools/BlurCubeFace", rt);             
150               
151                //rt->writeContentsToFile("shadowmap_blurred_" + StringConverter::toString(facenum) + ".dds");
[2375]152        }       
[790]153}
154
155void OgreDepthShadowMapRenderingRun::updateDepthMap()
156{
[2379]157       
[1120]158        RenderTarget* rt = depthMapTexture->getBuffer().getPointer()->getRenderTarget();       
159        Viewport* vp = rt->getViewport(0);
160       
[2379]161        //setMaterialForVisibles(materialName, depthMapCamera, true, false, triggerName);       
[2410]162        RenderQueue* rq = Root::getSingleton()._getCurrentSceneManager()->getRenderQueue();             
163        rq->setRenderableListener(this);
164
[1055]165        rt->update();
[1130]166       
[2379]167        //restoreMaterials();
[2410]168        rq->setRenderableListener(0);
169
[2333]170        if(OgreIlluminationManager::getSingleton().getBlurShadowMap(light->getType()))
[1628]171        {
172                rt = blurredDepthMapTexture->getBuffer().getPointer()->getRenderTarget();
173                Material*  mat = (Material*) MaterialManager::getSingleton().getByName("GameTools/Blur").getPointer();
174                mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(depthMapTexture->getName());
175                renderFullscreenQuad("GameTools/Blur", rt);
176        }       
[1130]177       
[2182]178        //rt->writeContentsToFile("shadowmap1.dds");
[1130]179
180        //depthMapTexture->();
[1055]181}
[1688]182
183const String& OgreDepthShadowMapRenderingRun::getDepthMapTextureName()
[1055]184{
[2333]185                if(OgreIlluminationManager::getSingleton().getBlurShadowMap(light->getType()))
[1628]186                        return blurredname;
[790]187
[1628]188                return name;
[790]189}
190
[1103]191void OgreDepthShadowMapRenderingRun::refreshLight(unsigned long frameNum)
[790]192{
193        if(light!= 0)
194        {
[2333]195                bool uselispsm = OgreIlluminationManager::getSingleton().getUseLISPSM(light->getType());
196                bool usefocusing = OgreIlluminationManager::getSingleton().getFocusingShadowMap(light->getType());
[790]197                if(light->getType() == Light::LT_DIRECTIONAL)
198                {
[2379]199                        triggerName = "ILLUM_TRIGGER_SM_DIRECTIONAL";
[1125]200                        Camera* viewcam = OgreIlluminationManager::getSingleton().getMainCamera();                     
[1055]201                       
[1103]202                        OgreFocusingMapRenderingRun* frun = (OgreFocusingMapRenderingRun*)
[1125]203                                OgreIlluminationManager::getSingleton().getGlobalRun(ILLUMRUN_FOCUSING_MAP)->asOgreRenderingRun();
204                        frun->setCameraMatrices(viewcam->getViewMatrix(), viewcam->getProjectionMatrix());
[1055]205
[2333]206                        Vector3 lightpos = light->getDerivedPosition();
207                        Vector3 lightdir = light->getDerivedDirection();
[1125]208                        lightdir.normalise();           
209                       
210                        Vector3 min;
211                        Vector3 max;                   
[1055]212
[1628]213                       
[1125]214                        if(uselispsm)
215                        {
216                                Camera* maincam = OgreIlluminationManager::getSingleton().getMainCamera();
217                                Vector3 viewdir = maincam->getDirection();
218                                viewdir.normalise();
219                                Vector3 campos = maincam->getPosition();
220                                float nearclip = maincam->getNearClipDistance();
[1055]221
[1125]222                                float dotprod = viewdir.dotProduct(lightdir);
223                                float sinGamma = sqrt(1.0 - dotprod * dotprod);
224                               
225                                Vector3 left = lightdir.crossProduct(viewdir);
[1628]226                                left.normalise();
[1125]227                                Vector3 up = left.crossProduct(lightdir);
228                                up.normalise();
229                                //left = lightdir.crossProduct(up);
230                                left.normalise();                               
231                                Matrix4 viewMatrix( left.x,      left.y,      left.z,            0,
232                                                                        up.x,            up.y,            up.z,                  0,
233                                                                        lightdir.x,  lightdir.y,  lightdir.z,    0,
234                                                                        0,           0,           0,             1);                           
235                               
236                                frun->setLightMatrix(viewMatrix);                               
237                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
238                                                                                                                                                        frameNum);                     
239                                frun->getMinMax(min, max);
240
241                                float n;
242                                float f;
243                                float d = abs(max.y - min.y);
244                                       
245                                float z_n = nearclip / sinGamma;
246                                float one_min_singamma = (1 - sinGamma);
247                                float fact = d * pow(one_min_singamma, 2);
248                                float z_f = z_n + d * sinGamma * fact;
249                                n = (z_n + sqrt(z_f * z_n)) / sinGamma;
250                                ///n = 100000;
251                                f = n + d;
252
253                                Vector3 pos = campos - up * (n - nearclip);
254                                Matrix4 newViewMatrix(  left.x,      left.y,      left.z,                -left.dotProduct(pos),
255                                                                                up.x,            up.y,            up.z,                  -up.dotProduct(pos),
[1628]256                                                                                -lightdir.x,  -lightdir.y,  -lightdir.z,    lightdir.dotProduct(pos),
[1125]257                                                                                0,           0,           0,             1);
258
[1130]259                                Matrix4 lispMat = Matrix4::IDENTITY;
[1125]260                               
[1130]261                                lispMat[1][1] = f / (f - n);
262                                lispMat[1][3] = f * n / (f - n);
263                                lispMat[3][1] = 1;
264                                lispMat[3][3] = 0;
265                               
266                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
267                                depthMapCamera->setCustomViewMatrix(true, lispMat * newViewMatrix);
[1125]268                        }
269                        else
270                        {
[1130]271                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
[1125]272                                depthMapCamera->setCustomViewMatrix(false);
273                                depthMapCamera->setPosition(lightpos);
[1130]274                                depthMapCamera->setDirection(lightdir);                         
[1125]275                        }
276
277
[1130]278                        Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
[1125]279                        frun->setLightMatrix(lightMatrix);
[1120]280                       
[1125]281                        OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
282                                                                                                                                                frameNum);
283
284                        frun->getMinMax(min, max);                     
285
286                                               
[1120]287                        Vector3 scale = (max - min);
[1125]288                        scale *= 1.5; // just for safety
[1628]289                        if(uselispsm)
290                                scale.z += 1;
291                        else
292                                scale.z += 1000; //TODO: get scene bounding box to set z scale 
[1125]293                        Matrix4 projection = Matrix4::IDENTITY;
[1628]294                        Matrix4 trans = Matrix4::IDENTITY;
295                        trans.setTrans(Vector3(-(max.x + min.x) / 2.0,
296                                                                   -(max.y + min.y) / 2.0,
297                                                                   -(max.z + min.z) / 2.0));
298                        Matrix4 scaleM = Matrix4::IDENTITY;
299                        scaleM.setScale(Vector3(2.0 / scale.x, 2.0 / scale.y, -2.0 / scale.z));
300                        projection = scaleM * trans;                   
[1130]301                        depthMapCamera->setCustomProjectionMatrix(true, projection);                   
[790]302                }
303                else if(light->getType() == Light::LT_SPOTLIGHT)
304                {
[2379]305                        triggerName = "ILLUM_TRIGGER_SM_SPOT";
[1628]306                        Camera* viewcam = OgreIlluminationManager::getSingleton().getMainCamera();                     
307                       
308                        OgreFocusingMapRenderingRun* frun = (OgreFocusingMapRenderingRun*)
309                                OgreIlluminationManager::getSingleton().getGlobalRun(ILLUMRUN_FOCUSING_MAP)->asOgreRenderingRun();
310                        frun->setCameraMatrices(viewcam->getViewMatrix(), viewcam->getProjectionMatrix());
311
[2333]312                        Vector3 lightpos = light->getDerivedPosition();
313                        Vector3 lightdir = light->getDerivedDirection();
[1628]314                        lightdir.normalise();           
315                        Radian lightangle = light->getSpotlightOuterAngle();
316                               
317                        Vector3 min;
318                        Vector3 max;
319                       
320                        if(uselispsm)
321                        {
322                                Camera* maincam = OgreIlluminationManager::getSingleton().getMainCamera();
323                                Vector3 viewdir = maincam->getDirection();
324                                viewdir.normalise();
325                                Vector3 campos = maincam->getPosition();
326                                float nearclip = maincam->getNearClipDistance();
327
328                                float dotprod = viewdir.dotProduct(lightdir);
329                                float sinGamma = sqrt(1.0 - dotprod * dotprod);
330                               
331                                Vector3 left = lightdir.crossProduct(viewdir);
332                                Vector3 up = left.crossProduct(lightdir);
333                                up.normalise();
334                                //left = lightdir.crossProduct(up);
335                                left.normalise();
336                               
337                                depthMapCamera->setCustomProjectionMatrix(false);
338                                depthMapCamera->setProjectionType(PT_PERSPECTIVE);
339                                depthMapCamera->setFOVy(lightangle);
340                                depthMapCamera->setAspectRatio(1);
341                                depthMapCamera->setNearClipDistance(0.1);
342                                depthMapCamera->setFarClipDistance(1.0);
343
344                                Matrix4 projMatrix = depthMapCamera->getProjectionMatrixWithRSDepth();
345
346                                Matrix4 viewMatrix( left.x,      left.y,      left.z,            0,
347                                                                        up.x,            up.y,            up.z,                  0,
348                                                                        -lightdir.x,  -lightdir.y,  -lightdir.z,    0,
349                                                                        0,           0,           0,             1);                           
350                               
351                                frun->setLightMatrix(projMatrix * viewMatrix);                         
352                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
353                                                                                                                                                        frameNum);                     
354                                frun->getMinMax(min, max);
355
356                                float n;
357                                float f;
358                                float d = abs(max.y - min.y);
359                                       
360                                float z_n = nearclip / sinGamma;
361                                float one_min_singamma = (1 - sinGamma);
362                                float fact = d * pow(one_min_singamma, 2);
363                                float z_f = z_n + d * sinGamma * fact;
364                                n = (z_n + sqrt(z_f * z_n)) / sinGamma;
365                                ///n = 100000;
366                                f = n + d;
367
368                                Vector3 pos = campos - up * (n - nearclip);
369                                Matrix4 newViewMatrix(  left.x,      left.y,      left.z,                -left.dotProduct(pos),
370                                                                                up.x,            up.y,            up.z,                  -up.dotProduct(pos),
371                                                                                -lightdir.x,  -lightdir.y,  -lightdir.z,    lightdir.dotProduct(pos),
372                                                                                0,           0,           0,             1);
373
374                                Matrix4 lispMat = Matrix4::IDENTITY;
375                               
376                                lispMat[1][1] = f / (f - n);
377                                lispMat[1][3] = f * n / (f - n);
378                                lispMat[3][1] = 1;
379                                lispMat[3][3] = 0;
380                               
381                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
382                                depthMapCamera->setCustomViewMatrix(true, lispMat * projMatrix * newViewMatrix);
383                        }
384                        else
385                        {
386                                depthMapCamera->setCustomProjectionMatrix(false);
387                                depthMapCamera->setCustomViewMatrix(false);
388                                depthMapCamera->setPosition(lightpos);
389                                depthMapCamera->setDirection(lightdir);
390                                depthMapCamera->setProjectionType(PT_PERSPECTIVE);
391                                depthMapCamera->setFOVy(lightangle);
392                                depthMapCamera->setAspectRatio(1);
[2189]393                                depthMapCamera->setNearClipDistance(OgreIlluminationManager::getSingleton().getAreaLightRadius());
[1628]394                                depthMapCamera->setFarClipDistance(1.0);
395                        }
396                       
[1639]397                        if(!usefocusing)
[1628]398                        {
[1670]399                                lightFarPlane = light->getAttenuationRange();
400                                depthMapCamera->setFarClipDistance(lightFarPlane);
401                               
[1639]402                        }
403                        else
404                        {
405                                Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
406                                frun->setLightMatrix(lightMatrix);
407                               
408                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
409                                                                                                                                                        frameNum);
[1628]410
[1639]411                                frun->getMinMax(min, max);                     
[1628]412                               
[1639]413                                if(min.z < 0)
414                                {
415                                        float farP= -1.5 * min.z;
416                                        if(farP < 0.2) farP = 0.2;
[1670]417                                                depthMapCamera->setFarClipDistance(farP);
418                                        lightFarPlane = farP;
419                               
[1639]420                                        Vector3 scale = (max - min);
421                                        scale *= 1.5; // just for safety
422                                       
423                                        Matrix4 projection = Matrix4::IDENTITY;
424                                        Matrix4 trans = Matrix4::IDENTITY;
425                                        trans.setTrans(Vector3(-(max.x + min.x) / 2.0,
426                                                                        -(max.y + min.y) / 2.0,
427                                                                                0));
428                                        Matrix4 scaleM = Matrix4::IDENTITY;
429                                        scaleM.setScale(Vector3(2.0 / scale.x, 2.0 / scale.y, 1));
430                                        projection = scaleM * trans;                   
431                                        depthMapCamera->setCustomProjectionMatrix(true, projection * depthMapCamera->getProjectionMatrix());                                           
432                                }
[1628]433                        }
[790]434                }
435                else//point light
436                {
[2333]437                        lightFarPlane = light->getAttenuationRange();
[2379]438                        triggerName = "ILLUM_TRIGGER_SM_POINT";         
[2333]439                        //no other adjustment needed                   
[790]440                }
441        }
442}
443
[1120]444Matrix4 OgreDepthShadowMapRenderingRun::getLightViewMatrix()
[790]445{
[2333]446        Camera* cam = depthMapCamera;
447        if(light->getType() == Light::LT_POINT)
448         cam = depthMapTexture->getBuffer(4, 0).getPointer()->getRenderTarget()->getViewport(0)->getCamera();   
449       
450        return cam->getViewMatrix();
[790]451}
452
[1120]453Matrix4 OgreDepthShadowMapRenderingRun::getLightViewProjMatrix()
[790]454{
[2333]455        Camera* cam = depthMapCamera;
456        if(light->getType() == Light::LT_POINT)
457         cam = depthMapTexture->getBuffer(4, 0).getPointer()->getRenderTarget()->getViewport(0)->getCamera();   
458       
459        return cam->getProjectionMatrixWithRSDepth() * cam->getViewMatrix();
[790]460}
461
[2320]462void OgreDepthShadowMapRenderingRun::freeAllResources()
463{
[2321]464        this->blurredDepthMapTexture = 0;
465        this->depthMapTexture = 0;
[2320]466        TextureManager::getSingleton().remove(name);
467        TextureManager::getSingleton().remove(blurredname);
468        Root::getSingleton()._getCurrentSceneManager()->destroyCamera(name + "_CAMERA");       
469}
Note: See TracBrowser for help on using the repository browser.