我创建了一个带有3个半透明tImage3D的FireMonkey应用程序。 这是代码和屏幕。一切似乎都很好。
procedure TForm1.Form3DCreate(Sender: TObject);
// create a new semi-transparent timage3d
// object with color and Z position.
procedure NewImage ( const nColor : tColor;
const nZ : integer );
begin
// create the image
with tImage3D . Create ( self ) do
begin
// put it on the screen
Parent := self;
// set the size
Width := 10;
Height := 10;
// set the image to a single pixel.
Bitmap . Width := 1;
Bitmap . Height := 1;
// set the Alpha to $80 to make it
// semi-transparent
Bitmap . Pixels [ 0, 0 ] := $80000000 + nColor;
// set the z position
Position . Z := nZ;
end;
end;
begin
NewImage ( claRed, +10 );
NewImage ( claGreen, 0 );
NewImage ( claBlue, -10 );
end;
现在撤销订单。现在它们是不透明的。
begin
NewImage ( claRed, -10 );
NewImage ( claGreen, 0 );
NewImage ( claBlue, +10 );
end;
我错过了什么?
答案 0 :(得分:4)
FireMonkey(截至目前)不支持在3D中渲染半透明对象。
FireMonkey仅支持混合半透明对象(通过Opacity属性或因为它们的纹理,例如半透明的PNG图像),但仅blending不是足以使用Z-Buffer(这是FMX和大多数3D应用程序正在使用的)在3D中使用它。
有关技术说明,您可以阅读Transparency sorting,该文章是关于OpenGL的,但也适用于DirectX。
因此,为了获得正确的渲染,您需要从相机的角度将半透明对象从前到后排序。
您可以在此帖子中获取更多详细信息和一些代码来解决此问题:
Rendering semi-transparent object in FireMonkey
但请记住,这只是一种解决方法。
理想情况下,这应由FireMonkey场景图处理,因为它依赖于渲染,否则,您最终必须更改场景图结构,这可能会产生各种其他副作用,甚至更成问题如果你有多个摄像机在同一个场景中。
此外,排序方法仅适用于不相交的凸对象,并且没有三重叠,例如:
没有正确的排序(其他元素都不在其他元素之前)。
答案 1 :(得分:0)
正如您已经发现的那样,您必须从后向前绘制透明对象。
绘制透明对象时,会绘制对象,并与其后面的像素混合。
所以当你从后面画到前面时会发生这种情况:
您绘制红色图像,它与白色背景混合。您可以通过“粉红色”而不是纯红色来判断它是否与白色背景混合。然后绘制绿色图像,它与已绘制的白色背景和红色图像混合。最后绘制蓝色图像,该图像与已绘制的对象混合。
但现在我们从前到后画画:
我们首先绘制红色平面。它与您可以看到的白色背景混合,因为它是粉红色而不是红色。现在我们绘制绿色飞机。它与白色背景混合,你可以通过颜色来判断,它不是纯净,深沉,绿色。但是,渲染器看到一部分落在红色平面后面,所以它不会绘制那个部分。但是,你认为:红色飞机是透明的,渲染器应该在红色飞机后面绘制!嗯不,渲染器只跟踪z缓冲区/深度缓冲区中像素的深度/ z顺序,它不知道该像素是否透明。蓝色平面也是如此,只绘制了未被其他物体遮挡的部分。
你说的深度缓冲是什么?
在深度缓冲器中,存储每个像素的深度。当您在2,2处以z为1绘制像素时,2,2处的深度缓冲区将更新为值1.现在,当您从1,2到3,2绘制一条线,其中az为3时,渲染器将仅绘制深度缓冲器具有值> = 3的像素。因此绘制像素1,2(并且将1,2的深度缓冲器设置为3)。未绘制像素2,2,因为深度缓冲区表示该像素已经以较小的深度绘制(1对3)。绘制像素3,2并将3,2的深度缓冲设置为3
因此,深度缓冲区用于跟踪每个像素的z顺序,以防止用更远的像素覆盖该像素。
如果您想以正确的方式绘制透明对象,请参阅this answer。
摘录答案:
我不知道FireMonkey是否支持禁用深度缓冲区写入,您必须自己查找。