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

Revision 1628, 12.6 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
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                if(light->getType() == Light::LT_DIRECTIONAL)
122                {
123                        Camera* viewcam = OgreIlluminationManager::getSingleton().getMainCamera();                     
124                       
125                        OgreFocusingMapRenderingRun* frun = (OgreFocusingMapRenderingRun*)
126                                OgreIlluminationManager::getSingleton().getGlobalRun(ILLUMRUN_FOCUSING_MAP)->asOgreRenderingRun();
127                        frun->setCameraMatrices(viewcam->getViewMatrix(), viewcam->getProjectionMatrix());
128
129                        Vector3 lightpos = light->getParentSceneNode()->getWorldPosition();
130                        Vector3 lightdir = light->getDirection();
131                        lightdir.normalise();           
132                       
133                        Vector3 min;
134                        Vector3 max;                   
135
136                       
137                        if(uselispsm)
138                        {
139                                Camera* maincam = OgreIlluminationManager::getSingleton().getMainCamera();
140                                Vector3 viewdir = maincam->getDirection();
141                                viewdir.normalise();
142                                Vector3 campos = maincam->getPosition();
143                                float nearclip = maincam->getNearClipDistance();
144
145                                float dotprod = viewdir.dotProduct(lightdir);
146                                float sinGamma = sqrt(1.0 - dotprod * dotprod);
147                               
148                                Vector3 left = lightdir.crossProduct(viewdir);
149                                left.normalise();
150                                Vector3 up = left.crossProduct(lightdir);
151                                up.normalise();
152                                //left = lightdir.crossProduct(up);
153                                left.normalise();                               
154                                Matrix4 viewMatrix( left.x,      left.y,      left.z,            0,
155                                                                        up.x,            up.y,            up.z,                  0,
156                                                                        lightdir.x,  lightdir.y,  lightdir.z,    0,
157                                                                        0,           0,           0,             1);                           
158                               
159                                frun->setLightMatrix(viewMatrix);                               
160                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
161                                                                                                                                                        frameNum);                     
162                                frun->getMinMax(min, max);
163
164                                float n;
165                                float f;
166                                float d = abs(max.y - min.y);
167                                       
168                                float z_n = nearclip / sinGamma;
169                                float one_min_singamma = (1 - sinGamma);
170                                float fact = d * pow(one_min_singamma, 2);
171                                float z_f = z_n + d * sinGamma * fact;
172                                n = (z_n + sqrt(z_f * z_n)) / sinGamma;
173                                ///n = 100000;
174                                f = n + d;
175
176                                Vector3 pos = campos - up * (n - nearclip);
177                                Matrix4 newViewMatrix(  left.x,      left.y,      left.z,                -left.dotProduct(pos),
178                                                                                up.x,            up.y,            up.z,                  -up.dotProduct(pos),
179                                                                                -lightdir.x,  -lightdir.y,  -lightdir.z,    lightdir.dotProduct(pos),
180                                                                                0,           0,           0,             1);
181
182                                Matrix4 lispMat = Matrix4::IDENTITY;
183                               
184                                lispMat[1][1] = f / (f - n);
185                                lispMat[1][3] = f * n / (f - n);
186                                lispMat[3][1] = 1;
187                                lispMat[3][3] = 0;
188                               
189                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
190                                depthMapCamera->setCustomViewMatrix(true, lispMat * newViewMatrix);
191                        }
192                        else
193                        {
194                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
195                                depthMapCamera->setCustomViewMatrix(false);
196                                depthMapCamera->setPosition(lightpos);
197                                depthMapCamera->setDirection(lightdir);                         
198                        }
199
200
201                        Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
202                        frun->setLightMatrix(lightMatrix);
203                       
204                        OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
205                                                                                                                                                frameNum);
206
207                        frun->getMinMax(min, max);                     
208
209                                               
210                        Vector3 scale = (max - min);
211                        scale *= 1.5; // just for safety
212                        if(uselispsm)
213                                scale.z += 1;
214                        else
215                                scale.z += 1000; //TODO: get scene bounding box to set z scale 
216                        Matrix4 projection = Matrix4::IDENTITY;
217                        Matrix4 trans = Matrix4::IDENTITY;
218                        trans.setTrans(Vector3(-(max.x + min.x) / 2.0,
219                                                                   -(max.y + min.y) / 2.0,
220                                                                   -(max.z + min.z) / 2.0));
221                        Matrix4 scaleM = Matrix4::IDENTITY;
222                        scaleM.setScale(Vector3(2.0 / scale.x, 2.0 / scale.y, -2.0 / scale.z));
223                        projection = scaleM * trans;                   
224                        depthMapCamera->setCustomProjectionMatrix(true, projection);                   
225                }
226                else if(light->getType() == Light::LT_SPOTLIGHT)
227                {
228                        Camera* viewcam = OgreIlluminationManager::getSingleton().getMainCamera();                     
229                       
230                        OgreFocusingMapRenderingRun* frun = (OgreFocusingMapRenderingRun*)
231                                OgreIlluminationManager::getSingleton().getGlobalRun(ILLUMRUN_FOCUSING_MAP)->asOgreRenderingRun();
232                        frun->setCameraMatrices(viewcam->getViewMatrix(), viewcam->getProjectionMatrix());
233
234                        Vector3 lightpos = light->getParentSceneNode()->getWorldPosition ();
235                        Vector3 lightdir = light->getDirection();
236                        lightdir.normalise();           
237                        Radian lightangle = light->getSpotlightOuterAngle();
238                               
239                        Vector3 min;
240                        Vector3 max;
241                       
242                        if(uselispsm)
243                        {
244                                Camera* maincam = OgreIlluminationManager::getSingleton().getMainCamera();
245                                Vector3 viewdir = maincam->getDirection();
246                                viewdir.normalise();
247                                Vector3 campos = maincam->getPosition();
248                                float nearclip = maincam->getNearClipDistance();
249
250                                float dotprod = viewdir.dotProduct(lightdir);
251                                float sinGamma = sqrt(1.0 - dotprod * dotprod);
252                               
253                                Vector3 left = lightdir.crossProduct(viewdir);
254                                Vector3 up = left.crossProduct(lightdir);
255                                up.normalise();
256                                //left = lightdir.crossProduct(up);
257                                left.normalise();
258                               
259                                depthMapCamera->setCustomProjectionMatrix(false);
260                                depthMapCamera->setProjectionType(PT_PERSPECTIVE);
261                                depthMapCamera->setFOVy(lightangle);
262                                depthMapCamera->setAspectRatio(1);
263                                depthMapCamera->setNearClipDistance(0.1);
264                                depthMapCamera->setFarClipDistance(1.0);
265
266                                Matrix4 projMatrix = depthMapCamera->getProjectionMatrixWithRSDepth();
267
268                                Matrix4 viewMatrix( left.x,      left.y,      left.z,            0,
269                                                                        up.x,            up.y,            up.z,                  0,
270                                                                        -lightdir.x,  -lightdir.y,  -lightdir.z,    0,
271                                                                        0,           0,           0,             1);                           
272                               
273                                frun->setLightMatrix(projMatrix * viewMatrix);                         
274                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
275                                                                                                                                                        frameNum);                     
276                                frun->getMinMax(min, max);
277
278                                float n;
279                                float f;
280                                float d = abs(max.y - min.y);
281                                       
282                                float z_n = nearclip / sinGamma;
283                                float one_min_singamma = (1 - sinGamma);
284                                float fact = d * pow(one_min_singamma, 2);
285                                float z_f = z_n + d * sinGamma * fact;
286                                n = (z_n + sqrt(z_f * z_n)) / sinGamma;
287                                ///n = 100000;
288                                f = n + d;
289
290                                Vector3 pos = campos - up * (n - nearclip);
291                                Matrix4 newViewMatrix(  left.x,      left.y,      left.z,                -left.dotProduct(pos),
292                                                                                up.x,            up.y,            up.z,                  -up.dotProduct(pos),
293                                                                                -lightdir.x,  -lightdir.y,  -lightdir.z,    lightdir.dotProduct(pos),
294                                                                                0,           0,           0,             1);
295
296                                Matrix4 lispMat = Matrix4::IDENTITY;
297                               
298                                lispMat[1][1] = f / (f - n);
299                                lispMat[1][3] = f * n / (f - n);
300                                lispMat[3][1] = 1;
301                                lispMat[3][3] = 0;
302                               
303                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
304                                depthMapCamera->setCustomViewMatrix(true, lispMat * projMatrix * newViewMatrix);
305                        }
306                        else
307                        {
308                                depthMapCamera->setCustomProjectionMatrix(false);
309                                depthMapCamera->setCustomViewMatrix(false);
310                                depthMapCamera->setPosition(lightpos);
311                                depthMapCamera->setDirection(lightdir);
312                                depthMapCamera->setProjectionType(PT_PERSPECTIVE);
313                                depthMapCamera->setFOVy(lightangle);
314                                depthMapCamera->setAspectRatio(1);
315                                depthMapCamera->setNearClipDistance(0.1);
316                                depthMapCamera->setFarClipDistance(1.0);
317                        }
318                       
319
320                        Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
321                        frun->setLightMatrix(lightMatrix);
322                       
323                        OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
324                                                                                                                                                frameNum);
325
326                        frun->getMinMax(min, max);                     
327                       
328                        if(min.z < 0)
329                        {
330                                float farP= -1.5 * min.z;
331                                if(farP < 0.2) farP = 0.2;
332                                depthMapCamera->setFarClipDistance(farP);
333
334                                Vector3 scale = (max - min);
335                                scale *= 1.5; // just for safety
336                               
337                                Matrix4 projection = Matrix4::IDENTITY;
338                                Matrix4 trans = Matrix4::IDENTITY;
339                                trans.setTrans(Vector3(-(max.x + min.x) / 2.0,
340                                                                   -(max.y + min.y) / 2.0,
341                                                                     0));
342                                Matrix4 scaleM = Matrix4::IDENTITY;
343                                scaleM.setScale(Vector3(2.0 / scale.x, 2.0 / scale.y, 1));
344                                projection = scaleM * trans;                   
345                                depthMapCamera->setCustomProjectionMatrix(true, projection * depthMapCamera->getProjectionMatrix());                                           
346                        }
347                }
348                else//point light
349                {
350        /*              Vector3 pos = light->getParentNode()->getWorldPosition();
351                        Vector3 dir = -pos;
352                        depthMapCamera->setDirection( dir );
353                        depthMapCamera->setPosition(pos);
354                        depthMapCamera->setProjectionType(PT_PERSPECTIVE);
355                        depthMapCamera->setFOVy(Radian(Degree(140)));
356                        depthMapCamera->setNearClipDistance(1);
357                        // depthMapCamera->setFarClipDistance(200);
358       
359                        //OGRE_EXCEPT(0, "NOT implemented for Pointlight", "OgreDepthShadowMapRenderingRun::refreshLight");
360                */     
361                        /*Vector3 pos = light->getParentNode()->getWorldPosition();
362                        Vector3 dir = -pos;
363                        depthMapCamera->setDirection( dir );
364                        depthMapCamera->setPosition(pos);
365                        depthMapCamera->setProjectionType(PT_ORTHOGRAPHIC);
366                        depthMapCamera->*/
367                       
368                }
369        }
370}
371
372Matrix4 OgreDepthShadowMapRenderingRun::getLightViewMatrix()
373{
374        return depthMapCamera->getViewMatrix();
375}
376
377Matrix4 OgreDepthShadowMapRenderingRun::getLightViewProjMatrix()
378{
379        return depthMapCamera->getProjectionMatrixWithRSDepth() * depthMapCamera->getViewMatrix();
380}
381
Note: See TracBrowser for help on using the repository browser.