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

Revision 1688, 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}
107
108const String& OgreDepthShadowMapRenderingRun::getDepthMapTextureName()
109{
110                if(OgreIlluminationManager::getSingleton().getBlurShadowMap())
111                        return blurredname;
112
113                return name;
114}
115
116void OgreDepthShadowMapRenderingRun::refreshLight(unsigned long frameNum)
117{
118       
119        if(light!= 0)
120        {
121                bool uselispsm = OgreIlluminationManager::getSingleton().getUseLISPSM();
122                bool usefocusing = OgreIlluminationManager::getSingleton().getFocusingShadowMap();
123                if(light->getType() == Light::LT_DIRECTIONAL)
124                {
125                        Camera* viewcam = OgreIlluminationManager::getSingleton().getMainCamera();                     
126                       
127                        OgreFocusingMapRenderingRun* frun = (OgreFocusingMapRenderingRun*)
128                                OgreIlluminationManager::getSingleton().getGlobalRun(ILLUMRUN_FOCUSING_MAP)->asOgreRenderingRun();
129                        frun->setCameraMatrices(viewcam->getViewMatrix(), viewcam->getProjectionMatrix());
130
131                        Vector3 lightpos = light->getParentSceneNode()->getWorldPosition();
132                        Vector3 lightdir = light->getDirection();
133                        lightdir.normalise();           
134                       
135                        Vector3 min;
136                        Vector3 max;                   
137
138                       
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();
146
147                                float dotprod = viewdir.dotProduct(lightdir);
148                                float sinGamma = sqrt(1.0 - dotprod * dotprod);
149                               
150                                Vector3 left = lightdir.crossProduct(viewdir);
151                                left.normalise();
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),
181                                                                                -lightdir.x,  -lightdir.y,  -lightdir.z,    lightdir.dotProduct(pos),
182                                                                                0,           0,           0,             1);
183
184                                Matrix4 lispMat = Matrix4::IDENTITY;
185                               
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);
193                        }
194                        else
195                        {
196                                depthMapCamera->setCustomProjectionMatrix(true, Matrix4::IDENTITY);
197                                depthMapCamera->setCustomViewMatrix(false);
198                                depthMapCamera->setPosition(lightpos);
199                                depthMapCamera->setDirection(lightdir);                         
200                        }
201
202
203                        Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
204                        frun->setLightMatrix(lightMatrix);
205                       
206                        OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
207                                                                                                                                                frameNum);
208
209                        frun->getMinMax(min, max);                     
210
211                                               
212                        Vector3 scale = (max - min);
213                        scale *= 1.5; // just for safety
214                        if(uselispsm)
215                                scale.z += 1;
216                        else
217                                scale.z += 1000; //TODO: get scene bounding box to set z scale 
218                        Matrix4 projection = Matrix4::IDENTITY;
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;                   
226                        depthMapCamera->setCustomProjectionMatrix(true, projection);                   
227                }
228                else if(light->getType() == Light::LT_SPOTLIGHT)
229                {
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);
317                                depthMapCamera->setNearClipDistance(0.1);
318                                depthMapCamera->setFarClipDistance(1.0);
319                        }
320                       
321                        if(!usefocusing)
322                        {
323                                lightFarPlane = light->getAttenuationRange();
324                                depthMapCamera->setFarClipDistance(lightFarPlane);
325                               
326                        }
327                        else
328                        {
329                                Matrix4 lightMatrix = depthMapCamera->getViewMatrix();
330                                frun->setLightMatrix(lightMatrix);
331                               
332                                OgreIlluminationManager::getSingleton().updateGlobalRun( ILLUMRUN_FOCUSING_MAP,
333                                                                                                                                                        frameNum);
334
335                                frun->getMinMax(min, max);                     
336                               
337                                if(min.z < 0)
338                                {
339                                        float farP= -1.5 * min.z;
340                                        if(farP < 0.2) farP = 0.2;
341                                                depthMapCamera->setFarClipDistance(farP);
342                                        lightFarPlane = farP;
343                               
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                                }
357                        }
358                }
359                else//point light
360                {
361        /*              Vector3 pos = light->getParentNode()->getWorldPosition();
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");
371                */     
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
383Matrix4 OgreDepthShadowMapRenderingRun::getLightViewMatrix()
384{
385        return depthMapCamera->getViewMatrix();
386}
387
388Matrix4 OgreDepthShadowMapRenderingRun::getLightViewProjMatrix()
389{
390        return depthMapCamera->getProjectionMatrixWithRSDepth() * depthMapCamera->getViewMatrix();
391}
392
Note: See TracBrowser for help on using the repository browser.