transparency_sorting.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1">
  6. <title>Transparency Sorting :: jMonkeyEngine Docs</title>
  7. <link rel="canonical" href="https://wiki.jmonkeyengine.org/docs/jme3/intermediate/transparency_sorting.html">
  8. <link rel="prev" href="how_to_use_materials.html">
  9. <link rel="next" href="../external/blender.html">
  10. <meta name="keywords" content="transparent, sorting, bucket, z-buffer, alpha">
  11. <meta name="generator" content="Antora 2.3.3">
  12. <link rel="stylesheet" href="../../../_/css/site.css">
  13. <meta property="og:image" content="https://wiki.jmonkeyengine.org/_/img/iconx128.png">
  14. <meta property="og:description" content="Transparency Sorting">
  15. <meta property="og:title" content="jMonkeyEngine Docs">
  16. <link rel="stylesheet" href="../../../_/css/site-extra.css">
  17. <link rel="stylesheet" href="../../../_/css/vendor/docsearch.min.css">
  18. <!-- fetched from https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css -->
  19. <link rel="icon" href="../../../_/img/favicon.ico" type="image/x-icon">
  20. </head>
  21. <body class="article">
  22. <header class="header">
  23. <nav class="navbar">
  24. <div class="navbar-brand">
  25. <a class="navbar-item" href="https://wiki.jmonkeyengine.org">
  26. <img alt="" src="../../../_/img/jme-logo.png" height="32" type="image/x-icon">
  27. </a>
  28. <div class="navbar-item hide-for-print">
  29. <input id="search-input" type="text" placeholder="Search docs">
  30. </div>
  31. <button class="navbar-burger" data-target="topbar-nav">
  32. <span></span>
  33. <span></span>
  34. <span></span>
  35. </button>
  36. </div>
  37. <div id="topbar-nav" class="navbar-menu">
  38. <div class="navbar-end">
  39. <div class="navbar-item theme-switch-wrapper">
  40. <label class="theme-switch" for="checkbox">
  41. <input type="checkbox" id="checkbox" />
  42. <div class="slider round"></div>
  43. </label>
  44. </div>
  45. <a class="navbar-item" href="https://github.com/jmonkeyengine/wiki">Github</a>
  46. </div>
  47. </div>
  48. </nav>
  49. </header>
  50. <div class="body">
  51. <div class="nav-container" data-component="docs" data-version="master">
  52. <aside class="nav">
  53. <div class="panels">
  54. <div class="nav-panel-menu is-active" data-panel="menu">
  55. <nav class="nav-menu">
  56. <h3 class="title"><a href="../../documentation.html">Docs</a></h3>
  57. <ul class="nav-list">
  58. <li class="nav-item" data-depth="0">
  59. <ul class="nav-list">
  60. <li class="nav-item" data-depth="1">
  61. <a class="nav-link" href="../../documentation.html">Getting Started</a>
  62. </li>
  63. <li class="nav-item" data-depth="1">
  64. <a class="nav-link" href="https://javadoc.jmonkeyengine.org/v3.3.2-stable">JavaDoc</a>
  65. </li>
  66. <li class="nav-item" data-depth="1">
  67. <button class="nav-item-toggle"></button>
  68. <a class="nav-link" href="../../jme3.html">jMonkeyEngine 3</a>
  69. <ul class="nav-list">
  70. <li class="nav-item" data-depth="2">
  71. <button class="nav-item-toggle"></button>
  72. <span class="nav-text">Beginner Tutorials</span>
  73. <ul class="nav-list">
  74. <li class="nav-item" data-depth="3">
  75. <a class="nav-link" href="../beginner/hello_simpleapplication.html">Hello SimpleApplication</a>
  76. </li>
  77. <li class="nav-item" data-depth="3">
  78. <a class="nav-link" href="../beginner/hello_node.html">Hello Node</a>
  79. </li>
  80. <li class="nav-item" data-depth="3">
  81. <a class="nav-link" href="../beginner/hello_asset.html">Hello Asset</a>
  82. </li>
  83. <li class="nav-item" data-depth="3">
  84. <a class="nav-link" href="../beginner/hello_main_event_loop.html">Hello Main Event Loop</a>
  85. </li>
  86. <li class="nav-item" data-depth="3">
  87. <a class="nav-link" href="../beginner/hello_input_system.html">Hello Input System</a>
  88. </li>
  89. <li class="nav-item" data-depth="3">
  90. <a class="nav-link" href="../beginner/hello_material.html">Hello Material</a>
  91. </li>
  92. <li class="nav-item" data-depth="3">
  93. <a class="nav-link" href="../beginner/hello_animation.html">Hello Animation</a>
  94. </li>
  95. <li class="nav-item" data-depth="3">
  96. <a class="nav-link" href="../beginner/hello_picking.html">Hello Picking</a>
  97. </li>
  98. <li class="nav-item" data-depth="3">
  99. <a class="nav-link" href="../beginner/hello_collision.html">Hello Collision</a>
  100. </li>
  101. <li class="nav-item" data-depth="3">
  102. <a class="nav-link" href="../beginner/hello_terrain.html">Hello Terrain</a>
  103. </li>
  104. <li class="nav-item" data-depth="3">
  105. <a class="nav-link" href="../beginner/hello_audio.html">Hello Audio</a>
  106. </li>
  107. <li class="nav-item" data-depth="3">
  108. <a class="nav-link" href="../beginner/hello_effects.html">Hello Effects</a>
  109. </li>
  110. <li class="nav-item" data-depth="3">
  111. <a class="nav-link" href="../beginner/hello_physics.html">Hello Physics</a>
  112. </li>
  113. </ul>
  114. </li>
  115. <li class="nav-item" data-depth="2">
  116. <button class="nav-item-toggle"></button>
  117. <span class="nav-text">Intermediate Tutorials</span>
  118. <ul class="nav-list">
  119. <li class="nav-item" data-depth="3">
  120. <button class="nav-item-toggle"></button>
  121. <span class="nav-text">Concepts</span>
  122. <ul class="nav-list">
  123. <li class="nav-item" data-depth="4">
  124. <a class="nav-link" href="best_practices.html">Best Practices</a>
  125. </li>
  126. <li class="nav-item" data-depth="4">
  127. <a class="nav-link" href="simpleapplication.html">Simple Application</a>
  128. </li>
  129. <li class="nav-item" data-depth="4">
  130. <a class="nav-link" href="../features.html">Features</a>
  131. </li>
  132. <li class="nav-item" data-depth="4">
  133. <a class="nav-link" href="optimization.html">Optimization</a>
  134. </li>
  135. <li class="nav-item" data-depth="4">
  136. <a class="nav-link" href="../faq.html">FAQ</a>
  137. </li>
  138. </ul>
  139. </li>
  140. <li class="nav-item" data-depth="3">
  141. <button class="nav-item-toggle"></button>
  142. <span class="nav-text">Math Concepts</span>
  143. <ul class="nav-list">
  144. <li class="nav-item" data-depth="4">
  145. <a class="nav-link" href="../math_for_dummies.html">Math For Dummies</a>
  146. </li>
  147. <li class="nav-item" data-depth="4">
  148. <a class="nav-link" href="math.html">Math</a>
  149. </li>
  150. <li class="nav-item" data-depth="4">
  151. <a class="nav-link" href="../math.html">More Math</a>
  152. </li>
  153. <li class="nav-item" data-depth="4">
  154. <a class="nav-link" href="../rotate.html">Rotate</a>
  155. </li>
  156. <li class="nav-item" data-depth="4">
  157. <a class="nav-link" href="../math_video_tutorials.html">Math Video Tutorials</a>
  158. </li>
  159. </ul>
  160. </li>
  161. <li class="nav-item" data-depth="3">
  162. <button class="nav-item-toggle"></button>
  163. <span class="nav-text">3D Graphics Concepts</span>
  164. <ul class="nav-list">
  165. <li class="nav-item" data-depth="4">
  166. <a class="nav-link" href="multi-media_asset_pipeline.html">Multi-Media Asset Pipeline</a>
  167. </li>
  168. <li class="nav-item" data-depth="4">
  169. <a class="nav-link" href="../scenegraph_for_dummies.html">Scenegraph for Dummies</a>
  170. </li>
  171. <li class="nav-item" data-depth="4">
  172. <a class="nav-link" href="../beginner/hellovector.html">Hello Vector</a>
  173. </li>
  174. <li class="nav-item" data-depth="4">
  175. <a class="nav-link" href="../terminology.html">Terminology</a>
  176. </li>
  177. <li class="nav-item" data-depth="4">
  178. <a class="nav-link" href="how_to_use_materials.html">How to Use Materials</a>
  179. </li>
  180. <li class="nav-item is-current-page" data-depth="4">
  181. <a class="nav-link" href="transparency_sorting.html">Transparency and Sorting</a>
  182. </li>
  183. <li class="nav-item" data-depth="4">
  184. <a class="nav-link" href="../external/blender.html">Importing from Blender</a>
  185. </li>
  186. <li class="nav-item" data-depth="4">
  187. <a class="nav-link" href="../external/3dsmax.html">Importing from 3DS Max</a>
  188. </li>
  189. </ul>
  190. </li>
  191. </ul>
  192. </li>
  193. </ul>
  194. </li>
  195. <li class="nav-item" data-depth="1">
  196. <a class="nav-link" href="../../logo.html">Logo Usage</a>
  197. </li>
  198. <li class="nav-item" data-depth="1">
  199. <a class="nav-link" href="../../bsd_license.html">License</a>
  200. </li>
  201. <li class="nav-item" data-depth="1">
  202. <a class="nav-link" href="../../github_tips.html">Github Tips</a>
  203. </li>
  204. </ul>
  205. </li>
  206. <li class="nav-item" data-depth="0">
  207. <button class="nav-item-toggle"></button>
  208. <span class="nav-text">SDK</span>
  209. <ul class="nav-list">
  210. <li class="nav-item" data-depth="1">
  211. <a class="nav-link" href="../../sdk.html">jMonkeyEngine SDK</a>
  212. </li>
  213. </ul>
  214. </li>
  215. </ul>
  216. </nav>
  217. </div>
  218. <div class="nav-panel-explore" data-panel="explore">
  219. <div class="context">
  220. <span class="title">Docs</span>
  221. <span class="version">master</span>
  222. </div>
  223. <ul class="components">
  224. <li class="component is-current">
  225. <span class="title">Docs</span>
  226. <ul class="versions">
  227. <li class="version is-current is-latest">
  228. <a href="../../documentation.html">master</a>
  229. </li>
  230. </ul>
  231. </li>
  232. <li class="component">
  233. <span class="title">Wiki UI</span>
  234. <ul class="versions">
  235. <li class="version is-latest">
  236. <a href="../../../wiki-ui/index.html">master</a>
  237. </li>
  238. </ul>
  239. </li>
  240. </ul>
  241. </div>
  242. </div>
  243. </aside>
  244. </div>
  245. <main class="article">
  246. <div class="toolbar" role="navigation">
  247. <button class="nav-toggle"></button>
  248. <nav class="breadcrumbs" aria-label="breadcrumbs">
  249. <ul>
  250. <li><a href="../../documentation.html">Docs</a></li>
  251. <li><a href="../../jme3.html">jMonkeyEngine 3</a></li>
  252. <li>Intermediate Tutorials</li>
  253. <li>3D Graphics Concepts</li>
  254. <li><a href="transparency_sorting.html">Transparency and Sorting</a></li>
  255. </ul>
  256. </nav>
  257. <div class="edit-this-page"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/docs/modules/ROOT/pages/jme3/intermediate/transparency_sorting.adoc">Edit this Page</a></div>
  258. </div>
  259. <div class="content">
  260. <article class="doc">
  261. <h1 class="page">Transparency Sorting</h1>
  262. <div class="paragraph">
  263. <p>There is often a lot of confusion with how pixels get processed in relation to the z-buffer and why sorting is important. Most importantly it can be mind-warping trying to wrap one&#8217;s head around how to 'fix' the cases where proper sorting isn&#8217;t possible.</p>
  264. </div>
  265. <div class="paragraph">
  266. <p>Hopefully these diagrams help show the futility of it all… I mean the trade offs one has to make to get transparency looking its best in the general case.</p>
  267. </div>
  268. <div class="paragraph">
  269. <p>The first image I&#8217;ll show is the 'best case' where all objects are drawn back to front. I&#8217;ll then discuss briefly the steps JME goes through to try to make that happen.</p>
  270. </div>
  271. <div class="imageblock text-center">
  272. <div class="content">
  273. <img src="../../_images/jme3/intermediate/transparency_sorting1.png" alt="transparency_sorting1.png" width="600" height="">
  274. </div>
  275. </div>
  276. <div class="paragraph">
  277. <p>In JME, the opaque layer would generally be placed in the opaque bucket. All opaque layers are drawn first and within the ability to sort them, they are sorted front to back to prevent overdraw.</p>
  278. </div>
  279. <div class="paragraph">
  280. <p>After the opaque bucket is drawn, the transparent bucket is drawn and it is sorted back to front. So in the ideal case it would appear exactly as in this picture.</p>
  281. </div>
  282. <div class="admonitionblock note">
  283. <table>
  284. <tr>
  285. <td class="icon">
  286. <i class="fa icon-note" title="Note"></i>
  287. </td>
  288. <td class="content">
  289. <div class="paragraph">
  290. <p>Sorting is done at the object level and it can never be perfect. It is impossible to properly sort objects by distance in the general case even if they were just triangles. Simply imagine intersecting triangles and it&#8217;s clear there is no proper order. JME tries its best.</p>
  291. </div>
  292. </td>
  293. </tr>
  294. </table>
  295. </div>
  296. <div class="paragraph">
  297. <p>Next I&#8217;ll show an image of the worst case scenario to show why sorting is important and how your 'best friend' the z-buffer is really transparency&#8217;s worst enemy.</p>
  298. </div>
  299. <div class="imageblock text-center">
  300. <div class="content">
  301. <img src="../../_images/jme3/intermediate/transparency_sorting2.png" alt="transparency_sorting2.png" width="600" height="">
  302. </div>
  303. </div>
  304. <div class="paragraph">
  305. <p>This is what will happen if you put all of your objects in the opaque buffer. JME will sort them front to back and you will get these strange 'windows' into your background.</p>
  306. </div>
  307. <div class="admonitionblock note">
  308. <table>
  309. <tr>
  310. <td class="icon">
  311. <i class="fa icon-note" title="Note"></i>
  312. </td>
  313. <td class="content">
  314. <div class="paragraph">
  315. <p>Because sorting is done at the object level, you may have triangle to triangle overlap even within the same mesh if it is non-convex. Think of a glass donut where the near surface triangles are drawn before the hole&#8217;s triangles. There will be this same issue where they occlude the farther triangles. A different angle on the donut might produce the correct results depending on the order of the triangles in the mesh.</p>
  316. </div>
  317. </td>
  318. </tr>
  319. </table>
  320. </div>
  321. <div class="paragraph">
  322. <p>Finally, I&#8217;ll augment the worst case sorting with something like <code>alphaDiscardThreshold</code> (or the old alphaTest/alphaFalloff values). In this example, let&#8217;s pretend we only discard pixels with alpha = 0.</p>
  323. </div>
  324. <div class="imageblock text-center">
  325. <div class="content">
  326. <img src="../../_images/jme3/intermediate/transparency_sorting3.png" alt="transparency_sorting3.png" width="600" height="">
  327. </div>
  328. </div>
  329. <div class="paragraph">
  330. <p>It&#8217;s better but not perfect. Any partially transparent pixels will still show the issue. Partial transparency will drive you crazy if you let it.</p>
  331. </div>
  332. <div class="paragraph">
  333. <p>Bottom line:</p>
  334. </div>
  335. <div class="ulist">
  336. <ul>
  337. <li>
  338. <p>back to front sorting would fix all issues</p>
  339. </li>
  340. <li>
  341. <p>accurate back to front sorting in the general case is impossible</p>
  342. </li>
  343. <li>
  344. <p>for purely on/off a = 1 or a = 0 transparency then a discard threshold is the best bet to mitigate sorting problems.</p>
  345. </li>
  346. <li>
  347. <p>Where 0 &lt; alpha &lt; 1, improper sorting of triangles/pixels will always cause artifacts.</p>
  348. </li>
  349. </ul>
  350. </div>
  351. <nav class="pagination">
  352. <span class="prev"><a href="how_to_use_materials.html">How to Use Materials</a></span>
  353. <span class="next"><a href="../external/blender.html">Importing from Blender</a></span>
  354. </nav>
  355. </article>
  356. <aside class="toc sidebar" data-title="Contents" data-levels="2">
  357. <div class="toc-menu"></div>
  358. </aside>
  359. </div>
  360. </main>
  361. </div>
  362. <footer class="footer">
  363. <p>Copyright 2020 jMonkeyEngine Wiki Contributors. Licensed BSD-3.</p>
  364. </footer>
  365. <script src="../../../_/js/vendor/docsearch.min.js"></script>
  366. <!-- fetched from https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js -->
  367. <script>
  368. var search = docsearch({
  369. apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
  370. indexName: 'jmonkeyengine',
  371. inputSelector: '#search-input',
  372. autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
  373. algoliaOptions: { hitsPerPage: 10 }
  374. }).autocomplete
  375. search.on('autocomplete:closed', function () { search.autocomplete.setVal() })
  376. function focusSearchInput () { document.querySelector('#search-input').focus() }
  377. if (document.querySelector('.home-link.is-current')) window.addEventListener('load', focusSearchInput)
  378. </script>
  379. <script src="../../../_/js/site.js"></script>
  380. <script async src="../../../_/js/vendor/highlight.js"></script>
  381. </body>
  382. </html>