本文主要是介绍#OSG+VS#第七周 关于osgearth中shadowing的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
成果总结:
本周三天工作日,完成两件事。
一是重写了shadowing.h和shadowing.cpp,因为直接修改原始的库代码不起作用,师姐说是因为我们的代码开头只是包含头文件,对应的.lib和.dll没有变化(实际运行的是dll)。(还是基础不够啊)
重写之后,还要修改类的命名(不与shadowing重复),删除命名空间,并在mainwindow中作相应修改。这样就能对其进行操作,修改参数看效果了。
尝试删除bias,发现屋顶的Peter panning基本消失,猜测整个房屋的阴影偏移应该也能解决,但是由于房屋是悬空的,所以不敢确定。也就不能进一步确定自投影问题是否完全解决。
二是弄懂shadowing.cpp的后半部分,也就是矩阵变换部分。
下面是我对整个shadowing.cpp的理解。
1.原理
shadow map深度纹理算法分为两步,首先将视点放在光源位置,得到此时的深度图,将光源距最近物体的距离(depth)与每个纹理坐标采样点的深度(c.z-bias)比较,判断是否处于阴影中;再将视点放在正常的观察位置,正常渲染出光亮和阴影。
2.代码
cpp文件的主体可分为两个部分,(按代码的书写顺序)一是GLSL着色语言部分,对深度的判断和着色;二是矩阵变换,投影变换用于第一部分深度判断。所以还是从矩阵变换开始讲。
(图片来自网上)
osg::Matrix MV = *cv->getModelViewMatrix();osg::Matrix inverseMV;inverseMV.invert(MV);
↑得到模型视图矩阵。
osg::Vec4d lp4 = _light->getPosition();osg::Vec3d lightVectorWorld( -lp4.x(), -lp4.y(), -lp4.z() );lightVectorWorld.normalize();osg::Vec3d lightPosWorld = osg::Vec3d(0,0,0) * inverseMV;//视点坐标系下的视点(0,0,0)在世界坐标系下为:Pworld=(0,0,0)* MV逆
↑得到光源的世界坐标。
osg::Matrix lightViewMat;lightViewMat.makeLookAt(lightPosWorld, lightPosWorld+lightVectorWorld, camUp);//相机放在光源位置to be a view matrix
↑得到光源的视图矩阵。
osg::Matrix proj = _prevProjMatrix;//cv->clampProjectionMatrix(proj, n, f);double fovy,ar,zn,zf;proj.getPerspective(fovy,ar,zn,zf);
这篇关于#OSG+VS#第七周 关于osgearth中shadowing的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!