查看: 5639|回复: 12

光照与纹理混合冲突

[复制链接]

该用户从未签到

发表于 2009-2-28 13:37:27 | 显示全部楼层 |阅读模式
OPENGL是先处理光照再处理纹理 这样的话 纹理混合时选osg::TexEnv::Mode::REPLACE就会出问题把光照效果给代替了 请问有什么方法能既保留光照效果 又能达到REPLACE时的纹理效果

该用户从未签到

发表于 2009-2-28 15:04:54 | 显示全部楼层
着色语言……嗯,最近一直醉心于此

该用户从未签到

 楼主| 发表于 2009-2-28 21:42:58 | 显示全部楼层
看来我真的研究研究着色语言了 ARRAY给个方向吧 怎么我问的问题你都是同一个答复啊 哈哈

该用户从未签到

发表于 2009-2-28 23:31:36 | 显示全部楼层
因为我个人觉得这是个大趋势啊,传统渲染管线正慢慢走向末路吧~~
着色语言的话,nVIDIA Cg是发展最迅速的,HLSL也很迅速,并且和CgFX的语法兼容;GLSL的发展就有些拖后腿。OSG本身全面支持GLSL,也可以使用osgNV来支持Cg。

该用户从未签到

发表于 2010-12-14 17:51:11 | 显示全部楼层
楼主的问题,咋没人回答呢?
我现在也遇到了相同的问题,从OpenGL红宝书上面看,是找不到理由的。
的确启用了多重纹理之后,光照效果就没有了。

“OpenGL是先处理光照,然后再处理纹理,导致多重纹理之后光照效果消失”:该理由我认为不妥。若是这个原因,那么为什么在普通单一纹理的情况下,光照效果很好呢?偏偏等到多重纹理的时候光照才失效?

有人能够回答该问题么?具体该怎么解决?

该用户从未签到

发表于 2010-12-14 18:35:56 | 显示全部楼层
这个问题不解决,我要发疯了的。
我是这样遇到问题的:
一个完整的DEM地形,要更新其中的局部区域纹理。我已经精确计算出更新区域所在的位置,将新的图片放上去。新图片放上去的方式有两种:
1、直接修改原有纹理的像素值。但是我无法获取原有纹理的像素值。osg::Texture2D里面的image对象多半是NULL。在没有OpenGL设备上下文的情况下(OSG每一帧都在使用wglMakeCurrent来设置上下文),也别指望能够使用glCopyTexImage2D之类的鸟函数来获取纹理的像素。若使用啥DrawCallback之类的,趁OSG还没有放掉设备上下文的时候赶快偷取纹理像素。但是这样劳师动众的划不来,会导致我的程序逻辑上牵扯太广。
2、使用多重纹理,使用DECAL或者BLEND方式,将第二重纹理覆盖上去。这样覆盖起来效果很好,快捷清晰,可惜发现地形在该局部失去了光照效果……郁闷ing

有谁能够解决该问题?一个物体使用了两重纹理,它的光照效果竟然就没了,看起来其明暗不受光源控制了,咋办?

该用户从未签到

发表于 2010-12-15 10:57:19 | 显示全部楼层
从osgmultitexture这个例子中看来,并没有您说的这种情况

该用户从未签到

发表于 2010-12-16 17:19:05 | 显示全部楼层
我使用osgMultitexture来进一步核实,若使用DECAL方式,则会发生这种情况。

该用户从未签到

发表于 2010-12-16 17:43:24 | 显示全部楼层
BLEND方式的多重纹理,我还不怎么会用,模拟不出DECAL的效果。
直接使用DECAL方式,则光照效果消失。

该用户从未签到

发表于 2010-12-16 17:47:58 | 显示全部楼层
进一步研究,发现即便不是多重纹理,就一个纹理贴图,若在OpenGL下调用了
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

那么该物体的光照效果就会消失。

该用户从未签到

发表于 2010-12-16 17:56:02 | 显示全部楼层
不光是DECAL方式,REPLACE方式也是如此。
也就是说,OpenGL的“光照先于纹理处理”在这里应验了?感觉不对劲。

该用户从未签到

发表于 2010-12-16 17:59:16 | 显示全部楼层
Decal的效果就是覆盖点之前的texture吧?
我用3dLab  shaderGen得到的实现等同OPENGL两个纹理贴图, T0 GL_MODULATE T1 GL_DECAL, 的效果的fragment shader是:

  1. uniform sampler2D texUnit0;
  2. uniform sampler2D texUnit1;

  3. void main (void)
  4. {
  5.     vec4 color;

  6.     color = gl_Color;

  7.     color *= texture2D(texUnit0, gl_TexCoord[0].xy);

  8.     vec4 texture1 = texture2D(texUnit1, gl_TexCoord[1].xy);
  9.     vec3 tempColor1 = mix(color.rgb, texture1.rgb, texture1.a);
  10.     color = vec4 (tempColor1, color.a);

  11.     gl_FragColor = color;
  12. }
复制代码
可以看出,如果texture1的alpha是1.0的话,最后的颜色的rgb将会是texture1的rgb,与光照及t0都没有关系了。

该用户从未签到

发表于 2010-12-16 18:02:10 | 显示全部楼层
若要使用osgMultiTexture范例程序来验证,那么加入如下代码:
viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

程序跑起来之后,按‘L’键来开关光照效果,看物体的亮度是否会变。若物体的亮度不变,那么显然,该物体已经禁用了光照,它的颜色不受光照影响。
基于这一点,可以试验着修改一下TexEnv对象的那个setMode的参数。
噢,为了能够明显地看出效果,最好不要使用CessnaFire.osg文件,那个文件只有粒子上面有纹理,很难看出来的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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