C# XNA透明纹理渲染问题
以前这个问题有一两个问题,但我再也找不到了,所以我来了 使用BasicFect渲染具有部分透明纹理的模型时,基本解决方案是按距离摄影机的距离对所有对象进行排序,然后从后向前绘制,以获得正确的图像。但是,当模型相互交叉时,越近的一个部分将落后于另一个部分,透明度将呈现不正确 例如: 两个相交的项目只有一个带有纹理的矩形模型。 由于游戏最终将包含更多三维形状的指示器,并且必须穿过其他对象,这对我来说是一个大问题,我无法找到解决方案 请帮忙。谢谢, 佐利金 编辑:这是非常基本的,但为了完整起见,这里是绘图代码(减去不相关的绒毛): 编辑2:我刚刚发现一篇文章,它甚至可以解决排序无法解决的问题(duh),但必须有某种渲染技巧才能解决这个问题。图形应用程序在其编辑器窗口中实时渲染类似情况,任何使用带有纹理的平面模型的3D粒子效果都必须处理此问题C# XNA透明纹理渲染问题,c#,xna,rendering,transparency,alpha,C#,Xna,Rendering,Transparency,Alpha,以前这个问题有一两个问题,但我再也找不到了,所以我来了 使用BasicFect渲染具有部分透明纹理的模型时,基本解决方案是按距离摄影机的距离对所有对象进行排序,然后从后向前绘制,以获得正确的图像。但是,当模型相互交叉时,越近的一个部分将落后于另一个部分,透明度将呈现不正确 例如: 两个相交的项目只有一个带有纹理的矩形模型。 由于游戏最终将包含更多三维形状的指示器,并且必须穿过其他对象,这对我来说是一个大问题,我无法找到解决方案 请帮忙。谢谢, 佐利金 编辑:这是非常基本的,但为了完整起见,这里
基本上,所有需要做的是检测冲突像素的位置(例如,必须在已绘制透明度的对象后面绘制一些东西),并在重叠区域使用较慢的、基于光线的方法来确定像素颜色。如果没有内置内容,我很乐意手动编写,但我不知道如何深入渲染的细节。我已经有一段时间没有编写或思考XNA了。可能不相关,但可能包含一些有用的见解-似乎使用了一些诡计,与透明度有关。。。据我所知,不是物体碰撞。谢谢,但这并不能解决这个问题。只要我的模型没有交叉,我就没有问题,这是你链接的问题/答案中的一个前提。我怀疑,如果有交叉,这是值得一试的。这就是为什么一些“引擎”在渲染之前分割/镶嵌三角形,所以交叉三角形被分割成非交叉三角形
private void sortDrawables()
{
float[] distances = new float[drawables.Length];
for (int i=0; i<drawables.Length; i++)
{
if (drawables[i] is Character)
{
distances[i] = Vector3.Distance(cameraPosition, ((Character) drawables[i]).marker.position);
}
else if (drawables[i] is FixObject)
{
distances[i] = Vector3.Distance(cameraPosition, ((FixObject) drawables[i]).marker.position);
}
else if (drawables[i] is PositionSpike)
{
distances[i] = Vector3.Distance(cameraPosition, ((PositionSpike) drawables[i]).position);
}
}
for (int i=0; i<drawables.Length; i++)
{
int largestIndex = i;
float largestDistance = -1f;
for (int j=i; j<drawables.Length; j++)
{
if (drawables[j] is Character)
{
if (Vector3.Distance(((Character) drawables[j]).marker.position, cameraPosition) > largestDistance)
{
largestDistance = Vector3.Distance(((Character) drawables[j]).marker.position, cameraPosition);
largestIndex = j;
}
}
else if (drawables[j] is FixObject)
{
if (Vector3.Distance(((FixObject) drawables[j]).marker.position, cameraPosition) > largestDistance)
{
largestDistance = Vector3.Distance(((FixObject) drawables[j]).marker.position, cameraPosition);
largestIndex = j;
}
}
}
float tempDistance = distances[i];
distances[i] = distances[largestIndex];
distances[largestIndex] = tempDistance;
Object tempCharacter = drawables[i];
drawables[i] = drawables[largestIndex];
drawables[largestIndex] = tempCharacter;
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
sb.GraphicsDevice.BlendState = BlendState.AlphaBlend;
foreach (ModelMesh mesh in board.Meshes)
{
foreach (BasicEffect be in mesh.Effects)
{
UniversalLighting.MatchEffect(be);
be.View = view;
be.Projection = projection;
be.World = Matrix.CreateTranslation(new Vector3(0, 0, 0));
}
mesh.Draw();
}
sortDrawables();
foreach (Object c in drawables)
{
if (c is Character)
{
((Character) c).Draw(projection, view, cameraPosition, animMatrix, sources);
}
else if (c is FixObject)
{
((FixObject) c).Draw(projection, view, cameraPosition, sources, Matrix.Identity);
}
else if (c is PositionSpike)
{
((PositionSpike) c).Draw(projection, view, orangePixel);
}
}
public void Draw(Matrix projection, Matrix view, Texture2D texture, Texture2D[] frontLights, Texture2D[] backLights, LightSource[] sources, GraphicsDevice gd, Vector3 cameraPosition, Matrix animMatrix, float rotation = 0f, Texture2D otherSide = null)
{
foreach (ModelMesh m in model.Meshes)
{
foreach (BasicEffect be in m.Effects)
{
UniversalLighting.MatchEffect(be);
be.TextureEnabled = true;
be.Texture = texture;
be.View = view;
be.Projection = projection;
be.World = Matrix.CreateScale(new Vector3(stretch.X*-1, stretch.Y*-1, 1)) *
Matrix.CreateRotationY(rotation) *
animMatrix *
Matrix.CreateTranslation(position - new Vector3(0, stretch.Y/-2*MODEL_SIZE, 0) + rotNormal * 0.0005f * orderify);
}
m.Draw();
}
if (otherSide != null)
{
foreach (ModelMesh m in model.Meshes)
{
foreach (BasicEffect be in m.Effects)
{
UniversalLighting.MatchEffect(be);
be.TextureEnabled = true;
be.Texture = otherSide;
be.View = view;
be.Projection = projection;
be.World = Matrix.CreateScale(new Vector3(stretch.X, stretch.Y*-1, 1)) *
Matrix.CreateRotationY(rotation + (float) Math.PI * 2) *
animMatrix *
Matrix.CreateTranslation(position - new Vector3(0, stretch.Y/-2*MODEL_SIZE, 0) + rotNormal * -0.0005f * orderify);
}
m.Draw();
}
}
}