简体   繁体   English

使用混合创建由黑色包围的多个透明区域

[英]Using blending to create multiple areas of transparency surrounded by black

I've been playing around in openGL a little bit and I was wondering how I can take an image (say for example a black background) and then render a smaller white gradient over the top but have it make the white gradient transparent (instead of white) and remove from the black background. 我一直在openGL中玩一下,我想知道如何拍摄一张图片(例如黑色背景),然后在顶部渲染一个较小的白色渐变,但让白色渐变透明(而不是白色)并从黑色背景中删除。 Leaving a black background with a transparent gradient in the center. 在中心留下透明渐变的黑色背景。 I'm using LWJGL if that helps. 如果有帮助,我正在使用LWJGL。

Is there any way of doing this with blending? 有没有办法混合这样做?

Edit: Okay, is there any way of instead of subtracting two images, I draw black around an image? 编辑:好的,有没有办法减去两张图像,我在图像周围绘制黑色? So I have my white gradient, change it to be transparent and then draw black all around that? 所以我有我的白色渐变,将其改为透明,然后在周围绘制黑色?

Fixed function is usually implemented using shaders in modern GL drivers (there are old ATI's presentations with SM2.0+ shaders for all of the fixed functionality). 固定功能通常使用现代GL驱动程序中的着色器实现(有旧的ATI演示文稿,SM2.0 +着色器用于所有固定功能)。

The close-to-trivial blending fragment shader like this 像这样的接近平凡的混合片段着色器

in vec2 TexCoord;

uniform sampler2D Texture0;
uniform sampler2D Texture1;

out vec4 out_FragColor;

void main()
{
     vec4 Color = texture(Texture0, TexCoord);

     /// The mask contains (R,G,B,A) - image + transparency
     /// for both the mask and the source
     vec4 Mask  = texture(Texture1, TexCoord);

     /// Mask is also significant as a color source, not only the alpha
     out_FragColor = Color * ( 1.0 - Mask.a ) + Mask * Mask.a;

     /// Thanks to Tim's comment, the last line can be done simpler:
     /* out_FragColor = mix(Color, Mask, Mask.a); */
}

should mix the image the way you want to. 应该按照你想要的方式混合图像。

This is not overkill for modern hardware and it is 100% compatible even with the GL ES 2.0 hardware. 这对于现代硬件来说并不过分,即使与GL ES 2.0硬件也完全兼容。

EDIT: 编辑:

The image from one of my projects (simple mask used to create the fade-away reflection). 来自我的一个项目的图像(用于创建渐弱反射的简单蒙版)。

We use this mask 我们使用这个面具

阴影面具

and get the final result in this image: Gallery 并获得此图像的最终结果: 图库

It may be possible to achieve what you want in the specific case, but in general once you 'draw a black background', there's no way to make it transparent afterward. 在特定情况下可能实现您想要的效果,但一般来说,一旦“绘制黑色背景”,之后就无法使其变得透明。 You can't remove or erase pixels that have already been drawn. 您无法删除或删除已绘制的像素。

If you can draw the gradient before the black background, then you can deposit the alpha into the framebuffer, and then sample the destination alpha when you draw the black background afterward. 如果您可以在黑色背景之前绘制渐变,则可以将alpha存入帧缓冲区,然后在绘制黑色背景时对目标alpha进行采样。 You'll need to have a real alpha texture though, as you can't really convert a white gradient to an alpha gradient at draw time. 你需要有一个真正的alpha纹理,因为在绘制时你无法真正将白色渐变转换为alpha渐变。

Here's my suggested pseudocode: 这是我建议的伪代码:

  1. draw whatever you want in the background 在背景中绘制你想要的任何东西
  2. create texture with alpha gradient 用alpha渐变创建纹理
  3. lock color channels with glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_TRUE); 使用glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_TRUE);锁定颜色通道glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_TRUE);
  4. draw alpha gradient over background 在背景上绘制alpha渐变
  5. unmask color channels with glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); 使用glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);颜色通道glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
  6. draw 'black texture' with following blend options: glBlend(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA) 使用以下混合选项绘制'黑色纹理': glBlend(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA)

That should leave you with a black texture with a blended gradient to whatever was underneath it. 这应该给你留下一个黑色纹理,混合渐变到它下面的任何东西。

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

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