如何修复 3D 模型中这个奇怪的透明区域?
How to fix this weird transparent areas in 3D model?
有些东西没有正常工作。如果您查看屏幕截图,您会发现结果很奇怪。展馆的地板渲染正确,但柱子有点透明,屋顶也很奇怪。我使用 Assimp.NET 从 .obj 文件导入他的网格。在其他引擎中它看起来正确。另一件事是:如果我将 CullMode 设置为 Back - 它会剔除正面?!我认为可能是 3 件事:1,网格导入错误,或者 z Buffer 不工作,或者我可能需要多个世界矩阵(我只使用一个)。
也许有人知道这可能是什么吗?!
截图:
这是一些代码:
DepthBuffer/DepthStencilView
var depthBufferDescription = new Texture2DDescription
{
Format = Format.D32_Float_S8X24_UInt,
ArraySize = 1,
MipLevels = 1,
Width = BackBuffer.Description.Width,
Height = BackBuffer.Description.Height,
SampleDescription = swapChainDescription.SampleDescription,
BindFlags = BindFlags.DepthStencil
};
var depthStencilViewDescription = new DepthStencilViewDescription
{
Dimension = SwapChain.Description.SampleDescription.Count > 1 || SwapChain.Description.SampleDescription.Quality > 0 ? DepthStencilViewDimension.Texture2DMultisampled : DepthStencilViewDimension.Texture2D
};
var depthStencilStateDescription = new DepthStencilStateDescription
{
IsDepthEnabled = true,
DepthComparison = Comparison.Always,
DepthWriteMask = DepthWriteMask.All,
IsStencilEnabled = false,
StencilReadMask = 0xff,
StencilWriteMask = 0xff,
FrontFace = new DepthStencilOperationDescription
{
Comparison = Comparison.Always,
PassOperation = StencilOperation.Keep,
FailOperation = StencilOperation.Keep,
DepthFailOperation = StencilOperation.Increment
},
BackFace = new DepthStencilOperationDescription
{
Comparison = Comparison.Always,
PassOperation = StencilOperation.Keep,
FailOperation = StencilOperation.Keep,
DepthFailOperation = StencilOperation.Decrement
}
};
正在加载网格文件:
public static Mesh Stadafax_ModelFromFile(string path)
{
if (_importContext.IsImportFormatSupported(Path.GetExtension(path)))
{
var imported = _importContext.ImportFile(path, PostProcessSteps.Triangulate | PostProcessSteps.FindDegenerates | PostProcessSteps.FindInstances | PostProcessSteps.FindInvalidData | PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.OptimizeGraph | PostProcessSteps.ValidateDataStructure | PostProcessSteps.FlipUVs);
Mesh engineMesh = new Mesh();
Assimp.Mesh assimpMesh = imported.Meshes[0];
foreach(Face f in assimpMesh.Faces)
{
engineMesh.Structure.Faces.Add(new Rendering.Triangle((uint)f.Indices[0], (uint)f.Indices[1], (uint)f.Indices[2]));
}
List<Vector3D>[] uv = assimpMesh.TextureCoordinateChannels;
for(int i = 0; i < assimpMesh.Vertices.Count; i++)
{
engineMesh.Structure.Vertices.Add(new Vertex(new Vector4(assimpMesh.Vertices[i].X, assimpMesh.Vertices[i].Y, assimpMesh.Vertices[i].Z, 1), RenderColorRGBA.White, new Vector2(uv[0][i].X, uv[0][i].Y)));
}
return engineMesh;
}
else
NoëlEngine.Common.Output.Log("Model format not supported!", "Importeur", true); return null;
}
}
如果有人只是知道这可能是什么,请发表评论。
您看到的是多边形实际上位于其他多边形之后,但仍绘制在它们上方。
当您通过 DepthStencilStateDescription
配置深度缓冲区时,您将 DepthComparison
设置为 Comparison.Always
。这不是你想要的,你要用 Comparison.Less
.
背后的逻辑是什么?检查像素的每个深度值是否可以实际写入深度缓冲区。此检查配置了您指定的 Comparison
。
Comparison.Always
总是 允许写入新值。因此,无论一个多边形实际上是在其他人的后面还是在他们之上或其他什么,它都会 总是 覆盖 ("draw above") 已经存在的东西 - 即使它在空间上落后于它。
Comparison.Less
仅当该值小于深度缓冲区中的当前值 时才写入该值。不要忘记较小的深度值离观察者更近。因此,更接近现有多边形的多边形将覆盖 ("draw above") 旧多边形。但如果它在它后面,它就不会绘制。这正是您想要的。
您还可以猜测其他 Comparison
枚举现在做什么,并尝试一下:)
有些东西没有正常工作。如果您查看屏幕截图,您会发现结果很奇怪。展馆的地板渲染正确,但柱子有点透明,屋顶也很奇怪。我使用 Assimp.NET 从 .obj 文件导入他的网格。在其他引擎中它看起来正确。另一件事是:如果我将 CullMode 设置为 Back - 它会剔除正面?!我认为可能是 3 件事:1,网格导入错误,或者 z Buffer 不工作,或者我可能需要多个世界矩阵(我只使用一个)。
也许有人知道这可能是什么吗?!
截图:
这是一些代码:
DepthBuffer/DepthStencilView
var depthBufferDescription = new Texture2DDescription
{
Format = Format.D32_Float_S8X24_UInt,
ArraySize = 1,
MipLevels = 1,
Width = BackBuffer.Description.Width,
Height = BackBuffer.Description.Height,
SampleDescription = swapChainDescription.SampleDescription,
BindFlags = BindFlags.DepthStencil
};
var depthStencilViewDescription = new DepthStencilViewDescription
{
Dimension = SwapChain.Description.SampleDescription.Count > 1 || SwapChain.Description.SampleDescription.Quality > 0 ? DepthStencilViewDimension.Texture2DMultisampled : DepthStencilViewDimension.Texture2D
};
var depthStencilStateDescription = new DepthStencilStateDescription
{
IsDepthEnabled = true,
DepthComparison = Comparison.Always,
DepthWriteMask = DepthWriteMask.All,
IsStencilEnabled = false,
StencilReadMask = 0xff,
StencilWriteMask = 0xff,
FrontFace = new DepthStencilOperationDescription
{
Comparison = Comparison.Always,
PassOperation = StencilOperation.Keep,
FailOperation = StencilOperation.Keep,
DepthFailOperation = StencilOperation.Increment
},
BackFace = new DepthStencilOperationDescription
{
Comparison = Comparison.Always,
PassOperation = StencilOperation.Keep,
FailOperation = StencilOperation.Keep,
DepthFailOperation = StencilOperation.Decrement
}
};
正在加载网格文件:
public static Mesh Stadafax_ModelFromFile(string path)
{
if (_importContext.IsImportFormatSupported(Path.GetExtension(path)))
{
var imported = _importContext.ImportFile(path, PostProcessSteps.Triangulate | PostProcessSteps.FindDegenerates | PostProcessSteps.FindInstances | PostProcessSteps.FindInvalidData | PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.OptimizeGraph | PostProcessSteps.ValidateDataStructure | PostProcessSteps.FlipUVs);
Mesh engineMesh = new Mesh();
Assimp.Mesh assimpMesh = imported.Meshes[0];
foreach(Face f in assimpMesh.Faces)
{
engineMesh.Structure.Faces.Add(new Rendering.Triangle((uint)f.Indices[0], (uint)f.Indices[1], (uint)f.Indices[2]));
}
List<Vector3D>[] uv = assimpMesh.TextureCoordinateChannels;
for(int i = 0; i < assimpMesh.Vertices.Count; i++)
{
engineMesh.Structure.Vertices.Add(new Vertex(new Vector4(assimpMesh.Vertices[i].X, assimpMesh.Vertices[i].Y, assimpMesh.Vertices[i].Z, 1), RenderColorRGBA.White, new Vector2(uv[0][i].X, uv[0][i].Y)));
}
return engineMesh;
}
else
NoëlEngine.Common.Output.Log("Model format not supported!", "Importeur", true); return null;
}
}
如果有人只是知道这可能是什么,请发表评论。
您看到的是多边形实际上位于其他多边形之后,但仍绘制在它们上方。
当您通过 DepthStencilStateDescription
配置深度缓冲区时,您将 DepthComparison
设置为 Comparison.Always
。这不是你想要的,你要用 Comparison.Less
.
背后的逻辑是什么?检查像素的每个深度值是否可以实际写入深度缓冲区。此检查配置了您指定的 Comparison
。
Comparison.Always
总是 允许写入新值。因此,无论一个多边形实际上是在其他人的后面还是在他们之上或其他什么,它都会 总是 覆盖 ("draw above") 已经存在的东西 - 即使它在空间上落后于它。Comparison.Less
仅当该值小于深度缓冲区中的当前值 时才写入该值。不要忘记较小的深度值离观察者更近。因此,更接近现有多边形的多边形将覆盖 ("draw above") 旧多边形。但如果它在它后面,它就不会绘制。这正是您想要的。
您还可以猜测其他 Comparison
枚举现在做什么,并尝试一下:)