2011-01-08 69 views
1

以下是GLSL覆盖掺合物算法的实现,从OpenGL的Shading®语言绘制,第三版:如何将GLSL叠加混合转换为OpenGL ES 1.1?

12年6月19日叠加

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),不使用着色?我可以使用混合函数或纹理合并来实现这一点吗?

+0

布拉德,谢谢。 我发现石英2D具有混合函数CGContextSetBlendMode,我可以用它代替opengl-es – Cylon 2011-01-10 12:14:45

回答

1

有关记录留下一个答案,假设没有进一步的优化可以使的目的,你可以:

1)负载亮度值到alpha通道

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

然后启用alpha通道和禁用红色,绿色和蓝色通道。使用DOT3延伸(从一开始就已经支持在iPhone上)与亮度值来填充目标alpha通道。

2)拆分纹理成三个纹理,基于亮度

一个简单的方案将只是在亮度= 0.5分裂并忽略线性混合。如果你这样做,你可以再次使用framebuffer对象来分割GPU上的纹理。此时使用Alpha函数(glAlphaFunc并且一定要启用它)来传递所有这些领域与α大于0.50绘制一个纹理,绘图到另一个时通过所有这些特征与α小于0.50。

虽然可以做只有一个每像素阿尔法测试,这意味着不能在单个步骤中的范围0.45分离出〜0.55,可以这样做,在两个步骤。

3)使用正常混合模式到复合材料中的两个或三个纹理到您的帧缓冲区

可以颠覆照明系统,以抵消并在必要时在渲染期间缩放alpha通道。


显然你会通过执行那些相同的每一个取水只有一次的步骤,在启动优化。这可能意味着永久性地将当前一个纹理存储为两个或三个纹理。

+0

很好的解决方案! – Cylon 2011-01-12 04:46:19