以下是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)中实现类似的功能?我可以使用混合函数或纹理组合来实现它吗?
答案 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通道。
显然,您可以通过在启动时执行每次绘制相同的步骤进行优化。这可能意味着将当前一个纹理永久存储为两个或三个。