2013-07-03 53 views
0

我将一个非常简单的代码从OpenGLES 1.0移植到OpenGLES 2.0。将混合问题从OpenGLES 1.0移植到2.0(iOS)

在原来的版本,我已经融合了

glEnable(GL_BLEND); 
glBlendEquation(GL_FUNC_ADD); 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

启用我使用相同的代码在我的ES 2.0的实现,因为我需要什么是渲染缓冲器混合的新渲染的四边形(我保留渲染缓冲区,我无法重新渲染场景)。

我使用了一个纹理(alpha值显示从中心到外部的径向渐变,alpha从1到0),用作alpha蒙版,只包含具有不同alpha值的白色像素。我给我的顶点使用与100/255的alpha相同的颜色。我的背景是透明的黑色。在那之下,我有一个普通的白色表面(UIView)。我呈现4个四边形。

结果与OpenGLES 1.0(期望的结果) enter image description here

我的意见告诉我,该片段着色器应该简单地:

gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); 

(我用我的顶点尝试不同的价值观得到了这样的结论)

我想写一些OpenGL 2.0代码(包括顶点+片段着色器),它会给我确切的山姆e的结果就像在OpenGLES 1.0中一样,没有什么比这更少的了。除了在纹理上应用顶点颜色之外,我不需要/不想在片段着色器中进行任何混合。使用简单的着色器,这里是我得到的结果: enter image description here

我尝试了几乎所有*,+,混合我可以想到的组合,但我无法重现相同的结果。这是我迄今为止最接近的,但是这绝对不是正确的(并且不作任何任何意义)

varying lowp vec4 DestinationColor; 
varying lowp vec2 TexCoordOut; 
uniform sampler2D Texture; 

void main(void) { 
    lowp vec4 texture0Color = texture2D(Texture, TexCoordOut); 
    gl_FragColor.rgb = mix(texture0Color.rgb, DestinationColor.rgb, texture0Color.a); 
    gl_FragColor.a = texture0Color.a * DestinationColor.a; 
} 

这个shader给了我下面的: enter image description here

+0

对不起,但您的问题对我来说有点不清楚。你需要的结果究竟是什么?你是否也在ES 2.0中使用混合? – Reigertje

+0

如果不清楚,我表示歉意。是的,我以同样的方式启用了ES 2.0中的混合。我基本上需要与ES 1.0中相同的结果,但不能清楚地描述它。尽管我试图描述如何在ES 1.0中进行设置。这可能是不够的...... – user1727274

+0

我认为这个问题现在应该更清晰 – user1727274

回答

0

愚蠢的错误。我只需要标准化顶点着色器中的顶点颜色,因为我传递了无符号字节。

+0

作为一个提示,你不需要自己规范这些。这就是'glVertexAttribPointer'的'normalize'参数(你可能总是设置为'GL_FALSE')。 –

+1

如果这是您的问题的解决方案,请随时[接受](http://meta.stackexchange.com/q/5234/162011)您的答案。 –

+0

需要等待48小时...但会 – user1727274

0

通过阅读和this,可以构造混合函数。

由于您使用的是glBlendFunc而不是glBlendFuncSeparate,所有4个通道正在混合使用。使用GL_FUNC_ADD参数将输出O设置为O = sS + dD,其中sd是混合参数,并且SD是源和目标颜色。

sd参数由glBlendFunc设置。 GL_ONEs(1, 1, 1, 1)GL_ONE_MINUS_SRC_ALPHAd(1-As, 1-As, 1-As, 1-As),其中As是来源的alpha值。因此,您的混合是这样做的(向量形式):

O = S + (1-As) * DGLSLO = mix(D, S, As),或: gl_FragColor = mix(DestinationColor, TexCoordOut, As)

如果结果看起来不相似,请确认您没有使用glBlend或任何其他可能会改变最终结果外观的OpenGL API。如果这没有帮助,请张贴不同输出的屏幕截图。

+0

我想我需要在Vasaka指出的时候继续混合(除非渲染纹理并读取着色器中现有的帧缓冲区)。我认为我需要的只是一种将顶点颜色应用于我的纹理的方法,就像在ES 1.0中完成的那样。 – user1727274

0

这不能用着色器轻松完成,因为混合必须读取当前帧缓冲区状态。 如果你可以在framebuffer中获得颜色,那么你可以通过渲染纹理并将其传递给着色器来实现这一点,那么你就可以。

您的公式为:

gl_FragColor = wouldBeFramebufferColor + (1-wouldBeFramebufferColor.a) * texture0Color; 

但是你为什么想要做着色器AFAIK混合在OpenGL ES未除去2.0

+1

我不想在着色器中进行混合。我只需要将我的代码移植到OpenGL 2.0中,以便尝试最近在iOS中添加的实例化绘图。我只是试图复制与我的OpenGL 1.0代码完全相同的东西。 – user1727274

+0

刚发布的图片,可能会帮助 – user1727274

+1

我同意使用'glBlend'。但是,从iOS 6开始,可以使用着色器,使用[GL_EXT_shader_framebuffer_fetch](http://www.khronos.org/registry/gles/extensions/EXT/EXT_EXT_Shader_framebuffer_fetch.txt)扩展名来完成。 – StatusReport