我想使用 glClear 和 glClearColor 用包括 alpha 透明度的颜色填充帧缓冲区。然而,当绑定到渲染到屏幕的纹理时,帧缓冲区总是渲染为不透明的。
我希望渲染到帧缓冲区的所有内容都保持其透明度。我只是想改变背景。
请参阅以下代码:
def create_texture(surface):
surface.texture = glGenTextures(1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() #Loads model matrix
glBindTexture(GL_TEXTURE_2D, surface.texture) #Binds the current 2D texture to the texture to be drawn
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) #Required to be set for maping the pixel data
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) #Similar as above
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface.surface_size[0], surface.surface_size[1], 0, GL_RGBA,GL_UNSIGNED_BYTE, surface.data) #Put surface pixel data into texture
if surface.data == None:
setup_framebuffer(surface)
c = [float(sc)/255.0 for sc in surface.colour] #Divide colours by 255 …Run Code Online (Sandbox Code Playgroud) 是否可以使用 OpenGL 对每个组件使用一个 alpha 通道(一个用于红色,一个用于绿色,一个用于蓝色)进行混合?如果没有,有哪些可能的解决方法?
我正在尝试通过 php 制作多个具有背景透明度的 .png 的合成图像,并将生成的图像存储在我的数据库中。我的问题是,当我合并图像时,图像的透明部分被删除。
这是我创建合成图像的代码:
$base = imagecreatefrompng('application/assets/images/vel1_bg.png');
imagealphablending($base, true);
list($baseWidth, $baseHeight, $type, $attr) = getimagesize('application/assets/images/vel1_bg.png');
$user_board_items = $this->config->item('user_board_items');
foreach($array as $key => $value){
$item = imagecreatefrompng('application/assets/images/items/' . $user_board_items[$value[0]] . '.png');
imagealphablending($item, true);
list($width, $height, $type, $attr) = getimagesize('application/assets/images/items/'. $user_board_items[$value[0]] . '.png');
imagecopymerge($base,
$item,
floor(($value[1] / 100) * $baseWidth),
floor(($value[2] / 100) * $baseHeight),
0,
0,
$width,
$height,
100);
imagedestroy($item);
}
//We have to capture the output buffer
ob_start();
imagepng($base);
$baseimg = ob_get_clean();
Run Code Online (Sandbox Code Playgroud)
这会产生如下图像:

我正在寻找更像这样的东西:
(注意透明部分的表示方式)
这是一个关于Processing.org的问题。
我通过在每个帧的视图上绘制一个半透明的白色矩形来淡出以前绘制的对象。
然而,它们似乎永远不会褪色到完全白色。褪色在一些明显的非白色灰色阴影处有一个固定点。尝试淡入黑色时也会发生同样的事情。
这是 alpha 混合如何在处理中工作的标准功能吗?有没有一种相对简单的方法来实现完全白色的背景(给定足够的步骤)?
我想象得到的颜色将是混合颜色的线性组合,这意味着限制应该是白色。也许非白色固定点是四舍五入的人工制品?
说明问题的示例代码:
void setup() {
size(300,300);
background(0);
noStroke();
frameRate(15);
}
void draw() {
fill(255,10);
rect(0,0,width,height);
fill(255);
rect(0,0,50,50); // for comparison to white
}
Run Code Online (Sandbox Code Playgroud)
编辑:添加了java标签,希望得到更多关注
最终编辑:
已解决...只需深入了解 alpha 混合如何工作。我应该有: oBlendStateDesc.RenderTarget[a].DestBlendAlpha = D3D11_BLEND_ZERO; ...设置为 D3D11_BLEND_ONE 以保留 Alpha。
当渲染到后台缓冲区时,问题不会被注意到,因为颜色混合正常,这就是最终输出。当渲染到纹理时,同样的情况也适用,然后将纹理渲染到后缓冲区,不正确的 alpha 会导致错误地将纹理混合到后缓冲区。
然后我遇到了另一个问题,阿尔法似乎在减少。这是因为颜色混合了两次,例如......
Source.RBGA = 1.0f, 0.0f, 0.0f, 0.5f
Dest.RGBA = 0.0f, 0.0f, 0.0f, 0.0f
Run Code Online (Sandbox Code Playgroud)
渲染成纹理...
Result.RGB = Source.RBG * Source.A + Dest.RGB * (1 - Source.A) = 0.5f, 0.0f, 0.0f
Result.A = Source.A * 1 + Dest.A * 1 = 0.5f
Run Code Online (Sandbox Code Playgroud)
现在...
Source.RBGA = 0.5f, 0.0f, 0.0f, 0.5f
Dest.RGBA = 0.0f, 0.0f, 0.0f, 0.0f
Run Code Online (Sandbox Code Playgroud)
渲染到后台缓冲区...
Result.RGB = Source.RBG * Source.A + Dest.RGB * (1 - Source.A) = …Run Code Online (Sandbox Code Playgroud) 有人可以解释一下为什么使用预乘 alpha(和校正后的混合函数)渲染看起来与“正常”alpha 不同,而从数学上来说,它们是相同的?
我研究了这篇文章以了解预乘阿尔法:
http://blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx
作者还说最终计算是一样的:
“查看传统与预乘 Alpha 的混合方程。如果将此颜色格式转换替换为预乘混合函数,您将得到传统混合函数,因此无论哪种方式都会产生相同的最终结果。不同之处在于预乘 Alpha 应用了(source.rgb * source.a) 计算作为预处理,而不是在混合硬件内部。”
我错过了什么吗?那为什么结果不同呢?
内肖内
我正在使用 SDL 2.0 开发 2D 游戏,但我的照明系统出现问题。我想用雾填充屏幕并在玩家周围创建一个透明圆圈(左下)。我知道如何使用 SDL_BLENDMODE_MOD(右下)制作一个带有彩色灯光的暗室,但我无法制作雾气。我尝试使用我能想到的 SDL_SetRenderDrawBlendMode() 和 SDL_SetTextureBlendMode() 的每种组合在屏幕上分层多个纹理。

我已经搜查,在计算器上像发现解决这个,但他们使用SDL表面和预先制作的光图像。我将动态更改输入图像(右上角)的形状和大小,因此我需要更灵活的东西。
解决方案 1:我使用黑色圆圈和海军背景,而不是白色圆圈和黑色背景。然后我使用屏幕混合来混合它并得到我的雾(我已经在图像编辑器中测试过这个以获得左下角的图像)。不幸的是,SDL 没有 SDL_BLENDMODE_SCREEN。
解决方案2:创建一个半透明的雾层并在其中打一个全透明的孔。不幸的是,我不知道如何用透明孔覆盖纹理。我尝试将我的绘图模式设置为 SDL_BLENDMODE_NONE 并绘制一个完全透明的圆圈,但它只能创建完全不透明的圆圈。文档说我可以替换目标 alpha 但这似乎不起作用......
我有一个金属视图,显示一些纹理四边形。纹理是从 PNG 加载的,因此会进行预乘。一些纹理具有透明像素。
当我启用混合并按正确的顺序绘制时,透明度起作用,您可以通过纹理的透明部分看到其他四边形下方的四边形。但是,我必须通过排序来计算正确的绘制顺序,这是昂贵的并且会大大减慢我的渲染速度。
当我尝试使用深度模板并以任何顺序绘制时,我可以使用 z 位置使顺序正确工作,但混合会停止工作。纹理的透明部分显示金属场景的背景颜色,而不是下面的四边形。
我究竟做错了什么?有没有办法让它工作并且有人可以提供一些示例代码?
我看到的另一个选择是尝试在 GPU 上进行排序,这很好,因为 GPU 帧时间明显小于 CPU 帧时间。但是,我也不确定如何做到这一点。
任何帮助将不胜感激。:)
我正在尝试使用 OpenGL 对透明对象尝试不同的 alpha 混合方程,但看起来片段着色器对单个对象上的片段颜色进行操作,并且无法考虑对象后面的场景。
另一方面,似乎没有办法用任意 GLSL 代码拦截混合阶段,例如,我想不出用当前 OpenGL 基元重现柔光混合模式的方法。
有没有办法调和这些?
我想使用特殊的混合模式(在我的例子中为覆盖模式)将 UIView 与我的应用程序的背景混合。然而,要混合的视图包含在复杂的视图层次结构中。
\n\n可以使用 来实现将视图与其直接同级视图混合view.layer.compositingFilter = "overlayBlendMode",但该视图不会与非同级视图(例如应用程序背景)混合。
为了重现这个问题,我制作了以下游乐场:
\n\nimport UIKit\nimport PlaygroundSupport\n\nclass MyViewController : UIViewController {\n override func loadView() {\n let parentView = UIView()\n parentView.backgroundColor = .purple\n\n // Child view\n let childView = UIView(frame: CGRect(x: 50, y: 50, width: 200, height: 200))\n childView.layer.borderColor = UIColor.orange.cgColor\n childView.layer.borderWidth = 3\n parentView.addSubview(childView)\n\n // Child child view\n let childChildView = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 50))\n childChildView.backgroundColor = .white\n childChildView.layer.compositingFilter = "overlayBlendMode"\n childView.addSubview(childChildView)\n\n self.view = parentView\n }\n}\n// …Run Code Online (Sandbox Code Playgroud) alphablending ×10
opengl ×3
c++ ×2
ios ×2
calayer ×1
colors ×1
core-image ×1
depth-buffer ×1
directx-11 ×1
framebuffer ×1
gd ×1
glsl ×1
graphics ×1
java ×1
lighting ×1
metal ×1
php ×1
png ×1
processing ×1
pyopengl ×1
python ×1
rendering ×1
rendertarget ×1
sdl-2 ×1
swift ×1
textures ×1