From 6fcf1bbe7945bd6fb6fa1a046c42470306ffac94 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 5 Dec 2016 03:11:34 +0000 Subject: [PATCH] Somewhat improve rendering of transparent meshes. After this commit, any transparent triangles are drawn last, which causes them to not clobber the depth buffer, and so if they overlap some opaque triangles, then these opaque triangles will be visible. There are still issues with overlapping transparent triangles, and with transparent triangles overlapping outlines and entities. --- src/groupmesh.cpp | 5 +++++ src/mesh.cpp | 15 +++++++++++++-- src/polygon.h | 2 ++ src/srf/surface.cpp | 1 - 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index 261148d..6d1b2a7 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -416,6 +416,11 @@ void Group::GenerateDisplayItems() { } } + // If we render this mesh, we need to know whether it's transparent, + // and we'll want all transparent triangles last, to make the depth test + // work correctly. + displayMesh.PrecomputeTransparency(); + displayDirty = false; } } diff --git a/src/mesh.cpp b/src/mesh.cpp index 4231a19..d8bf959 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -34,8 +34,6 @@ void SMesh::AddTriangle(STriMeta meta, Vector a, Vector b, Vector c) { AddTriangle(&t); } void SMesh::AddTriangle(const STriangle *st) { - RgbaColor color = st->meta.color; - if(!color.IsEmpty() && color.alpha != 255) isTransparent = true; l.Add(st); } @@ -1091,3 +1089,16 @@ void SOutlineList::MakeFromCopyOf(SOutlineList *sol) { l.Add(so); } } + +void SMesh::PrecomputeTransparency() { + std::sort(l.begin(), l.end(), + [&](const STriangle &sta, const STriangle &stb) { + RgbaColor colora = sta.meta.color, + colorb = stb.meta.color; + bool opaquea = colora.IsEmpty() || colora.alpha == 255, + opaqueb = colorb.IsEmpty() || colorb.alpha == 255; + + if(!opaquea || !opaqueb) isTransparent = true; + return (opaquea != opaqueb && opaquea == true); + }); +} diff --git a/src/polygon.h b/src/polygon.h index 2bd0f8a..072cd9c 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -276,6 +276,8 @@ public: void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d); void MakeOutlinesInto(SOutlineList *sol, EdgeKind type); + void PrecomputeTransparency(); + bool IsEmpty() const; void RemapFaces(Group *g, int remap); diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp index a068ead..21c628e 100644 --- a/src/srf/surface.cpp +++ b/src/srf/surface.cpp @@ -441,7 +441,6 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) { for(i = start; i < sm->l.n; i++) { STriangle *st = &(sm->l.elem[i]); st->meta = meta; - if(st->meta.color.alpha != 255) sm->isTransparent = true; st->an = NormalAt(st->a.x, st->a.y); st->bn = NormalAt(st->b.x, st->b.y); st->cn = NormalAt(st->c.x, st->c.y);