首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

多光源时,亮度叠加怎么实现

2012-03-28 
多光源时,亮度叠加如何实现?多光源时,各个光源的亮度如何实现叠加?在编程时,无论怎样,不管什么亮度的色彩

多光源时,亮度叠加如何实现?
多光源时,各个光源的亮度如何实现叠加?
在编程时,无论怎样,不管什么亮度的色彩最终都要用RGB分量表示,
这样,当两个光源照射一个物体时,叠加起来的颜色的每个分量都有可能超出最大容许值255,这怎么行?
当然,可以简单地限制每个分量最大为255,但这样亮度的连续性就成问题。

[解决办法]
没办法,
[解决办法]
倒是有个办法,x是原的亮度 255*(1-e-(x/255))
[解决办法]
先相加,然后用我那个式子处理一下。
[解决办法]

探讨
引用:
先相加,然后用我那个式子处理一下。


也就是说,把X当做多个光源的RGB某分量的和,这就存在我上面指出的问题啊!

[解决办法]
探讨
举例说,设环境光的RGB为(150,150,150),又一个定向光的RGB为(250,250,250),
则一个物体(例如一个球)被照射得最亮的地方的RGB是多少?
简单叠加任何一个分量得到X=150+250=400,
按照你这个公式计算,新的X值X'应为:
X'=255*(1-e-(400/255))
~255*(1-exp(-400/255))
~255*(1-exp……

[解决办法]
我的想法是把255*(1-e-(x/255))作为显示前最后一步处理
平常把环境光就当做150,定向光就当250,两者之和就当400;

到需要显示时,最后一步时再处理,产生的这个<=255的数只是显示用,并不覆盖原来模型里的数据。
 
[解决办法]
不用那么复杂,用paddusb指令做byte饱和运算,要求很低,支持MMX的CPUs就可以。

[解决办法]
SSE指令的byte饱和运算就是a+b>255则a+b=255

[解决办法]
根据情况不同,有的光照本身就不是完全平滑的,平行光就不是平滑的,例如用手电往墙上照会看到明显的光圈的。光照如果你不用sdk的话,还是很麻烦的,有个公式c = i(c1 + c2) + c3,其中c为最终像素颜色,c1为镜面反射c2为漫反射c3为环境光i为衰减系数,对于多个光源,对i(c1 + c2)进行累加,因为环境光是均匀照亮所有物体的,所以最终结果在和环境光求和而不对环境光进行累加,也不对环境光进行衰减。这个公式展开比较麻烦,就说一下c1的求法
c1 = (n * h)m1 x s (x) m2
n为法向量,h为指向观察点和指向光源的2个归一化向量的中间向量,m1是表面光泽度,s是镜面的漫反射色,m2材质反射色,m1是n * h的指数,*表示点乘,x表示乘,(x)表示叉乘。具体可参看“3d数学基础”的第15章,越界的问题只能对颜色进行规格化处理或截断,例如对rgb分量都乘以一个系数使他降到范围内。最好的办法是在设计的时候就计算好光照强度而避免越界的发生。
[解决办法]
我觉得我的公式最好了,在低亮度时近似于正常的累加,另外函数和函数的各阶导数都是连续的。
[解决办法]
从资料来分析,也许颜色的溢出处理很简单,例如经过光照后的像素颜色为cl(150, 200, 300),要修正这个像素颜色只要根据最大的上溢值300求出系数r=255/300,然后cl * r就可以了,d3d可能就是这样处理的,因为d3d的内部实现不知道,所以我估计还有一个阀值,对于偏色超过一定值的像素直接就截断溢出的分量了,例如偏绿的颜色(20, 300 ,30)直接截断300为255其他不变,这样既不会影响整体色调也节省了几次浮点运算。另外就像lz举的那个球体的例子,物体总有向光面和背光面,如果存在除了环境光以外的其他光源,肯定会有明显的分界的。
[解决办法]
这样的话可以提升数据宽度来解决,比如RGB都用integer,最终结果截断到小于等于255。

[解决办法]
比较有深度的问题,我关注一下。顶!
[解决办法]
多光源,不应该用数值相加,而是取最大光源的值吧

热点排行