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

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