【问题标题】:How can I translate a GLSL overlay blend to OpenGL ES 1.1?如何将 GLSL 叠加混合转换为 OpenGL ES 1.1?
【发布时间】:2011-01-11 00:10:50
【问题描述】:

以下是 GLSL 中叠加混合算法的实现,取自 OpenGL Shading® Language,第三版:

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)中实现类似的功能?我可以使用混合函数或纹理组合来实现吗?

【问题讨论】:

  • 布拉德,谢谢。我发现quartz 2D有混合函数CGContextSetBlendMode,我可以用它代替opengl-es

标签: iphone opengl-es glsl


【解决方案1】:

为了在记录中留下答案并假设您无法进行进一步优化,您可以:

1) 将亮度值加载到 Alpha 通道中

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

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

2) 根据亮度将纹理拆分为三个纹理

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

虽然您只能对每个像素进行一次 Alpha 测试,这意味着您无法一步分离出 0.45 到 0.55 的范围,但您可以分两步进行。

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

如有必要,您可以在渲染期间颠覆照明系统以偏移和缩放 Alpha 通道。


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 2012-04-21
    • 1970-01-01
    • 2012-02-19
    相关资源
    最近更新 更多