在顶点颜色中使用 GL_MODULATE 和 alpha 时,GLKit 不显示纹理
GLKit does not display texture when using GL_MODULATE with alpha in vertex color
我有一张与 GLKit 一起使用的纹理图像。如果我在纹理上使用 GL_MODULATE 并具有顶点 RGBA (1.0, 1.0, 1.0, 1.0),那么纹理将完全显示为它在 GL_REPLACE 中的表现。完全不透明。
然后,如果我对顶点 RGB 使用红色 (1.0, 0.0, 0.0, 1.0),则纹理再次显示为红色调制纹理。
到目前为止,一切都很好。
但是,当我更改顶点颜色的透明度并使用 RGBA(1.0, 0.0, 0.0, 0.5) 时,只能看到浅红色并且看不到纹理,因此颜色将完全替换纹理。
纹理本身没有alpha,是RGB565纹理。
我将 GLKit 与 GLKTextureEnvModeModulate 结合使用。
self.effect.texture2d0.envMode = GLKTextureEnvModeModulate;
关于为什么在我指定 alpha 时纹理会消失的任何帮助?
添加快照:
这是原始纹理
RGBA (1.0, 1.0, 1.0, 1.0) - 白色,无预乘,不透明,纹理可见
RGBA (1.0, 1.0, 1.0, 0.5) - 白色,无预乘,alpha = 0.5,纹理丢失[=20=]
RGBA (1.0, 0, 0, 1.0) - 红色,无预乘,不透明,纹理可见
RGBA (1.0, 0, 0, 0.5) - 红色,无预乘,alpha = 0.5,纹理丢失[=20=]
RGBA (0.5, 0, 0, 0.5) - 红色,预乘,alpha = 0.5 每个@andon,纹理可见,但你可能需要放大才能看到它
RGBA (0.1, 0, 0, 0.1) - 红色,预乘,alpha = 0.1 每@andon,纹理丢失,可能是因为没有足够的对比度
RGBA (0.9, 0, 0, 0.9) - 红色,预乘,alpha = 0.9 每@andon,纹理可见,但你可能需要放大才能看到它
The texture itself has no alpha, it is RGB565 texture
RGB565
隐式具有常量 alpha(不透明 -> 1.0)。 这听起来可能不重要,但是用纹理颜色调制顶点颜色会进行分量乘法运算,如果 alpha 不是 1.0.[=42,那根本行不通=]
My blend function is for pre-multiplied - One, One - Src.
这需要用 A 分量预乘顶点颜色的 RGB 分量。 所有 颜色必须预乘,这包括纹素和顶点颜色。
您可以在下面看到原因:
Vtx = (1.0, 0.0, 0.0, 0.5)
Tex = (R, G, B, 1.0)
// Modulate Vertex and Tex
Src = Vtx * Tex = (R, 0, 0, 0.5)
// Pre-multiplied Alpha Blending (done incorrectly)
Blend_RGB = Src * 1 + (1 - Src.a) * Dst
= Src + Dst / 2.0
= (R, 0, 0) + Dst / 2.0
唯一要做的就是将目标颜色除以 2,然后将未更改的源颜色添加到其中。 假设类似于线性插值(a * c + (1 - c) * b
).
正确的混合应该是这样的:
// Traditional Blending
Blend_RGB = Src * Src.a + (1 - Src.a) * Dst
= (0.5R, 0, 0) + Dst / 2.0
如果将顶点颜色的 RGB 部分乘以 A,则可以使用原始混合函数来完成此操作。
修正预乘alpha混合(通过预乘顶点颜色):
Vtx = (0.5, 0.0, 0.0, 0.5) // Pre-multiply: RGB *= A
Tex = (R, G, B, 1.0)
// Modulate Vertex and Tex
Src = Vtx * Tex = (0.5R, 0, 0, 0.5)
// Pre-multiplied Alpha Blending (done correctly)
Blend_RGB = Src * 1 + (1 - Src.a) * Dst
= (0.5R, 0, 0) + Dst / 2.0
我有一张与 GLKit 一起使用的纹理图像。如果我在纹理上使用 GL_MODULATE 并具有顶点 RGBA (1.0, 1.0, 1.0, 1.0),那么纹理将完全显示为它在 GL_REPLACE 中的表现。完全不透明。
然后,如果我对顶点 RGB 使用红色 (1.0, 0.0, 0.0, 1.0),则纹理再次显示为红色调制纹理。
到目前为止,一切都很好。
但是,当我更改顶点颜色的透明度并使用 RGBA(1.0, 0.0, 0.0, 0.5) 时,只能看到浅红色并且看不到纹理,因此颜色将完全替换纹理。
纹理本身没有alpha,是RGB565纹理。
我将 GLKit 与 GLKTextureEnvModeModulate 结合使用。
self.effect.texture2d0.envMode = GLKTextureEnvModeModulate;
关于为什么在我指定 alpha 时纹理会消失的任何帮助?
添加快照:
The texture itself has no alpha, it is RGB565 texture
RGB565
隐式具有常量 alpha(不透明 -> 1.0)。 这听起来可能不重要,但是用纹理颜色调制顶点颜色会进行分量乘法运算,如果 alpha 不是 1.0.[=42,那根本行不通=]
My blend function is for pre-multiplied - One, One - Src.
这需要用 A 分量预乘顶点颜色的 RGB 分量。 所有 颜色必须预乘,这包括纹素和顶点颜色。
您可以在下面看到原因:
Vtx = (1.0, 0.0, 0.0, 0.5)
Tex = (R, G, B, 1.0)
// Modulate Vertex and Tex
Src = Vtx * Tex = (R, 0, 0, 0.5)
// Pre-multiplied Alpha Blending (done incorrectly)
Blend_RGB = Src * 1 + (1 - Src.a) * Dst
= Src + Dst / 2.0
= (R, 0, 0) + Dst / 2.0
唯一要做的就是将目标颜色除以 2,然后将未更改的源颜色添加到其中。 假设类似于线性插值(a * c + (1 - c) * b
).
正确的混合应该是这样的:
// Traditional Blending
Blend_RGB = Src * Src.a + (1 - Src.a) * Dst
= (0.5R, 0, 0) + Dst / 2.0
如果将顶点颜色的 RGB 部分乘以 A,则可以使用原始混合函数来完成此操作。
修正预乘alpha混合(通过预乘顶点颜色):
Vtx = (0.5, 0.0, 0.0, 0.5) // Pre-multiply: RGB *= A
Tex = (R, G, B, 1.0)
// Modulate Vertex and Tex
Src = Vtx * Tex = (0.5R, 0, 0, 0.5)
// Pre-multiplied Alpha Blending (done correctly)
Blend_RGB = Src * 1 + (1 - Src.a) * Dst
= (0.5R, 0, 0) + Dst / 2.0