zoukankan      html  css  js  c++  java
  • Premultiplied alpha and GL_ONE vs. raw and GL_SRC_ALPHA

    转载自:http://lists.apple.com/archives/mac-opengl/2011/Jan/msg00010.html

    • Subject: Premultiplied alpha and GL_ONE vs. raw and GL_SRC_ALPHA
    • From: Zack Morris <email@hidden>
    • Date: Sat, 8 Jan 2011 11:22:49 -0700
    • Delivered-to: email@hidden
    • Delivered-to: email@hidden
    • Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;h=domainkey-signature:received:received:subject:from:content-type:message-id:date:to:content-transfer-encoding:mime-version:x-mailer;bh=yl2si8aAoAa2wUNxGL35pGCwm16Z8zfBlGgk4X3yugE=;b=JTI3ormi8c0eqDLTvRsZgi+XfYnWddvN2KripyHGkSPw1RyhM286DfzF+F3j8uPrds/iuG9u2p7bBNhQrBALgtGUYTSlF+zyr+WEl91Sei2FAqYHgcpgjB9aKiQkMpddgriSBaq9isyg40hhfVQTGX6GWWY9/kN7JWGpP00yQ6U=
    • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma;h=subject:from:content-type:message-id:date:to:content-transfer-encoding:mime-version:x-mailer;b=VR8oDlOZFF95QbJP+12AdFUVVEncY+E0Pe4E4lHHll18xJhc/1bQFvN9FNFrcGLkeQzBGsVXwVo4IC8r1iTDzkue6HRkfrqSoO+Hw7Qr32c6GF/P+S4qmUY1Hcfs3SkLdKNKNc+RACO+LPNy0wJgKv/nkvbolbJwwnv/HmD+row=

    Hi, I was hoping someone on this list might know the answer to this.  I'm on a 1.83 Intel Mac Mini with GMA 950 and 10.6.6.
    
    My partner is more the artist and I'm more the engineer, and he's adamant about using premultiplied alpha PNGs because "that's how the iPhone does it".  I started with a background in math, reading the red book etc, and I honestly don't see what the hype is about.  Premultiplied seems good for a storage format, since any pixels without alphas become 0 after multiplication and zip better.  But there are pretty severe drawbacks to using them during the game, because we can't altar the pixel values or do special fx without changing the opacity of the pixels, because they are not independent of the alpha byte.
    
    Here is our code, we have texture buffers with a boolean saying whether they are premultiplied, and we do special fx by setting the draw color etc:
    
    if( premultipliedAlpha )
    {
    	glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
    	glColor4f( this->red*this->opacity, this->green*this->opacity, this->blue*this->opacity, this->opacity );
    }
    else
    {
    	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    	glColor4f( this->red, this->green, this->blue, this->opacity );
    }
    
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    
    glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices );
    
    Here is a table I made of all of the modes, white means I set the 0 alpha pixels to white (1.0, 1.0, 1.0), premul means they have been multiplied by the alpha (so are 0.0, 0.0, 0.0), and black means I set them to black (0.0, 0.0, 0.0).  There are 3 sizes (small, 1:1 and full screen), and the "moved" cases are just captures where the ship is on an even pixel value or if it's moved and interpolation is happening:
    
    http://oi52.tinypic.com/ml31jo.jpg
    
    My question is, is glBlendFunc( GL_ONE, ... ) and premultiplied equivalent to glBlendFunc( GL_SRC_ALPHA, ... ) and the black case?  Mathematically, premultiplied and black should be equivalent.  But I swear that the GL_ONE case looks "smoother" and I can't figure out why.  My partner thinks that the GL_ONE case doesn't bother to draw the 0 alpha pixels at all, but I don't think that is possible.  There has to be something to interpolate out to.  You can see what happens most visibly in the lower left white case.
    
    To understand what causes the halos, imagine you have 2 pixels, a red and a clear in RRGGBBAA hex:
    
    [red][clear]:
    
    [FF0000FF][00000000]
    
    And you stretch it up to 3 pixels:
    
    [FF0000FF][7F00007F][00000000]
    
    The middle pixel that is interpolated has to stretch across both color and alpha.  So you get a dark red pixel at half opacity (which looks dark over a white background).  The strange thing is, I swear I'm not seeing those dark pixels in premultiplied mode with GL_ONE, and I don't understand why?
    
    I personally prefer to keep the color and alpha values independent, so I store my graphics unadulterated, where the clear pixel still contains the color info of its nearest neighbor (so there is something to interpolate to), and use non-premultiplied:
    
    [red][clear]:
    
    [FF0000FF][FF000000]
    
    Stretched:
    
    [FF0000FF][FF00007F][FF000000]
    
    This way the middle pixel is still red but at half opacity, which looks correct over any background.
    
    P.S. this all started because there is a bug in photoshop where it's not storing the 0 alpha pixels properly, so they come out undefined.  When we stretch them in our games, we see edge artifacts of random colors if we don't use premultiplied.  There are plugins that supposedly bleed out the edge pixel colors into their 0 alpha neighbors, but they don't seem to save properly either.
    
    So as a fix to get us by and allow us to still use special fx on our graphics without affecting their opacity, I wrote a loop that fills in any 0 alpha pixels with an average of their nonzero alpha neighbors weighted by their alphas at load time.  It actually works great, but I hate that I have to do this.  Photoshop should be saving better.
    
    I know this is a long email and I'm sorry, but this has caused a great deal of strife with my partner.  I need to know mathematically what is happening, and if GL_ONE has some kind of special case happening to ignore the 0 alpha pixels.  He won't believe me and frankly doesn't care about the math, he just wants something that "works".  I consider the premultiplied mode a special case that mostly saves file space, but if it really can draw over any background and completely ignore the 0 alpha pixels, then I would like to know why.  I want a general case where I can apply fx to any texture without having to worry about what format I am loading.  If GL_ONE is equivalent to the black case, then the raw mode with bled edges is actually better, and I have some evidence to provide to him as to why it's a better solution than premultiplied.
    
    Thanx for any insights,
    
    --Zack
    
    "Go to the edge of the cliff and jump off. Build your wings on the way down."
    
    - Ray Bradbury _______________________________________________
    Do not post admin requests to the list. They will be ignored.
    Mac-opengl mailing list      (email@hidden)
    Help/Unsubscribe/Update your Subscription:
    
    This email sent to email@hidden
  • 相关阅读:
    单片机第11课:串口通信查询方式---从计算机接受数据
    Android(Lollipop/5.0) Material Design(四) 创建列表和卡片
    智能指针
    [ACM] ural 1057 Amount of degrees (数位统计)
    vs2008,2010,2012安装包下载
    《智能主义》:360未来5年的方向是物联网安全与安全硬件。3星。
    《近视怎么办》:三甲医院眼科医生的科普。4星
    《当黑天鹅坐上无人车》。耐药性的蔓延是“公地悲剧”的例子之一;负责的人看不到造成的损失。3星
    《特朗普经济学》:考虑到全球供应链的新世界,征收关税就像在工厂中央竖起一堵墙。3星。
    《互联网大败局》:3星。10多年来中国互联网失败案例的公开资料汇编。
  • 原文地址:https://www.cnblogs.com/senior-engineer/p/15665708.html
Copyright © 2011-2022 走看看