如何将GLSL叠加混合转换为OpenGL ES 1.1?

时间:2011-01-08 14:09:15

标签: iphone opengl-es glsl

以下是GLSL中叠加混合算法的实现,它来自OpenGLShading®语言,第三版:

  

19.6.12叠加

     

OVERLAY首先计算亮度   的基值。

     

如果亮度值小于   0.5,将混合和基础值相乘。

     

如果亮度值大于   在图0.5中,执行屏幕操作。

     

效果是基值是   相反,混合了混合值   而不是被取代。这允许   图案和颜色覆盖   基本图像,但阴影和高光   在基本图像中保留。

     

亮度发生不连续   = 0.5。为了提供平滑过渡,我们实际上做了线性混合   两个亮度方程   范围[0.45,0.55]。

float luminance = dot(base, lumCoeff);

if (luminance < 0.45)

    result = 2.0 * blend * base;

else if (luminance > 0.55)

    result = white - 2.0 * (white - blend) * (white - base);

else {

    vec4 result1 = 2.0 * blend * base;
    vec4 result2 = white - 2.0 * (white - blend) * (white - base);
    result = mix(result1, result2, (luminance - 0.45) * 10.0);

}

如何在不使用着色器的情况下在OpenGL ES 1.1(针对iPhone 3G)中实现类似的功能?我可以使用混合函数或纹理组合来实现它吗?

1 个答案:

答案 0 :(得分:1)

为了在记录上留下答案,假设你没有进一步的优化,你可以:

1)将亮度值加载到alpha通道

设置一个与原始纹理大小相同的framebuffer对象。使用glColorMask启用或禁用写入不同的通道。首先,启用红色,绿色和蓝色通道并禁用Alpha通道。正常绘制纹理。这将复制纹理的颜色信息。

然后启用Alpha通道并禁用红色,绿色和蓝色通道。使用dot3扩展(从一开始就支持iPhone),用亮度值填充目标alpha通道。

2)根据亮度

将纹理分割成三个纹理

一个简单的方案就是在亮度= 0.5时分割并忽略线性混合。如果你这样做,你可以再次使用framebuffer对象在GPU上分割纹理。这次使用alpha函数(glAlphaFunc并确保启用它)在绘制到一个纹理时传递所有那些alpha大于0.50的区域,在绘制到另一个纹理时传递所有那些alpha小于0.50的特征。

虽然每个像素只能进行一次alpha测试,这意味着您无法在一步中将0.45到0.55的范围分开,但您可以分两步完成。

3)使用普通混合模式将两个或三个纹理合成到帧缓冲区

如果需要,您可以颠覆照明系统以在渲染过程中偏移和缩放Alpha通道。


显然,您可以通过在启动时执行每次绘制相同的步骤进行优化。这可能意味着将当前一个纹理永久存储为两个或三个。