查看: 2230|回复: 11

渲染到纹理的问题

[复制链接]

该用户从未签到

发表于 2010-1-7 19:40:23 | 显示全部楼层 |阅读模式
我做了一个渲染水的小程序在渲染近处的倒影,我渲染了一张倒影图做后期处理
效果如下:

镜头不动时

镜头不动时

这个倒影是镜像桥后,渲染到纹理的
问题是:镜头移动时渲染到纹理的那张图延迟了,不能和主相机同步

移动镜头

移动镜头


试过了很多方法控制渲染到纹理的相机,都不能解决,不知道是不是渲染到纹理的相机设置的不对

代码如下:


osg::ref_ptr<osg::Camera> reflectionCamera = new osg::Camera;

reflectionCamera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f));

reflectionCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

reflectionCamera->setViewport(0, 0, 1024, 1024);

reflectionCamera->setRenderOrder(osg::Camera:RE_RENDER);

reflectionCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER);

reflectionCamera->setReferenceFrame(osg::Transform::RELATIVE_RF);

reflectionCamera->attach(osg::Camera::COLOR_BUFFER, reflectionTexture);

reflectionCamera->addChild(reflectionNode);

//reflectionCamera->setUpdateCallback(new RttReflCameraNodeCallback(sceneViewer.getCamera(), waterM->getBound()._center));


无论是指定渲染到纹理的相机的callback与主相机同步,还是指定主相机callback控制渲染到纹理相机都不能同步

像上面那样指定相机osg::Transform::RELATIVE_RF也不行

实在没办法了,忘有高人指点

该用户从未签到

发表于 2010-1-8 08:35:24 | 显示全部楼层
setReferenceFrame和同步没有什么关系,它指定了子相机的参考坐标系;如果您没有自己设置reflectionCamera的观察矩阵和投影矩阵的话,那么用RELATIVE_RF将使其继承主相机的相应设置。

其他的片段代码看起来问题不大,那么问题说不定就在这里:您的构想中是否就是要使reflectionCamera继承sceneViewer.getCamera()的观察和投影矩阵呢?所谓的“不同步”也许只是因为您的观察矩阵设置有偏差而已。不过这需要您进一步阐述自己的问题和实现方法

该用户从未签到

 楼主| 发表于 2010-1-8 09:03:42 | 显示全部楼层
谢谢您的回答

我再说详细点,水体的渲染分全局反射,局部反射,和折射
其中:局部反射和折射的效果需要将要相关的node渲染到纹理,做进一步处理,我用shader处理的

reflectionCamera 应该与 sceneViewer.getCamera() 保持一个“调整矩阵”,我这里的“调整矩阵”就是单位矩阵

当sceneViewer.getCamera()移动的时候,reflectionCamera是不是延迟 1帧呢,因为桥体的倒影在主相机停止时,就慢慢归到正确的位置了。主相机动得越快,位置偏差越大

该用户从未签到

 楼主| 发表于 2010-1-8 09:15:04 | 显示全部楼层
刚才又调试了一下,问题解决了。上面的代码段没问题而是另一处RTT相机设置错了。

还是要通过设置reflectionCamera->setReferenceFrame(osg::Transform::RELATIVE_RF);来指定与主相机的关系,这样指定能保证reflectionCamera和sceneViewer.getCamera()在一帧内关系正确。

而,使用reflectionCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF)
而后通过使用
osg::Camera:rawCallback 或者 osg::NodeCallback 来控制reflectionCamera的绝对位置时,会与sceneViewer.getCamera()偏差x帧。
即,键盘控制主相机到某个观察矩阵后,从相机并不能马上响应,而要到下一帧才能接到改变观察矩阵的消息

该用户从未签到

发表于 2010-1-8 09:20:12 | 显示全部楼层
这个延迟1帧通常并不会造成本质的影响,至少在我这里的应用都没有什么问题;不知您所谓的“慢慢归到正确的位置”是什么意思?如果只是延迟1帧的话,难道不应该在下一帧就立即归于原位吗?如果您看到的不是这种情况,请检查自己的代码实现。

该用户从未签到

 楼主| 发表于 2010-1-8 10:33:58 | 显示全部楼层
估计我的表达有误吧,延迟1帧只是我的猜测,由于我的机器很慢,帧数相当低,所以看起来慢慢的

该用户从未签到

发表于 2010-1-8 10:52:01 | 显示全部楼层
因为RenderToTexture的实现确实需要延迟一帧,所以不排除这会影响您的效果实现;不过您最好换一台好一点的机器进行试验

该用户从未签到

发表于 2010-1-8 16:37:46 | 显示全部楼层
注意一下Viewer::updateTraversal()实现中用操作器矩阵更新相机观察矩阵的操作与节点更新回调操作的顺序,可以看到,主相机观察矩阵的更新是在节点更新回调之后执行的,因此,任何在更新回调中获取主相机观察矩阵以更新自身属性的实现,都会导致滞后一帧的情况!
一个解决办法是简单修改一下Viewer::updateTraversal()的实现,把相机观察矩阵的更新放在节点更新回调前执行。

该用户从未签到

发表于 2010-1-8 16:44:24 | 显示全部楼层
那这是osg故意这样的,还是疏忽呢~~

该用户从未签到

发表于 2010-1-8 16:59:35 | 显示全部楼层
呵呵,应该是有所考虑,不过indef不妨到osg-users上去问一下

该用户从未签到

 楼主| 发表于 2010-1-13 09:09:43 | 显示全部楼层
这个延迟还真的很不方便,昨天调用UnifromCallBack,依旧滞后,搞得我好郁闷

该用户从未签到

发表于 2010-1-13 12:06:19 | 显示全部楼层
那您可以按照indif的建议,把updateTraversal中的顺序对调一下,看看效果如何
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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