查看: 1580|回复: 4

关于阴影光空间到观察空间的问题

[复制链接]

该用户从未签到

发表于 2013-4-3 10:23:43 | 显示全部楼层 |阅读模式
目的:做一个通过glsl实现的光照阴影效果
我的实现步骤:
第一步:建立rttcamera设置
  1. osg::ref_ptr<osg::Node> node = osgDB::readNodeFile( "some model file" );
  2. osg::ref_ptr<osg::Texture2D> tex2D = new osg::Texture2D;
  3. tex2D->setTextureSize( 1024, 1024 );
  4. tex2D->setInternalFormat( GL_DEPTH_COMPONENT24 );
  5. tex2D->setSourceFormat( GL_DEPTH_COMPONENT );
  6. tex2D->setShadowComparison(true);
  7. tex2D->setShadowTextureMode(osg::Texture2D::LUMINANCE);
  8. tex2D->setSourceType( GL_FLOAT );
  9. osg::ref_ptr<osg::Camera> camera = new osg::Camera;
  10. camera->setClearColor( osg::Vec4() );
  11. camera->setClearMask( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
  12. camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
  13. camera->setRenderOrder( osg::Camera::PRE_RENDER );
  14. tex2D->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
  15. tex2D->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
  16. tex->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
  17. osg::BoundingSphere& bs = scene->getBound();
  18. float znear = 1.0f * bs.radius();
  19. float zfar = 3.0f * bs.radius();
  20. float proj_top = 0.5f * zfar;
  21. float proj_right = 0.75f * zfar;
  22. znear *= 0.9f;
  23. zfar *= 1.1f;
  24. camera->setProjectionMatrixAsFrustum(-proj_right, proj_right, -proj_top, proj_top,znear, zfar);
  25. camera->setViewport( 0, 0, tex2D->getTextureWidth(), tex2D->getTextureHeight() );
  26. camera->attach( osg::Camera::DEPTH_BUFFER, tex2D );
  27. camera->addChild( root.get() );
  28. camera->setViewMatrix(osg::Matrix::lookAt(...));
复制代码
然后在camera中加入自己的glsl代码,能够正常输出(通过相机attach一张imange输出到本地磁盘检测);

第二步:将tex2D作为texture传入
继上面的代码
  1. osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
  2. mt->addChild(node.get());
  3. mt->getOrCreateStateSet()->setTextureAttributeAndModes(7, tex2D.get(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
  4. mt->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
  5. //最加入自己的glsl代码,并设置相应的uniform
复制代码
第三步:将mt和camera加入一个group节点,传入viewer。

在上面第二步中,我要将每个顶点进行矩阵转换来对应到rtt渲染后的深度图中对应的值。下面是部分glsl 的代码
  1. // vertSource

  2. varying vec4 PreVertex;  
  3. varying vec4 PreNormal;                                             
  4. varying vec4 DepthCoord; // 深度纹理坐标                                                                                                
  5. uniform mat4 MatToShadow;     // 转换矩阵                                         
  6. uniform mat4 osg_ViewMatrixInverse;
  7. void main(void)                                                     
  8. {                                 
  9.         // 求出世界坐标系下的值
  10.         PreVertex = osg_ViewMatrixInverse *gl_ModelViewMatrix* gl_Vertex;
  11.        
  12.         // 求出阴影纹理坐标的值
  13.         DepthCoord =PreVertex * MatToShadow; or DepthCoord = MatToShadow * PreVertex;
  14.         ...
  15.        
  16. }

复制代码
问题:

我自己的一些思考,根据projCoord = VM * PM; 我把MatToShadow设置为 camera->getViewMatrix() * camera->getProjectionMatrix(); 然后用DepthCoord =PreVertex * MatToShadow;计算,但是不对。
问题来了,请问需要传入什么样的矩阵才能获取我想要的结果????? 或者说在以上的步骤当中我缺少了哪些环节,哪些环节是错误的。请大家帮我指点一下。

该用户从未签到

发表于 2013-4-3 10:28:29 | 显示全部楼层
我不知道您的MatToShadow是什么内容,如果只是view * proj肯定是不够的,因为这样得到的结果是[-1,1]之间,需要变换到[0,1]空间才算是正确的。

该用户从未签到

 楼主| 发表于 2013-4-3 10:36:36 | 显示全部楼层
array 发表于 2013-4-3 10:28
我不知道您的MatToShadow是什么内容,如果只是view * proj肯定是不够的,因为这样得到的结果是[-1,1]之间, ...

mattoshadow就是我想要的变换矩阵,那么按照您的意识,我将 matToShadow 设置为 camera的 view × proj,然后将glsl里面的PreVertex × tempvert,所获取的值 乘以0.5加上0.5就是我想要的深度图对于的纹理坐标了?

该用户从未签到

发表于 2013-4-3 11:08:50 | 显示全部楼层

该用户从未签到

 楼主| 发表于 2013-4-3 11:19:52 | 显示全部楼层
liuzhiyu123 发表于 2013-4-3 11:08

那么我再多问一句。这样的话我是不是只要texture2D(传入的sampler2D与付给mt的参数一致,转换后的纹理坐标.xy);就可以找到该坐标的值?
在那个算出来的PreVertex需不需要在和mattoshadow相乘前除以PreVertex.w?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表