@@ -275,48 +275,44 @@ void Model::draw(const Shader& shader, const glm::mat4& viewProj) const {
275275 viewProj[2 ][3 ] + (i % 2 == 0 ? 1 : -1 ) * viewProj[2 ][i / 2 ],
276276 viewProj[3 ][3 ] + (i % 2 == 0 ? 1 : -1 ) * viewProj[3 ][i / 2 ]
277277 );
278+ const float length = glm::length (glm::vec3 (planes[i]));
279+ if (length > 0 .0f ) {
280+ planes[i] /= length;
281+ }
278282 }
279283
280- auto & [drawOrder, sortFuture] = sortContexts[this ];
281-
282- if (drawOrder.size () != meshes.size ()) {
283- drawOrder.resize (meshes.size ());
284- std::iota (drawOrder.begin (), drawOrder.end (), 0 );
285- }
284+ std::vector<unsigned int > opaqueIndices;
285+ std::vector<unsigned int > transparentIndices;
286+ opaqueIndices.reserve (meshes.size ());
287+ transparentIndices.reserve (meshes.size ());
286288
287- if (sortFuture.valid () && sortFuture.wait_for (std::chrono::seconds (0 )) == std::future_status::ready) {
288- if (std::vector<unsigned int > newOrder = sortFuture.get (); newOrder.size () == meshes.size ()) {
289- drawOrder = std::move (newOrder);
289+ for (unsigned int i = 0 ; i < meshes.size (); ++i) {
290+ if (meshes[i].isBlended ) {
291+ transparentIndices.push_back (i);
292+ } else {
293+ opaqueIndices.push_back (i);
290294 }
291295 }
292296
293- if (!sortFuture.valid ()) {
294- std::vector<glm::vec3> centers;
295- centers.reserve (meshes.size ());
296- for (const auto & mesh : meshes) {
297- centers.push_back ((mesh.aabbMin + mesh.aabbMax ) * 0 .5f );
298- }
299-
300- sortFuture = std::async (std::launch::async, [centers = std::move (centers), viewProj]() {
301- std::vector<unsigned int > indices (centers.size ());
302- std::iota (indices.begin (), indices.end (), 0 );
297+ std::vector<float > distances (meshes.size ());
298+ for (size_t i = 0 ; i < meshes.size (); ++i) {
299+ const glm::vec3 center = (meshes[i].aabbMin + meshes[i].aabbMax ) * 0 .5f ;
300+ distances[i] = (viewProj * glm::vec4 (center, 1 .0f )).w ;
301+ }
303302
304- std::vector< float > distances (centers. size ());
305- for ( size_t i = 0 ; i < centers. size (); ++i ) {
306- distances[i] = (viewProj * glm::vec4 (centers[i], 1 . 0f )). w ;
307- }
303+ // Sort Opaque Front-to-Back (Optimizes overdraw)
304+ std::sort (opaqueIndices. begin (), opaqueIndices. end (), [&]( unsigned int a, unsigned int b ) {
305+ return distances[a] < distances[b] ;
306+ });
308307
309- std::ranges::sort (indices, [&](unsigned int a, unsigned int b) {
310- return distances[a] > distances[b];
311- });
312- return indices;
313- });
314- }
308+ // Sort Transparent Back-to-Front (Required for correct blending)
309+ std::sort (transparentIndices.begin (), transparentIndices.end (), [&](unsigned int a, unsigned int b) {
310+ return distances[a] > distances[b];
311+ });
315312
316- // Pass 1: Opaque meshes
317- for (const unsigned int i : drawOrder ) {
313+ // Pass 1: Opaque meshes (including cutout transparency)
314+ for (const unsigned int i : opaqueIndices ) {
318315 const Mesh& mesh = meshes[i];
319- if (mesh.isTransparent ) continue ;
320316
321317 const glm::vec3 center = (mesh.aabbMin + mesh.aabbMax ) * 0 .5f ;
322318 const glm::vec3 extents = (mesh.aabbMax - mesh.aabbMin ) * 0 .5f ;
@@ -334,10 +330,9 @@ void Model::draw(const Shader& shader, const glm::mat4& viewProj) const {
334330 }
335331 }
336332
337- // Pass 2: Transparent meshes (sorted back-to-front by distances[a] > distances[b])
338- for (const unsigned int i : drawOrder ) {
333+ // Pass 2: Blended transparent meshes (sorted back-to-front by distances[a] > distances[b])
334+ for (const unsigned int i : transparentIndices ) {
339335 const Mesh& mesh = meshes[i];
340- if (!mesh.isTransparent ) continue ;
341336
342337 const glm::vec3 center = (mesh.aabbMin + mesh.aabbMax ) * 0 .5f ;
343338 const glm::vec3 extents = (mesh.aabbMax - mesh.aabbMin ) * 0 .5f ;
0 commit comments