|
|
发表于 2005-2-24 01:17:00
|
显示全部楼层
Re:快速8-bit通道的伪HDR
那个不是他的笔误,因为这个本身就是近似效果,不过就像我最开始的那个帖子提到的,如果场景不是非低频场景,那么这种近似法必然会产生赝像(就是你说的虚边)不过这种方法的特点是代价低廉,想要效果好的话,那就用多pass实现吧:如果想要比较高程度的blur效果则先down sample一下原场景,然后再使用一些blur filter就行了(可以参考shaderX2上的《实时景深效果》文章,那里提供了2种常用blur filter)
至于速度慢,那么首要问题是代码:
color += texture2D(texture,vec2(gl_TexCoord[0].s+delp,gl_TexCoord[0].t-delp))*5.0 /22.0;
每一条都使用了dependent texture read,这是比较消耗硬件资源的,而楼主的代码明显是用到了GPU的FP寄存器和FP ALU,这对于NV3x是很不利的。我建议的优化是这样(由于我对OpenGL的Vertex/Fragment不熟,所以用D3D代替,和楼主的原理完全一样)
首先,制作一张曝光查表纹理,这里要用到一个简单技巧,由于曝光系数会大于1,为了保证精度,我们将其编码到纹理的rgba 4个通道,r保存sat(exposure);g保存sat(exposure - 1);b保存sat(exposure - 2);a保存sat(exposure - 3);这样,exposure = r+g+b+a,范围是[0,4],可以足够保证expfactor = 1.92时不出现消顶失真,这样我们以u为e, v为expfactor/2.0,依照公式exposure = exp(expfactor) - exp(expfactor-e)制作该纹理,将其设置到texture[5]
在vs中计算纹理坐标,因为纹理坐标只不过是平移,所以在vs中计算的效果不会比ps中计算的效果差,设为t0-t4
ps代码如下:
ps_1_4
def c0,0.30,0.59,0.11,1.0
def c1,0.2273,0.0909,0.8,0.4 //5.0/22.0,2.0/22.0,sharpness,expfactor/2.0
texld r0, t0
texld r1, t1
texld r2, t2
texld r3, t3
texld r4, t4
mul r5, r0, c1.y
mad r5, r1, c1.x,r5
mad r5, r2, c1.x,r5
mad r5, r3, c1.x,r5
mad r5, r4, c1.x,r5 //blur map
dp3 r1, r5, c0 //blur map luminance
lrp r0, c1.z, r0, r5 //blur the source image
mov r1.y,c1.w //move expfactor
phase
texld r5, r1 //get exposure map
add r2, r5.x, r5.w //r+a
mul r3.xyz, r0, r2
add r2, r5.y, r5.z //b+g
mad_sat r0.xyz, r0, r2, r3
+mov r0.w, c0.w
说明一下,由于nv3x在ps1.4中临时寄存器范围是[-2,2]所以不能采用r+g+b+a,这样会消顶失真,所以采用r+a,b+g两步计算。 |
|