繁体   English   中英

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

[英]How can I translate a GLSL overlay blend to OpenGL ES 1.1?

以下是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)将亮度值加载到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通道。


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM