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 261148df..6d1b2a7a 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 4231a198..d8bf9591 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 2bd0f8ab..072cd9c1 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 a068ead3..21c628e1 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);