<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>illustration of life</title>
    <link>https://illu.tistory.com/</link>
    <description>Technical Artist / All rights reserved by illu since 2001 / illustor@gmail.com</description>
    <language>ko</language>
    <pubDate>Sun, 5 Jul 2026 14:47:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>illu_yun</managingEditor>
    <image>
      <title>illustration of life</title>
      <url>https://t1.daumcdn.net/cfile/tistory/210C333658DB4B740A</url>
      <link>https://illu.tistory.com</link>
    </image>
    <item>
      <title>GPU Works Graphs(1)</title>
      <link>https://illu.tistory.com/1516</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;원문 링크 : &lt;a href=&quot;https://coburggraphicslab.github.io/files/Kuth25GWG.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://coburggraphicslab.github.io/files/Kuth25GWG.pdf&lt;/a&gt; &amp;nbsp;&lt;br /&gt;AMD link : &lt;a href=&quot;https://gpuopen.com/learn/gpu-work-graphs/gpu-work-graphs-intro/?fbclid=IwY2xjawMmIAdleHRuA2FlbQIxMQABHvl4MRxkz6uzfhsgcnV6SgLYsQZoHE3HDRoOOCj6KsiYqLPplTJ3GkFz1yWC_aem_0q3oWG-YVfEeWqZ8Q2ZhKw&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/learn/gpu-work-graphs/gpu-work-graphs-intro/?fbclid=IwY2xjawMmIAdleHRuA2FlbQIxMQABHvl4MRxkz6uzfhsgcnV6SgLYsQZoHE3HDRoOOCj6KsiYqLPplTJ3GkFz1yWC_aem_0q3oWG-YVfEeWqZ8Q2ZhKw&lt;/a&gt; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to 103page&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beRiqf/btsQmGWVaHu/kyKQZW2hLUZd1ElKB8Hvr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beRiqf/btsQmGWVaHu/kyKQZW2hLUZd1ElKB8Hvr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beRiqf/btsQmGWVaHu/kyKQZW2hLUZd1ElKB8Hvr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeRiqf%2FbtsQmGWVaHu%2FkyKQZW2hLUZd1ElKB8Hvr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1272&quot; height=&quot;704&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;704&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;702&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/umlZN/btsQkmZ1weI/jjVgcFYENBOFP7fzAcoVY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/umlZN/btsQkmZ1weI/jjVgcFYENBOFP7fzAcoVY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/umlZN/btsQkmZ1weI/jjVgcFYENBOFP7fzAcoVY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FumlZN%2FbtsQkmZ1weI%2FjjVgcFYENBOFP7fzAcoVY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1269&quot; height=&quot;702&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;702&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V0jiN/btsQl8fjMu1/VBKyYlPbKawYKev8szPl6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V0jiN/btsQl8fjMu1/VBKyYlPbKawYKev8szPl6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V0jiN/btsQl8fjMu1/VBKyYlPbKawYKev8szPl6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV0jiN%2FbtsQl8fjMu1%2FVBKyYlPbKawYKev8szPl6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1263&quot; height=&quot;704&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;704&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;오늘 SIGGRAPH에서 Work Graphs에 대한 강좌를 진행합니다. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;코부르크 대학교와 AMD는 2023년 1월부터 바이에른 주의 지원을 받아 Work Graphs의 실질적인 연구에 공동으로 집중해 왔습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;지난 2년 반 동안 Work Graphs는 우리의 업무 환경을 지배해 왔으며, 이 새로운 기술을 활용하여 저희와 다른 연구자들이 지금까지 무엇을 했는지 간략하게 말씀드리고자 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1264&quot; data-origin-height=&quot;705&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8wd9c/btsQmlepVia/dUGr3zyiDgPx4eboUZmoR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8wd9c/btsQmlepVia/dUGr3zyiDgPx4eboUZmoR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8wd9c/btsQmlepVia/dUGr3zyiDgPx4eboUZmoR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8wd9c%2FbtsQmlepVia%2FdUGr3zyiDgPx4eboUZmoR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1264&quot; height=&quot;705&quot; data-origin-width=&quot;1264&quot; data-origin-height=&quot;705&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;우리가 연구를 진행하는 동안 Work Graphs는 샘플 코드가 포함된 미리보기로 제공되었고, Vulkan 지원이 추가되었으며, AMD는 여러 개의 Work Graphs 샘플을 게시했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Work&amp;nbsp;Graphs&amp;nbsp;Preview&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/learn/gpu-work-graphs/gpu-work-graphs-intro/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/learn/gpu-work-graphs/gpu-work-graphs-intro/&lt;/a&gt;&lt;br /&gt;▪&amp;nbsp;Sample&amp;nbsp;Code&lt;br /&gt;&lt;a href=&quot;https://github.com/GPUOpen-LibrariesAndSDKs/WorkGraphsHelloWorkGraphs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/GPUOpen-LibrariesAndSDKs/WorkGraphsHelloWorkGraphs&lt;/a&gt;&lt;br /&gt;▪&amp;nbsp;Vulkan&amp;nbsp;Support&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/gpu-work-graphs-in-vulkan/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/gpu-work-graphs-in-vulkan/&lt;/a&gt;&lt;br /&gt;▪&amp;nbsp;Work&amp;nbsp;Graph&amp;nbsp;Samples&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/learn/rgp-work-graphs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/learn/rgp-work-graphs/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/learn/work_graphs_learning_sample/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/learn/work_graphs_learning_sample/&lt;/a&gt; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1266&quot; data-origin-height=&quot;702&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CmY3V/btsQjhY9okb/Pj3TiTMjEX6nlktVPfILX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CmY3V/btsQjhY9okb/Pj3TiTMjEX6nlktVPfILX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CmY3V/btsQjhY9okb/Pj3TiTMjEX6nlktVPfILX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCmY3V%2FbtsQjhY9okb%2FPj3TiTMjEX6nlktVPfILX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1266&quot; height=&quot;702&quot; data-origin-width=&quot;1266&quot; data-origin-height=&quot;702&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;게임 개발자 컨퍼런스(GDC) 2024에서 Work Graphs를 활용한 첫 데모를 선보였습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;또한, 연구 결과를 고성능 그래픽(HPG) 2024에 발표했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GDC&amp;nbsp;2024&amp;nbsp;-&amp;nbsp;GPU&amp;nbsp;Work&amp;nbsp;Graphs:&amp;nbsp;Welcome&amp;nbsp;to&amp;nbsp;the&amp;nbsp;Future&amp;nbsp;of&amp;nbsp;GPU&amp;nbsp;Programming&lt;br /&gt;&lt;a href=&quot;https://youtu.be/QQP6-JF64DQ?si=s1CA8AIouDfdZYom&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/QQP6-JF64DQ?si=s1CA8AIouDfdZYom&lt;/a&gt;&lt;br /&gt;GDC&amp;nbsp;2024&amp;nbsp;We&amp;nbsp;reveal&amp;nbsp;incredible&amp;nbsp;Work&amp;nbsp;Graphs&amp;nbsp;perf,&amp;nbsp;AMD&amp;nbsp;FSR&amp;nbsp;3.1,&amp;nbsp;GI&amp;nbsp;with&amp;nbsp;Brixelizer,&amp;nbsp;and&amp;nbsp;so&amp;nbsp;much&amp;nbsp;more&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/events/amd-at-gdc-2024/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/events/amd-at-gdc-2024/&lt;/a&gt;&lt;br /&gt;GDC&amp;nbsp;2024&amp;nbsp;Work&amp;nbsp;graphs&amp;nbsp;and&amp;nbsp;draw&amp;nbsp;calls&amp;nbsp;&amp;ndash;&amp;nbsp;a&amp;nbsp;match&amp;nbsp;made&amp;nbsp;in&amp;nbsp;heaven!&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/learn/gdc-2024-workgraphs-drawcalls/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/learn/gdc-2024-workgraphs-drawcalls/&lt;/a&gt; &amp;nbsp;&lt;br /&gt;&lt;br /&gt;Real-Time&amp;nbsp;Procedural&amp;nbsp;Generation&amp;nbsp;with&amp;nbsp;GPU&amp;nbsp;Work&amp;nbsp;Graphs&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/download/Real-Time_Procedural_Generation_with_GPU_Work_Graphs-GPUOpen_preprint.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/download/Real-Time_Procedural_Generation_with_GPU_Work_Graphs-GPUOpen_preprint.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;635&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMCX6n/btsQlYw2Wf9/pi5w8Rc8hIxG3e3LG9jG2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMCX6n/btsQlYw2Wf9/pi5w8Rc8hIxG3e3LG9jG2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMCX6n/btsQlYw2Wf9/pi5w8Rc8hIxG3e3LG9jG2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMCX6n%2FbtsQlYw2Wf9%2Fpi5w8Rc8hIxG3e3LG9jG2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1126&quot; height=&quot;635&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;635&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;저희 연구는 2024년 3분기에 출시된 메시 노드를 활용합니다. 또한 works graph와 mesh node에 대한 내용을 담은 여러 블로그 게시물을 작성했습니다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_1&quot; id=&quot;footnote_link_1516_1&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 1)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 1)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;1&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;웍스 그래프의 장점을 강조하는 데모 영상은 여기에서 확인하실 수 있습니다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://gpuopen.com/learn/gdc-2024-workgraphs-drawcalls/&quot;&gt;https://gpuopen.com/learn/gdc-2024-workgraphs-drawcalls/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sk7rH/btsQjENn9ip/GZsoyf5VkgL4C1oKVlS5uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sk7rH/btsQjENn9ip/GZsoyf5VkgL4C1oKVlS5uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sk7rH/btsQjENn9ip/GZsoyf5VkgL4C1oKVlS5uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsk7rH%2FbtsQjENn9ip%2FGZsoyf5VkgL4C1oKVlS5uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1017&quot; height=&quot;564&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GDC 데모와 HPG 논문이 많은 관심을 불러일으켜 2024년 네덜란드 브레다에서 열리는 그래픽 프로그래밍 컨퍼런스 마스터 클래스에 초청받았습니다. 바로 이 자리에서 Work Graph Playground 앱을 처음 출시했습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이 수업에서도 이 앱을 사용할 예정입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;노트북을 가져오셨다면 Work Graph Playground 앱을 직접 사용해 보실 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uE3cp/btsQmd1LQjr/zTtXA3iSNj5ebXkCIzSizk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uE3cp/btsQmd1LQjr/zTtXA3iSNj5ebXkCIzSizk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uE3cp/btsQmd1LQjr/zTtXA3iSNj5ebXkCIzSizk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuE3cp%2FbtsQmd1LQjr%2FzTtXA3iSNj5ebXkCIzSizk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1012&quot; height=&quot;561&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;561&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;앱을 바이너리로 설치하려면 다음 단계를 따르세요.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;지금 바로 설치하시기 바랍니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;약 30분 후에 앱을 사용해 보세요.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GPU가 Work Graphs를 지원하지 않는 경우, WARP(소프트웨어 에뮬레이션) 어댑터를 사용하세요. &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;DownloadWarpAdapter.bat 배치 스크립트를 사용하여 해당 DLL을 다운로드하세요.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GitHub 저장소의 지침에 따라 소스 코드에서 빌드할 수도 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://github.com/GPUOpen-LibrariesAndSDKs/WorkGraphPlayground&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/GPUOpen-LibrariesAndSDKs/WorkGraphPlayground&lt;/a&gt; &amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://github.com/GPUOpen-LibrariesAndSDKs/WorkGraphPlayground/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/GPUOpen-LibrariesAndSDKs/WorkGraphPlayground/releases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;563&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/br3Tux/btsQlYqj7TH/NtPhnxkTYyDPfRSsD307k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/br3Tux/btsQlYqj7TH/NtPhnxkTYyDPfRSsD307k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/br3Tux/btsQlYqj7TH/NtPhnxkTYyDPfRSsD307k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbr3Tux%2FbtsQlYqj7TH%2FNtPhnxkTYyDPfRSsD307k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1018&quot; height=&quot;563&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;563&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;앱 외에도 GDC 2025를 위해 Work Graphs를 사용하여 GPU에서 직접 식물을 생성하는 데모도 만들었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBjexe/btsQjiX7VCQ/BSEpn0yGsc12ZrOKBx80Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBjexe/btsQjiX7VCQ/BSEpn0yGsc12ZrOKBx80Mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBjexe/btsQjiX7VCQ/BSEpn0yGsc12ZrOKBx80Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBjexe%2FbtsQjiX7VCQ%2FBSEpn0yGsc12ZrOKBx80Mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1006&quot; height=&quot;560&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;저희 데모에는 몇 주 전 HPG 2025에서 공유할 수 있었던 연구 결과가 가득합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;HPG에서 Bastian의 강연 영상은 여기에서 시청하실 수 있습니다: &lt;a href=&quot;https://www.youtube.com/watch?v=SPWDLMc-9h4&amp;amp;t=26050s&quot;&gt;https://www.youtube.com/watch?v=SPWDLMc-9h4&amp;amp;t=26050s&lt;/a&gt; &lt;br /&gt;전체 논문은 여기에서 확인하실 수 있습니다: &lt;a href=&quot;https://diglib.eg.org/bitstream/handle/10.2312/hpg20251168/hpg20251168.pdf&quot;&gt;https://diglib.eg.org/bitstream/handle/10.2312/hpg20251168/hpg20251168.pdf&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdosUz/btsQlZW2akX/15KJVmW5dY0f0YGLko1zN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdosUz/btsQlZW2akX/15KJVmW5dY0f0YGLko1zN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdosUz/btsQlZW2akX/15KJVmW5dY0f0YGLko1zN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdosUz%2FbtsQlZW2akX%2F15KJVmW5dY0f0YGLko1zN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1015&quot; height=&quot;559&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;6월에는 미리보기 단계를 포함하여 Work Graphs 출시 2주년을 기념했습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;Work Graphs가 공식 발표된 지 1년 반도 채 되지 않았습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; 따라서 상당히 새로운 기술입니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;이 과정의 목표는 여러분께 Work Graphs의 사용법을 알려드리고, 이를 여러분의 애플리케이션에 직접 활용할 수 있도록 돕는 것입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RJsQ6/btsQjTX3iMi/qQ3gJUSLw8w6lIXpV7I7s1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RJsQ6/btsQjTX3iMi/qQ3gJUSLw8w6lIXpV7I7s1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RJsQ6/btsQjTX3iMi/qQ3gJUSLw8w6lIXpV7I7s1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRJsQ6%2FbtsQjTX3iMi%2FqQ3gJUSLw8w6lIXpV7I7s1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1019&quot; height=&quot;561&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;561&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;오늘 다룰 주제에 대한 간략한 개요는 다음과 같습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;563&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6iJmc/btsQk4LlkyM/IiRTjuzBLpwJvrY5E3Ncx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6iJmc/btsQk4LlkyM/IiRTjuzBLpwJvrY5E3Ncx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6iJmc/btsQk4LlkyM/IiRTjuzBLpwJvrY5E3Ncx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6iJmc%2FbtsQk4LlkyM%2FIiRTjuzBLpwJvrY5E3Ncx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1005&quot; height=&quot;563&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;563&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Work Graphs의 강력한 기능을 보여주는 몇 가지 애플리케이션을 살펴보았습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;자세한 내용을 살펴보기 전에 먼저 핵심 질문부터 답해 보겠습니다. &lt;br /&gt;&lt;br /&gt;왜 Work Graphs를 사용해야 할까요?&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;이 질문에는 다른 접근 방식과 Work Graphs를 왜 선호해야 하는지에 대한 질문이 뒤따릅니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;하지만 그 전에 Work Graphs에 중요한 GPU 개념을 간략하게 살펴보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;565&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dk9Ygt/btsQjc4H2Wm/u7w1z6x8WcKrW9nXcxDYG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dk9Ygt/btsQjc4H2Wm/u7w1z6x8WcKrW9nXcxDYG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dk9Ygt/btsQjc4H2Wm/u7w1z6x8WcKrW9nXcxDYG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdk9Ygt%2FbtsQjc4H2Wm%2Fu7w1z6x8WcKrW9nXcxDYG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1005&quot; height=&quot;565&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;우리는 이러한 개념이 Work Graphs에 중요하다고 믿습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVrf2y/btsQjenWYGQ/iCKycLrR0c4uTU6osJey41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVrf2y/btsQjenWYGQ/iCKycLrR0c4uTU6osJey41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVrf2y/btsQjenWYGQ/iCKycLrR0c4uTU6osJey41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVrf2y%2FbtsQjenWYGQ%2FiCKycLrR0c4uTU6osJey41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1017&quot; height=&quot;557&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GPU 발전의 간략한 역사를 통해 이러한 개념을 가장 잘 설명할 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;더 큰 유연성에 대한 요구는 지난 수십 년 동안 GPU 프로그래밍 기능의 발전을 주도해 왔습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;초기 레지스터 결합기는 초보적인 프래그먼트 처리[Kilgard 1999]를 가능하게 했고, 이후 정점 처리는 프로그래밍이 가능해졌습니다[Lindholm et al.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;2001].&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;2002년 DirectX 9.0 Shader Model 2.0은 최초의 프로그래밍 가능 하드웨어 정점 및 픽셀 셰이더 파이프라인으로 간주됩니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;2년 후, Shader Model 3.0은 동적 제어 흐름을 추가했습니다[Akenine-M&amp;ouml;ller 2018].&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;지오메트리 셰이더[Blythe 2006]는 프로그래밍 가능한 프리미티브별 처리를 선보였습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;하드웨어 테셀레이션[Andrews and Barker 2006]은 빠른 온-칩(on-chip) 지오메트리 증폭[Niessner et al.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;2016]을 가능하게 했습니다.&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;컴퓨트 셰이더[Peercy et al., Nvidia 2007]의 도입은 하드웨어 지향 프로그래밍 모델, 즉 GPGPU의 시작을 드러냈습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;GPU Gems 3 책[Nguyen 2007]에서 볼 수 있듯이, 이를 통해 GPU는 고성능 그래픽 및 비그래픽 애플리케이션을 실행할 수 있게 되었습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;또한, 하드웨어에서의 최신 GPU 레이 트레이싱[Haines and Akenine-M&amp;ouml;ller 2019]은 컴퓨트 셰이더 기반 레이 트레이싱 구현[Parker et al.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;2010]에서 유래했습니다.&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;indirect execution &lt;span&gt;&lt;span&gt;또는 execute indirect &lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_2&quot; id=&quot;footnote_link_1516_2&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 2)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 2)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;2&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;를 통해 드로우 콜과 디스패치의 크기를 GPU 메모리에서 가져와 GPU 기반 작업 생성을 가능하게 합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;증폭(Amplification)&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_3&quot; id=&quot;footnote_link_1516_3&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 3)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 3)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;3&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt; 및 메시 셰이더[Kubisch 2018]는 컴퓨트 셰이더의 프로그래밍 모델을 따라 래스터화 워크로드를 위한 단일 레벨의 비재귀적 증폭 파이프라인을 제공합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;Works Graph[Microsoft 2024]는 컴퓨팅 및 래스터화 워크로드의 다단계 자체 재귀적 증폭을 제공하여 GPU 프로그래밍 가능성을 높입니다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_4&quot; id=&quot;footnote_link_1516_4&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 4)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 4)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;4&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZFk12/btsQkhdlU8Q/WL1eqEUX8TKX65TxvKVCG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZFk12/btsQkhdlU8Q/WL1eqEUX8TKX65TxvKVCG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZFk12/btsQkhdlU8Q/WL1eqEUX8TKX65TxvKVCG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZFk12%2FbtsQkhdlU8Q%2FWL1eqEUX8TKX65TxvKVCG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1010&quot; height=&quot;557&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;우리는 이러한 이정표가 GPU 파이프라인의 기본 개념을 설명하기에 충분하다고 생각합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1011&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIpIXl/btsQjbY6JAd/R82HCj4T2gi7Rfl8VyntG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIpIXl/btsQjbY6JAd/R82HCj4T2gi7Rfl8VyntG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIpIXl/btsQjbY6JAd/R82HCj4T2gi7Rfl8VyntG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIpIXl%2FbtsQjbY6JAd%2FR82HCj4T2gi7Rfl8VyntG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1011&quot; height=&quot;562&quot; data-origin-width=&quot;1011&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;hellip;그리고 프로그래밍 가능한 정점 및 픽셀 셰이딩을 도입한 Shader Model 2부터 시작합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vkpuq/btsQl2lXLwy/u4WEhjaynEqv0Ws8QJBGSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vkpuq/btsQl2lXLwy/u4WEhjaynEqv0Ws8QJBGSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vkpuq/btsQl2lXLwy/u4WEhjaynEqv0Ws8QJBGSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVkpuq%2FbtsQl2lXLwy%2Fu4WEhjaynEqv0Ws8QJBGSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1310&quot; height=&quot;728&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;파이프라인을 간략하게 표현한 버전입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;파란색과 노란색 상자는 파이프라인의 각 단계를 나타냅니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eH2yiY/btsQkarLWBk/S4o6kLqseLNtMrvzvIkRP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eH2yiY/btsQkarLWBk/S4o6kLqseLNtMrvzvIkRP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eH2yiY/btsQkarLWBk/S4o6kLqseLNtMrvzvIkRP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeH2yiY%2FbtsQkarLWBk%2FS4o6kLqseLNtMrvzvIkRP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1306&quot; height=&quot;733&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;원으로 표시된 꼭짓점을 가진 삼각형 메시가 주어졌습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;검은색 모서리는 꼭짓점을 연결하여 삼각형을 형성합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;꼭짓점 좌표는 열 벡터로 표시된 4D 좌표입니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;이들은 오른쪽에 보여지는 표시된 파이프라인에 입력됩니다&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;output으로 슬라이드 왼쪽 하단의 픽셀 그리드에 표시된 것처럼 픽셀 그래픽을 얻습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1305&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMET5S/btsQk3r6MQ6/uYiXoCJUO0v9gmfguZaxyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMET5S/btsQk3r6MQ6/uYiXoCJUO0v9gmfguZaxyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMET5S/btsQk3r6MQ6/uYiXoCJUO0v9gmfguZaxyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMET5S%2FbtsQk3r6MQ6%2FuYiXoCJUO0v9gmfguZaxyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1305&quot; height=&quot;733&quot; data-origin-width=&quot;1305&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;정점(vertex) 좌표는 vertex buffer라 불리는 배열에 저장됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1305&quot; data-origin-height=&quot;735&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TImHs/btsQjCoDAeR/b8pM5Yee7vkAxojzRLmzV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TImHs/btsQjCoDAeR/b8pM5Yee7vkAxojzRLmzV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TImHs/btsQjCoDAeR/b8pM5Yee7vkAxojzRLmzV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTImHs%2FbtsQjCoDAeR%2Fb8pM5Yee7vkAxojzRLmzV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1305&quot; height=&quot;735&quot; data-origin-width=&quot;1305&quot; data-origin-height=&quot;735&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그리고 vertex index는 index buffer라고 불리는 곳에 저장됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5x1Ym/btsQma48AK0/iKEkdHlba7Pfrvdg5CRz2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5x1Ym/btsQma48AK0/iKEkdHlba7Pfrvdg5CRz2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5x1Ym/btsQma48AK0/iKEkdHlba7Pfrvdg5CRz2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5x1Ym%2FbtsQma48AK0%2FiKEkdHlba7Pfrvdg5CRz2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1307&quot; height=&quot;723&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;파이프라인에 정점 버퍼와 인덱스 버퍼를 입력하면 어떤 일이 일어나는지 다시 살펴보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;먼저, 인덱스 버퍼의 각 요소가 &lt;b&gt;&lt;i&gt;input assembler&lt;/i&gt;&lt;/b&gt;에 입력됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;729&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coF6v7/btsQmp8OJwP/UrUzlXNKd7DJkSaK8GY0Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coF6v7/btsQmp8OJwP/UrUzlXNKd7DJkSaK8GY0Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coF6v7/btsQmp8OJwP/UrUzlXNKd7DJkSaK8GY0Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoF6v7%2FbtsQmp8OJwP%2FUrUzlXNKd7DJkSaK8GY0Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1306&quot; height=&quot;729&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;729&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그런 다음 인풋 어셈블러는 정점 버퍼에서 요소(elements, 여기서는 vertex 내의 값들)를 수집하여 outputs에서 ​​사용할 수 있도록 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLwLkR/btsQmtwB2aO/e5vwQNxTp9i6eu32hMlQv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLwLkR/btsQmtwB2aO/e5vwQNxTp9i6eu32hMlQv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLwLkR/btsQmtwB2aO/e5vwQNxTp9i6eu32hMlQv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLwLkR%2FbtsQmtwB2aO%2Fe5vwQNxTp9i6eu32hMlQv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1302&quot; height=&quot;732&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;인풋 어셈블러는 각 요소를 독립적으로 처리할 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이를 통해 GPU는 높은 수준의 병렬성을 확보할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EfXEs/btsQk03hXSi/0GkKudpetipkBX8s9ut3n0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EfXEs/btsQk03hXSi/0GkKudpetipkBX8s9ut3n0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EfXEs/btsQk03hXSi/0GkKudpetipkBX8s9ut3n0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEfXEs%2FbtsQk03hXSi%2F0GkKudpetipkBX8s9ut3n0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1301&quot; height=&quot;724&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그런 다음 정점은 다음 단계인 정점 셰이더로 전달됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;727&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mn4Hr/btsQkI9DYOV/gKPpodiiQwQkTUbebw6NEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mn4Hr/btsQkI9DYOV/gKPpodiiQwQkTUbebw6NEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mn4Hr/btsQkI9DYOV/gKPpodiiQwQkTUbebw6NEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmn4Hr%2FbtsQkI9DYOV%2FgKPpodiiQwQkTUbebw6NEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1299&quot; height=&quot;727&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;727&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;정점 셰이더에서는 프로그래머가 왼쪽에 표시된 것처럼 셰이더 코드를 작성할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJiiIT/btsQjC9U79h/iC0w8FZN4HKeeZDxIVBDF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJiiIT/btsQjC9U79h/iC0w8FZN4HKeeZDxIVBDF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJiiIT/btsQjC9U79h/iC0w8FZN4HKeeZDxIVBDF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJiiIT%2FbtsQjC9U79h%2FiC0w8FZN4HKeeZDxIVBDF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1304&quot; height=&quot;726&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인풋&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;어셈블러의 출력을 설명하는 구조체를 정의합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;동시에 이 구조체는 정점 셰이더의 입력으로 사용됩니다.&lt;/span&gt;&lt;/span&gt; 인풋&lt;span&gt;&lt;span&gt;&amp;nbsp;어셈블러가 출력하는 각 정점에 대해 GPU는 하나의 정점 셰이더 스레드를 실행합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;첫 번째 정점을 예로 들어 보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QoyTw/btsQmu976fe/0dT7KBrC99UtjrKk7AYyU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QoyTw/btsQmu976fe/0dT7KBrC99UtjrKk7AYyU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QoyTw/btsQmu976fe/0dT7KBrC99UtjrKk7AYyU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQoyTw%2FbtsQmu976fe%2F0dT7KBrC99UtjrKk7AYyU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1300&quot; height=&quot;723&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;노란색 상자 안의 정점은 하나의 정점 셰이더 스레드에 대한 입력 역할을 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/maIeD/btsQja0a7vd/se9650hWqKipNNW75HNxN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/maIeD/btsQja0a7vd/se9650hWqKipNNW75HNxN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/maIeD/btsQja0a7vd/se9650hWqKipNNW75HNxN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmaIeD%2FbtsQja0a7vd%2Fse9650hWqKipNNW75HNxN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1300&quot; height=&quot;726&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;해당 입력을 통해 정점 셰이더 스레드는 프로그래머가 지정한 작업을 수행합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pBLfg/btsQkXeCt0e/MOyho6SeaXmjy0T9igLh5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pBLfg/btsQkXeCt0e/MOyho6SeaXmjy0T9igLh5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pBLfg/btsQkXeCt0e/MOyho6SeaXmjy0T9igLh5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpBLfg%2FbtsQkXeCt0e%2FMOyho6SeaXmjy0T9igLh5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1308&quot; height=&quot;728&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;hellip; 그리고 프로그래머가 파란색 상자에 표시된 구조체로 정의한 출력을 작성합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;729&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OlExn/btsQmfyAumA/iUmy9MA5fLrJ4kpyxLvYr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OlExn/btsQmfyAumA/iUmy9MA5fLrJ4kpyxLvYr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OlExn/btsQmfyAumA/iUmy9MA5fLrJ4kpyxLvYr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOlExn%2FbtsQmfyAumA%2FiUmy9MA5fLrJ4kpyxLvYr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1299&quot; height=&quot;729&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;729&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그러면 결과가 정점 셰이더 출력에서 ​​제공됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1293&quot; data-origin-height=&quot;729&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGA4ZG/btsQjdijU5U/p0qXlkXIWLoNZLE5HMdHck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGA4ZG/btsQjdijU5U/p0qXlkXIWLoNZLE5HMdHck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGA4ZG/btsQjdijU5U/p0qXlkXIWLoNZLE5HMdHck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGA4ZG%2FbtsQjdijU5U%2Fp0qXlkXIWLoNZLE5HMdHck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1293&quot; height=&quot;729&quot; data-origin-width=&quot;1293&quot; data-origin-height=&quot;729&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;다른 모든 정점도 같은 운명을 겪습니다. 즉, 서로 다른 입력을 사용하여 동일한 정점 셰이더 코드를 통과합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEgHx6/btsQjbktffJ/J9FClo1kskuhcW9m1LSJg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEgHx6/btsQjbktffJ/J9FClo1kskuhcW9m1LSJg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEgHx6/btsQjbktffJ/J9FClo1kskuhcW9m1LSJg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEgHx6%2FbtsQjbktffJ%2FJ9FClo1kskuhcW9m1LSJg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1300&quot; height=&quot;717&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이것은 매우 중요한 개념입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;동일한 코드가 서로 다른 데이터 항목에 대해 실행됩니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;즉, 하나의 명령어(&lt;b&gt;&lt;i&gt;Single Instruction)&lt;/i&gt;&lt;/b&gt;가 여러 데이터에 대해 동작합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;따라서 단일 명령어, 다중 데이터&amp;hellip;라는 이름이 붙었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IMqHc/btsQjenZJbS/Zh1oB2PJnISp9sdowHCRuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IMqHc/btsQjenZJbS/Zh1oB2PJnISp9sdowHCRuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IMqHc/btsQjenZJbS/Zh1oB2PJnISp9sdowHCRuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIMqHc%2FbtsQjenZJbS%2FZh1oB2PJnISp9sdowHCRuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1294&quot; height=&quot;725&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;hellip; 또는 줄여서 SIMD라고도 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; SIMD는 GPU의 기본 병렬 컴퓨팅 모델이며, GPU 성능에 매우 중요합니다.&lt;/span&gt;&lt;/span&gt;&amp;nbsp; 웍스&lt;span&gt;&lt;span&gt;&amp;nbsp;그래프는 GPU에서 실행되므로 SIMD 모델을 사용합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;참고 : GPU와 관련하여, 대규모 병렬 기반 컴퓨팅 모델은 SIMT(Single Instruction, Multiple Threads)라고도 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNlpv9/btsQkdIPPXz/t8tPz2TLEdc4KIiRQrGBl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNlpv9/btsQkdIPPXz/t8tPz2TLEdc4KIiRQrGBl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNlpv9/btsQkdIPPXz/t8tPz2TLEdc4KIiRQrGBl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNlpv9%2FbtsQkdIPPXz%2Ft8tPz2TLEdc4KIiRQrGBl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1302&quot; height=&quot;725&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;추상적인 관점에서 보면, SIM&lt;b&gt;D&lt;/b&gt;의 &lt;b&gt;D(데이터)&lt;/b&gt;와 같은 정점 속성은 작업 항목&lt;b&gt;(Work Items)&lt;/b&gt;입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHr41I/btsQjD15Fq8/5e5fIdqZ6UKLiVfSuQBsE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHr41I/btsQjD15Fq8/5e5fIdqZ6UKLiVfSuQBsE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHr41I/btsQjD15Fq8/5e5fIdqZ6UKLiVfSuQBsE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHr41I%2FbtsQjD15Fq8%2F5e5fIdqZ6UKLiVfSuQBsE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1303&quot; height=&quot;730&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;hellip; 파이프라인을 통해 진행됩니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;파이프라인에서 한 단계는 생산자 역할을 하고, 그 다음 단계는 소비자 역할을 합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;각 단계는 항목을 소비하고 동시에 생산할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;파이프라인을 통해 흐르는 항목을 &lt;b&gt;작업 항목(work items)&lt;/b&gt;이라고 합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;이러한 관점에서 볼 때, 그래픽스 파이프라인은 이미 Work Graphs에서도 사용되는 데이터 흐름 지향 모델(data-flow-oriented model)을 제공하고 있지만, 훨씬 더 정교한 방식으로 제공됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;729&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0sHRX/btsQjixaNDm/bnZDsROQDEgUWkySI3K7j1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0sHRX/btsQjixaNDm/bnZDsROQDEgUWkySI3K7j1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0sHRX/btsQjixaNDm/bnZDsROQDEgUWkySI3K7j1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0sHRX%2FbtsQjixaNDm%2FbnZDsROQDEgUWkySI3K7j1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1299&quot; height=&quot;729&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;729&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;하지만 이미 익숙한 버텍스-픽셀 셰이더 파이프라인으로 돌아가 보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;버텍스 셰이더는 방금 버텍스를 변환했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8p507/btsQk4xSfzf/rzUnIpdbVLH1c6ujp3MtE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8p507/btsQk4xSfzf/rzUnIpdbVLH1c6ujp3MtE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8p507/btsQk4xSfzf/rzUnIpdbVLH1c6ujp3MtE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8p507%2FbtsQk4xSfzf%2FrzUnIpdbVLH1c6ujp3MtE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1308&quot; height=&quot;730&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;래스터라이저는 세 개의 정점으로 구성된 튜플을 수집하고 삼각형을 프래그먼트로 이산화(discretizes)&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_5&quot; id=&quot;footnote_link_1516_5&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 5)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 5)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;5&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;이는 작업 증폭(work amplification)으로 볼 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;삼각형을 입력 데이터 항목으로 가정합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이 입력 데이터 항목을 훨씬 더 많은 출력 항목, 즉 프래그먼트로 증폭합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yoG1W/btsQjiqjYO5/Cp9PvzoAANMG7TQk77uGT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yoG1W/btsQjiqjYO5/Cp9PvzoAANMG7TQk77uGT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yoG1W/btsQjiqjYO5/Cp9PvzoAANMG7TQk77uGT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyoG1W%2FbtsQjiqjYO5%2FCp9PvzoAANMG7TQk77uGT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1303&quot; height=&quot;726&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;하지만 래스터라이저는 프래그먼트를 생성하지 않는 삼각형을 제거하는 등 작업을 완전히 줄일 수도 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;722&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rqn9m/btsQl0V0nz5/CUkUkLoHp87YR4FmRgGkO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rqn9m/btsQl0V0nz5/CUkUkLoHp87YR4FmRgGkO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rqn9m/btsQl0V0nz5/CUkUkLoHp87YR4FmRgGkO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRqn9m%2FbtsQl0V0nz5%2FCUkUkLoHp87YR4FmRgGkO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1302&quot; height=&quot;722&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;722&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;픽셀 셰이더는 다시 SIMD 모델을 사용하는 프로그램입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;각 프래그먼트는 입력 작업 항목(input work item)입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;727&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dh4yk8/btsQlADgxxe/NqRWTzmN2KLZMIeuWkKRD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dh4yk8/btsQlADgxxe/NqRWTzmN2KLZMIeuWkKRD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dh4yk8/btsQlADgxxe/NqRWTzmN2KLZMIeuWkKRD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdh4yk8%2FbtsQlADgxxe%2FNqRWTzmN2KLZMIeuWkKRD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1304&quot; height=&quot;727&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;727&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;hellip;그리고 GPU의 한 스레드에 의해 실행(executed)됩니다&amp;hellip;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1309&quot; data-origin-height=&quot;721&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxDcvj/btsQjzZIk7S/gStk29kQEepaTVyADTas61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxDcvj/btsQjzZIk7S/gStk29kQEepaTVyADTas61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxDcvj/btsQjzZIk7S/gStk29kQEepaTVyADTas61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxDcvj%2FbtsQjzZIk7S%2FgStk29kQEepaTVyADTas61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1309&quot; height=&quot;721&quot; data-origin-width=&quot;1309&quot; data-origin-height=&quot;721&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;hellip; 어느 색상이 출력될지 계산합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1309&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQ1MIa/btsQmDsrCbE/uW9p70Ulg9kQEI3LRuJQ21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQ1MIa/btsQmDsrCbE/uW9p70Ulg9kQEI3LRuJQ21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQ1MIa/btsQmDsrCbE/uW9p70Ulg9kQEI3LRuJQ21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQ1MIa%2FbtsQmDsrCbE%2FuW9p70Ulg9kQEI3LRuJQ21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1309&quot; height=&quot;728&quot; data-origin-width=&quot;1309&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;각 프래그먼트 셰이더 스레드는 출력 데이터 항목을 출력 병합기에 전달합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IvuNM/btsQmsqY7WS/guT4aDYHsdHWMwak6oDU40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IvuNM/btsQmsqY7WS/guT4aDYHsdHWMwak6oDU40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IvuNM/btsQmsqY7WS/guT4aDYHsdHWMwak6oDU40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIvuNM%2FbtsQmsqY7WS%2FguT4aDYHsdHWMwak6oDU40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1296&quot; height=&quot;725&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그런 다음 output 병합기는 프래그먼트를 기존에 있던것과 병합하여 최종 이미지를 형성합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcCXOE/btsQl0uXTCe/u8kXx7qJzm6DTpm3vVQ89k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcCXOE/btsQl0uXTCe/u8kXx7qJzm6DTpm3vVQ89k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcCXOE/btsQl0uXTCe/u8kXx7qJzm6DTpm3vVQ89k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcCXOE%2FbtsQl0uXTCe%2Fu8kXx7qJzm6DTpm3vVQ89k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1294&quot; height=&quot;733&quot; data-origin-width=&quot;1294&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이것으로 2002년의 버텍스 및 픽셀 셰이더 파이프라인에 대한 이야기를 마칩니다. &lt;br /&gt;&lt;br /&gt;Work Graph에 사용할 일부 개념은 당시에도 이미 존재했다는 것을 살펴보았습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z4Ehl/btsQl5XjqGZ/zpU2YppKlRkixtKD8AiAUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z4Ehl/btsQl5XjqGZ/zpU2YppKlRkixtKD8AiAUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z4Ehl/btsQl5XjqGZ/zpU2YppKlRkixtKD8AiAUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz4Ehl%2FbtsQl5XjqGZ%2FzpU2YppKlRkixtKD8AiAUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1301&quot; height=&quot;725&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;파이프라인에는 두 개의 프로그래밍 가능한 스테이지와 여러 개의 구성 가능한 고정 기능 스테이지가 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C0rBu/btsQkk2j8RX/0kOgFFyKJ62wYta6MV5PZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C0rBu/btsQkk2j8RX/0kOgFFyKJ62wYta6MV5PZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C0rBu/btsQkk2j8RX/0kOgFFyKJ62wYta6MV5PZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC0rBu%2FbtsQkk2j8RX%2F0kOgFFyKJ62wYta6MV5PZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1304&quot; height=&quot;724&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;버텍스 셰이더는 버텍스에 대해 SIMD를 사용하고, 프래그먼트 셰이더는 프래그먼트에 대해 SIMD를 사용합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;2006년, D3D10은 또 다른 프로그래밍 가능 단계인 지오메트리 셰이더를 도입했습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이 단계는 삼각형 및 기타 기본 요소에 대해 SIMD를 사용합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;하드웨어 설계자들은 모든 프로그래밍 가능 단계가 동일한 기본 SIMD 원리를 사용한다는 것을 발견했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqhKBM/btsQkRMfxKV/BckvdgedUobyVaOHUiYMDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqhKBM/btsQkRMfxKV/BckvdgedUobyVaOHUiYMDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqhKBM/btsQkRMfxKV/BckvdgedUobyVaOHUiYMDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqhKBM%2FbtsQkRMfxKV%2FBckvdgedUobyVaOHUiYMDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1306&quot; height=&quot;724&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;공통된 추상화를 제공하기 위해 통합 셰이더 모델을 만들었습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;각 스레드는 셰이더 코어에 매핑됩니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;여러 셰이더 코어는 하나의 작업 그룹 프로세서로 그룹화됩니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;예를 들어, AMD RDNA 3 아키텍처에서는 작업 그룹 프로세서당 128개의 셰이더 코어가 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;작업 그룹 프로세서의 셰이더 코어는 AMD RDNA 3 GPU에서 128KiB의 공유 메모리를 통해 통신할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;729&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLHz7u/btsQmqfCDcy/WmxtZdSpyWltzy8w1lo741/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLHz7u/btsQmqfCDcy/WmxtZdSpyWltzy8w1lo741/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLHz7u/btsQmqfCDcy/WmxtZdSpyWltzy8w1lo741/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLHz7u%2FbtsQmqfCDcy%2FWmxtZdSpyWltzy8w1lo741%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1300&quot; height=&quot;729&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;729&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이러한 여러 개의 작업 그룹 프로세서가 GPU에 탑재되어 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;AMD Radeon RX 7800 XT에는 30개의 작업 그룹 프로세서가 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;작업 그룹 프로세서는 공통 그래픽 메모리를 공유합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;현재 이 메모리는 수 GB에 달합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;727&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMGz0S/btsQlY4ZSGw/44CLiafPTMBZkz1rdee1h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMGz0S/btsQlY4ZSGw/44CLiafPTMBZkz1rdee1h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMGz0S/btsQlY4ZSGw/44CLiafPTMBZkz1rdee1h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMGz0S%2FbtsQlY4ZSGw%2F44CLiafPTMBZkz1rdee1h1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1302&quot; height=&quot;727&quot; data-origin-width=&quot;1302&quot; data-origin-height=&quot;727&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GPU의 추상 모델이 이렇게 완성되었으니, 새로운 셰이더 유형을 정의하는 것은 당연한 일이었습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이를 통해 컴퓨트 셰이더&lt;i&gt;&lt;b&gt;(Compute Shader)&lt;/b&gt;&lt;/i&gt;가 탄생했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djnN1i/btsQkcwq8Ws/ZaeF9zrLHN7wRLVL53cIkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djnN1i/btsQkcwq8Ws/ZaeF9zrLHN7wRLVL53cIkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djnN1i/btsQkcwq8Ws/ZaeF9zrLHN7wRLVL53cIkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjnN1i%2FbtsQkcwq8Ws%2FZaeF9zrLHN7wRLVL53cIkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1301&quot; height=&quot;724&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;컴퓨트 셰이더는 GPU 추상화&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_6&quot; id=&quot;footnote_link_1516_6&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 6)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 6)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;6&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;를 필요로 합니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;공통 그룹 공유 메모리에 접근하는 스레드를 포함하는 셰이더입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;스레드는 셰이더 코어에 매핑되고, 그룹 공유 메모리는 공유 메모리에 매핑됩니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;스레드들은 스레드 그룹으로 클러스터링됩니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;GPU 하드웨어에서 스레드 그룹은 작업 그룹 프로세서에서 실행됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1543&quot; data-origin-height=&quot;862&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwjqpW/dJMcaaZDwWP/rGuIaIK1LUFw1IsPaCHffk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwjqpW/dJMcaaZDwWP/rGuIaIK1LUFw1IsPaCHffk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwjqpW/dJMcaaZDwWP/rGuIaIK1LUFw1IsPaCHffk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwjqpW%2FdJMcaaZDwWP%2FrGuIaIK1LUFw1IsPaCHffk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1543&quot; height=&quot;862&quot; data-origin-width=&quot;1543&quot; data-origin-height=&quot;862&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨트 셰이더 프로그램에서 SV_GroupThreadID 시맨틱은 스레드 그룹 내 최대 1024개 스레드의 그리드에서 3차원 인덱스를 제공합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1561&quot; data-origin-height=&quot;865&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wK3km/dJMb990Mbjv/gKHKFZZo4ZKWH6ni6MG8AK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wK3km/dJMb990Mbjv/gKHKFZZo4ZKWH6ni6MG8AK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wK3km/dJMb990Mbjv/gKHKFZZo4ZKWH6ni6MG8AK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwK3km%2FdJMb990Mbjv%2FgKHKFZZo4ZKWH6ni6MG8AK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1561&quot; height=&quot;865&quot; data-origin-width=&quot;1561&quot; data-origin-height=&quot;865&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;// 최대 1024개 스레드의 1D, 2D, 3D 그리드
uint3 gtid : SV_GroupThreadID;

// 각 차원마다 최대 65536개 스레드 그룹의
// 1D, 2D, 3D 그리드
uint3 gid : SV_GroupID;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드 그룹의 위치를 찾기 위해 SV_GroupID 시맨틱은 프로그래머에게 스레드 그룹 그리드 내의 3차원 인덱스를 제공합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1553&quot; data-origin-height=&quot;858&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvpqk8/dJMcacXsa0J/TU6P0NijxuqFKymbpKZdRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvpqk8/dJMcacXsa0J/TU6P0NijxuqFKymbpKZdRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvpqk8/dJMcacXsa0J/TU6P0NijxuqFKymbpKZdRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvpqk8%2FdJMcacXsa0J%2FTU6P0NijxuqFKymbpKZdRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1553&quot; height=&quot;858&quot; data-origin-width=&quot;1553&quot; data-origin-height=&quot;858&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;struct Data {
    float3 u;
    float2 v;
};

StructuredBuffer&amp;lt;Data&amp;gt; A : register(t0);
StructuredBuffer&amp;lt;Data&amp;gt; B : register(t1);
RWStructuredBuffer&amp;lt;Data&amp;gt; C : register(u0);

[numthreads(128, 1, 1)]
void main(uint3 gtid : SV_GroupThreadID,
          uint3 gid  : SV_GroupID) {

    const uint t = gtid.x + gid.x * 128;

    C[t].u = A[t].u + B[t].u;
    C[t].v = A[t].v * B[t].v;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-WEB:a36ca8e6-7b8c-43a4-b087-95305bf4d8f1-3&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-turn-start-message=&quot;true&quot; data-message-model-slug=&quot;gpt-5-5&quot; data-message-id=&quot;6f2b1f2e-808c-43ee-b2f2-3dfa82844880&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;594&quot; data-start=&quot;548&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨트 셰이더는 SIMD 모델을 따르는 셰이더 프로그램을 사용하여 프로그래밍됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-end=&quot;104&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;스레드 그룹 크기(이 예제에서는 128개 스레드)를 알고 있을 때, SV_GroupThreadID 와 SV_GroupID 를 사용하여 각 스레드를 고유하게 식별할 수 있습니다.&lt;br /&gt;&lt;br /&gt;이러한 고유 ID를 사용해 메모리(이 예제에서는 StructuredBuffer)를 인덱싱하여 계산을 수행합니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1542&quot; data-origin-height=&quot;851&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0Nmhw/dJMcaf7G2c2/XB1fqtPfbKwfqY5NgXK5ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0Nmhw/dJMcaf7G2c2/XB1fqtPfbKwfqY5NgXK5ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0Nmhw/dJMcaf7G2c2/XB1fqtPfbKwfqY5NgXK5ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0Nmhw%2FdJMcaf7G2c2%2FXB1fqtPfbKwfqY5NgXK5ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1542&quot; height=&quot;851&quot; data-origin-width=&quot;1542&quot; data-origin-height=&quot;851&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-end=&quot;170&quot; data-start=&quot;145&quot; data-section-id=&quot;1y24hzl&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;170&quot; data-start=&quot;145&quot; data-section-id=&quot;1y24hzl&quot; data-ke-size=&quot;size16&quot;&gt;Work Graphs를 위한 GPU 개념&lt;/p&gt;
&lt;p data-end=&quot;306&quot; data-start=&quot;172&quot; data-ke-size=&quot;size16&quot;&gt;✅ SIMD&lt;br /&gt;✅ 작업 항목(Work Item)&lt;br /&gt;✅ 작업 증폭(Work Amplification), 작업 축소(Work Reduction)&lt;br /&gt;✅ 컴퓨트 셰이더(Compute Shaders)&lt;br /&gt;❓ 메시 셰이더(Mesh Shaders)&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;362&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;따라서 우리는 네 번째 개념인 &amp;ldquo;컴퓨트 셰이더(Compute Shaders)&amp;rdquo;를 얻게 되었습니다&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;854&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KQOLU/dJMcagMmJ26/oANRQefE9Qstzlg2q5UfKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KQOLU/dJMcagMmJ26/oANRQefE9Qstzlg2q5UfKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KQOLU/dJMcagMmJ26/oANRQefE9Qstzlg2q5UfKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKQOLU%2FdJMcagMmJ26%2FoANRQefE9Qstzlg2q5UfKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1552&quot; height=&quot;854&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;854&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-WEB:a36ca8e6-7b8c-43a4-b087-95305bf4d8f1-6&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-turn-start-message=&quot;true&quot; data-message-model-slug=&quot;gpt-5-5&quot; data-message-id=&quot;a0dcb3ce-7883-4d0f-a8ce-a08e99ea70af&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;305&quot; data-start=&quot;267&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 컴퓨트 셰이더는 그래픽스 파이프라인과 어떻게 상호작용할까요?&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;862&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biiC8W/dJMcajoFhlk/8YduK92xsbHWR3ZwHXG4j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biiC8W/dJMcajoFhlk/8YduK92xsbHWR3ZwHXG4j0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biiC8W/dJMcajoFhlk/8YduK92xsbHWR3ZwHXG4j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiiC8W%2FdJMcajoFhlk%2F8YduK92xsbHWR3ZwHXG4j0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1548&quot; height=&quot;862&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;862&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-end=&quot;513&quot; data-start=&quot;428&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;// Compute Shader로 지오메트리 처리&lt;/span&gt;&lt;br /&gt;&lt;span&gt;commandList&lt;/span&gt;&lt;span&gt;-&amp;gt;SetPipelineState(...);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;commandList&lt;/span&gt;&lt;span&gt;-&amp;gt;Dispatch(...);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;commandList&lt;/span&gt;&lt;span&gt;-&amp;gt;Barrier(...);&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;513&quot; data-start=&quot;428&quot; data-ke-size=&quot;size16&quot;&gt;이 예제에서 컴퓨트 셰이더는 CPU로부터 디스패치됩니다. GPU에서는 컴퓨트 셰이더의 스레드들이 그래픽스 메모리로부터 전달된 인스턴스 목록을 처리합니다.&lt;br /&gt;&lt;br /&gt;예를 들어, 컴퓨트 셰이더의 작업이 뷰 프러스텀(view frustum) 밖의 인스턴스를 컬링하는 것이라고 가정합니다. 컴퓨트 셰이더는 화면에 보이는 인스턴스만 다시 그래픽스 메모리에 기록합니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1557&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpNkRW/dJMcaciOuAi/WfoKc82g54EJ7XxPsnjTyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpNkRW/dJMcaciOuAi/WfoKc82g54EJ7XxPsnjTyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpNkRW/dJMcaciOuAi/WfoKc82g54EJ7XxPsnjTyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpNkRW%2FdJMcaciOuAi%2FWfoKc82g54EJ7XxPsnjTyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1557&quot; height=&quot;856&quot; data-origin-width=&quot;1557&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-end=&quot;513&quot; data-start=&quot;428&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;// Graphics Pipeline로 지오메트리 처리&lt;/span&gt;&lt;br /&gt;&lt;span&gt;commandList&lt;/span&gt;&lt;span&gt;-&amp;gt;SetPipelineState(...);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;commandList&lt;/span&gt;&lt;span&gt;-&amp;gt;DrawIndexedInstanced(...);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;commandList&lt;/span&gt;&lt;span&gt;-&amp;gt;Barrier(...);&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-WEB:a36ca8e6-7b8c-43a4-b087-95305bf4d8f1-9&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-turn-start-message=&quot;true&quot; data-message-model-slug=&quot;gpt-5-5&quot; data-message-id=&quot;71731679-ac15-48dc-96c5-65b672dfe181&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;666&quot; data-start=&quot;563&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 그래픽스 파이프라인은 화면에 보이는 인스턴스만 렌더링합니다. 그래픽스 메모리에서 해당 데이터를 읽어 2D 이미지를 생성하며, 생성된 이미지는 다시 그래픽스 메모리에 기록됩니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;862&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4cnRo/dJMcaja7gwt/rJYHjikAmm8vAJmqsEMiXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4cnRo/dJMcaja7gwt/rJYHjikAmm8vAJmqsEMiXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4cnRo/dJMcaja7gwt/rJYHjikAmm8vAJmqsEMiXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4cnRo%2FdJMcaja7gwt%2FrJYHjikAmm8vAJmqsEMiXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1548&quot; height=&quot;862&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;862&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;666&quot; data-start=&quot;563&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;// 컴퓨트 셰이더로 Post Process 처리&lt;br /&gt;commandList-&amp;gt;SetPipelineState(...);&lt;br /&gt;commandList-&amp;gt;Dispatch(...);&lt;br /&gt;commandList-&amp;gt;Barrier(...)&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;666&quot; data-start=&quot;563&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그런 다음, 다른 컴퓨트 셰이더를 실행합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;예를 들어, 이 셰이더는 이미지에 대한 포스트 프로세싱을 수행할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; 따라서 모든 픽셀을 읽고, 변환한 다음, 그래픽 메모리에 다시 기록합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1553&quot; data-origin-height=&quot;868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHrdGX/dJMcadWldaP/JMXdF2av0hmpXOJvHCdT0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHrdGX/dJMcadWldaP/JMXdF2av0hmpXOJvHCdT0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHrdGX/dJMcadWldaP/JMXdF2av0hmpXOJvHCdT0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHrdGX%2FdJMcadWldaP%2FJMXdF2av0hmpXOJvHCdT0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1553&quot; height=&quot;868&quot; data-origin-width=&quot;1553&quot; data-origin-height=&quot;868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div&gt;
&lt;p data-end=&quot;490&quot; data-start=&quot;468&quot; data-section-id=&quot;zoznqt&quot; data-ke-size=&quot;size16&quot;&gt;Compute Shader의 문제점&lt;/p&gt;
&lt;p data-end=&quot;507&quot; data-start=&quot;492&quot; data-ke-size=&quot;size16&quot;&gt;❌ 배리어(Barriers)&lt;/p&gt;
&lt;p data-end=&quot;613&quot; data-start=&quot;509&quot; data-ke-size=&quot;size16&quot;&gt;하지만 두 가지 문제가 있습니다. 첫 번째 문제는 배리어(barrier)입니다.&lt;br /&gt;배리어는 파이프라인 간의 읽기/쓰기 충돌(read/write hazard)을 방지하기 위해 필요합니다.&lt;/p&gt;
&lt;p data-end=&quot;686&quot; data-start=&quot;615&quot; data-ke-size=&quot;size16&quot;&gt;하나의 파이프라인은 다른 파이프라인이 시작되기 전에 전체 연산을 모두 끝마쳐야 합니다. 이러한 동작은 배리어에 의해 보장됩니다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;768&quot; data-start=&quot;688&quot; data-ke-size=&quot;size16&quot;&gt;이로 인해 많은 워크그룹 프로세서가 유휴 상태(idle)로 남을 수 있으며, 특히 파이프라인 연산이 거의 끝나갈 때 이러한 현상이 두드러집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1559&quot; data-origin-height=&quot;864&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nKoKE/dJMcajoFhOf/z5K4xlsEfxFkF1kfohrrek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nKoKE/dJMcajoFhOf/z5K4xlsEfxFkF1kfohrrek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nKoKE/dJMcajoFhOf/z5K4xlsEfxFkF1kfohrrek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnKoKE%2FdJMcajoFhOf%2Fz5K4xlsEfxFkF1kfohrrek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1559&quot; height=&quot;864&quot; data-origin-width=&quot;1559&quot; data-origin-height=&quot;864&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;두 번째 문제는 파이프라인 간 통신이 그래픽 메모리를 통해 이루어지는데, 이것이 성능 저하의 원인이 될 수 있다는 점입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1545&quot; data-origin-height=&quot;867&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbWvM5/dJMcahYLa2C/oUCTGuqFjsYuOd8hqALYC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbWvM5/dJMcahYLa2C/oUCTGuqFjsYuOd8hqALYC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbWvM5/dJMcahYLa2C/oUCTGuqFjsYuOd8hqALYC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbWvM5%2FdJMcahYLa2C%2FoUCTGuqFjsYuOd8hqALYC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1545&quot; height=&quot;867&quot; data-origin-width=&quot;1545&quot; data-origin-height=&quot;867&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU &amp;lt;&amp;gt; CPU Memory 약 64GiB/s&lt;br /&gt;GPU &amp;lt;&amp;gt; Graphics Memory 약 1TiB/s(GPU Memory Bandwidth)&lt;br /&gt;CPU Memory &amp;lt;&amp;gt; Graphics Memory 약 59GiB/s(PCIe 5.0x16 - 상호연결 대역폭).&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_7&quot; id=&quot;footnote_link_1516_7&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 7)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 7)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;7&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기 몇 가지 수치를 보겠습니다. 시스템 내의 다른 메모리 버스와 비교하면, GPU의 워크그룹 프로세서와 그래픽스 메모리 사이의 1 TiB/s 대역폭은 매우 커 보입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;776&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z46Rw/dJMcadosoiG/EM8UjsEBnSZdw3kNPUoXxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z46Rw/dJMcadosoiG/EM8UjsEBnSZdw3kNPUoXxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z46Rw/dJMcadosoiG/EM8UjsEBnSZdw3kNPUoXxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ46Rw%2FdJMcadosoiG%2FEM8UjsEBnSZdw3kNPUoXxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1382&quot; height=&quot;776&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;776&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;347&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이 그래프에서 볼 수 있듯이, 지난 수년 동안 GPU 연산 성능(GPU Compute Performance)의 증가 속도는 GPU 메모리 대역폭(GPU Memory Bandwidth)의 증가 속도를 앞질렀습니다.&lt;/p&gt;
&lt;p data-end=&quot;585&quot; data-start=&quot;471&quot; data-ke-size=&quot;size16&quot;&gt;출처:&lt;br /&gt;이미지는 다음 자료를 기반으로 수정됨:&lt;br /&gt;&lt;a href=&quot;https://github.com/amirgholami/ai_and_memory_wall/blob/main/imgs/pngs/hw_scaling.png&quot;&gt;https://github.com/amirgholami/ai_and_memory_wall/blob/main/imgs/pngs/hw_scaling.png&lt;/a&gt;&lt;/p&gt;
&lt;p data-end=&quot;742&quot; data-start=&quot;587&quot; data-ke-size=&quot;size16&quot;&gt;논문 출처:&lt;br /&gt;Gholami A, Yao Z, Kim S, Mahoney MW, Keutzer K.&lt;br /&gt;AI and Memory Wall.&lt;br /&gt;RiseLab Medium Blog Post, University of California Berkeley, 2021년 3월 29일.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daZc9u/dJMcagle4xy/i3db45coBbHH5ZaSTzaaiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daZc9u/dJMcagle4xy/i3db45coBbHH5ZaSTzaaiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daZc9u/dJMcagle4xy/i3db45coBbHH5ZaSTzaaiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaZc9u%2FdJMcagle4xy%2Fi3db45coBbHH5ZaSTzaaiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1384&quot; height=&quot;768&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-WEB:a36ca8e6-7b8c-43a4-b087-95305bf4d8f1-14&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-turn-start-message=&quot;true&quot; data-message-model-slug=&quot;gpt-5-5&quot; data-message-id=&quot;c2309f40-b037-4293-a675-3fbe2002bc37&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;332&quot; data-start=&quot;296&quot; data-ke-size=&quot;size16&quot;&gt;따라서 그래픽스 메모리에 대해 1 TiB/s의 대역폭이 있더라도&amp;hellip;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;765&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JnIOj/dJMcaa6rqkj/CFffDAwgq21ozTwL8VGVj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JnIOj/dJMcaa6rqkj/CFffDAwgq21ozTwL8VGVj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JnIOj/dJMcaa6rqkj/CFffDAwgq21ozTwL8VGVj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJnIOj%2FdJMcaa6rqkj%2FCFffDAwgq21ozTwL8VGVj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1382&quot; height=&quot;765&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;765&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;코어 내부에는 훨씬 빠른 공유 메모리가 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;실제로 그래픽 메모리에 비해 지연 시간이 매우 짧습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;하지만 메모리 용량은 훨씬 작습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;763&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJIqXg/dJMcageu8hE/OQKdHdD4FICVm2K7HzzGdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJIqXg/dJMcageu8hE/OQKdHdD4FICVm2K7HzzGdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJIqXg/dJMcageu8hE/OQKdHdD4FICVm2K7HzzGdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJIqXg%2FdJMcageu8hE%2FOQKdHdD4FICVm2K7HzzGdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1380&quot; height=&quot;763&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;763&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 2009년 당시에도 입출력(I/O)은 이미 문제였습니다. I/O를 줄이기 위해 2009년에 하드웨어 테셀레이션(hardware tessellation)이 도입되었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DFmxj/dJMcaarPKyd/83s8k1XXYewnUFBKMrKDAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DFmxj/dJMcaarPKyd/83s8k1XXYewnUFBKMrKDAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DFmxj/dJMcaarPKyd/83s8k1XXYewnUFBKMrKDAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDFmxj%2FdJMcaarPKyd%2F83s8k1XXYewnUFBKMrKDAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1380&quot; height=&quot;768&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이것은 헐 셰이더와 도메인 셰이더라는 두 개의 추가된 프로그래밍 가능한 스테이지와 고정 기능 하드웨어 테셀레이터를 포함하고 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwHmVg/dJMcafNs9Fg/fR7MCERtM1K5HGnKOUhgJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwHmVg/dJMcafNs9Fg/fR7MCERtM1K5HGnKOUhgJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwHmVg/dJMcafNs9Fg/fR7MCERtM1K5HGnKOUhgJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwHmVg%2FdJMcafNs9Fg%2FfR7MCERtM1K5HGnKOUhgJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1373&quot; height=&quot;771&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;771&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;하드웨어 테셀레이션은 몇 개의 제어점으로 이루어진 지오메트리 구조를 더 많은 삼각형으로 확장할 수 있게 해줍니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;하지만 다소 경직된 테셀레이션 패턴은 원하는 만큼의 토폴로지의 자유도를 제공하지 못합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1383&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C1RBo/dJMcahqX1nD/giKtmESDRTO03vQBrWMsTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C1RBo/dJMcahqX1nD/giKtmESDRTO03vQBrWMsTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C1RBo/dJMcahqX1nD/giKtmESDRTO03vQBrWMsTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC1RBo%2FdJMcahqX1nD%2FgiKtmESDRTO03vQBrWMsTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1383&quot; height=&quot;768&quot; data-origin-width=&quot;1383&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이것이 바로 2018년에 파이프라인에 메시 셰이딩이 추가된 이유입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;메시 셰이딩은 워크 그래프에도 중요합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjtFA7/dJMb997vIPz/d80NUiNkbkDPNwpLtgEwE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjtFA7/dJMb997vIPz/d80NUiNkbkDPNwpLtgEwE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjtFA7/dJMb997vIPz/d80NUiNkbkDPNwpLtgEwE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjtFA7%2FdJMb997vIPz%2Fd80NUiNkbkDPNwpLtgEwE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1377&quot; height=&quot;768&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;//&amp;nbsp;Process&amp;nbsp;Geometry&amp;nbsp;with&amp;nbsp;Computer&amp;nbsp;Shader&lt;br /&gt;commandList-&amp;gt;SetPipelineState(...);&lt;br /&gt;commandList-&amp;gt;Dispatch(...);&lt;br /&gt;commandList-&amp;gt;Barrier(...);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그렇다면 메시 셰이딩은 어떤 문제를 해결하는 것일까요?&lt;/span&gt;&lt;/span&gt; 지오메트리를&lt;span&gt;&lt;span&gt;&amp;nbsp;생성하거나 변환하는 컴퓨트 셰이더를 생각해 봅시다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;그런데 이 컴퓨트 셰이더는 출력을 그래픽 메모리에 저장해야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;770&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfvXPd/dJMcad25FBR/ywGnkPgdq0iManJOoijKnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfvXPd/dJMcad25FBR/ywGnkPgdq0iManJOoijKnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfvXPd/dJMcad25FBR/ywGnkPgdq0iManJOoijKnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfvXPd%2FdJMcad25FBR%2FywGnkPgdq0iManJOoijKnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1374&quot; height=&quot;770&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;770&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;//&amp;nbsp;Process&amp;nbsp;Geometry&amp;nbsp;with&amp;nbsp;Graphics&amp;nbsp;Pipeline&lt;br /&gt;commandList-&amp;gt;SetPipelineState(...);&lt;br /&gt;commandList-&amp;gt;DrawIndexedInstanced(...);&lt;br /&gt;commandList-&amp;gt;Barrier(...);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그러면 그래픽 파이프라인이 그래픽 메모리에서 읽을 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;따라서 메모리 쓰기와 읽기 작업이 각각 한 번씩 발생하므로, 이를 줄일 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;그래픽 메모리 접근은 상당히 비용이 많이 드는 작업이라는 점을 기억하세요.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n4hvn/dJMcabYAj14/mxj57f8kZlUb81UpS4jK40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n4hvn/dJMcabYAj14/mxj57f8kZlUb81UpS4jK40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n4hvn/dJMcabYAj14/mxj57f8kZlUb81UpS4jK40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn4hvn%2FdJMcabYAj14%2Fmxj57f8kZlUb81UpS4jK40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1370&quot; height=&quot;764&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;//&amp;nbsp;Process&amp;nbsp;with&amp;nbsp;Mesh&amp;nbsp;Shader&lt;br /&gt;commandList-&amp;gt;SetPipelineState(...);&lt;br /&gt;commandList-&amp;gt;DispatchMesh(...);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;메시 셰이딩의 핵심 아이디어는 컴퓨트 셰이더에서 래스터라이저로 직접 데이터를 전달하는 것입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이를 통해 그래픽 메모리 접근 횟수를 줄일 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wzDS9/dJMcahqX1Dj/0vf6TwIrU37CaUC5KHCBqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wzDS9/dJMcahqX1Dj/0vf6TwIrU37CaUC5KHCBqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wzDS9/dJMcahqX1Dj/0vf6TwIrU37CaUC5KHCBqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwzDS9%2FdJMcahqX1Dj%2F0vf6TwIrU37CaUC5KHCBqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1380&quot; height=&quot;768&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이로써 우리는 세 번째 파이프라인인 메시 셰이딩 파이프라인을 얻게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;763&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz5pNe/dJMcagFBJIR/3OK41PFidhkgOH8RALR6xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz5pNe/dJMcagFBJIR/3OK41PFidhkgOH8RALR6xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz5pNe/dJMcagFBJIR/3OK41PFidhkgOH8RALR6xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz5pNe%2FdJMcagFBJIR%2F3OK41PFidhkgOH8RALR6xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1380&quot; height=&quot;763&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;763&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;[outputtopology(&quot;triangle&quot;)]&lt;br /&gt;[numthreads(128,&amp;nbsp;1,&amp;nbsp;1)]&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;main(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;uint3 gtid : SV_GroupThreadID,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; uint3&amp;nbsp;gid&amp;nbsp;:&amp;nbsp;SV_GroupID,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; out&amp;nbsp;vertices&amp;nbsp;float3&amp;nbsp;smallVertexBuffer[256],&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; out&amp;nbsp;indices&amp;nbsp;uint3&amp;nbsp;smallIndexBuffer[256])&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;컴퓨트 셰이더처럼 메시 셰이더 스레드 그룹 그리드를 실행합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;따라서 코드에는 SV_GroupThreadID와 SV_GroupID 시맨틱이 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;각 메시 셰이더 스레드 그룹은 최대 128개의 스레드를 가질 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;삼각형(또는 다른 primitives)을 최대 256개의 정점과 삼각형을 저장할 수 있는 작은 정점 및 인덱스 버퍼에 출력할 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;메시 셰이더의 출력은 작은 메시와 같으므로 일반적으로 메시렛이라고 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;761&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wgt5e/dJMcaa6rLxv/0KFijdwFlcCOKVpnrfhnk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wgt5e/dJMcaa6rLxv/0KFijdwFlcCOKVpnrfhnk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wgt5e/dJMcaa6rLxv/0KFijdwFlcCOKVpnrfhnk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwgt5e%2FdJMcaa6rLxv%2F0KFijdwFlcCOKVpnrfhnk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1366&quot; height=&quot;761&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;761&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;여러 개의 메시 셰이더 스레드 그룹을 사용하면 여러 개의 메시렛을 출력할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDyLrx/dJMcadWly9a/pYGKJLoIAFKCE54TmE0ty1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDyLrx/dJMcadWly9a/pYGKJLoIAFKCE54TmE0ty1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDyLrx/dJMcadWly9a/pYGKJLoIAFKCE54TmE0ty1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDyLrx%2FdJMcadWly9a%2FpYGKJLoIAFKCE54TmE0ty1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;764&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-hveid=&quot;6&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;더 큰 모델을 렌더링하려면 먼저 전처리 단계에서 모델을 여러 개의 메쉬렛으로 분해해야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bO6I1B/dJMcafmnKJR/LeQhy3XWAX40odqKndOfJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bO6I1B/dJMcafmnKJR/LeQhy3XWAX40odqKndOfJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bO6I1B/dJMcafmnKJR/LeQhy3XWAX40odqKndOfJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO6I1B%2FdJMcafmnKJR%2FLeQhy3XWAX40odqKndOfJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1356&quot; height=&quot;757&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그런 다음 각 메쉬렛에 대해 메쉬 셰이더 스레드 그룹을 실행합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1367&quot; data-origin-height=&quot;771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rq2Vi/dJMcahRYTL0/Mglki8kPEz2hRzD52BKLD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rq2Vi/dJMcahRYTL0/Mglki8kPEz2hRzD52BKLD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rq2Vi/dJMcahRYTL0/Mglki8kPEz2hRzD52BKLD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRq2Vi%2FdJMcahRYTL0%2FMglki8kPEz2hRzD52BKLD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1367&quot; height=&quot;771&quot; data-origin-width=&quot;1367&quot; data-origin-height=&quot;771&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;메시 셰이더 스레드 그룹은 이러한 메시렛을 변환한 다음 래스터라이저로 전달합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;770&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K4Enz/dJMcaarP5cR/3Z4GsY30ytrJF1JhDb1V1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K4Enz/dJMcaarP5cR/3Z4GsY30ytrJF1JhDb1V1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K4Enz/dJMcaarP5cR/3Z4GsY30ytrJF1JhDb1V1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK4Enz%2FdJMcaarP5cR%2F3Z4GsY30ytrJF1JhDb1V1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1388&quot; height=&quot;770&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;770&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;메시 셰이딩은 워크 그래프의 초경량 버전입니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;자세한 내용은 다음 블로그 게시물 시리즈를 참조하세요.&lt;br /&gt;&lt;a href=&quot;https://gpuopen.com/learn/mesh_shaders/mesh_shaders-index&quot;&gt;https://gpuopen.com/learn/mesh_shaders/mesh_shaders-index&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1367&quot; data-origin-height=&quot;767&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rA4FB/dJMcabK44G1/0DThnPM2izBdo8yE4UBF61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rA4FB/dJMcabK44G1/0DThnPM2izBdo8yE4UBF61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rA4FB/dJMcabK44G1/0DThnPM2izBdo8yE4UBF61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrA4FB%2FdJMcabK44G1%2F0DThnPM2izBdo8yE4UBF61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1367&quot; height=&quot;767&quot; data-origin-width=&quot;1367&quot; data-origin-height=&quot;767&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;하지만 이제 메쉬 셰이딩이 생겼으니, 워크 그래프에 필요한 모든 개념을 한데 모을 수 있게 되었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이제 문제는 왜 우리에게 워크 그래프가 필요한 가? 하는 것입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;769&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H8WOn/dJMcag6Dkxf/tDIwiyjxy2H1jpY1SA2m50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H8WOn/dJMcag6Dkxf/tDIwiyjxy2H1jpY1SA2m50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H8WOn/dJMcag6Dkxf/tDIwiyjxy2H1jpY1SA2m50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH8WOn%2FdJMcag6Dkxf%2FtDIwiyjxy2H1jpY1SA2m50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;769&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;769&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그 질문에 답하기 위해 먼저 파이프라인에 추가된 또 다른 기능이 해결하려는 문제를 살펴보겠습니다. 제가 말하는 것은 &quot;간접 실행 - indirect execute&quot;입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;749&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx90SN/dJMcabc9aF1/Ghlt7f9YVL4XUKxPkC7sYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx90SN/dJMcabc9aF1/Ghlt7f9YVL4XUKxPkC7sYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx90SN/dJMcabc9aF1/Ghlt7f9YVL4XUKxPkC7sYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx90SN%2FdJMcabc9aF1%2FGhlt7f9YVL4XUKxPkC7sYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1382&quot; height=&quot;749&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;749&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;컴퓨팅 파이프라인과 그래픽 파이프라인이 있다고 가정해 봅시다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dv7Dm/dJMcadaWcH0/2Lt31n94deK7ExspMSZuJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dv7Dm/dJMcadaWcH0/2Lt31n94deK7ExspMSZuJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dv7Dm/dJMcadaWcH0/2Lt31n94deK7ExspMSZuJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDv7Dm%2FdJMcadaWcH0%2F2Lt31n94deK7ExspMSZuJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1373&quot; height=&quot;768&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;235&quot; data-start=&quot;208&quot; data-ke-size=&quot;size16&quot;&gt;그리고 CPU에서 컴퓨트 파이프라인을 시작합니다.&lt;/p&gt;
&lt;p data-end=&quot;323&quot; data-start=&quot;237&quot; data-ke-size=&quot;size16&quot;&gt;그 다음 GPU는 컴퓨트 파이프라인을 사용하여 계산을 수행합니다. 이를 위해 그래픽스 메모리에서 데이터를 읽고, 결과를 다시 그래픽스 메모리에 기록합니다.&lt;/p&gt;
&lt;p data-end=&quot;381&quot; data-start=&quot;325&quot; data-ke-size=&quot;size16&quot;&gt;모든 데이터가 그래픽스 메모리에 기록되었는지 보장하기 위해 배리어(barrier)를 포함해야 합니다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_8&quot; id=&quot;footnote_link_1516_8&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 8)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 8)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;8&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;505&quot; data-start=&quot;383&quot; data-ke-size=&quot;size16&quot;&gt;배리어에 도달한 이후에야 그래픽스 파이프라인을 시작할 수 있습니다. 따라서 반드시 기다려야 합니다. 이후 그래픽스 파이프라인은 메모리에서 데이터를 읽어 픽셀 출력을 생성합니다. 그 다음에는 또 다른 배리어가 필요합니다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;572&quot; data-start=&quot;507&quot; data-ke-size=&quot;size16&quot;&gt;이러한 배리어는 시스템이 적극적으로 대기(active wait)해야 하기 때문에 심각한 성능 문제가 될 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RqOg7/dJMcagyMnEQ/Kf2OM26BmZhNVO3E8bIqdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RqOg7/dJMcagyMnEQ/Kf2OM26BmZhNVO3E8bIqdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RqOg7/dJMcagyMnEQ/Kf2OM26BmZhNVO3E8bIqdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRqOg7%2FdJMcagyMnEQ%2FKf2OM26BmZhNVO3E8bIqdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;766&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;프로듀서(즉, 컴퓨트 커널)&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_9&quot; id=&quot;footnote_link_1516_9&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 9)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 9)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;9&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;가 가변적인 수의 데이터 항목을 생성할 때 상황은 더욱 심각해집니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;예를 들어, 수만 개의 객체가 있는 장면을 상상해 보세요.&lt;/span&gt;&lt;/span&gt; 프로듀서의&lt;span&gt;&lt;span&gt;&amp;nbsp;역할은 보이지 않는 객체를 제거하는 것입니다.&lt;/span&gt;&lt;/span&gt; 프로듀서&lt;span&gt;&lt;span&gt;&amp;nbsp;커널이 실행된 후, 5000개의 보이는 객체를 데이터에 출력합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;그리고 거기에 N = 5000이라고 기록합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btS9Oe/dJMcahYLw2C/rQrSyA1Q1w4zwMbcjY05F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btS9Oe/dJMcahYLw2C/rQrSyA1Q1w4zwMbcjY05F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btS9Oe/dJMcahYLw2C/rQrSyA1Q1w4zwMbcjY05F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtS9Oe%2FdJMcahYLw2C%2FrQrSyA1Q1w4zwMbcjY05F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1374&quot; height=&quot;768&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;컨슈머는 5000개의 객체를 렌더링합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;하지만 이를 위해서는 CPU가 드로우 콜을 구성해야 하고, 이때 N이라는 숫자를 알아야 합니다. &lt;br /&gt;&lt;br /&gt;즉, CPU는 GPU로부터 N 값을 읽어와야 합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;따라서 CPU와 GPU를 동기화하는 펜스(fence)를 포함해야 합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이 펜스를 통과한 후에야 CPU는 N 값을 읽고 드로우 콜을 올바르게 구성할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1367&quot; data-origin-height=&quot;767&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XHZzc/dJMcajvvQ1G/9Dnm5yVkk3EqXmQjRkzAK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XHZzc/dJMcajvvQ1G/9Dnm5yVkk3EqXmQjRkzAK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XHZzc/dJMcajvvQ1G/9Dnm5yVkk3EqXmQjRkzAK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXHZzc%2FdJMcajvvQ1G%2F9Dnm5yVkk3EqXmQjRkzAK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1367&quot; height=&quot;767&quot; data-origin-width=&quot;1367&quot; data-origin-height=&quot;767&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;해당 데이터 핸들과 객체 개수를 알면 CPU는 화면에 표시되는 객체에 5000번의 드로우 콜을 실행할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; 단, 프로듀서와 컨슈머는 데이터 핸들(&amp;amp;Data)에 대해 사전에 합의해야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;776&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9QZdV/dJMcaffDpQq/InFUC2NRFpPskzy5s5ucM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9QZdV/dJMcaffDpQq/InFUC2NRFpPskzy5s5ucM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9QZdV/dJMcaffDpQq/InFUC2NRFpPskzy5s5ucM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9QZdV%2FdJMcaffDpQq%2FInFUC2NRFpPskzy5s5ucM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1386&quot; height=&quot;776&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;776&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&quot;간접 실행-indirect execute&quot;을 사용하면 숫자 N이 저장된 위치에 대한 핸들도 얻을 수 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이것이 어떻게 상황을 개선할 수 있는지 살펴보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tSqp3/dJMcahdpPVX/SW4QSQhzG7Bdrk8GID7Jl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tSqp3/dJMcahdpPVX/SW4QSQhzG7Bdrk8GID7Jl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tSqp3/dJMcahdpPVX/SW4QSQhzG7Bdrk8GID7Jl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtSqp3%2FdJMcahdpPVX%2FSW4QSQhzG7Bdrk8GID7Jl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1387&quot; height=&quot;773&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;773&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;프로듀서는 &amp;amp;N과 &amp;amp;Data라는 두 개의 핸들을 모두 받습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이전과 마찬가지로, 보이는 객체(Data)와 보이는 객체의 개수(N)를 출력합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cn8cH2/dJMcabqKnWD/wvpi2prpfoGeu2BEAur9k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cn8cH2/dJMcabqKnWD/wvpi2prpfoGeu2BEAur9k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cn8cH2/dJMcabqKnWD/wvpi2prpfoGeu2BEAur9k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcn8cH2%2FdJMcabqKnWD%2Fwvpi2prpfoGeu2BEAur9k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1374&quot; height=&quot;772&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;이제 CPU는 GPU 핸들의 위치는 알지만 실제 값은 알지 못합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;따라서 실제 값을 전송할 필요가 없습니다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;그러므로 펜스(fence)도 필요 없습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1383&quot; data-origin-height=&quot;761&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8MdlZ/dJMcaaL5YcL/7LUQSEpDO6v7RhTsWk73Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8MdlZ/dJMcaaL5YcL/7LUQSEpDO6v7RhTsWk73Mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8MdlZ/dJMcaaL5YcL/7LUQSEpDO6v7RhTsWk73Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8MdlZ%2FdJMcaaL5YcL%2F7LUQSEpDO6v7RhTsWk73Mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1383&quot; height=&quot;761&quot; data-origin-width=&quot;1383&quot; data-origin-height=&quot;761&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;CPU가 해야 할 일은 실제 값 대신 핸들을 매개변수로 사용하여 컨슈머를 호출하는 것뿐입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVfzky/dJMb99NaGcP/ewLT9Ey3XsskJ2ujY8lX91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVfzky/dJMb99NaGcP/ewLT9Ey3XsskJ2ujY8lX91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVfzky/dJMb99NaGcP/ewLT9Ey3XsskJ2ujY8lX91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVfzky%2FdJMb99NaGcP%2FewLT9Ey3XsskJ2ujY8lX91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;764&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;하지만 프로듀서와 컨슈머가 여전히 그래픽 메모리를 통해 통신하기 때문에 펜스는 여전히 ​​필요합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1372&quot; data-origin-height=&quot;761&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b53X9O/dJMcadPybIy/mMxLIfVCnWlw8loQwP7n6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b53X9O/dJMcadPybIy/mMxLIfVCnWlw8loQwP7n6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b53X9O/dJMcadPybIy/mMxLIfVCnWlw8loQwP7n6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb53X9O%2FdJMcadPybIy%2FmMxLIfVCnWlw8loQwP7n6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1372&quot; height=&quot;761&quot; data-origin-width=&quot;1372&quot; data-origin-height=&quot;761&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;또한, N=0인 경우 CPU가 컨슈머를 디스패치할 이유가 없습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;하지만 CPU는 N이 0인지 알 수 없으므로, 어떤 경우에도 드로우 콜을 디스패치해야 합니다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_10&quot; id=&quot;footnote_link_1516_10&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 10)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 10)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;10&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;이는 위험한 것은 아니지만, 배리어를 포함한 런치 오버헤드가 발생합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_11&quot; id=&quot;footnote_link_1516_11&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 11)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 11)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;11&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;759&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZ4Qro/dJMcaf0VKqe/U22szEkBRiNhSqkRFjrJk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZ4Qro/dJMcaf0VKqe/U22szEkBRiNhSqkRFjrJk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZ4Qro/dJMcaf0VKqe/U22szEkBRiNhSqkRFjrJk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZ4Qro%2FdJMcaf0VKqe%2FU22szEkBRiNhSqkRFjrJk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1384&quot; height=&quot;759&quot; data-origin-width=&quot;1384&quot; data-origin-height=&quot;759&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;간접 실행(indirect execute)의 또 다른 문제는 데이터에 포함될 수 있는 메모리를 예약해야 한다는 것입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;컬링 예제로 돌아가 보면, 모든 객체를 렌더링할 수도 있고, 객체를 하나도 렌더링하지 않을 수도 있습니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;이를 미리 알 수 없기 때문에 항상 최악의 경우를 대비해야 하며, 따라서 잠재적으로 메모리를 낭비하게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj1RGL/dJMcad25Iu7/EPtPX925nNWvIs1hqY0kbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj1RGL/dJMcad25Iu7/EPtPX925nNWvIs1hqY0kbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj1RGL/dJMcad25Iu7/EPtPX925nNWvIs1hqY0kbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj1RGL%2FdJMcad25Iu7%2FEPtPX925nNWvIs1hqY0kbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1370&quot; height=&quot;768&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;우리는 항상 최악의 시나리오를 고려해야 합니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;그렇지 않으면 위험한 메모리 오버플로 상황에 직면할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1JrzQ/dJMcad25Ixw/gnamkRNKBoSKFyRKrT7EMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1JrzQ/dJMcad25Ixw/gnamkRNKBoSKFyRKrT7EMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1JrzQ/dJMcad25Ixw/gnamkRNKBoSKFyRKrT7EMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1JrzQ%2FdJMcad25Ixw%2FgnamkRNKBoSKFyRKrT7EMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1385&quot; height=&quot;771&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;771&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;그러니까 이것들은 모두 기존의 간접 실행 문제들입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1379&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dg5RlW/dJMcagevvda/8Ia59Kc8I3qnqDIQR4DyJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dg5RlW/dJMcagevvda/8Ia59Kc8I3qnqDIQR4DyJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dg5RlW/dJMcagevvda/8Ia59Kc8I3qnqDIQR4DyJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdg5RlW%2FdJMcagevvda%2F8Ia59Kc8I3qnqDIQR4DyJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1379&quot; height=&quot;762&quot; data-origin-width=&quot;1379&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;276&quot; data-start=&quot;173&quot; data-ke-size=&quot;size16&quot;&gt;이러한 문제들을 메시 셰이더(mesh shaders)로 해결할 수 있을까요?&lt;br /&gt;아직 메시 셰이딩 파이프라인의 amplification shader 단계에 대해서는 설명하지 않았습니다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_12&quot; id=&quot;footnote_link_1516_12&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 12)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 12)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;12&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p data-end=&quot;390&quot; data-start=&quot;278&quot; data-ke-size=&quot;size16&quot;&gt;Amplification Shader는 GPU 상에서 직접 실행할 메시 셰이더 스레드 그룹의 개수를 제어할 수 있습니다. 본질적으로 이것은 작은 규모의 consumer-producer 파이프라인입니다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;444&quot; data-start=&quot;392&quot; data-ke-size=&quot;size16&quot;&gt;따라서 매우 단순한 시나리오에서는 메시 셰이딩이 이러한 문제들 중 일부를 해결할 수 있습니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVyN58/dJMcaciOQ5m/vk4UTt1CYP68CVjsWZwjh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVyN58/dJMcaciOQ5m/vk4UTt1CYP68CVjsWZwjh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVyN58/dJMcaciOQ5m/vk4UTt1CYP68CVjsWZwjh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVyN58%2FdJMcaciOQ5m%2Fvk4UTt1CYP68CVjsWZwjh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1373&quot; height=&quot;766&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;하지만 메시 셰이딩은 그래픽 처리 기능만 제공하며, 연산 처리 기능은 지원하지 않습니다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1516_13&quot; id=&quot;footnote_link_1516_13&quot; onmouseover=&quot;tistoryFootnote.show(this, 1516, 13)&quot; onmouseout=&quot;tistoryFootnote.hide(1516, 13)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;13&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1378&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZQoei/dJMcaaZDWkH/pRou8SkVdkKoNIaCu6bg60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZQoei/dJMcaaZDWkH/pRou8SkVdkKoNIaCu6bg60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZQoei/dJMcaaZDWkH/pRou8SkVdkKoNIaCu6bg60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZQoei%2FdJMcaaZDWkH%2FpRou8SkVdkKoNIaCu6bg60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1378&quot; height=&quot;764&quot; data-origin-width=&quot;1378&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;예를 들어 재귀적 세분화와 같은 자기 재귀를 원하는 경우 문제가 발생합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1Voxl/dJMcai4odHU/97BmpCtATIl9cJRWmgVN1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1Voxl/dJMcai4odHU/97BmpCtATIl9cJRWmgVN1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1Voxl/dJMcai4odHU/97BmpCtATIl9cJRWmgVN1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1Voxl%2FdJMcai4odHU%2F97BmpCtATIl9cJRWmgVN1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1385&quot; height=&quot;760&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;메쉬 셰이딩 파이프라인은 프로그래밍 가능한 단계가 하나 또는 두 개뿐입니다.&lt;/span&gt;&lt;/span&gt; &lt;span&gt;&lt;span&gt;따라서 긴 체인은 구현할 수 없습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1372&quot; data-origin-height=&quot;761&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czh86V/dJMcadveDGc/FwrOYkNEkYlENVRRCVknA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czh86V/dJMcadveDGc/FwrOYkNEkYlENVRRCVknA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czh86V/dJMcadveDGc/FwrOYkNEkYlENVRRCVknA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczh86V%2FdJMcadveDGc%2FFwrOYkNEkYlENVRRCVknA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1372&quot; height=&quot;761&quot; data-origin-width=&quot;1372&quot; data-origin-height=&quot;761&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;또는 여러 개의 서로 다른 셰이더 체인을 사용할 수도 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;763&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lcafP/dJMcaiXDhkU/VDKLW45X1g1NAcW2eKXVR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lcafP/dJMcaiXDhkU/VDKLW45X1g1NAcW2eKXVR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lcafP/dJMcaiXDhkU/VDKLW45X1g1NAcW2eKXVR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlcafP%2FdJMcaiXDhkU%2FVDKLW45X1g1NAcW2eKXVR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1370&quot; height=&quot;763&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;763&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;분류-실행 패턴(이 강좌의 재질 셰이딩 섹션 뒷부분 참조)과 같이 셰이더 체인에서 분기되는 방식 또한 불가능합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol class=&quot;footnotes&quot;&gt;
    &lt;li id=&quot;footnote_1516_1&quot;&gt; &lt;br /&gt;여기서 말하는 Mesh node는 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Mesh Shader 단계 전체를 &lt;b&gt;Work Graph의 한 노드&lt;/b&gt;로 취급한 개념으로 개별 커널 실행 단위(스레드 그룹 하나)가 아니라, &amp;ldquo;Mesh Shader 파이프라인 호출&amp;rdquo;을 그래프의 &lt;b&gt;노드 단위 작업&lt;/b&gt;으로 캡슐화 한 것을 말한다. 이 Mesh Node는 Work Graph 내 다른 노드(예: Culling Node, LOD Selection Node, Lighting Node)와 연결되어 데이터 플로우를 형성하게 된다.(works graph 상에서 추상화한 노드)&amp;nbsp;&lt;br /&gt;&lt;br /&gt;논문에서 말한 &amp;ldquo;2024년 3분기에 공개된 Mesh Nodes&amp;rdquo;는 &lt;b&gt;DirectX 12 Work Graphs의 Mesh Nodes&lt;/b&gt; 프리뷰를 이야기하며,. 이때부터 &lt;b&gt;그래프의 리프(leaf) 노드에서 메쉬 셰이더 파이프라인을 직접 실행&lt;/b&gt;할 수 있게 되어, CPU 드로우콜 없이 &lt;b&gt;그래프 안에서 바로 렌더링&lt;/b&gt;이 가능해졌다.(Microsoft가 &lt;b&gt;Agility SDK v1.715.0 프리뷰&lt;/b&gt;와 함께 Mesh Nodes를 공개했고, &lt;b&gt;AMD 라데온 공개 드라이버는 Q3 2024에 Mesh Nodes 지원이 탑재&lt;/b&gt;된다고 공지)&amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://devblogs.microsoft.com/directx/d3d12-mesh-nodes-in-work-graphs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://devblogs.microsoft.com/directx/d3d12-mesh-nodes-in-work-graphs/&lt;/a&gt; &amp;nbsp;&lt;br /&gt;&lt;br /&gt;기존 Work Graph 노드는 전부 &amp;ldquo;컴퓨트형&amp;rdquo;이었는데, Mesh Node는 &lt;b&gt;컴퓨트가 아니라 메쉬 셰이더 기반 그래픽스 파이프라인을 dispatch한다&lt;/b&gt;. 즉, 노드 자체가 mesh shader + (선택적) pixel shader + 래스터라이저 상태를 포함한 &lt;b&gt;그래픽스 프로그램(PSO 유사체)&lt;/b&gt;로 구성되게 된다. 이로 인해 그래프 내부에서 &lt;b&gt;드로우콜이 1급 시민&lt;/b&gt;이 되며, &lt;b&gt;PSO 선택/스위칭&lt;/b&gt;과 &lt;b&gt;(옵션) 순서 보장 래스터라이즈&lt;/b&gt;까지 지원하게된다. 이로인해 완전한 &lt;b&gt;GPU-driven&lt;/b&gt; 파이프라인을 구성할 수 있게 된다.&lt;br /&gt;&lt;br /&gt;AMD의 가이드 &lt;a href=&quot;https://gpuopen.com/learn/work_graphs_mesh_nodes/work_graphs_mesh_nodes-tips_tricks_best_practices/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gpuopen.com/learn/work_graphs_mesh_nodes/work_graphs_mesh_nodes-tips_tricks_best_practices/&lt;/a&gt;&amp;nbsp; 에서 이야기하는 주요 내용은 아래와 같다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1) 작게 쪼개진 디스패치를 합쳐라 :&lt;/b&gt; 작은 레코드 다발 대신 코얼레싱 노드나 그룹 출력으로 &amp;ldquo;한 번에 더 큰 메쉬 디스패치&amp;rdquo;를 날려 오버헤드를 가린다.&lt;br /&gt;&lt;b&gt;2) PSO 스위칭 최소화 :&lt;/b&gt; 가능한 공통 그래픽스 상태를 크게 유지해 스위칭 비용을 줄여라.&amp;nbsp;&lt;br /&gt;&lt;b&gt;3)&lt;/b&gt;.렌더 타깃 배열: 동일 그래프 내에서 다른 패스(G-Buffer/섀도우 등)를 동시에 그리려면 배열 슬라이스를 활용하라.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt; &lt;a href=&quot;#footnote_link_1516_1&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_2&quot;&gt; &lt;br /&gt;&lt;b&gt;Indirect Execution :&lt;/b&gt; GPU가 실행할 명령(드로우, 디스패치 등)의 파라미터를 메모리 버퍼에서 읽어와 실행하는 방식.&lt;br /&gt;&lt;b&gt;Execute Indirect :&lt;/b&gt; &amp;nbsp;DirectX12에서 제공하는 &lt;b&gt;Indirect Execution을 위한 구체적인 API &lt;/b&gt; &lt;a href=&quot;#footnote_link_1516_2&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_3&quot;&gt; &lt;b&gt;Amplification Shader (AS) &lt;/b&gt;: Mesh Shader 앞에서 실행되어, &lt;b&gt;몇 개의 Mesh Shader 그룹을 만들지 증폭(amplify)&lt;/b&gt;.하는 단계를 의미한다 &lt;a href=&quot;#footnote_link_1516_3&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_4&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Work Graphs에서의 &amp;ldquo;재귀적 증폭&quot;은 노드가 실행 중에 &lt;b&gt;자기 자신 또는 다른 노드를 새로 디스패치할 수 있다는 의미&lt;/b&gt;로 한 노드가 &amp;ldquo;Amplification 역할&amp;rdquo;을 하고, 그 결과가 다시 &lt;b&gt;추가적인 Amplification&lt;/b&gt;을 발생시킬 수 있다는 이야기이다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;다단계 증폭 (multi-level amplification) :&lt;/b&gt; Culling &amp;rarr; Binning &amp;rarr; LOD &amp;rarr; Mesh Node &amp;rarr; 또 다른 Mesh Node &amp;hellip; 와 같이 계층적으로 증폭 구조를 설계 가능&lt;br /&gt;&lt;b&gt;재귀적 증폭 (self-recursive amplification) :&lt;/b&gt; 하나의 노드가 자기 자신을 다시 실행해서 동적 워크로드를 계속 확장 가능 (예: 쿼드트리/옥트리 기반 지형 세분화, 파티클 시뮬레이션, LOD streaming)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;그래프 노드가 자기 자신이나 다른 노드를 동적으로 증폭&amp;middot;재귀 호출&lt;/b&gt;할 수 있는 일반화된 모델을 이야기 한다 &lt;a href=&quot;#footnote_link_1516_4&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_5&quot;&gt; 연속적인 삼각형을 실제 화면의 불연속적인 픽셀 그리드로 변환하는 과정을 이야기 한다 &lt;a href=&quot;#footnote_link_1516_5&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_6&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;GPU 하드웨어의 실제 구조를 개발자가 직접 다루지 않아도 되도록, GPU를 논리적인 실행 모델로 표현하는 개념으로 여기서 Compute Shader를 다음처럼 추상화하고 있다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;- GPU 작업을 수많은 &lt;b&gt;스레드(Thread)&lt;/b&gt; 로 구성&lt;br /&gt;&amp;nbsp;- 스레드들을그룹 내부에서는 각 스레드는 자신의 위치를 SV_GroupThreadID 로 식별&lt;br /&gt;&lt;br /&gt;실제 GPU 내부의 코어, SIMD 구조, 스케줄링 등을 직접 신경 쓰는 대신, &amp;ldquo;3차원 격자(Grid) 안에 있는 스레드들이 병렬로 실행된다&amp;rdquo; 라는 형태로 단순화해서 프로그래밍할 수 있게 만든 것을 이야기 한다.  &lt;a href=&quot;#footnote_link_1516_6&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_7&quot;&gt;GPU 내부보다 약 20배 느리다 &lt;a href=&quot;#footnote_link_1516_7&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_8&quot;&gt;Barrier가 포함되어야 하는것은 프로듀서가 생성된 데이터를 컨슈머가 먼저 접근하는 것을 막기위해 완료 보장을 하기 위함이다. 이로인해 데이터를 쓰는중에 접근해 데이터가 깨지거나 문제가 생기는걸 막는다  &lt;a href=&quot;#footnote_link_1516_8&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_9&quot;&gt; Compute Shader, Cull pass, Visibility pass등 버퍼등 데이터를 생성하는 쪽. 반대로 사용하는 것을 이 내용에서는 Consumer라고 지칭한다. &lt;a href=&quot;#footnote_link_1516_9&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_10&quot;&gt; 기존구조에서는 DrawIndirectInstanced를 호출하므로 실제로 N=0로 그릴게 없다 하더라도 파이프라인 전환 및 draw setup등 CPU/GPU 오버헤드는 존재하지만 ExecuteIndirect에서는 N=0일때는 GPU내부에서 실행할 draw가 없기에 CPU개입없이 GPU에서 그냥 넘어갈 수 있음. 대규모 씬 렌더링에서 &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;빈번하게 발생하는 경우 이러한 구조는 매우 유의미하게 이득일 수 있음 &lt;a href=&quot;#footnote_link_1516_10&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_11&quot;&gt; Producer와 Consumer 사이의 동기화는 여전히 필요하므로Barrier 문제를 완전히 없애지는 못함 &lt;a href=&quot;#footnote_link_1516_11&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_12&quot;&gt;왜 amplfication이냐면 입력 작업을 증폭(amplify)하기 때문이다. 예를 들면 하나의 오브젝트를 받아왔을때 이를 amplification shader stage에서 64개의 Mesh Shader task가 생성하는것도 가능하기 때문이다.(작업생성, 분배 및 수를 조절). 이 스테이지의 역할은 Mesh shader가 수행할 작업을 생성하는 단계라 생각하면 된다.  &lt;a href=&quot;#footnote_link_1516_12&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1516_13&quot;&gt;Mesh shader만 생성가능. 범용 GPU 작업은 불가 &lt;a href=&quot;#footnote_link_1516_13&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</description>
      <category>Technical Report/Graphics Tech Reports</category>
      <category>worksGraph</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1516</guid>
      <comments>https://illu.tistory.com/1516#entry1516comment</comments>
      <pubDate>Tue, 19 May 2026 16:22:59 +0900</pubDate>
    </item>
    <item>
      <title>[번역] No Graphics API</title>
      <link>https://illu.tistory.com/1520</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;원문 :&amp;nbsp;&lt;a href=&quot;https://www.sebastianaaltonen.com/blog/no-graphics-api?fbclid=IwY2xjawQIzflleHRuA2FlbQIxMQBzcnRjBmFwcF9pZBAyMjIwMzkxNzg4MjAwODkyAAEeYW1J5owAqUG6qDQ6kMcjFTaDESQHiSnX6N4FBO5IvW2YHyoZ4x_KlZQAlfk_aem_ZhEs0Y6LCVm17zbiTGNCWQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.sebastianaaltonen.com/blog/no-graphics-api?fbclid=IwY2xjawQIzflleHRuA2FlbQIxMQBzcnRjBmFwcF9pZBAyMjIwMzkxNzg4MjAwODkyAAEeYW1J5owAqUG6qDQ6kMcjFTaDESQHiSnX6N4FBO5IvW2YHyoZ4x_KlZQAlfk_aem_ZhEs0Y6LCVm17zbiTGNCWQ&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity 때 엔진팀 리드였던(DOTS hybrid) 세바스티앙 알토넨의 블로그 글.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;No&amp;nbsp;Graphics&amp;nbsp;API&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Introduction&lt;/h3&gt;
&lt;p data-end=&quot;234&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;그래픽스 API, 셰이더 프레임워크, 드라이버의 복잡성은 지난 수십 년 동안 급격히 증가해왔다. 파이프라인 상태 객체(PSO-Pipeline State Object)의 폭증은 이미 통제 불가능한 수준에 이르렀다. 우리는 어떻게 해서 100GB에 달하는 로컬 셰이더 파이프라인 캐시와 이를 호스팅하기 위한 대규모 클라우드 서버를 사용하게 되었을까? 이제는 GPU와 상호작용하는 방식을 단순화하기 위해 &lt;b&gt;추상화 계층과 API 표면을 어떻게 줄일지 논의할 때다&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;이 블로그 글에는 많은 저수준 하드웨어 세부 내용이 포함되어 있다. 이 글을 작성하면서 나는 공개된 Linux 오픈소스 드라이버를 교차 참고하기 위해 &amp;ldquo;GPT5 Thinking&amp;rdquo; AI 모델을 사용했으며, NDA(비밀 유지 계약) 정보가 포함되지 않았음을 확인했다. 참고 자료로는 AMD RDNA ISA 문서와 GPUOpen, Nvidia PTX ISA 문서, Intel PRM, Linux 오픈소스 GPU 드라이버(Mesa, Freedreno, Turnip, Asahi), 그리고 각 벤더의 최적화 가이드 및 발표 자료가 있다. 이 블로그 글은 공개 전에 여러 업계 관계자들의 검토를 거쳤다.&lt;/p&gt;
&lt;p data-end=&quot;234&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;234&quot; data-start=&quot;0&quot; data-ke-size=&quot;size23&quot;&gt;Low-level&amp;nbsp;graphics&amp;nbsp;APIs&amp;nbsp;change&amp;nbsp;the&amp;nbsp;industry&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;80b338b7-6f06-4fcd-b33a-72c4c651766c&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;461&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;10년 전, 새로운 저수준 PC 그래픽스 API가 등장하면서 실시간 컴퓨터 그래픽스 분야에 큰 전환점이 찾아왔다. AMD는 Xbox One(2013)과 PlayStation 4(2013) 계약을 모두 따냈고, 그들의 새로운 Graphics Core Next(GCN) 아키텍처는 AAA 게임 개발의 사실상 기준 플랫폼이 되었다. 당시 PC 그래픽스 API였던 DirectX 11과 OpenGL 4.5는 드라이버 오버헤드가 크고 단일 스레드 렌더링을 전제로 설계되어 있었다. AAA 개발자들은 PC에서 더 높은 성능을 낼 수 있는 API를 요구했다. 이에 DICE는 AMD와 협력해 PC용 저수준 AMD GCN 전용 API인 Mantle을 만들었다. 그에 대한 대응으로 Microsoft, Khronos, Apple이 각자의 저수준 API 개발에 착수했고, 그 결과 DirectX 12, Vulkan, Metal이 탄생했다.&lt;br /&gt;&lt;br /&gt;이 새로운 저수준 API에 대한 초기 반응은 엇갈렸다. 합성 벤치마크와 데모에서는 상당한 성능 향상이 나타났지만, Unreal이나 Unity 같은 주요 게임 엔진에서는 뚜렷한 성능 개선이 보이지 않았다. Ubisoft에서는 기존 DirectX 11 렌더러를 DirectX 12로 포팅할 경우 오히려 성능이 떨어지는 경우가 많다는 사실을 확인했다. 뭔가 잘못되어 있었다. &lt;br /&gt;&lt;br /&gt;기존의 고수준 API는 지속 상태가 거의 없고, 세분화된 상태 설정 함수와 개별 데이터 입력을 드로우 호출 직전에 셰이더에 바인딩하는 구조였다. 반면 새로운 저수준 API는 드로우 호출을 더 저렴하게 만들기 위해 셰이더 파이프라인 상태와 바인딩을 사전에 묶어 영속 객체로 만드는 방식을 채택했다. 당시 GPU 아키텍처는 매우 이질적이었기 때문에, 데이터 재매핑&amp;middot;검증&amp;middot;업로드를 미리 수행하는 것은 큰 이점이었다. 그러나 기존 게임 엔진의 렌더링 하드웨어 인터페이스(RHI)는 세분화된 즉시 모드 렌더링에 맞춰 설계되어 있었고, 새로운 저수준 API는 데이터를 영속 객체로 묶는 방식을 요구했다. &lt;br /&gt;&lt;br /&gt;이러한 비호환성을 해결하기 위해 RHI 아래에 새로운 저수준 그래픽 리매핑 레이어가 생겨났다. 이 레이어는 과거 OpenGL 및 DirectX 11 드라이버가 처리하던 복잡성을 떠안아, 세분화된 동적 사용자 공간 상태와 영속적인 저수준 GPU 상태 사이의 리소스 추적 및 매핑을 관리했다. 그 결과 그래픽스 프로그래머는 두 가지 역할로 분화되기 시작했다. 새로운 저수준 &amp;ldquo;드라이버&amp;rdquo; 레이어와 RHI를 다루는 저수준 그래픽스 프로그래머와, RHI 위에서 시각적 그래픽 알고리즘을 구현하는 고수준 그래픽스 프로그래머다. 한편 물리 기반 조명 모델, 컴퓨트 셰이더, 이후의 레이 트레이싱 도입 등으로 시각 프로그래밍 자체도 점점 더 복잡해지고 있었다. &lt;/p&gt;
&lt;p data-end=&quot;461&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Modern APIs?&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;234&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;DirectX 12, Vulkan, Metal은 흔히 &amp;ldquo;모던 API&amp;rdquo;라고 불린다. 하지만 이 API들도 이제 10년이 되었다. 이들은 오늘날 기준으로 13년이나 된 GPU를 지원하기 위해 설계되었는데, GPU 역사에서 13년은 엄청나게 긴 시간이다. 과거의 GPU 아키텍처는 오늘날처럼 범용적이고 연산 집약적인 워크로드보다는 전통적인 버텍스/픽셀 셰이더 작업에 최적화되어 있었다. 또한 벤더마다 서로 다른 바인딩 모델과 데이터 경로를 가지고 있었기 때문에, 이러한 하드웨어 차이를 하나의 공통 API 아래로 감싸야 했다. 이 과정에서 매핑, 업로드, 검증, 바인딩 비용을 사전에 처리하기 위해 미리 생성된 영속 객체(persistent object)가 중요했다. &lt;br /&gt;&lt;br /&gt;반면 콘솔 API와 Mantle은 AMD의 GCN 아키텍처만을 대상으로 설계되었으며, 당시로서는 매우 선구적인 구조였다. GCN은 완전한 읽기/쓰기 캐시 계층과 텍스처 및 버퍼 디스크립터를 저장할 수 있는 스칼라 레지스터를 갖추고 있어, 모든 것을 사실상 메모리처럼 취급할 수 있었다. 복잡한 데이터 리매핑 API가 필요하지 않았고, 사전 작업도 훨씬 적었다. 단일하고 현대적인 GPU 아키텍처만을 대상으로 했기 때문에, 콘솔 API와 Mantle은 API 복잡성이 훨씬 낮았다. &lt;br /&gt;&lt;br /&gt;그로부터 10년이 흐르는 동안 GPU는 크게 진화했다. 이제 모든 현대 GPU 아키텍처는 일관성을 갖춘 최상위 캐시를 포함한 완전한 캐시 계층을 제공한다. PCIe REBAR나 UMA를 통해 CPU가 GPU 메모리에 직접 쓸 수 있고, 64비트 GPU 포인터도 셰이더에서 직접 지원된다. 텍스처 샘플러는 바인드리스(bindless) 방식으로 동작해 CPU 드라이버가 디스크립터 바인딩을 구성할 필요가 없다. 텍스처 디스크립터는 GPU 메모리 내 배열(흔히 descriptor heap이라 불림)에 직접 저장될 수 있다. 오늘날의 GPU를 기준으로 API를 새롭게 설계한다면, 이러한 영속적인 &amp;ldquo;retained mode&amp;rdquo; 객체의 상당수는 더 이상 필요하지 않을 것이다. DirectX 12.0, Metal 1, Vulkan 1.0이 감수해야 했던 타협들은 이제 필요하지 않으며, API를 대폭 단순화할 수 있다. &lt;br /&gt;&lt;br /&gt;지난 10년은 이들 모던 API의 약점도 드러냈다. 그중 가장 큰 문제는 PSO(파이프라인 상태 객체) 조합 폭발이다. 벤더(Valve, Nvidia 등)는 아키텍처와 드라이버 조합별로 테라바이트 단위의 PSO를 저장하는 대규모 클라우드 서버를 운영하고 있다. 사용자 로컬 PSO 캐시가 100GB를 넘는 경우도 있다. 게이머들이 로딩 시간이 길고 끊김(stutter)이 발생한다고 불평하는 것도 무리가 아니다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;The history of GPUs and APIs&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 표면을 줄이는 이야기를 하기 전에, 그래픽스 API가 역사적으로 왜 이런 방식으로 설계되었는지를 이해할 필요가 있다. OpenGL이 일부러 느리게 설계된 것도 아니고, Vulkan이 일부러 복잡하게 만들어진 것도 아니다. 10~20년 전의 GPU 하드웨어는 매우 다양했고 빠르게 진화하고 있었다. 이렇게 이질적인 하드웨어 집합을 아우르는 크로스 플랫폼 API를 설계하려면 타협이 불가피했다. &lt;br /&gt;&lt;br /&gt;고전적인 사례부터 살펴보자. 3dFX Voodoo 2 12MB(1998)는 세 개의 칩으로 구성된 설계였다. 하나의 래스터라이저 칩이 4MB 프레임버퍼 메모리에 연결되어 있었고, 두 개의 텍스처 샘플링 칩이 각각 4MB 텍스처 메모리에 연결되어 있었다. 지오메트리 파이프라인도 없었고, 프로그래머블 셰이더도 존재하지 않았다. CPU가 변환을 마친 삼각형 정점을 래스터라이저로 직접 전송했다. 래스터라이저에는 정점 색상과 두 텍스처 샘플러 결과를 어떻게 결합할지 제어하는 블렌딩 방정식이 구성 가능하게 마련되어 있었다. 텍스처 샘플러는 서로의 메모리나 프레임버퍼를 읽을 수 없었기 때문에, 다중 렌더 패스를 지원하지 않았다. 또한 하드웨어가 윈도우 합성을 지원하지 못했기 때문에, 별도의 2D 비디오 카드와 연결하기 위한 루프백 케이블이 필요했다. 3D 렌더링은 전용 전체 화면 모드에서만 동작했다. &lt;br /&gt;&lt;br /&gt;당시의 3D 그래픽 카드는 오늘날의 대규모 프로그래머블 SIMD 배열을 갖춘 GPU와는 거의 공통점이 없는, 매우 특수화된 하드웨어였다. 이 시대의 하드웨어 특성은 DirectX(1995)와 OpenGL(1992)의 설계에 큰 영향을 미쳤다. 하위 호환성은 매우 중요한 요소였고, API는 점진적으로 개선되어 왔다. 그렇게 30년 전에 설계된 API 구조가 오늘날 우리가 소프트웨어를 작성하는 방식에도 여전히 영향을 미치고 있다. &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by5giS/dJMcacB9I07/7PKhJHEJB1NIzJAvvREeT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by5giS/dJMcacB9I07/7PKhJHEJB1NIzJAvvREeT1/img.png&quot; data-alt=&quot;3dFX Voodoo 2 12MB (1998) : 각 프로세서와 그에 연결된 전용 메모리 칩(프로세서당 1MB 칩 4개) 사이의 개별 배선이 뚜렷하게 보인다. 이미지 &amp;amp;copy; TechPowerUp.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by5giS/dJMcacB9I07/7PKhJHEJB1NIzJAvvREeT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby5giS%2FdJMcacB9I07%2F7PKhJHEJB1NIzJAvvREeT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;352&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;3dFX Voodoo 2 12MB (1998) : 각 프로세서와 그에 연결된 전용 메모리 칩(프로세서당 1MB 칩 4개) 사이의 개별 배선이 뚜렷하게 보인다. 이미지 &amp;copy; TechPowerUp.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nvidia의 GeForce 256은 &amp;ldquo;GPU&amp;rdquo;라는 용어를 처음 사용했다. 이 칩은 래스터라이저에 더해 지오메트리 프로세서를 포함하고 있었다. 지오메트리 프로세서, 래스터라이저, 텍스처 샘플링 유닛은 모두 하나의 다이에 통합되어 메모리를 공유했다. DirectX 7은 렌더 타깃 텍스처와 유니폼 상수라는 두 가지 새로운 개념을 도입했다. 멀티패스 렌더링이 가능해지면서 텍스처 샘플러가 래스터라이저의 출력을 읽을 수 있게 되었고, 이는 3dFX Voodoo 2의 분리된 메모리 구조를 무력화했다. &lt;br /&gt;&lt;br /&gt;지오메트리 프로세서 API는 변환 행렬(float4x4), 광원 위치, 색상(float4) 등을 위한 유니폼 데이터 입력을 제공했다. GPU 구현은 제조사마다 달랐으며, 많은 경우 지오메트리 엔진 내부에 소규모 상수 메모리 블록을 포함하는 방식을 택했다. 하지만 이것만이 유일한 방식은 아니었다. OpenGL API에서는 각 셰이더가 자체적인 영속 유니폼을 가졌다. 이 설계 덕분에 드라이버가 상수를 셰이더 명령 스트림에 직접 삽입할 수 있었는데, 이러한 API 특성은 오늘날 OpenGL 4.6과 ES 3.2에도 여전히 남아 있다. &lt;br /&gt;&lt;br /&gt;당시 GPU에는 범용 읽기/쓰기 캐시가 존재하지 않았다. 래스터라이저는 블렌딩과 깊이 버퍼링을 위한 화면 지역 캐시를 갖고 있었고, 텍스처 샘플러는 선형 보간된 정점 UV를 기반으로 데이터 프리패칭을 수행했다. DirectX 8의 셰이더 모델 1.0(SM 1.0)에서 셰이더가 도입되었을 때, 픽셀 셰이더 단계는 텍스처 UV를 계산하는 기능을 지원하지 않았다. UV는 정점 단위에서 계산되어 하드웨어에 의해 보간된 뒤, 텍스처 샘플러로 직접 전달되었다. &lt;br /&gt;&lt;br /&gt;DirectX 9는 셰이더 명령 수 제한을 크게 늘렸지만, 셰이더 모델 2.0은 새로운 데이터 경로를 노출하지는 않았다. 버텍스 셰이더와 픽셀 셰이더는 여전히 1:1 입력-출력 구조로 동작했으며, 사용자는 정점 위치와 속성의 변환 수학, 그리고 픽셀 색상만을 커스터마이즈할 수 있었다. 프로그래머블 로드/스토어는 지원되지 않았다. 고정 기능 입력 블록(버텍스 페치, 유니폼/상수 메모리, 텍스처 샘플러)은 계속 유지되었다. 버텍스 셰이더는 별도의 실행 유닛이었으며, 상수 인덱싱(float4 배열로 제한됨) 같은 새로운 기능을 얻었지만 여전히 텍스처 샘플링은 지원하지 않았다. &lt;br /&gt;&lt;br /&gt;DirectX 9 셰이더 모델 3.0은 명령 수 제한을 65,536으로 늘려, 사람이 셰이더 어셈블리를 직접 작성하고 유지하기 어렵게 만들었다. 이에 따라 고수준 셰이딩 언어가 등장했다. HLSL(2002)과 GLSL(2002~2004)이다. 이 언어들은 1:1 요소 단위 변환 설계를 계승했다. 각 셰이더 인보케이션은 하나의 데이터 요소(정점 또는 픽셀)에 대해 동작했다. 이러한 프레임워크식 셰이더 설계는 이후 그래픽스 API 설계에 큰 영향을 미쳤다. 당시에는 하드웨어 차이를 추상화하는 좋은 방법이었지만, 오늘날에는 확장성 측면에서 한계를 드러내고 있다. &lt;br /&gt;&lt;br /&gt;DirectX 11은 데이터 모델 측면에서 큰 전환점이었다. 컴퓨트 셰이더, 범용 읽기/쓰기 버퍼, 간접 드로우를 지원하기 시작하면서 GPU가 스스로 작업을 생성하고 처리할 수 있게 되었다. 범용 버퍼의 도입으로 셰이더는 프로그래머블 메모리 위치에 접근하고 수정할 수 있게 되었고, 이에 따라 하드웨어 벤더들은 범용 캐시 계층을 구현해야 했다. 셰이더는 더 이상 단순한 1:1 데이터 변환에 머물지 않게 되었고, 특수화된 고정 데이터 경로의 시대가 끝났다. GPU 하드웨어는 점차 범용 SIMD 설계로 이동했다. 이제 SIMD 유닛은 버텍스, 픽셀, 지오메트리, 헐, 도메인, 컴퓨트 등 모든 셰이더 유형을 실행한다. 오늘날 프레임워크에는 16개의 서로 다른 셰이더 엔트리 포인트가 존재한다. 이는 API 표면을 크게 늘리고 조합을 어렵게 만든다. 그 결과 GLSL과 HLSL은 여전히 활발한 라이브러리 생태계를 갖추지 못하고 있다. &lt;br /&gt;&lt;br /&gt;DirectX 11에는 하드웨어 데이터 경로의 특수성을 반영한 다양한 버퍼 유형이 존재했다. typed SRV &amp;amp; UAV, byte address SRV &amp;amp; UAV, structured SRV &amp;amp; UAV, append &amp;amp; consume(카운터 포함), constant, vertex, index 버퍼 등 일종의 &amp;ldquo;버퍼 동물원&amp;rdquo;이었다. 텍스처와 마찬가지로 DirectX의 버퍼는 불투명 디스크립터를 사용한다. 디스크립터는 하드웨어에 특화된(보통 128~256비트) 데이터 블록으로, 리소스의 크기, 포맷, 속성, GPU 메모리 주소를 인코딩한다. DirectX 11 GPU는 버퍼 로드(gather) 연산에 텍스처 샘플러를 활용했다. 샘플러는 타입 변환 하드웨어와 소형 읽기 전용 캐시를 이미 갖추고 있었기 때문이다. Typed 버퍼는 텍스처와 동일한 포맷을 지원했고, DirectX는 텍스처와 버퍼 모두에 동일한 SRV(Shader Resource View) 추상화를 사용했다. &lt;br /&gt;&lt;br /&gt;불투명 디스크립터를 사용한다는 것은 버퍼 포맷이 셰이더 컴파일 시점에 알려지지 않는다는 의미다. 읽기 전용 버퍼에서는 샘플러가 이를 처리했기 때문에 문제가 크지 않았다. 그러나 읽기/쓰기 버퍼(UAV)는 초기에는 32비트 및 128비트(vec4) 타입으로 제한되었다. 이후 API와 하드웨어 개정으로 typed UAV 로드의 제약이 완화되었지만, 근본적인 문제는 남아 있었다. 디스크립터는 간접 참조(포인터 포함)를 요구하고, 데이터 타입이 런타임에만 알려지므로 컴파일러 최적화가 제한되며, 포맷 변환 하드웨어는 지연(latency)을 추가하고, 로드 시 확장(expand at load)은 레지스터 점유 시간을 늘리며, 디스크립터 관리는 CPU 드라이버 복잡성을 증가시키고, API 자체도 지나치게 복잡하다(열 가지 버퍼 유형). &lt;br /&gt;&lt;br /&gt;DirectX 11에서 structured buffer는 사용자 정의 struct 타입을 허용한 유일한 버퍼였다. 다른 버퍼 유형은 단순한 스칼라/벡터 요소의 균질 배열이었다. 하지만 structured buffer는 다른 버퍼 유형과 레이아웃 호환이 되지 않았다. structured buffer 뷰를 typed buffer, byte address buffer, vertex/index buffer에 적용할 수 없었다. 그 이유는 structured buffer가 구형 vec4 아키텍처에 최적화된 AoSoA 스위즐 방식을 내부적으로 사용했기 때문이다. 이러한 하드웨어 특화 최적화는 structured buffer의 활용성을 제한했다. &lt;br /&gt;&lt;br /&gt;DirectX 12는 모든 버퍼를 선형 메모리 구조로 만들어 서로 호환되도록 했다. SM 6.2는 byte address buffer에 대해 load&amp;lt;T&amp;gt; 문법을 추가해 임의 오프셋에서 구조체를 깔끔하게 로드할 수 있게 했다. 하지만 하위 호환성 때문에 기존 버퍼 유형은 여전히 유지되고 있으며, 모든 버퍼는 여전히 불투명 디스크립터를 사용한다. HLSL은 여전히 64비트 GPU 포인터를 지원하지 않는다. 반면 Nvidia CUDA(2007)는 처음부터 64비트 포인터에 전적으로 의존했지만, 초기에는 학술 분야에 주로 사용되었다. 오늘날 CUDA는 AI 분야의 선도 플랫폼이 되었고, 하드웨어 설계에도 큰 영향을 미치고 있다. &lt;br /&gt;&lt;br /&gt;DirectX 12 출시 당시 16비트 레지스터 및 16비트 연산 지원은 혼란스러웠다. Microsoft는 DirectX 12를 Windows 7에 백포트하지 않는 결정을 내렸고, Windows 8용 셰이더 바이너리는 16비트 타입을 지원했지만 대부분의 게이머는 여전히 Windows 7을 사용했다. 개발자들은 두 종류의 셰이더를 배포하고 싶어하지 않았다. OpenGL의 lowp/mediump 명세도 혼란스러웠고, 비트 깊이가 명확히 표준화되지 않았다. mediump는 모바일 게임에서 인기 있는 최적화였지만, 많은 PC 드라이버는 이를 무시했다. PS4 Pro가 2016년에 double-rate fp16을 지원하기 전까지 AAA 게임은 16비트 연산을 거의 사용하지 않았다. &lt;br /&gt;&lt;br /&gt;AI, 레이 트레이싱, GPU 기반 렌더링이 부상하면서 GPU 벤더들은 원시 데이터 로드 경로를 최적화하고 더 크고 빠른 범용 캐시를 제공하는 데 집중하기 시작했다. 텍스처 샘플러를 통한 로드는 현대 셰이더에서 흔한 종속적 로드 체인에 과도한 지연을 초래했다. 하드웨어는 8비트, 16비트, 64비트 타입과 포인터를 네이티브로 지원하게 되었다. &lt;br /&gt;&lt;br /&gt;대부분의 벤더는 고정 기능 버텍스 페치 하드웨어를 제거하고, 대신 버텍스 셰이더에서 표준 raw load 명령을 사용하도록 했다. 완전한 프로그래머블 버텍스 페치는 클러스터 기반 GPU 주도 렌더링과 같은 새로운 알고리즘을 가능하게 했다. 고정 기능 하드웨어에 쓰이던 트랜지스터 예산은 다른 곳에 활용될 수 있었다. &lt;br /&gt;&lt;br /&gt;메시 셰이더는 래스터라이저 진화의 정점이라 할 수 있다. 인덱스 중복 제거 하드웨어와 포스트 트랜스폼 캐시를 제거하고, 모든 입력을 원시 메모리로 취급한다. 사용자는 메시를 내부적으로 정점을 공유하는 독립적인 메시릿(meshlet)으로 나누어야 하며, 이는 보통 오프라인에서 수행된다. GPU는 드로우 호출마다 병렬 인덱스 중복 제거를 수행할 필요가 없어 전력과 트랜지스터를 절약한다. 오늘날 Nvidia 매출의 90%가 AI에서 나오고 게임은 10%에 불과하며, 레이 트레이싱도 성장하고 있다는 점을 고려하면, 고정 기능 지오메트리 하드웨어가 최소 수준으로 축소되고 드라이버가 자동으로 버텍스 셰이더를 메시 셰이더로 변환하는 시점이 머지않았을 가능성이 크다. &lt;br /&gt;&lt;br /&gt;모바일 GPU는 타일 기반 렌더러다. 타일러는 삼각형을 작은 타일(보통 16x16~64x64 픽셀)로 분할한다. 메시 셰이더는 이 목적에는 너무 거칠다. 메시릿을 작은 타일로 다시 분할하면 과도한 지오메트리 오버셰이딩이 발생한다. 따라서 명확한 수렴 경로는 없으며, 여전히 버텍스 셰이더 경로를 지원해야 한다. &lt;br /&gt;&lt;br /&gt;DirectX 12.0, Vulkan 1.0, Metal 1.0이 등장한 10년 전에는 GPU 하드웨어가 바인드리스 리소스를 널리 지원하지 않았다. API는 하드웨어 차이를 추상화하기 위해 복잡한 바인딩 모델을 도입했다. DirectX는 스테이지당 최대 128개 리소스 인덱싱을 허용했지만, Vulkan과 Metal은 초기에는 디스크립터 인덱싱을 지원하지 않았다. 개발자들은 텍스처 아틀라스 패킹이나 메시 병합 같은 전통적 우회 기법을 계속 사용해야 했다. 지난 10년 동안 GPU 하드웨어는 크게 발전했고, 범용 바인드리스 SIMD 설계로 수렴했다. &lt;br /&gt;&lt;br /&gt;이제 현대적인 바인드리스 하드웨어만을 전제로 그래픽 API와 셰이더 언어를 설계한다면 얼마나 단순해질 수 있을지 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Modern GPU memory management&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;b8a0f844-b23e-4195-91d9-7519741cba13&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;345&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;메모리 관리부터 살펴보자. 과거의 그래픽스 API는 GPU 메모리 관리를 완전히 추상화했다. 이는 옛 GPU들이 분리된 메모리 구조를 갖거나, 캐시 일관성 문제가 있는 특수 데이터 경로를 사용했기 때문에 필요한 설계였다. 10년 전 DirectX 12와 Vulkan이 등장했을 무렵에는 GPU 하드웨어가 충분히 성숙해져, 사용자에게 배치 힙(placement heap)을 노출할 수 있게 되었다. 콘솔은 이미 여러 세대 전부터 메모리를 직접 노출해왔고, 개발자들도 PC와 모바일에서 비슷한 유연성을 요구했다. Apple은 Vulkan과 DirectX 12가 나온 지 4년 뒤 Metal 2에서 배치 힙을 도입했다.&lt;br /&gt;&lt;br /&gt;현대 API에서는 GPU 드라이버가 제공하는 메모리 유형을 파악하기 위해 사용자가 힙 타입을 열거해야 한다. 큰 덩어리로 메모리를 미리 할당하고 사용자 공간 할당자(suballocator)로 나누어 쓰는 것은 좋은 관행이다. 그러나 Vulkan에는 설계상의 문제가 있다. 먼저 텍스처나 버퍼 객체를 생성한 뒤에야, 해당 리소스와 호환되는 힙 타입을 질의할 수 있다. 이는 사용자를 지연 할당(lazy allocation) 패턴으로 몰아넣으며, 런타임에서 성능 끊김이나 메모리 급증을 유발할 수 있다. 또한 GPU 메모리 할당을 크로스 플랫폼 라이브러리로 감싸기 어렵게 만든다. 예를 들어 AMD VMA는 Vulkan 전용 버퍼/텍스처 객체를 생성하는 동시에 메모리 할당 까지 수행한다. 우리는 이 두 관심사를 완전히 분리하고자 한다. &lt;br /&gt;&lt;br /&gt;오늘날 CPU는 GPU 메모리를 완전히 가시적으로 접근할 수 있다. 통합 GPU는 UMA를 사용하고, 최신 외장 GPU는 PCIe Resizable BAR를 지원한다. 전체 GPU 힙을 매핑할 수 있다. Vulkan의 힙 API는 자연스럽게 CPU 매핑 GPU 힙을 지원하며, DirectX 12도 2023년에 HEAP_TYPE_GPU_UPLOAD를 통해 이를 지원하게 되었다. &lt;br /&gt;&lt;br /&gt;CUDA는 GPU 메모리 할당에 대해 단순한 설계를 갖는다. GPU malloc API는 크기를 입력받아 CPU에서 매핑된 포인터를 반환하고, GPU free API는 해당 메모리를 해제한다. CUDA는 CPU 매핑 GPU 메모리를 지원하지 않는다. GPU는 PCIe 버스를 통해 CPU 메모리를 읽는다. CUDA는 GPU 메모리 할당도 지원하지만, 이 메모리는 CPU가 직접 쓸 수 없다. &lt;br /&gt;&lt;br /&gt;우리는 CUDA의 malloc 설계와 CPU 매핑 GPU 메모리(UMA/ReBAR)를 결합한다. 이는 양쪽의 장점을 취한 방식이다. 데이터는 CPU가 쓰기에도 빠르고 GPU가 읽기에도 빠르며, 동시에 깔끔하고 사용하기 쉬운 설계를 유지할 수 있다. &lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Allocate&amp;nbsp;GPU&amp;nbsp;memory&amp;nbsp;for&amp;nbsp;array&amp;nbsp;of&amp;nbsp;1024&amp;nbsp;uint32&lt;/span&gt;&lt;br /&gt;uint32 * numbers = gpuMalloc(1024 * sizeof(uint32));&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Directly&amp;nbsp;initialize&amp;nbsp;(CPU&amp;nbsp;mapped&amp;nbsp;GPU&amp;nbsp;pointer)&lt;/span&gt;&lt;br /&gt;for&amp;nbsp;(int&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;1024;&amp;nbsp;i++)&amp;nbsp;numbers[i]&amp;nbsp;=&amp;nbsp;random();&lt;br /&gt;&lt;br /&gt;gpuFree(numbers);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;345&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;기본 gpuMalloc 정렬(alignment)은 16바이트(vec4 정렬)이다. 더 큰 정렬이 필요하면 gpuMalloc(size, alignment) 오버로드를 사용하면 된다. 예제 코드에서는 gpuMalloc&amp;lt;T&amp;gt; 래퍼를 사용해 gpuMalloc(elements * sizeof(T), alignof(T)) 형태로 호출한다. &lt;br /&gt;&lt;br /&gt;GPU 메모리에 데이터를 직접 쓰는 방식은 드로우 인자, 유니폼, 디스크립터 같은 작은 데이터에 최적이다. 그러나 큰 영속 데이터의 경우에는 여전히 복사(copy) 연산을 수행하는 것이 바람직하다. GPU는 캐시 지역성을 개선하기 위해 텍스처를 Morton-order와 유사한 스위즐 레이아웃으로 저장한다. DirectX 11.3과 12는 이 스위즐 레이아웃을 표준화하려 했지만, 모든 GPU 제조사를 설득하지는 못했다. 일반적으로 텍스처 스위즐은 드라이버가 제공하는 복사 명령을 통해 수행된다. 이 복사 명령은 CPU 매핑 &amp;ldquo;업로드&amp;rdquo; 힙에서 선형 텍스처 데이터를 읽어, 프라이빗 GPU 힙의 스위즐 레이아웃으로 기록한다. &lt;br /&gt;&lt;br /&gt;모든 최신 GPU는 무손실 델타 컬러 압축(DCC)도 지원한다. 최신 GPU의 복사 엔진은 DCC 압축과 해제를 처리할 수 있다. DCC와 Morton 스위즐은 텍스처를 프라이빗 GPU 힙으로 복사하려는 주요 이유다. 최근에는 버퍼 데이터에 대해서도 범용 무손실 메모리 압축이 추가되었다. 하지만 메모리 힙이 CPU 매핑 상태라면, CPU가 해당 압축 형식을 이해하지 못하기 때문에 GPU는 벤더별 무손실 압축을 활성화할 수 없다. 따라서 데이터를 압축하려면 복사 명령을 사용해야 한다. &lt;br /&gt;&lt;br /&gt;프라이빗 GPU 메모리를 지원하려면 gpuMalloc 함수에 메모리 타입 파라미터가 필요하다. 기본 메모리 타입은 CPU 매핑 GPU 메모리(write-combined CPU 접근)여야 한다. 이는 GPU가 읽기에 빠르고, CPU도 일반 포인터처럼 직접 쓸 수 있다. GPU 전용 메모리는 텍스처와 대형 GPU 전용 버퍼에 사용된다. CPU는 이 GPU 포인터에 직접 쓸 수 없다. 사용자는 먼저 CPU 매핑 GPU 메모리에 데이터를 작성한 뒤, 복사 명령을 발행해 데이터를 최적의 압축 형식으로 변환한다. 최신 텍스처 샘플러와 디스플레이 엔진은 압축된 GPU 데이터를 직접 읽을 수 있으므로, 이후 별도의 데이터 레이아웃 변환은 필요하지 않다(&amp;ldquo;Modern barriers&amp;rdquo; 장 참고). 업로드된 데이터는 즉시 사용 가능하다. &lt;br /&gt;&lt;br /&gt;GPU 포인터에는 두 가지 유형이 있다. 하나는 CPU 매핑 가상 주소이고, 다른 하나는 GPU 가상 주소다. GPU는 GPU 주소만 역참조할 수 있으므로, GPU 데이터 구조 내의 모든 포인터는 GPU 주소를 사용해야 한다. CPU 매핑 주소는 CPU가 데이터를 쓸 때만 사용된다. CUDA는 CPU 매핑 주소를 GPU 주소로 변환하는 API(cudaHostGetDevicePointer)를 제공한다. Metal 4의 버퍼 객체는 .contents(CPU 매핑 주소)와 .gpuAddress(GPU 주소) 두 가지 접근자를 제공한다. gpuMalloc API는 Metal처럼 관리 객체 핸들을 반환하는 대신 포인터를 반환하므로, 여기서는 CUDA 방식(gpuHostToDevicePointer)을 선택한다. 이 주소 변환 호출은 비용이 없지 않다. 드라이버는 이를 해시 맵으로 구현할 가능성이 높으며(기본 주소 외의 변환이 필요하면 트리 구조가 필요할 수도 있다). 이상적으로는 할당당 한 번만 주소 변환을 수행하고, 사용자 공간 구조체에 (void *cpu, void *gpu) 형태로 캐시하는 것이 좋다. 내가 구현한 사용자 공간 GPUBumpAllocator도 이 방식을 사용한다(전체 구현은 부록 참고). &lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Load&amp;nbsp;a&amp;nbsp;mesh&amp;nbsp;using&amp;nbsp;a&amp;nbsp;3rd&amp;nbsp;party&amp;nbsp;library&lt;/span&gt;&lt;br /&gt;auto&amp;nbsp;mesh&amp;nbsp;=&amp;nbsp;createMesh(&quot;mesh.obj&quot;);&lt;br /&gt;auto&amp;nbsp;upload&amp;nbsp;=&amp;nbsp;uploadBumpAllocator.allocate(mesh.byteSize);&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Custom&amp;nbsp;bump&amp;nbsp;allocator&amp;nbsp;(wraps&amp;nbsp;a&amp;nbsp;gpuMalloc&amp;nbsp;ptr)&lt;/span&gt;&lt;br /&gt;mesh.load(upload.cpu);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Allocate&amp;nbsp;GPU-only&amp;nbsp;memory&amp;nbsp;and&amp;nbsp;copy&amp;nbsp;into&amp;nbsp;it&lt;/span&gt;&lt;br /&gt;void*&amp;nbsp;meshGpu&amp;nbsp;=&amp;nbsp;gpuMalloc(mesh.byteSize,&amp;nbsp;MEMORY_GPU);&lt;br /&gt;gpuMemCpy(commandBuffer,&amp;nbsp;meshGpu,&amp;nbsp;upload.gpu);&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;ff45367a-c8d3-4a0f-8a12-93e98f842836&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;374&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;Vulkan에는 최근 &lt;b&gt;VK_EXT_host_image_copy&lt;/b&gt;라는 새로운 확장이 추가되었다. 이 확장은 드라이버가 CPU에서 GPU로 직접 이미지 복사를 수행하도록 하며, 이 과정에서 하드웨어 특화 텍스처 스위즐을 CPU에서 처리한다. 현재 이 확장은 UMA 아키텍처에서만 지원되지만, PCIe ReBAR 환경에서도 기술적으로 불가능한 것은 아니다. 다만 이 API는 DCC를 지원하지 않는다. CPU에서 DCC 압축을 수행하는 것은 비용이 너무 크기 때문이다. 이 확장은 주로 블록 압축 텍스처에 유용한데, 블록 압축 텍스처는 DCC가 필요하지 않기 때문이다. 따라서 이 방식은 하드웨어 복사를 통한 GPU 프라이빗 메모리 전송을 완전히 대체할 수는 없다.&lt;br /&gt;&lt;br /&gt;또한 리드백(readback)을 위해 세 번째 메모리 타입, 즉 CPU 캐시드 메모리도 필요하다. 이 메모리 타입은 CPU와의 캐시 일관성 때문에 GPU 쓰기 속도가 느리다. 게임에서는 리드백을 자주 사용하지 않으며, 대표적인 용도는 스크린샷이나 가상 텍스처링 리드백이다. 반면 AI 학습 및 추론과 같은 GPGPU 알고리즘은 CPU와 GPU 간의 효율적인 데이터 교환에 크게 의존한다. &lt;br /&gt;&lt;br /&gt;CUDA의 malloc 방식의 단순함과 CPU 매핑 GPU 메모리를 결합하면, 최소한의 API 표면으로도 유연하고 빠른 GPU 메모리 할당 시스템을 만들 수 있다. 이는 최소주의적인 현대 그래픽스 API를 설계하기 위한 훌륭한 출발점이 된다. &lt;/p&gt;
&lt;p data-end=&quot;374&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Modern data&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CUDA, Metal, OpenCL은 64비트 포인터 의미론을 지원하는 C/C++ 기반 셰이더 언어를 사용한다. 이러한 언어는 적절히 정렬된 GPU 메모리의 임의 위치로부터 구조체를 로드하고 저장할 수 있다. 넓은 로드(combine), 레지스터 매핑, 비트 추출과 같은 최적화는 컴파일러가 내부적으로 처리한다. 많은 최신 GPU는 레지스터의 8/16비트 부분을 추출하는 무료 명령어 수정자(instruction modifier)를 제공하므로, 컴파일러는 8비트 및 16비트 값을 하나의 레지스터에 패킹할 수 있다. 이는 셰이더 코드를 깔끔하고 효율적으로 유지하는 데 도움이 된다. &lt;br /&gt;&lt;br /&gt;예를 들어 32비트 값 8개로 이루어진 구조체를 로드하면, 컴파일러는 대개 128비트 폭의 로드 두 번(각각 4개 레지스터 채움)으로 변환한다. 이는 로드 명령 수를 4배 줄이는 효과가 있다. 특히 구조체에 8비트 또는 16비트 필드가 포함된 경우, 넓은 로드는 훨씬 빠르다. GPU는 ALU 밀도가 높고 레지스터 파일이 크지만, CPU에 비해 메모리 경로는 상대적으로 느리다. CPU는 보통 두 개의 로드 포트를 통해 매 사이클 로드를 수행할 수 있지만, 최신 GPU에서는 4사이클당 하나의 SIMD 로드가 가능하다. 따라서 넓은 로드 후 셰이더에서 언팩(unpack)하는 방식이 데이터 처리에 가장 효율적인 경우가 많다. &lt;br /&gt;&lt;br /&gt;DirectX 게임에서는 전통적으로 8~16비트의 압축 데이터가 텍셀 버퍼(Buffer&amp;lt;T&amp;gt;)에 저장되어 왔다. 그러나 현대 GPU는 컴퓨트 워크로드에 최적화되어 있다. 현재 원시(raw) 버퍼 로드 명령은 텍셀 버퍼 대비 최대 2배 높은 처리량과 최대 3배 낮은 지연 시간을 제공한다. 텍셀 버퍼는 더 이상 최적의 선택이 아니다. 텍셀 버퍼는 구조체 데이터를 지원하지 않아, 사용자는 데이터를 여러 텍셀 버퍼에 SoA(Structure of Arrays) 형태로 분리해야 한다. 각 텍셀 버퍼는 자체 디스크립터를 갖고 있으며, 데이터 접근 전에 이를 로드해야 한다. 이는 리소스(SGPR, 디스크립터 캐시 슬롯)를 소모하고, 단일 64비트 원시 포인터를 사용하는 것보다 초기 지연을 증가시킨다. 또한 SoA 레이아웃은 비선형 인덱스 조회(예: 머티리얼, 텍스처, 삼각형, 인스턴스, 본 ID)에서 캐시 미스를 크게 증가시킨다. 텍셀 버퍼는 정규화된([0,1] 및 [-1,1]) 타입을 부동소수점 레지스터로 무료 변환해준다는 장점이 있다. ALU 비용은 없지만, 넓은 로드를 지원하지 못하고(로드 결합 불가), 명령이 느린 텍스처 샘플러 경로를 통과한다. 좁은 텍셀 버퍼 로드는 레지스터 사용량도 증가시킨다. 예를 들어 RGBA8_UNORM을 vec4로 로드하면 즉시 4개의 벡터 레지스터가 할당된다. 샘플러 하드웨어는 결국 이 레지스터에 값을 기록한다. 컴파일러는 로드 지연을 숨기기 위해 로드&amp;rarr;사용 간 거리를 최대화하려고 셰이더 초반에 로드 명령을 배치한다. 이렇게 하면 ALU 연산과 겹치게 하여 지연을 숨기고 여러 로드를 중첩시킬 수 있다. 반면 넓은 원시 로드를 사용하면 uint8x4 데이터는 단 하나의 32비트 레지스터만 차지한다. 실제 사용 시점에 8비트 채널을 언팩하면 되므로 레지스터 수명도 훨씬 짧다. 현대 GPU는 언팩 없이도 16비트 레지스터의 상&amp;middot;하위 절반에 직접 접근할 수 있고, 일부는 8비트 접근도 가능하다(예: AMD의 SDWA 수정자). 패킹된 double-rate 연산은 2x16비트 변환 명령을 더 빠르게 수행할 수 있다. 또한 일부 GPU 아키텍처(Nvidia, AMD)는 64비트 포인터 기반 원시 로드를 VRAM에서 직접 그룹 공유 메모리로 수행할 수 있어, 지연 숨김을 위한 레지스터 사용량을 더욱 줄일 수 있다. &amp;nbsp;64비트 포인터를 사용하면, 게임 엔진은 AI 하드웨어 최적화의 이점을 자연스럽게 활용할 수 있다. &lt;br /&gt;&lt;br /&gt;포인터 기반 시스템은 메모리 정렬을 명시적으로 드러낸다. DirectX나 Vulkan에서 버퍼 객체를 할당할 때는 API를 통해 정렬 요구사항을 질의해야 하며, 버퍼 바인딩 오프셋도 올바르게 정렬되어야 한다. Vulkan은 바인딩 오프셋 정렬을 질의하는 API를 제공하고, DirectX는 고정된 정렬 규칙을 갖는다. 이러한 정렬 계약은 저수준 셰이더 컴파일러가 정렬된 4&amp;times;32바이트 폭 로드와 같은 최적 코드를 생성할 수 있게 해준다. 하지만 DirectX의 ByteAddressBuffer 추상화에는 설계상의 결함이 있다. load2, load3, load4 명령은 4바이트 정렬만 요구한다. SM 6.2의 load&amp;lt;T&amp;gt; 역시 요소 단위 정렬만 요구한다(예: half4 = 2, float4 = 4). 일부 GPU 벤더(예: Nvidia)는 ByteAddressBuffer.load4를 네 개의 개별 로드 명령으로 분할해야 한다. 버퍼 추상화가 항상 잘못된 코드 생성(codegen)을 가려주지는 못하며, 잘못된 코드 생성은 수정하기도 어렵다. CUDA나 Metal과 같은 C/C++ 기반 언어에서는 alignas 속성을 통해 구조체 정렬을 명시할 수 있다. 예제 코드의 루트 구조체에는 모두 alignas(16)을 사용한다. &lt;br /&gt;&lt;br /&gt;기본적으로 GPU 쓰기는 동일한 스레드 그룹(= 동일한 컴퓨트 유닛) 내의 스레드에서만 가시적이다. 이는 비일관성(non-coherent) L1 캐시 설계를 가능하게 한다. 그룹 간 가시성은 일반적으로 배리어로 보장한다. 단일 디스패치 내에서 그룹 간 메모리 가시성이 필요하다면, 사용자는 버퍼 바인딩에 [globallycoherent] 속성을 지정한다. 그러면 셰이더 컴파일러는 해당 버퍼 접근에 대해 일관성 있는 로드/스토어 명령을 생성한다. 우리는 버퍼 객체 대신 64비트 포인터를 사용하므로, 명시적인 일관성(coherent) 로드/스토어 명령을 제공한다. 문법은 원자적 로드/스토어와 유사하다. 또한 전체 캐시 계층을 우회하는 비일시적(non-temporal) 로드/스토어 명령도 제공할 수 있다. &lt;br /&gt;&lt;br /&gt;Vulkan은 2019년에 도입된 &lt;b&gt;&lt;a href=&quot;https://docs.vulkan.org/samples/latest/samples/extensions/buffer_device_address/README.html)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;VK_KHR_buffer_device_address extension&lt;/a&gt;&lt;/b&gt;을 통해 64비트 포인터를 지원한다. 이 확장은 모든 GPU 벤더(모바일 포함)에서 널리 지원되지만, Vulkan 1.4의 코어에는 포함되지 않았다. BDA의 주요 문제는 GLSL과 HLSL 셰이더 언어에서 포인터를 지원하지 않는다는 점이다. 사용자는 대신 원시 64비트 정수를 사용해야 한다. 64비트 정수는 구조체로 캐스팅할 수 있으며, 구조체는 별도의 BDA 전용 문법으로 정의된다. 배열 인덱싱을 위해서는 인덱스 주소 계산을 컴파일러가 생성하도록, 배열을 포함하는 별도의 BDA 구조체 타입을 선언해야 한다. 현재 디버깅 지원도 제한적이다. 사용성은 매우 중요하며, HLSL과 GLSL이 포인터를 네이티브로 지원하기 전까지 BDA는 틈새 기능에 머물 것이다. 이는 포인터 지원이 언어의 핵심인 CUDA, OpenCL, Metal과는 대조적이다. 이들 환경에서는 디버깅도 원활하다. &lt;br /&gt;&lt;br /&gt;DirectX 12는 셰이더에서 포인터를 지원하지 않는다. 그 결과 HLSL은 배열을 함수 매개변수로 전달할 수 없다. UBO/SSBO 안에 머티리얼 배열을 두는 것조차 매크로를 동원한 우회가 필요하다. groupshared 메모리 배열을 함수 간에 전달할 수 없기 때문에, prefix sum이나 정렬 같은 재사용 가능한 함수 작성도 사실상 불가능하다. 각 유틸리티 헤더/라이브러리마다 별도의 전역 배열을 선언할 수는 있지만, 컴파일러는 각 배열마다 groupshared 메모리를 따로 할당해 점유율(occupancy)을 낮춘다. groupshared 메모리를 쉽게 별칭(alias) 처리할 방법도 없다. GLSL도 동일한 문제를 가진다. 반면 CUDA나 Metal MSL 같은 포인터 기반 언어에서는 배열과 관련해 이런 제약이 없다. CUDA는 방대한 서드파티 라이브러리 생태계를 갖추고 있으며, 이 생태계는 Nvidia를 세계에서 가장 가치 있는 기업으로 만드는 데 기여했다. 그래픽 셰이딩 언어도 현대적 기준에 맞게 진화해야 한다. 우리에게도 라이브러리 생태계가 필요하다. &lt;br /&gt;&lt;br /&gt;이후 예제에서는 CUDA와 Metal MSL에 가까운 C/C++ 스타일 셰이딩 언어를 사용하되, 그래픽스 관련 요소에는 일부 HLSL 스타일의 시스템 값(SV) 시맨틱을 혼합해 설명할 것이다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Root arguments&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제의 스레딩 API는 일반적으로 스레드 함수에 하나의 64비트 void 포인터만 전달한다. 운영체제는 사용자의 데이터 입력 레이아웃에 관여하지 않는다. 이와 같은 철학을 GPU 커널의 데이터 입력에도 적용해보자. 셰이더 커널은 단 하나의 64비트 포인터를 전달받고, 커널 함수 시그니처에서 이를 원하는 구조체로 캐스팅한다. 개발자는 CPU와 GPU 양쪽에서 동일한 C/C++ 공용 헤더를 사용할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Common&amp;nbsp;header...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Data&lt;br /&gt;{&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Uniform&amp;nbsp;data&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float16x4&amp;nbsp;color;&amp;nbsp;//&amp;nbsp;16-bit&amp;nbsp;float&amp;nbsp;vector&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint16x2&amp;nbsp;offset;&amp;nbsp;//&amp;nbsp;16-bit&amp;nbsp;integer&amp;nbsp;vector&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;uint8*&amp;nbsp;lut;&amp;nbsp;//&amp;nbsp;pointer&amp;nbsp;to&amp;nbsp;8-bit&amp;nbsp;data&amp;nbsp;array&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Pointers&amp;nbsp;to&amp;nbsp;in/out&amp;nbsp;data&amp;nbsp;arrays&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;uint32*&amp;nbsp;input;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32*&amp;nbsp;output;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;CPU&amp;nbsp;code...&lt;/span&gt;&lt;br /&gt;gpuSetPipeline(commandBuffer,&amp;nbsp;computePipeline);&lt;br /&gt;&lt;br /&gt;auto&amp;nbsp;data&amp;nbsp;=&amp;nbsp;myBumpAllocator.allocate&amp;lt;Data&amp;gt;();&amp;nbsp;//&amp;nbsp;Custom&amp;nbsp;bump&amp;nbsp;allocator&amp;nbsp;(wraps&amp;nbsp;gpuMalloc&amp;nbsp;ptr,&amp;nbsp;see&amp;nbsp;appendix)&lt;br /&gt;data.cpu-&amp;gt;color&amp;nbsp;=&amp;nbsp;{1.0f,&amp;nbsp;0.0f,&amp;nbsp;0.0f,&amp;nbsp;1.0f};&lt;br /&gt;data.cpu-&amp;gt;offset&amp;nbsp;=&amp;nbsp;{16,&amp;nbsp;0};&lt;br /&gt;data.cpu-&amp;gt;lut&amp;nbsp;=&amp;nbsp;luts.gpu&amp;nbsp;+&amp;nbsp;64;&amp;nbsp;//&amp;nbsp;GPU&amp;nbsp;pointers&amp;nbsp;support&amp;nbsp;pointer&amp;nbsp;math&amp;nbsp;(no&amp;nbsp;need&amp;nbsp;for&amp;nbsp;offset&amp;nbsp;API)&lt;br /&gt;data.cpu-&amp;gt;input&amp;nbsp;=&amp;nbsp;input.gpu;&lt;br /&gt;data.cpu-&amp;gt;output&amp;nbsp;=&amp;nbsp;output.gpu;&lt;br /&gt;&lt;br /&gt;gpuDispatch(commandBuffer,&amp;nbsp;data.gpu,&amp;nbsp;uvec3(128,&amp;nbsp;1,&amp;nbsp;1));&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;GPU&amp;nbsp;kernel...&lt;/span&gt;&lt;br /&gt;[groupsize&amp;nbsp;=&amp;nbsp;(64,&amp;nbsp;1,&amp;nbsp;1)]&lt;br /&gt;void&amp;nbsp;main(uint32x3&amp;nbsp;threadId&amp;nbsp;:&amp;nbsp;SV_ThreadID,&amp;nbsp;const&amp;nbsp;Data*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;value&amp;nbsp;=&amp;nbsp;data-&amp;gt;input[threadId.x];&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;TODO:&amp;nbsp;Code&amp;nbsp;using&amp;nbsp;color,&amp;nbsp;offset,&amp;nbsp;lut,&amp;nbsp;etc...&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data-&amp;gt;output[threadId.x]&amp;nbsp;=&amp;nbsp;value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 코드에서는 GPU 인자 할당을 위해 단순한 선형 범프 할당자(myBumpAllocator)를 사용한다(구현은 부록 참고). 이 할당자는 { void * cpu, void * gpu } 구조체를 반환한다. CPU 포인터는 영구 매핑된 GPU 메모리에 직접 데이터를 쓰는 데 사용하고, GPU 포인터는 GPU 데이터 구조에 저장하거나 디스패치 명령 인자로 전달할 수 있다. &lt;br /&gt;&lt;br /&gt;대부분의 GPU는 웨이브를 실행하기 직전에 루트 유니폼(64비트 포인터 포함)을 상수 또는 스칼라 레지스터로 미리 로드한다. 이러한 최적화는 여전히 유효하다. 드로우/디스패치 명령은 기본 데이터 포인터를 전달하고, 모든 입력 유니폼(다른 데이터에 대한 포인터 포함)은 이 기본 포인터로부터 작은 고정 오프셋에 위치한다. 셰이더는 사전 컴파일되고, PSO 생성 시 장치별 마이크로코드로 추가 최적화되므로, 드라이버는 레지스터 프리로드나 루트 데이터 최적화를 충분히 수행할 수 있다. 일부 아키텍처에서는 루트 데이터 크기가 제한되어 있으므로, 가장 중요한 데이터는 루트 구조체의 앞부분에 배치하는 것이 좋다. 우리의 루트 구조체는 하드한 크기 제한이 없으며, 나머지 필드에 대해서는 셰이더 컴파일러가 일반적인(스칼라/유니폼) 메모리 로드를 생성한다. 셰이더에 전달되는 루트 데이터 포인터는 const다. 이는 명령 프로세서가 새 웨이브를 시작할 때 데이터를 재사용할 수 있기 때문에, 셰이더가 루트 입력 데이터를 수정해서는 안 되기 때문이다. 출력은 const가 아닌 포인터(예: 예제의 Data::output)를 통해 수행한다. 루트 데이터를 const로 강제하면 GPU 드라이버가 특수한 유니폼 데이터 경로 최적화를 적용할 수 있다. &lt;br /&gt;&lt;br /&gt;그렇다면 별도의 유니폼 버퍼 타입이 필요할까? 현대 셰이더 컴파일러는 자동 유니폼성 분석(uniformity analysis)을 수행한다. 어떤 명령의 모든 입력이 유니폼이면, 그 출력도 유니폼이 된다. 유니폼성은 셰이더 전체로 전파된다. 모든 최신 아키텍처는 스칼라 레지스터/로드(또는 Intel의 SIMD1과 같은 유사 개념)를 갖고 있다. 유니폼성 분석은 벡터 로드를 스칼라 로드로 변환하는 데 사용되며, 이는 레지스터를 절약하고 지연을 줄인다. 이 분석은 버퍼 타입(UBO vs SSBO)에 의존하지 않는다. 다만 리소스는 읽기 전용이어야 한다(그래서 GLSL에서는 SSBO에 readonly를 붙이고, DirectX 12에서는 UAV 대신 SRV를 사용하는 것이 좋다). 또한 컴파일러는 해당 포인터가 별칭(alias)되지 않는다는 것을 증명할 수 있어야 한다. C/C++의 const는 해당 포인터를 통해 수정할 수 없다는 의미일 뿐, 다른 읽기/쓰기 포인터가 같은 메모리를 참조하지 않는다는 보장은 하지 않는다. 이를 위해 C99는 restrict 키워드를 도입했으며, CUDA 커널에서도 자주 사용된다. Metal의 루트 포인터는 기본적으로 no-alias(restrict)이며, Vulkan과 DirectX 12의 버퍼 객체도 동일하다. 우리는 동일한 관례를 채택해 컴파일러가 더 자유롭게 최적화하도록 해야 한다. &lt;br /&gt;&lt;br /&gt;컴파일러가 항상 컴파일 시점에 주소의 유니폼성을 증명할 수 있는 것은 아니다. 현대 GPU는 동적으로 유니폼한 주소 로드를 기회주의적으로 최적화한다. 메모리 컨트롤러가 벡터 로드 명령의 모든 레인이 동일한 주소를 참조한다는 것을 감지하면, SIMD 폭의 gather 대신 단일 레인 로드를 수행하고 그 결과를 모든 레인에 복제한다. 이 최적화는 투명하게 이루어지며, 셰이더 코드 생성이나 레지스터 할당에 영향을 주지 않는다. 동적 유니폼 데이터의 성능 비용은 과거에 비해 훨씬 줄었으며, 특히 최신의 빠른 raw 로드 경로와 결합될 때 그 영향이 작다. &lt;br /&gt;&lt;br /&gt;일부 GPU 벤더(ARM Mali, Qualcomm Adreno)는 유니폼성 분석을 한 단계 더 확장한다. 셰이더 컴파일러가 유니폼 로드와 유니폼 연산을 추출해, 셰이더 실행 전에 스칼라 프리앰블을 실행한다. 유니폼 메모리 로드와 연산은 드로우/디스패치당 한 번만 수행되고, 결과는 특수 하드웨어 상수 레지스터(루트 상수에 사용되는 동일한 레지스터)에 저장된다. &lt;br /&gt;&lt;br /&gt;이러한 모든 최적화를 종합하면, 전통적인 16KB/64KB 유니폼/상수 버퍼 추상화보다 더 나은 유니폼 데이터 처리 방식이 가능하다. 많은 GPU는 여전히 루트 상수, 시스템 값, 프리앰블 실행을 위한 특수 유니폼 레지스터를 갖고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Texture bindings&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;30ce495c-3928-4824-8d87-30b04610926a&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;246&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;이상적으로는 텍스처 디스크립터도 GPU 메모리의 일반 데이터처럼 동작해, 다른 데이터와 함께 구조체 안에 자유롭게 섞어 쓸 수 있어야 한다. 그러나 이러한 수준의 유연성은 아직 모든 최신 GPU에서 보편적으로 지원되지는 않는다. 다행히 지난 10년간 바인드리스 텍스처 샘플러 설계는 점차 수렴해왔으며, 현재는 크게 두 가지 방식만 남아 있다. &lt;b&gt;256비트 원시(raw) 디스크립터 방식&lt;/b&gt;과 &lt;b&gt;인덱스 기반 디스크립터 힙 방식&lt;/b&gt;이다.&lt;br /&gt;&lt;br /&gt;AMD의 원시 디스크립터 방식은 256비트 디스크립터를 GPU 메모리에서 직접 로드해 컴퓨트 유닛의 스칼라 레지스터에 저장한다. 32비트 스칼라 레지스터 8개가 하나의 디스크립터를 구성한다. SIMD 텍스처 샘플 명령 실행 시, 셰이더 코어는 256비트 텍스처 디스크립터와 각 레인의 UV를 샘플러 유닛에 전달한다. 이를 통해 샘플러는 추가적인 간접 참조 없이 텍셀을 주소 지정하고 로드할 수 있다. 단점은 256비트 디스크립터가 많은 레지스터 공간을 차지하며, 샘플 명령마다 다시 전달해야 한다는 점이다. &lt;br /&gt;&lt;br /&gt;인덱스 기반 디스크립터 힙 방식은 32비트 인덱스(구형 Intel iGPU는 20비트)를 사용한다. 32비트 인덱스는 구조체에 저장하기 쉽고, 표준 SIMD 레지스터에 로드하기도 간단하며, 전달 비용도 적다. SIMD 샘플 명령 시 셰이더 코어는 텍스처 인덱스와 각 레인의 UV를 샘플러에 전달한다. 샘플러는 디스크립터 힙에서 디스크립터를 가져온다: 힙 기본 주소 + 텍스처 인덱스 &amp;times; 스트라이드(현대 GPU에서는 256비트). 텍스처 힙의 기본 주소는 Vulkan/Metal에서는 드라이버가 추상화하며, DirectX 12에서는 사용자가 SetDescriptorHeaps로 설정한다. 힙 기본 주소 변경은 구형 하드웨어에서 내부 파이프라인 배리어를 유발할 수 있다. 현대 GPU에서는 샘플 명령 데이터에 64비트 힙 기본 주소가 포함되어 여러 힙을 자연스럽게 샘플링할 수 있다(64비트 기본 주소 + 레인당 32비트 오프셋). 샘플러 유닛은 최초 접근 이후 간접 읽기를 피하기 위해 작은 내부 디스크립터 캐시를 갖는다. 디스크립터 힙이 수정되면 캐시를 무효화해야 한다. &lt;br /&gt;&lt;br /&gt;몇 년 전까지만 해도 AMD의 스칼라 레지스터 기반 디스크립터 방식이 장기적으로 더 유리해 보였다. 스칼라 레지스터는 디스크립터 힙보다 유연해, 디스크립터를 GPU 데이터 구조 안에 직접 포함할 수 있기 때문이다. 하지만 단점도 있다. 최신 GPU 워크로드(예: 레이 트레이싱, Nanite 기반 지연 텍스처링)는 비균일(non-uniform) 텍스처 인덱스를 많이 사용한다. SIMD 웨이브 내에서 텍스처 힙 인덱스가 균일하지 않다. 32비트 인덱스는 4바이트에 불과해 레인마다 전달할 수 있지만, 256비트 디스크립터는 32바이트이므로 레인마다 전체 디스크립터를 전달하는 것은 비현실적이다. Nvidia, Apple, Qualcomm의 최신 GPU는 샘플 명령에서 레인별 디스크립터 인덱스를 지원해 비균일 경우를 효율적으로 처리한다. 필요 시 샘플러 유닛이 내부 루프를 수행한다. 입력/출력은 힙 인덱스의 균일성과 무관하게 한 번만 전달된다. 반면 AMD의 스칼라 레지스터 기반 방식은 비균일 인덱스 처리 시 셰이더 컴파일러가 스칼라화 루프를 생성해야 한다. 이는 추가 ALU 비용을 발생시키고, 샘플러 데이터 송수신을 여러 번(부분 마스크 포함) 수행해야 한다. Nvidia가 레이 트레이싱에서 AMD보다 빠른 이유 중 하나다. ARM과 Intel도 32비트 힙 인덱스를 사용하지만, 최신 아키텍처에서도 레인별 힙 인덱스 모드를 완전히 지원하지는 않아 AMD와 유사한 스칼라화 루프를 생성한다. &lt;br /&gt;&lt;br /&gt;이러한 차이점은 통합된 텍스처 디스크립터 힙 추상화로 감쌀 수 있다. 사실상의 디스크립터 크기는 256비트이며(Apple은 텍스처 디스크립터 192비트 + 샘플러 32비트 분리), 텍스처 힙은 256비트 디스크립터 블롭의 균질 배열로 표현할 수 있다. 인덱싱은 단순하다. DirectX 12 SM 6.6은 이와 유사한 추상화를 제공하지만, 디스크립터 힙 메모리에 대한 CPU 또는 컴퓨트 셰이더의 직접 쓰기를 허용하지 않는다. 디스크립터 생성 및 CPU&amp;rarr;GPU 복사를 위한 별도 API를 사용하며, GPU는 디스크립터를 직접 쓸 수 없다. 오늘날에는 이 API 추상화를 제거하고 CPU와 GPU가 디스크립터 힙에 직접 쓸 수 있도록 할 수 있다. 필요한 것은 256비트(uint64[4]) 하드웨어 특화 디스크립터 블롭을 생성하는 간단한 사용자 공간 드라이버 헬퍼 함수뿐이다. 최신 GPU는 UMA 또는 PCIe ReBAR를 지원하므로 CPU가 GPU 메모리에 직접 디스크립터 블롭을 쓸 수 있다. 사용자는 컴퓨트 셰이더로 디스크립터를 복사하거나 생성할 수도 있다. 셰이더 언어에도 디스크립터 생성 내장 함수가 있어, 하드웨어 특화 uint64x4 디스크립터 블롭을 반환하도록 한다(이는 CPU API와 유사하다). 이러한 접근은 API 복잡성을 크게 줄이면서 DirectX 12의 디스크립터 업데이트 모델보다 더 빠르고 유연하다. &lt;b&gt;&lt;a href=&quot;https://www.khronos.org/blog/vk-ext-descriptor-buffer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Vulkan의 VK_EXT_descriptor_buffer&lt;/a&gt; &lt;/b&gt;확장(2022)은 이 제안과 유사하게 CPU 및 GPU의 직접 쓰기를 허용하며, 대부분의 벤더가 지원하지만 아직 Vulkan 1.4 코어 사양에는 포함되지 않았다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;App&amp;nbsp;startup:&amp;nbsp;Allocate&amp;nbsp;a&amp;nbsp;texture&amp;nbsp;descriptor&amp;nbsp;heap&amp;nbsp;(for&amp;nbsp;example&amp;nbsp;65536&amp;nbsp;descriptors)&lt;/span&gt;&lt;br /&gt;GpuTextureDescriptor&amp;nbsp;*textureHeap&amp;nbsp;=&amp;nbsp;gpuMalloc&amp;lt;GpuTextureDescriptor&amp;gt;(65536);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Load&amp;nbsp;an&amp;nbsp;image&amp;nbsp;using&amp;nbsp;a&amp;nbsp;3rd&amp;nbsp;party&amp;nbsp;library&lt;/span&gt;&lt;br /&gt;auto&amp;nbsp;pngImage&amp;nbsp;=&amp;nbsp;pngLoad(&quot;cat.png&quot;);&lt;br /&gt;auto&amp;nbsp;uploadMemory&amp;nbsp;=&amp;nbsp;uploadBumpAllocator.allocate(pngImage.byteSize);&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;//&amp;nbsp;Custom&amp;nbsp;bump&amp;nbsp;allocator&amp;nbsp;(wraps&amp;nbsp;gpuMalloc&amp;nbsp;ptr)&lt;/span&gt;&lt;br /&gt;pngImage.load(uploadMemory.cpu);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Allocate&amp;nbsp;GPU&amp;nbsp;memory&amp;nbsp;for&amp;nbsp;our&amp;nbsp;texture&amp;nbsp;(optimal&amp;nbsp;layout&amp;nbsp;with&amp;nbsp;metadata)&lt;/span&gt;&lt;br /&gt;GpuTextureDesc&amp;nbsp;textureDesc&amp;nbsp;{&amp;nbsp;.dimensions&amp;nbsp;=&amp;nbsp;pngImage.dimensions,&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RGBA8_UNORM,&amp;nbsp;.usage&amp;nbsp;=&amp;nbsp;SAMPLED&amp;nbsp;};&lt;br /&gt;GpuTextureSizeAlign&amp;nbsp;textureSizeAlign&amp;nbsp;=&amp;nbsp;gpuTextureSizeAlign(textureDesc);&lt;br /&gt;void&amp;nbsp;*texturePtr&amp;nbsp;=&amp;nbsp;gpuMalloc(textureSizeAlign.size,&amp;nbsp;textureSizeAlign.align,&amp;nbsp;MEMORY_GPU);&lt;br /&gt;GpuTexture&amp;nbsp;texture&amp;nbsp;=&amp;nbsp;gpuCreateTexture(textureDesc,&amp;nbsp;texturePtr);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Create&amp;nbsp;a&amp;nbsp;256-bit&amp;nbsp;texture&amp;nbsp;view&amp;nbsp;descriptor&amp;nbsp;and&amp;nbsp;store&amp;nbsp;it&lt;/span&gt;&lt;br /&gt;textureHeap[0]&amp;nbsp;=&amp;nbsp;gpuTextureViewDescriptor(texture,&amp;nbsp;{&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RGBA8_UNORM&amp;nbsp;});&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Batched&amp;nbsp;upload:&amp;nbsp;begin&lt;/span&gt;&lt;br /&gt;GpuCommandBuffer&amp;nbsp;uploadCommandBuffer&amp;nbsp;=&amp;nbsp;gpuStartCommandRecording(queue);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Copy&amp;nbsp;all&amp;nbsp;textures&amp;nbsp;here!&lt;/span&gt;&lt;br /&gt;gpuCopyToTexture(uploadCommandBuffer,&amp;nbsp;texturePtr,&amp;nbsp;uploadMemory.gpu,&amp;nbsp;texture);&lt;br /&gt;//&amp;nbsp;TODO&amp;nbsp;other&amp;nbsp;textures...&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Batched&amp;nbsp;upload:&amp;nbsp;end&lt;/span&gt;&lt;br /&gt;gpuBarrier(uploadCommandBuffer,&amp;nbsp;STAGE_TRANSFER,&amp;nbsp;STAGE_ALL,&amp;nbsp;HAZARD_DESCRIPTORS);&lt;br /&gt;gpuSubmit(queue,&amp;nbsp;{&amp;nbsp;uploadCommandBuffer&amp;nbsp;});&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;Later&amp;nbsp;during&amp;nbsp;rendering...&lt;br /&gt;gpuSetActiveTextureHeapPtr(commandBuffer,&amp;nbsp;gpuHostToDevicePointer(textureHeap));&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론적으로는 CPU 측 텍스처 객체(GpuTexture)를 거의 완전히 제거하는 것도 가능하다. 그러나 아쉽게도 모든 최신 GPU의 삼각형 래스터라이저 유닛은 아직 바인드리스가 아니다. CPU 드라이버는 렌더 타깃, 깊이-스텐실 버퍼의 바인딩, 클리어 및 리졸브 등을 위해 명령 패킷을 준비해야 한다. 이러한 API는 256비트 GPU 텍스처 디스크립터를 사용하지 않는다. 따라서 드라이버 전용의 추가 CPU 데이터가 필요하며, 이는 GpuTexture 객체에 저장된다. &lt;br /&gt;&lt;br /&gt;셰이더에서 텍스처를 참조하는 가장 단순한 방법은 32비트 인덱스를 사용하는 것이다. 하나의 인덱스는 디스크립터 범위의 시작 오프셋을 나타낼 수도 있다. 이는 별도의 API 없이 DirectX 12의 디스크립터 테이블 추상화와 Vulkan의 디스크립터 세트 추상화를 구현할 수 있는 간단한 방법을 제공한다. 또한 빠른 머티리얼 전환(use case)에 대해서도 우아한 해결책을 제시한다. 필요한 것은 머티리얼 데이터 구조체(머티리얼 속성 + 32비트 텍스처 힙 시작 인덱스 포함)를 가리키는 하나의 64비트 GPU 포인터뿐이다.&amp;nbsp;Vulkan의 vkCmdBindDescriptorSets나 DirectX 12의 SetGraphicsRootDescriptorTable은 비교적 빠른 API 호출이지만, 영구 매핑된 GPU 메모리에 단일 64비트 포인터를 쓰는 것만큼 빠르지는 않다. 리소스 바인딩 API 객체를 생성&amp;middot;업데이트&amp;middot;삭제할 필요가 없어지면서 많은 복잡성이 제거된다. 또한 사용자 측에서 디스크립터 세트 해시 맵을 유지할 필요가 없어 CPU 시간도 절약된다. 이는 게임 엔진에서 즉시 모드와 보존 모드 간의 불일치를 해결하기 위해 흔히 사용되던 접근 방식이었다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Common&amp;nbsp;header...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Data&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;srcTextureBase;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;dstTexture;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;invDimensions;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;GPU&amp;nbsp;kernel...&lt;/span&gt;&lt;br /&gt;const&amp;nbsp;Texture&amp;nbsp;textureHeap[];&lt;br /&gt;&lt;br /&gt;[groupsize&amp;nbsp;=&amp;nbsp;(8,&amp;nbsp;8,&amp;nbsp;1)]&lt;br /&gt;void&amp;nbsp;main(uint32x3&amp;nbsp;threadId&amp;nbsp;:&amp;nbsp;SV_ThreadID,&amp;nbsp;const&amp;nbsp;Data*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;textureColor&amp;nbsp;=&amp;nbsp;textureHeap[data-&amp;gt;srcTextureBase&amp;nbsp;+&amp;nbsp;0];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;textureNormal&amp;nbsp;=&amp;nbsp;textureHeap[data-&amp;gt;srcTextureBase&amp;nbsp;+&amp;nbsp;1];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;texturePBR&amp;nbsp;=&amp;nbsp;textureHeap[data-&amp;gt;srcTextureBase&amp;nbsp;+&amp;nbsp;2];&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sampler&amp;nbsp;sampler&amp;nbsp;=&amp;nbsp;{.minFilter&amp;nbsp;=&amp;nbsp;LINEAR,&amp;nbsp;.magFilter&amp;nbsp;=&amp;nbsp;LINEAR};&amp;nbsp;//&amp;nbsp;Embedded&amp;nbsp;sampler&amp;nbsp;(Metal-style)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv&amp;nbsp;=&amp;nbsp;float32x2(threadId.xy)&amp;nbsp;*&amp;nbsp;data-&amp;gt;invDimensions;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;color&amp;nbsp;=&amp;nbsp;sample(textureColor,&amp;nbsp;sampler,&amp;nbsp;uv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;normal&amp;nbsp;=&amp;nbsp;sample(textureNormal,&amp;nbsp;sampler,&amp;nbsp;uv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;pbr&amp;nbsp;=&amp;nbsp;sample(texturePBR,&amp;nbsp;sampler,&amp;nbsp;uv);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;lit&amp;nbsp;=&amp;nbsp;calculateLighting(color,&amp;nbsp;normal,&amp;nbsp;pbr);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TextureRW&amp;nbsp;dstTexture&amp;nbsp;=&amp;nbsp;TextureRW(textureHeap[data-&amp;gt;dstTexture]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dstTexture[threadId.xy]&amp;nbsp;=&amp;nbsp;lit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Metal 4는 텍스처 디스크립터 힙을 자동으로 관리한다. 텍스처 객체에는 .gpuResourceID라는 64비트 힙 인덱스가 있으며(Xcode GPU 디버거에서는 0x3 같은 작은 값으로 보인다), 이를 DirectX SM 6.6이나 Vulkan(디스크립터 버퍼 확장)에서 텍스처 인덱스를 사용하는 것처럼 GPU 구조체에 직접 기록할 수 있다. 하지만 Metal에서는 힙 관리가 자동이기 때문에 사용자가 텍스처 디스크립터를 연속된 범위로 할당할 수 없다. 일반적으로는 첫 번째 텍스처의 32비트 인덱스를 저장하고, 나머지 텍스처의 인덱스를 계산하는 방식을 사용한다(위 코드 예시 참고). Metal은 이를 지원하지 않는다. 사용자는 각 텍스처마다 64비트 핸들을 개별적으로 기록해야 한다. 예를 들어 5개의 텍스처 세트를 참조하려면 Metal에서는 40바이트(5 &amp;times; 64비트)가 필요하지만, Vulkan과 DirectX 12에서는 4바이트(32비트 인덱스 1개)면 충분하다. Apple GPU 하드웨어는 SM 6.6 스타일의 텍스처 힙을 구현할 수 있지만, 제약은 Metal API(소프트웨어) 쪽에 있다. &lt;br /&gt;&lt;br /&gt;텍셀 버퍼는 하위 호환성을 위해 계속 지원할 수 있다. DirectX 12에서는 텍셀 버퍼 디스크립터를 텍스처 디스크립터와 동일한 힙에 저장한다. 텍셀 버퍼는 1D 텍스처(비필터링 tfetch 경로)와 유사하게 동작한다. 주 용도가 하위 호환성이라면, 드라이버 벤더가 이를 내부적으로 raw 메모리 로드 같은 더 빠른 코드 경로로 교체하기 위해 복잡한 우회 구현을 할 필요는 없다. 개인적으로는 드라이버 백그라운드 스레드나 셰이더 교체 방식은 선호하지 않는다. &lt;br /&gt;&lt;br /&gt;비균일 텍스처 인덱스(Non-Uniform texture index)는 GLSL과 HLSL의 NonUniformResourceIndex 표기법과 유사한 방식으로 처리해야 한다. 이는 저수준 GPU 셰이더 컴파일러가 레인별 힙 인덱스를 사용하는 특수 텍스처 명령을 생성하거나, 균일 디스크립터만 지원하는 GPU에서는 스칼라화 루프를 생성하도록 지시한다. 버퍼는 디스크립터가 아니므로 NonUniformResourceIndex가 필요 없다. 단순히 레인당 64비트 포인터를 전달하면 된다. 이는 모든 최신 GPU에서 동작하며, 스칼라화 루프도 필요 없고 복잡성도 없다. 또한 언어는 ptr[index] 형태의 메모리 로드를 네이티브로 지원해야 한다. 여기서 index는 32비트이다. 일부 GPU는 32비트 레인 오프셋을 사용하는 raw 메모리 로드 명령을 지원해 레지스터 압박을 줄일 수 있다. GPU 벤더에게 제안하자면, 아직 지원하지 않는 아키텍처라면 64비트 공유 베이스 + 32비트 레인 오프셋을 사용하는 raw 로드 명령과 16비트 UV(W) 텍스처 로드 명령을 추가해주기 바란다. &lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;const&amp;nbsp;Texture&amp;nbsp;textureHeap[];&lt;br /&gt;&lt;br /&gt;[groupsize&amp;nbsp;=&amp;nbsp;(8,&amp;nbsp;8,&amp;nbsp;1)]&lt;br /&gt;void&amp;nbsp;main(uint32x3&amp;nbsp;threadId&amp;nbsp;:&amp;nbsp;SV_ThreadID,&amp;nbsp;const&amp;nbsp;Data*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Non-uniform&amp;nbsp;&quot;buffer&amp;nbsp;data&quot;&amp;nbsp;is&amp;nbsp;not&amp;nbsp;an&amp;nbsp;issue&amp;nbsp;with&amp;nbsp;pointer&amp;nbsp;semantics!&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Material*&amp;nbsp;material&amp;nbsp;=&amp;nbsp;data-&amp;gt;materialMap[threadId.xy];&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Non-uniform&amp;nbsp;texture&amp;nbsp;heap&amp;nbsp;index&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;textureBase&amp;nbsp;=&amp;nbsp;NonUniformResourceIndex(material.textureBase);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;textureColor&amp;nbsp;=&amp;nbsp;textureHeap[textureBase&amp;nbsp;+&amp;nbsp;0];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;textureNormal&amp;nbsp;=&amp;nbsp;textureHeap[textureBase&amp;nbsp;+&amp;nbsp;1];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;texturePBR&amp;nbsp;=&amp;nbsp;textureHeap[textureBase&amp;nbsp;+&amp;nbsp;2];&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sampler&amp;nbsp;sampler&amp;nbsp;=&amp;nbsp;{.minFilter&amp;nbsp;=&amp;nbsp;LINEAR,&amp;nbsp;.magFilter&amp;nbsp;=&amp;nbsp;LINEAR};&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv&amp;nbsp;=&amp;nbsp;float32x2(threadId.xy)&amp;nbsp;*&amp;nbsp;data-&amp;gt;invDimensions;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;color&amp;nbsp;=&amp;nbsp;sample(textureColor,&amp;nbsp;sampler,&amp;nbsp;uv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;normal&amp;nbsp;=&amp;nbsp;sample(textureNormal,&amp;nbsp;sampler,&amp;nbsp;uv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;pbr&amp;nbsp;=&amp;nbsp;sample(texturePBR,&amp;nbsp;sampler,&amp;nbsp;uv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;color&amp;nbsp;*=&amp;nbsp;material.color;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pbr&amp;nbsp;*=&amp;nbsp;material.pbr;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Rest&amp;nbsp;of&amp;nbsp;the&amp;nbsp;shader&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;11d7b27c-eaf1-4828-8b36-e5ccd14a23d2&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;107&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;현대적인 바인드리스 텍스처링을 사용하면 모든 텍스처 바인딩 API를 제거할 수 있다. 전역적으로 인덱싱 가능한 텍스처 힙을 두면, 모든 텍스처가 모든 셰이더에서 가시적으로 접근 가능해진다. 물론 텍스처 데이터는 여전히 DCC 및 Morton 스위즐을 활성화하기 위해 복사 명령을 통해 GPU 메모리에 로드되어야 한다. 또한 텍스처 디스크립터 생성에는 얇은(thin) GPU 특화 사용자 공간 API가 필요하다.&amp;nbsp;그러나 텍스처 힙 자체는 CPU와 GPU 모두에 원시 GPU 메모리 배열로 직접 노출할 수 있으며, 이를 통해 DirectX 12 SM 6.6과 비교해 텍스처 힙 관련 API 복잡성을 대부분 제거할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;107&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Shader pipelines&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;셰이더의 루트 데이터가 단일 64비트 포인터이고, 텍스처가 단순한 32비트 인덱스라면 셰이더 파이프라인 생성은 매우 단순해진다. 텍스처 바인딩, 버퍼 바인딩, 바인드 그룹(디스크립터 세트, 아규먼트 버퍼), 루트 시그니처를 정의할 필요가 없다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;auto&amp;nbsp;shaderIR&amp;nbsp;=&amp;nbsp;loadFile(&quot;computeShader.ir&quot;);&lt;br /&gt;GpuPipeline&amp;nbsp;computePipeline&amp;nbsp;=&amp;nbsp;gpuCreateComputePipeline(shaderIR);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;107&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;DirectX 12와 Vulkan은 루트 시그니처, 푸시 디스크립터, 푸시 상수, 디스크립터 세트 등을 바인딩하고 설정하기 위해 복잡한 API를 사용한다. 하지만 현대 GPU 드라이버의 본질적인 동작은 GPU 메모리에 하나의 구조체를 구성하고, 그 포인터를 커맨드 프로세서에 전달하는 것에 가깝다. 우리는 이러한 API 복잡성이 불필요하다는 점을 보였다. 사용자는 루트 구조체를 영구 매핑된 GPU 메모리에 직접 작성하고, 64비트 GPU 포인터를 드로우/디스패치 함수에 그대로 전달하면 된다. 또한 구조체 내부에 64비트 포인터와 32비트 텍스처 힙 인덱스를 포함해 원하는 간접 데이터 레이아웃을 자유롭게 구성할 수 있다. 루트 바인딩 API와 DirectX 12의 복잡한 버퍼 체계는 64비트 포인터로 효율적으로 대체할 수 있다. 이는 셰이더 파이프라인 생성을 획기적으로 단순화하며, 데이터 레이아웃을 별도로 정의할 필요도 없다. 거대한 API 복잡성을 제거하면서 사용자에게 더 많은 유연성을 제공하는 셈이다.&lt;/p&gt;
&lt;p data-end=&quot;107&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Static constants&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vulkan, Metal, WebGPU에는 셰이더 파이프라인 생성 시 고정되는 정적(특수화, specialization) 상수 개념이 있다. 드라이버의 내부 셰이더 컴파일러는 이 상수를 입력 셰이더 IR에 리터럴로 적용하고, 이후 상수 전파 및 데드 코드 제거를 수행한다. 이를 통해 파이프라인 생성 시 동일한 셰이더의 여러 변형을 만들 수 있으며, 모든 셰이더 조합을 오프라인에서 컴파일하는 데 필요한 시간과 저장 공간을 줄일 수 있다. &lt;br /&gt;&lt;br /&gt;Vulkan과 Metal은 특수화 상수와 그 값을 기술하기 위한 별도의 API와 전용 셰이더 문법을 제공한다. 하지만 셰이더 측에서 정의한 상수 구조체와 동일한 C 구조체를 그대로 전달하는 방식이 더 간단하고 바람직하다. 이는 API 표면을 최소화하면서도 중요한 개선을 제공할 수 있다. &lt;br /&gt;&lt;br /&gt;Vulkan의 특수화 상수에는 설계상의 한계가 있다. 특수화 상수는 디스크립터 세트 레이아웃을 변경할 수 없다. 입력과 출력 데이터 레이아웃이 고정된다. 사용자는 모든 가능한 입력/출력을 포함하는 &amp;lsquo;우버 레이아웃&amp;rsquo;을 정의하고 사용하지 않는 디스크립터를 갱신하지 않는 방식으로 우회할 수 있지만, 이는 번거롭고 비효율적이다. 우리가 제안하는 설계에는 이러한 문제가 없다. 상수에 따라 분기하면(반대편 경로는 데드 코드 제거됨) 셰이더 입력 포인터를 다른 구조체로 재해석할 수 있다. C++ 상속 레이아웃을 모방할 수도 있다. 입력 구조체의 앞부분은 공통 레이아웃으로 두고, 특수화된 데이터는 뒤에 배치하는 방식이다. 이를 통해 정적 다형성(static polymorphism)을 깔끔하게 구현할 수 있다. 런타임 성능은 수작업으로 최적화한 셰이더와 동일하다. 특수화 구조체에는 GPU 포인터도 포함할 수 있어, 런타임 메모리 위치를 상수처럼 하드코딩할 수 있다. 이는 간접 참조를 피하게 해주며, 기존 셰이더 언어에서는 불가능했던 방식이다. 과거에는 GPU 벤더가 런타임에 셰이더를 분석해 유사한 교체 최적화를 수행하기 위해 백그라운드 스레드를 사용해야 했고, 이는 CPU 비용과 드라이버 복잡성을 크게 증가시켰다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Common&amp;nbsp;header...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Constants&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int32&amp;nbsp;qualityLevel;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8*&amp;nbsp;blueNoiseLUT;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;CPU&amp;nbsp;code...&lt;/span&gt;&lt;br /&gt;Constants&amp;nbsp;constants&amp;nbsp;{&amp;nbsp;.qualityLevel&amp;nbsp;=&amp;nbsp;2,&amp;nbsp;blueNoiseLUT&amp;nbsp;=&amp;nbsp;blueNoiseLUT.gpu&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;auto&amp;nbsp;shaderIR&amp;nbsp;=&amp;nbsp;loadFile(&quot;computeShader.ir&quot;);&lt;br /&gt;GpuPipeline&amp;nbsp;computePipeline&amp;nbsp;=&amp;nbsp;gpuCreateComputePipeline(shaderIR,&amp;nbsp;&amp;amp;constants);&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;GPU&amp;nbsp;kernel...&lt;br /&gt;[groupsize&amp;nbsp;=&amp;nbsp;(8,&amp;nbsp;8,&amp;nbsp;1)]&lt;br /&gt;void&amp;nbsp;main(uint32x3&amp;nbsp;threadId&amp;nbsp;:&amp;nbsp;SV_ThreadID,&amp;nbsp;const&amp;nbsp;Data*&amp;nbsp;data,&amp;nbsp;const&amp;nbsp;Constants&amp;nbsp;constants)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(constants.qualityLevel&amp;nbsp;==&amp;nbsp;3)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Dead&amp;nbsp;code&amp;nbsp;eliminated&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 셰이더 퍼뮤테이션 지옥&lt;/b&gt;&lt;/span&gt;은 현대 그래픽스에서 가장 큰 문제 중 하나다. 게이머는 끊김(stutter)을 호소하고, 개발자는 오프라인 셰이더 컴파일에 몇 시간이 걸린다고 불평한다. 이 새로운 설계는 사용자에게 더 큰 유연성을 제공한다. 셰이더 내부에서 정적 동작과 동적 동작을 전환할 수 있어, 범용(fallback) 경로와 필요 시 특수화를 쉽게 함께 구현할 수 있다. 이는 셰이더 퍼뮤테이션 수를 줄이고, 파이프라인 생성으로 인한 런타임 정지를 감소시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Barriers and fences&lt;/h2&gt;
&lt;p data-end=&quot;336&quot; data-start=&quot;276&quot; data-ke-size=&quot;size16&quot;&gt;현대 그래픽스 API에서 가장 미움받는 기능은 아마도 배리어일 것이다. 배리어는 두 가지 목적을 가진다 : 생산자&amp;rarr;소비자 실행 의존성을 보장하는 그리고 텍스처를 서로 다른 레이아웃 간에 전환하는 것.&lt;br /&gt;&lt;br /&gt;많은 그래픽스 프로그래머는 GPU 동기화에 대해 잘못된 정신 모델을 가지고 있다. 흔히 GPU 동기화가 개별 텍스처와 버퍼 단위의 세밀한 의존성 추적으로 이루어진다고 믿지만, 실제로 현대 GPU 하드웨어는 개별 리소스 자체에는 크게 관심이 없다. 우리는 사용자 공간에서 각 리소스의 상태와 레이아웃 변화를 정리하느라 많은 CPU 시간을 쓰지만, 현대 GPU 드라이버는 사실상 그 목록을 대부분 무시한다. 추상화와 실제 하드웨어 동작이 일치하지 않는다.&lt;br /&gt;&lt;br /&gt;현대의 바인드리스 아키텍처는 GPU에 많은 자유를 준다. 셰이더는 전역 디스크립터 힙의 어떤 텍스처든, 어떤 64비트 포인터든 쓸 수 있다. CPU는 GPU가 어떤 결정을 내릴지 알 수 없다. 그렇다면 CPU는 어떻게 각 리소스에 대해 전환 배리어를 발행할 수 있을까? 이는 바인드리스 아키텍처와 전통적인 CPU 주도 렌더링 API 사이의 명백한 불일치다. 왜 10년 전 API가 이렇게 설계되었는지 살펴보자.&lt;br /&gt;&lt;br /&gt;AMD의 GCN 아키텍처는 현대 그래픽 API 설계에 큰 영향을 미쳤다. GCN은 비동기 컴퓨트와 바인드리스 텍스처링(스칼라 레지스터에 디스크립터 저장)에서 시대를 앞서갔지만, 델타 컬러 압축(DCC)과 캐시 설계에는 중요한 제약이 있었다. 이 제약은 오늘날 배리어 모델이 복잡해진 이유를 잘 보여준다. GCN은 일관성 있는 마지막 레벨 캐시가 없었다. ROP(래스터 연산, 즉 픽셀 셰이더 출력)는 VRAM에 직접 연결된 특수 비일관성 캐시를 가지고 있었다. 픽셀 셰이더 출력이 다른 셰이더나 샘플러에서 보이도록 하려면, 드라이버는 먼저 ROP 캐시를 메모리에 플러시하고, 그다음 L2 캐시를 무효화해야 했다. 커맨드 프로세서 또한 L2 캐시의 클라이언트가 아니었다. 컴퓨트 셰이더에서 작성한 간접 인자는 L2 캐시를 전체 무효화하고 더티 라인을 VRAM으로 플러시하지 않으면 커맨드 프로세서에 보이지 않았다.&amp;nbsp;GCN 3는 ROP용 델타 컬러 압축(DCC)을 도입했지만, AMD의 텍스처 샘플러는 DCC 압축 텍스처나 압축 깊이 버퍼를 직접 읽을 수 없었다. 드라이버는 내부적으로 디컴프레스 컴퓨트 셰이더를 실행해 압축을 제거해야 했다. 디스플레이 엔진도 DCC 압축 텍스처를 직접 읽을 수 없었다. 렌더 타깃을 샘플링하는 일반적인 경우에는 두 번의 내부 배리어와 모든 캐시 플러시가 필요했다(ROP 완료 대기 &amp;rarr; ROP 캐시 및 L2 플러시 &amp;rarr; 디컴프레스 컴퓨트 실행 &amp;rarr; 컴퓨트 완료 대기).&lt;br /&gt;&lt;br /&gt;AMD의 최신 RDNA 아키텍처는 여러 중요한 개선을 이뤘다. 모든 메모리 연산을 포괄하는 일관성 있는 L2 캐시를 갖추고 있으며, ROP와 커맨드 프로세서도 L2의 클라이언트다. 비일관성 캐시는 컴퓨트 유닛 내부의 작은 L0 캐시와 스칼라 캐시(K$)뿐이다. 이제 배리어는 작은 캐시의 미완료 쓰기를 상위 캐시로 플러시하는 것만으로 충분하다. 드라이버가 L2 캐시를 VRAM으로 플러시할 필요가 없어 배리어가 훨씬 빨라졌다. RDNA의 개선된 디스플레이 엔진은 DCC 압축 텍스처를 직접 읽을 수 있고, L2와 L0 텍스처 캐시 사이에는 (디)컴프레서가 위치한다. 텍스처를 샘플링하기 전에 VRAM에 디컴프레스할 필요가 없어져, 압축/비압축 레이아웃 전환이 필요 없다. 오늘날 데스크톱과 모바일 GPU 벤더들은 비슷한 결론에 도달했다. 병목은 대역폭이다. 리소스를 VRAM에 디코딩하는 데 대역폭을 낭비해서는 안 된다. 레이아웃 전환은 더 이상 필요하지 않다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1327&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBSTHI/dJMcaiPQNfE/ZT7ACygep9Z5zzIFnUaDM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBSTHI/dJMcaiPQNfE/ZT7ACygep9Z5zzIFnUaDM1/img.png&quot; data-alt=&quot;AMD RDNA (2019) : RDNA 아키텍처에서는 캐시 계층, DCC, 디스플레이 엔진이 크게 개선되었다. L2 캐시는 DCC 압축 데이터를 저장하며, (디)컴프레서는 L2와 하위 레벨 캐시 사이에 위치한다. L0(텍스처 캐시)는 압축이 해제된 데이터를 사용한다. (이미지 &amp;amp;copy; AMD)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBSTHI/dJMcaiPQNfE/ZT7ACygep9Z5zzIFnUaDM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBSTHI%2FdJMcaiPQNfE%2FZT7ACygep9Z5zzIFnUaDM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1327&quot; height=&quot;738&quot; data-origin-width=&quot;1327&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AMD RDNA (2019) : RDNA 아키텍처에서는 캐시 계층, DCC, 디스플레이 엔진이 크게 개선되었다. L2 캐시는 DCC 압축 데이터를 저장하며, (디)컴프레서는 L2와 하위 레벨 캐시 사이에 위치한다. L0(텍스처 캐시)는 압축이 해제된 데이터를 사용한다. (이미지 &amp;copy; AMD)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;644&quot; data-start=&quot;146&quot; data-ke-size=&quot;size16&quot;&gt;리소스 목록은 DirectX 12와 Vulkan에서 배리어의 가장 성가신 측면이다. 사용자는 각 리소스의 상태를 개별적으로 추적하고, 각 배리어에 대해 이전 상태와 다음 상태를 그래픽스 API에 알려야 한다. 이는 10년 전 GPU에서는 필요했다. 벤더들이 다양한 디컴프레스 명령을 배리어 API 아래에 숨겨두었기 때문이다. 배리어 명령은 디컴프레스 명령의 역할을 했기 때문에, 어떤 리소스가 디컴프레스가 필요한지 알아야 했다. 오늘날 하드웨어는 텍스처 레이아웃이나 디컴프레스 단계를 필요로 하지 않는다. Vulkan은 최근 VK_KHR_unified_image_layouts 확장(&lt;a href=&quot;https://www.khronos.org/blog/so-long-image-layouts-simplifying-vulkan-synchronisation&quot;&gt;https://www.khronos.org/blog/so-long-image-layouts-simplifying-vulkan-synchronisation&lt;/a&gt;) (2025)을 도입해 배리어 명령에서 이미지 레이아웃 전환을 제거했다. 그러나 여전히 사용자가 개별 텍스처와 버퍼를 나열하도록 요구한다. 왜 그럴까?&lt;br /&gt;&lt;br /&gt;주된 이유는 레거시 API 및 툴링과의 호환성이다. 사람들은 리소스 의존성에 대해 생각하는 방식에 익숙하며, 기존 Vulkan 및 DirectX 12 검증 레이어도 그 방식으로 설계되어 있다. 그러나 GPU가 실행하는 배리어 명령에는 텍스처나 버퍼에 대한 정보가 전혀 없다. 리소스 목록은 오직 드라이버에서만 소비된다.&lt;br /&gt;&lt;br /&gt;현대 드라이버는 사용자의 리소스 목록을 순회하며 플래그 집합을 채운다. 드라이버는 더 이상 리소스 레이아웃이나 마지막 레벨 캐시 일관성을 걱정할 필요는 없지만, 여전히 특정 경우에 플러시해야 하는 작은 비일관성 캐시가 존재한다. 현대 GPU는 대부분의 비일관성 캐시를 모든 배리어에서 자동으로 플러시한다. 예를 들어 AMD의 L0$와 K$(스칼라 캐시)는 항상 플러시된다. 모든 패스가 어떤 출력을 쓰며, 이 출력은 이러한 캐시에 존재하기 때문이다. 모든 쓰기 주소를 세밀하게 추적하는 것은 비용이 너무 크다. 작은 비일관성 캐시는 대개 포함(inclusive) 구조다. 수정된 라인은 상위 캐시 레벨로 플러시된다. 이는 빠르며 VRAM 트래픽을 발생시키지 않는다. 일부 아키텍처에는 자동으로 플러시되지 않는 특수 캐시가 있다. 예: 텍스처 샘플러의 디스크립터 캐시(위 장 참고), 래스터라이저 ROP 캐시 및 HiZ 캐시. 커맨드 프로세서는 웨이브 생성 지연을 줄이기 위해 일반적으로 앞서 실행된다. 셰이더에서 간접 인자를 썼다면, 레이스를 피하기 위해 커맨드 프로세서 프리패처를 멈추도록 GPU에 알려야 한다. GPU는 실제로 컴퓨트 셰이더가 간접 인자 버퍼에 썼는지 알지 못한다. DirectX 12에서는 해당 버퍼를 D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT로 전환하고, Vulkan에서는 소비자 의존성에 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT라는 특별한 단계를 사용한다. 이러한 리소스 전환이나 단계 의존성이 있는 배리어의 경우, 드라이버는 배리어에 커맨드 프로세서 프리패처 정지 플래그를 포함한다.&lt;br /&gt;&lt;br /&gt;현대적인 배리어 설계는 리소스 목록을, 이러한 특수 비일관성 캐시에 어떤 일이 일어나는지를 설명하는 단일 비트필드로 대체한다. 특수한 경우에는 다음이 포함된다: 텍스처 디스크립터 무효화, 드로우 인자 무효화, 깊이 캐시 무효화. 이러한 플래그는 드로우 인자를 생성하거나, 디스크립터 힙에 쓰거나, 컴퓨트 셰이더로 깊이 버퍼에 쓸 때 필요하다. 대부분의 배리어는 특별한 캐시 무효화 플래그가 필요하지 않다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;일부 GPU는 여전히 특수한 경우에 데이터를 디컴프레스해야 한다. 예를 들어 복사 또는 클리어 명령 중에(클리어 색상이 변경된 경우 fast clear eliminate). 복사 및 클리어 명령은 영향을 받는 리소스를 매개변수로 받는다. 필요하다면 드라이버가 데이터를 디코딩하는 데 필요한 조치를 취할 수 있다. 이러한 특수 경우를 위해 배리어에 리소스 목록이 필요하지 않다. 모든 포맷과 사용 플래그가 압축을 지원하는 것은 아니다. 이러한 경우 드라이버는 데이터를 압축되지 않은 상태로 유지하며, 대역폭을 낭비하면서 앞뒤로 전환하지 않는다.&lt;br /&gt;&lt;br /&gt;표준 UAV 배리어(컴퓨트 &amp;rarr; 컴퓨트)는 단순하다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;
&lt;div id=&quot;block-yui_3_17_2_1_1765889087118_569070&quot; data-block-type=&quot;44&quot;&gt;
&lt;div&gt;gpuBarrier(commandBuffer,&amp;nbsp;STAGE_COMPUTE,&amp;nbsp;STAGE_COMPUTE);&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;50&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;텍스처 디스크립터 힙에 쓰기를 하는 경우(드문 경우), 특별한 플래그를 추가해야 한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;gpuBarrier(commandBuffer,&amp;nbsp;STAGE_COMPUTE,&amp;nbsp;STAGE_COMPUTE,&amp;nbsp;HAZARD_DESCRIPTORS);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;래스터라이저 출력과 픽셀 셰이더 사이의 배리어는 오프스크린 렌더 타깃 &amp;rarr; 샘플링에서 흔한 경우다. 우리의 예제는 배리어가 버텍스 셰이더를 막지 않도록 의존 단계가 설정되어 있어, 이전 패스와 버텍스 셰이딩(모바일 GPU에서는 타일 비닝)이 겹쳐 실행될 수 있다. 래스터 출력 단계(또는 그 이후)를 프로듀서로 하는 배리어는 GPU 아키텍처가 필요로 하는 경우 비일관성 ROP 캐시를 자동으로 플러시한다. 이에 대해 별도의 명시적 플래그는 필요하지 않다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;gpuBarrier(commandBuffer,&amp;nbsp;STAGE_RASTER_COLOR_OUT&amp;nbsp;|&amp;nbsp;STAGE_RASTER_DEPTH_OUT,&amp;nbsp;STAGE_PIXEL_SHADER);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;309&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 큐 실행 의존성만 기술한다: 프로듀서 및 컨슈머 단계 마스크. 개별 텍스처와 버퍼 리소스 상태를 추적할 필요가 없어, 현재 DirectX 12 및 Vulkan 설계 대비 많은 복잡성을 제거하고 상당한 CPU 시간을 절약할 수 있다. Metal 2는 이미 현대적인 배리어 설계를 갖고 있으며, 리소스 목록을 사용하지 않는다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;많은 GPU는 커스텀 스크래치패드 메모리를 갖고 있다: 각 컴퓨트 유닛 내부의 그룹 공유 메모리, 타일 메모리, Qualcomm GMEM과 같은 대형 공유 스크래치패드 등이 있다. 이러한 메모리는 드라이버가 자동으로 관리한다. 그룹 공유 메모리와 같은 임시 스크래치패드는 절대 메모리에 저장되지 않는다. 타일 메모리는 타일 래스터라이저에 의해 자동으로 저장된다(store op == store). 유니폼 레지스터는 읽기 전용이며 각 드로우 호출 전에 미리 채워진다. 스크래치패드와 유니폼 레지스터는 캐시 일관성 프로토콜을 갖지 않으며, 배리어와 직접적으로 상호작용하지 않는다.&lt;br /&gt;&lt;br /&gt;현대 GPU는 특정 셰이더 단계가 끝났을 때 메모리에 값을 쓰는 동기화 명령과, 특정 메모리 위치에 값이 나타날 때까지 다음 셰이더 단계가 시작되지 않도록 기다리는 명령(대기에는 선택적 캐시 플러시 의미론 포함)을 지원한다. 이는 배리어를 두 개로 나눈 것과 같다: 프로듀서와 컨슈머. DirectX 12의 스플릿 배리어와 Vulkan의 event&amp;rarr;wait가 이러한 설계의 예다. 배리어를 컨슈머&amp;rarr;프로듀서로 분리하면, 그 사이에 독립적인 작업을 배치해 GPU를 비우지 않고도 실행할 수 있다.&lt;br /&gt;&lt;br /&gt;Vulkan의 event&amp;rarr;wait(DX12 스플릿 배리어 포함)는 거의 사용되지 않는다. 주된 이유는 일반 배리어 자체가 이미 매우 복잡해 개발자들이 추가 복잡성을 피하려 하기 때문이다. 과거에는 스플릿 배리어에 대한 드라이버 지원도 완벽하지 않았다. 리소스 목록을 제거하면 스플릿 배리어는 훨씬 단순해진다. 또한 스플릿 배리어를 타임라인 세마포어와 유사한 의미론으로 만들 수 있다: signal 명령은 단조 증가하는 64비트 값(atomic max)을 메모리에 쓰고, wait 명령은 해당 값이 N 이상(&amp;gt;=)이 될 때까지 기다린다. 이 카운터는 단순한 GPU 메모리 포인터일 뿐, 별도의 영구 API 객체가 필요하지 않다. 이는 훨씬 단순한 event&amp;rarr;wait API를 제공한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;gpuSignalAfter(commandBuffer,&amp;nbsp;STAGE_RASTER_COLOR_OUT,&amp;nbsp;gpuPtr,&amp;nbsp;counter,&amp;nbsp;SIGNAL_ATOMIC_MAX);&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Put&amp;nbsp;independent&amp;nbsp;work&amp;nbsp;here&lt;/span&gt;&lt;br /&gt;gpuWaitBefore(commandBuffer,&amp;nbsp;STAGE_PIXEL_SHADER,&amp;nbsp;gpuPtr,&amp;nbsp;counter++,&amp;nbsp;OP_GREATER_EQUAL);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 API는 기존 VkEvent API보다 훨씬 단순하면서도 더 높은 유연성을 제공한다. 위 예제에서는 타임라인 세마포어 의미론을 구현했지만, 다른 패턴도 구현할 수 있다. 예를 들어 비트마스크를 사용해 여러 프로듀서를 기다리는 방식이다: SIGNAL_ATOMIC_OR로 비트를 설정하고, 특정 마스크의 모든 비트가 설정될 때까지 기다린다(마스크는 gpuWaitBefore 명령의 선택적 매개변수다).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1323&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZjAsX/dJMcaaK6iS9/9EGc2udah0dT9kDkbUI6o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZjAsX/dJMcaaK6iS9/9EGc2udah0dT9kDkbUI6o0/img.png&quot; data-alt=&quot;독립적인 작업을 프로듀서&amp;amp;rarr;컨슈머 사이에 배치하는 연쇄적인 signal&amp;amp;rarr;wait는 GPU 정지를 방지한다. 이미지 &amp;amp;copy; Timothy Lottes.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZjAsX/dJMcaaK6iS9/9EGc2udah0dT9kDkbUI6o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZjAsX%2FdJMcaaK6iS9%2F9EGc2udah0dT9kDkbUI6o0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1323&quot; height=&quot;675&quot; data-origin-width=&quot;1323&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;독립적인 작업을 프로듀서&amp;rarr;컨슈머 사이에 배치하는 연쇄적인 signal&amp;rarr;wait는 GPU 정지를 방지한다. 이미지 &amp;copy; Timothy Lottes.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU&amp;rarr;CPU 동기화는 초기 Vulkan과 Metal에서 다소 혼란스러웠다. 사용자는 제출마다 별도의 펜스 객체를 생성해야 했다. 객체를 재사용하기 위해 N 버퍼링이 일반적인 기법이었다. 이는 위에서 언급한 VkEvent와 유사한 사용성 문제다. DirectX 12는 타임라인 세마포어를 통해 GPU&amp;rarr;CPU 동기화를 깔끔하게 해결한 최초의 API였다. 이후 Vulkan 1.2와 Metal 2도 동일한 설계를 채택했다. 타임라인 세마포어는 단 하나의 64비트 단조 증가 카운터만 필요하다. 이는 많은 엔진이 오늘날까지 사용 중인 이전 Vulkan 및 Metal 펜스 API보다 복잡성을 크게 줄여준다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;#define&amp;nbsp;FRAMES_IN_FLIGHT&amp;nbsp;2&lt;br /&gt;&lt;br /&gt;GpuSemaphore&amp;nbsp;frameSemaphore&amp;nbsp;=&amp;nbsp;gpuCreateSemaphore(0);&lt;br /&gt;uint64&amp;nbsp;nextFrame&amp;nbsp;=&amp;nbsp;1;&lt;br /&gt;&lt;br /&gt;while&amp;nbsp;(running)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(nextFrame&amp;nbsp;&amp;gt;&amp;nbsp;FRAMES_IN_FLIGHT)&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gpuWaitSemaphore(frameSemaphore,&amp;nbsp;nextFrame&amp;nbsp;-&amp;nbsp;FRAMES_IN_FLIGHT);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Render&amp;nbsp;the&amp;nbsp;frame&amp;nbsp;here&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gpuSubmit(queue,&amp;nbsp;{commandBuffer},&amp;nbsp;frameSemaphore,&amp;nbsp;nextFrame++);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;gpuDestroySemaphore(frameSemaphore);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 제안하는 배리어 설계는 DirectX 12와 Vulkan에 비해 큰 개선이다. API 복잡성을 크게 줄인다. 사용자는 더 이상 개별 리소스를 추적할 필요가 없다. 우리의 단순한 해저드 추적은 큐 + 단계(stage) 단위의 세밀도를 가진다. 이는 오늘날 GPU 하드웨어가 실제로 동작하는 방식과 일치한다. 게임 엔진의 그래픽스 백엔드는 단순해질 수 있고, CPU 사이클도 절약된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Command buffers&lt;/h3&gt;
&lt;p data-end=&quot;440&quot; data-start=&quot;238&quot; data-ke-size=&quot;size16&quot;&gt;Vulkan과 DirectX 12는 리소스를 사전 생성하고 재사용하도록 장려하는 방식으로 설계되었다. 초기 Vulkan 예제들은 시작 시 하나의 커맨드 버퍼를 기록하고, 이를 매 프레임 재생했다. 그러나 개발자들은 곧 커맨드 버퍼 재사용이 비현실적이라는 것을 깨달았다. 실제 게임 환경은 동적이며 카메라는 끊임없이 움직인다. 가시 객체 집합(visible object set)도 자주 변경된다.&lt;br /&gt;&lt;br /&gt;게임 엔진들은 사전 기록된 커맨드 버퍼를 사실상 무시했다. Metal과 WebGPU는 일시적(transient) 커맨드 버퍼를 제공한다. 이들은 기록 직전에 생성되고, GPU가 렌더링을 마치면 사라진다. 이는 커맨드 버퍼 관리의 필요성을 제거하고, 동일한 명령을 여러 번 제출하는 것을 방지한다. Vulkan에서도 GPU 벤더들은 원샷(one-shot) 커맨드 버퍼(프레임별 리셋 가능한 커맨드 풀)를 권장한다. 이는 드라이버 내부 메모리 관리(힙 할당자 대신 범프 할당자 사용)를 단순화하기 때문이다. 이러한 모범 사례는 Metal과 WebGPU의 설계와 일치한다. 영속적인 커맨드 버퍼 객체는 제거해도 된다. 그 API 복잡성은 실질적으로 가치 있는 기능을 제공하지 못했다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;
&lt;div id=&quot;block-yui_3_17_2_1_1765889087118_737461&quot; data-block-type=&quot;44&quot;&gt;
&lt;div&gt;while&amp;nbsp;(running)&lt;br /&gt;`&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GpuCommandBuffer&amp;nbsp;commandBuffer&amp;nbsp;=&amp;nbsp;gpuStartCommandRecording(queue);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Render&amp;nbsp;frame&amp;nbsp;here&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Graphics shaders&lt;/h3&gt;
&lt;p data-end=&quot;43&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;가장 뜨거운 질문부터 시작해보자 : 이제 그래픽스 셰이더가 정말로 필요한가?&amp;nbsp;UE5의 Nanite는 64비트 원자 연산을 사용해 픽셀을 찍는 컴퓨트 셰이더를 사용한다. 상위 비트에는 픽셀 깊이를, 하위 비트에는 페이로드를 담는다. atomic-min은 가장 가까운 표면이 남도록 보장한다. 이 기법은 2015년 SIGGRAPH에서 Media Molecule Dreams(Alex Evans)에 의해 처음 발표되었다. 하드웨어 래스터라이저는 여전히 계층적/조기 깊이-스텐실 테스트와 같은 장점을 갖는다. Nanite는 오직 거친 클러스터 컬링에만 의존해야 하며, 그 결과 키트배시된 콘텐츠에서는 추가적인 오버드로우가 발생한다. Ubisoft(필자와 Ulrich Haar)는 2015년 SIGGRAPH에서 이 2패스 클러스터 컬링 알고리즘을 발표했다. Ubisoft는 클러스터 컬링을 하드웨어 래스터라이저와 결합해 더 세밀한 컬링을 구현했다. 오늘날 GPU는 바인드리스이며, 이러한 GPU 주도 워크로드에 훨씬 더 적합하다. 10년 전 Ubisoft는 바인드리스 텍스처링 대신 가상 텍스처링(모든 텍스처를 하나의 아틀라스에 배치)에 의존해야 했다. 오늘날 Nanite, SDF 구면 추적, DDA 보셀 트레이싱 등 많은 컴퓨트 전용 래스터라이저가 존재하지만, 하드웨어 래스터라이저는 여전히 게임에서 삼각형을 렌더링하는 가장 일반적인 기법이다. 따라서 래스터라이제이션 파이프라인을 더 유연하고 사용하기 쉽게 만드는 방법을 논의할 가치가 충분하다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;현대 셰이더 프레임워크는 16개의 셰이더 엔트리 포인트로 확장되었다. 래스터라이제이션용 8개(픽셀, 버텍스, 지오메트리, 헐, 도메인, 패치 상수, 메시, 앰플리피케이션)와 레이 트레이싱용 6개(레이 생성, 미스, 최근접 히트, 애니 히트, 교차, 호출 가능)가 있다. 이에 비해 CUDA는 단 하나의 엔트리 포인트만 가진다: 커널. 이 구조 덕분에 CUDA는 조합 가능하다. CUDA는 건강한 서드파티 라이브러리 생태계를 갖고 있다. 텐서 코어(AI)와 같은 새로운 GPU 하드웨어 블록은 내장 함수(intrinsic)로 노출된다. 그래픽스에서도 처음에는 이런 방식이었다. 텍스처 샘플링이 첫 번째 내장 함수였다. 오늘날 텍스처 샘플링은 완전한 바인드리스이며 드라이버 설정조차 필요 없다. 이것이 개발자들이 선호하는 설계다. 단순하고, 조합 가능하며, 확장 가능하다. &lt;br /&gt;&lt;br /&gt;최근 우리는 더 많은 내장 함수를 얻었다: 인라인 레이 트레이싱과 코어퍼레이티브 매트릭스(DirectX 12의 wave matrix, Metal의 subgroup matrix). 이것이 새로운 방향이 되기를 바란다. 거대한 16개 셰이더 프레임워크를 해체하고, 유연하게 조합 가능한 내장 함수로 대체해야 한다. &lt;br /&gt;&lt;br /&gt;셰이더 프레임워크의 복잡성을 해결하는 것은 매우 방대한 주제다. 이 글의 범위를 유지하기 위해, 오늘은 컴퓨트 셰이더와 래스터 파이프라인만 다루겠다. 다음 글에서는 레이 트레이싱, 셰이더 실행 재정렬(SER), 동적 레지스터 할당 확장, 그리고 Apple의 새로운 L1 캐시 기반 레지스터 파일(다이내믹 캐싱)과 같은 현대적 주제를 포함해 셰이더 프레임워크 단순화에 대해 다룰 예정이다.&lt;/p&gt;
&lt;p data-end=&quot;43&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Raster pipelines&lt;/h2&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;오늘날 관련 있는 래스터 파이프라인은 두 가지다: &lt;b&gt;버텍스+픽셀&lt;/b&gt;과 &lt;b&gt;메시+픽셀&lt;/b&gt;이다. 타일 기반 지연 렌더링(TBDR)을 사용하는 모바일 GPU는 삼각형 단위로 타일 비닝을 수행한다. 타일 크기는 일반적으로 16x16에서 64x64 픽셀 사이이며, 이 때문에 메슐릿(meshlet)은 비닝에 사용하기에는 너무 거친 단위의 프리미티브다. 메슐릿은 레인과 버텍스 간에 명확한 1:1 매핑이 없으며, 선택된 삼각형만을 대상으로 부분적인 메시 셰이더 웨이브를 실행할 간단한 방법도 없다. 이것이 모바일 GPU 벤더들이 Nvidia와 AMD가 설계한 데스크톱 중심 메시 셰이더 API를 적극적으로 채택하지 않은 주요 이유다. 모바일에서는 여전히 버텍스 셰이더가 중요하다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;지오메트리, 헐, 도메인, 패치 상수(테셀레이션) 셰이더는 여기서 다루지 않는다. 그래픽스 커뮤니티는 이들 셰이더 타입을 대체로 실패한 실험으로 본다. 설계상 치명적인 성능 문제가 있다. 관련된 모든 사용 사례에서, 인덱스 버퍼를 생성하는 컴퓨트 프리패스를 실행하는 것이 이들 단계를 능가할 수 있다. 또한 메시 셰이더는 온칩 메모리에 압축된 8비트 인덱스 버퍼를 생성할 수 있어, 이러한 레거시 셰이더 단계와의 성능 격차를 더욱 벌린다.&lt;br /&gt;&lt;br /&gt;우리의 목표는 베이크된 상태를 최소화한 현대적인 PSO 추상화를 구축하는 것이다. Vulkan과 DirectX 12에 대한 주요 비판 중 하나는 파이프라인 퍼뮤테이션 폭증이다. PSO 내부의 상태가 적을수록 파이프라인 퍼뮤테이션도 줄어든다. 개선해야 할 주요 영역은 두 가지다: 그래픽스 셰이더 데이터 바인딩과 래스터라이저 상태다.&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Graphics shader bindings&amp;nbsp;&lt;/h2&gt;
&lt;p data-end=&quot;127&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;버텍스+픽셀 셰이더 파이프라인은 컴퓨트 커널에 비해 몇 가지 추가 입력이 필요하다: 버텍스 버퍼, 인덱스 버퍼, 래스터라이저 상태, 렌더 타깃 뷰, 깊이-스텐실 뷰다. 먼저 셰이더에서 보이는 데이터 바인딩에 대해 논의해보자.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;버텍스 버퍼 바인딩은 쉽게 해결할 수 있다: 그냥 제거하면 된다. 현대 GPU는 빠른 raw 로드 경로를 갖고 있다. 대부분의 GPU 벤더는 이미 여러 세대에 걸쳐 버텍스 페치 하드웨어를 에뮬레이션해왔다. 그들의 저수준 셰이더 컴파일러는 사용자 정의 버텍스 레이아웃을 읽고, 버텍스 셰이더 시작 부분에 적절한 raw 로드 명령을 생성한다.&lt;br /&gt;&lt;br /&gt;버텍스 바인딩 선언은 구조체 메모리 레이아웃을 정의하기 위한 또 하나의 특수한 C/C++ 스타일 API의 예다. 이는 복잡성을 증가시키고, 서로 다른 레이아웃에 대해 여러 PSO 퍼뮤테이션을 컴파일하도록 강제한다. 우리는 버텍스 버퍼를 표준 C/C++ 구조체로 단순히 대체한다. 별도의 API는 필요 없다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;//&amp;nbsp;Common&amp;nbsp;header...&lt;br /&gt;struct&amp;nbsp;Vertex&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8x4&amp;nbsp;normal;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8x4&amp;nbsp;tangent;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint16x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Data&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4x4&amp;nbsp;matrixMVP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;Vertex&amp;nbsp;*vertices;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;CPU&amp;nbsp;code...&lt;br /&gt;gpuSetPipeline(commandBuffer,&amp;nbsp;graphicsPipeline);&lt;br /&gt;&lt;br /&gt;auto&amp;nbsp;data&amp;nbsp;=&amp;nbsp;myBumpAllocator.allocate&amp;lt;Data&amp;gt;();&lt;br /&gt;data.cpu-&amp;gt;matrixMVP&amp;nbsp;=&amp;nbsp;camera.viewProjection&amp;nbsp;*&amp;nbsp;modelMatrix;&lt;br /&gt;data.cpu-&amp;gt;vertices&amp;nbsp;=&amp;nbsp;mesh.vertices;&lt;br /&gt;&lt;br /&gt;gpuDrawIndexed(commandBuffer,&amp;nbsp;data.gpu,&amp;nbsp;mesh.indices,&amp;nbsp;mesh.indexCount);&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;Vertex&amp;nbsp;shader...&lt;br /&gt;struct&amp;nbsp;VertexOut&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;:&amp;nbsp;SV_Position;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float16x4&amp;nbsp;normal;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;VertexOut&amp;nbsp;main(uint32&amp;nbsp;vertexIndex&amp;nbsp;:&amp;nbsp;SV_VertexID,&amp;nbsp;const&amp;nbsp;Data*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Vertex&amp;nbsp;vertex&amp;nbsp;=&amp;nbsp;data-&amp;gt;vertices[vertexIndex];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;=&amp;nbsp;data-&amp;gt;matrixMVP&amp;nbsp;*&amp;nbsp;vertex.position;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;TODO:&amp;nbsp;Normal&amp;nbsp;transform&amp;nbsp;here&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;.position&amp;nbsp;=&amp;nbsp;position,&amp;nbsp;.normal&amp;nbsp;=&amp;nbsp;normal,&amp;nbsp;.uv&amp;nbsp;=&amp;nbsp;vertex.uv&amp;nbsp;};&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스별(per-instance) 데이터와 다중 버텍스 스트림도 마찬가지다. 이 역시 raw 메모리 로드로 효율적으로 구현할 수 있다. raw 로드 명령을 사용하면 버텍스 스트라이드를 동적으로 조정하고, 보조 버텍스 버퍼 로드를 조건 분기로 건너뛰며, 클러스터 기반 GPU 드리븐 렌더링, 파티클 쿼드 확장, 고차 곡면, 효율적인 지형 렌더링 등 다양한 알고리즘을 구현하기 위해 커스텀 공식으로 버텍스 인덱스를 계산할 수 있다. 추가적인 셰이더 엔트리 포인트나 바인딩 API는 필요 없다. 새로운 정적 상수 시스템을 사용해 파이프라인 생성 시 사용하지 않는 버텍스 스트림을 데드 코드 제거할 수 있고, 원한다면 정적 버텍스 스트라이드를 제공할 수도 있다. 기존의 모든 최적화 전략은 그대로 유지되지만, 이제는 렌더러의 요구에 맞게 기법들을 자유롭게 조합할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Common&amp;nbsp;header...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;VertexPosition&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;VertexAttributes&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8x4&amp;nbsp;normal;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8x4&amp;nbsp;tangent;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint16x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Instance&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4x4&amp;nbsp;matrixModel;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Data&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4x4&amp;nbsp;matrixViewProjection;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;VertexPosition&amp;nbsp;*vertexPositions;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;VertexAttributes&amp;nbsp;*vertexAttribues;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;Instance&amp;nbsp;*instances;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;CPU&amp;nbsp;code...&lt;/span&gt;&lt;br /&gt;gpuSetPipeline(commandBuffer,&amp;nbsp;graphicsPipeline);&lt;br /&gt;&lt;br /&gt;auto&amp;nbsp;data&amp;nbsp;=&amp;nbsp;myBumpAllocator.allocate&amp;lt;Data&amp;gt;();&lt;br /&gt;data.cpu-&amp;gt;matrixViewProjection&amp;nbsp;=&amp;nbsp;camera.viewProjection;&lt;br /&gt;data.cpu-&amp;gt;vertexPositions&amp;nbsp;=&amp;nbsp;mesh.positions;&lt;br /&gt;data.cpu-&amp;gt;vertexAttributes&amp;nbsp;=&amp;nbsp;mesh.attributes;&lt;br /&gt;data.cpu-&amp;gt;instances&amp;nbsp;=&amp;nbsp;batcher.instancePool&amp;nbsp;+&amp;nbsp;instanceOffset;&amp;nbsp;//&amp;nbsp;pointer&amp;nbsp;arithmetic&amp;nbsp;is&amp;nbsp;convenient&lt;br /&gt;&lt;br /&gt;gpuDrawIndexedInstanced(commandBuffer,&amp;nbsp;data.gpu,&amp;nbsp;mesh.indices,&amp;nbsp;mesh.indexCount,&amp;nbsp;instanceCount);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Vertex&amp;nbsp;shader...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;VertexOut&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;:&amp;nbsp;SV_Position;&amp;nbsp;//&amp;nbsp;SV&amp;nbsp;values&amp;nbsp;are&amp;nbsp;not&amp;nbsp;real&amp;nbsp;struct&amp;nbsp;fields&amp;nbsp;(doesn't&amp;nbsp;affect&amp;nbsp;the&amp;nbsp;layout)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float16x4&amp;nbsp;normal;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;VertexOut&amp;nbsp;main(uint32&amp;nbsp;vertexIndex&amp;nbsp;:&amp;nbsp;SV_VertexID,&amp;nbsp;uint32&amp;nbsp;instanceIndex&amp;nbsp;:&amp;nbsp;SV_InstanceID,&amp;nbsp;const&amp;nbsp;Data*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Instance&amp;nbsp;instance&amp;nbsp;=&amp;nbsp;data-&amp;gt;instances[SV_InstanceIndex];&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;NOTE:&amp;nbsp;Splitting&amp;nbsp;positions/attributes&amp;nbsp;benefits&amp;nbsp;TBDR&amp;nbsp;GPUs&amp;nbsp;(vertex&amp;nbsp;shader&amp;nbsp;is&amp;nbsp;split&amp;nbsp;in&amp;nbsp;two&amp;nbsp;parts)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VertexPosition&amp;nbsp;vertexPosition&amp;nbsp;=&amp;nbsp;data-&amp;gt;vertexPositions[SV_VertexIndex];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VertexAttributes&amp;nbsp;vertexAttributes&amp;nbsp;=&amp;nbsp;data-&amp;gt;vertexAttributes[SV_VertexIndex];&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4x4&amp;nbsp;matrix&amp;nbsp;=&amp;nbsp;data-&amp;gt;matrixViewProjection&amp;nbsp;*&amp;nbsp;instance.matrixModel;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;=&amp;nbsp;matrix&amp;nbsp;*&amp;nbsp;vertexPosition.position;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;TODO:&amp;nbsp;Normal&amp;nbsp;transform&amp;nbsp;here&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;.position&amp;nbsp;=&amp;nbsp;position,&amp;nbsp;.normal&amp;nbsp;=&amp;nbsp;normal,&amp;nbsp;.uv&amp;nbsp;=&amp;nbsp;vertexAttributes.uv&amp;nbsp;};&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;383&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;인덱스 버퍼 바인딩은 여전히 특별한 경우다. GPU에는 인덱스 중복 제거 하드웨어가 있다. 동일한 버텍스에 대해 버텍스 셰이더를 두 번 실행하고 싶지는 않다. 인덱스 중복 제거 하드웨어는 버텍스 웨이브를 재구성해 중복 버텍스를 제거한다. 인덱스 버퍼링은 오늘날에도 여전히 중요한 최적화다. 비인덱스 지오메트리는 삼각형당 3번의 버텍스 셰이더 호출(레인)을 실행한다. 완벽한 그리드는 셀당 두 개의 삼각형을 가지므로, (마지막 행/열을 제외하면) 두 개의 삼각형당 한 번의 버텍스 셰이더 호출만 필요하다. 최신 오프라인 버텍스 캐시 최적화 도구는 삼각형당 약 0.7 버텍스 효율의 메시를 출력한다. 실제 환경에서는 인덱스 버퍼를 통해 버텍스 셰이딩 비용을 약 4~6배 줄일 수 있다.&lt;br /&gt;&lt;br /&gt;오늘날 인덱스 버퍼 하드웨어는 다른 GPU 유닛과 동일한 캐시 계층에 연결되어 있다. 인덱스 버퍼는 단순히 drawIndexed 호출에 전달되는 추가 GPU 포인터일 뿐이다. 인덱스 버퍼링에 필요한 API 표면은 이것이 전부다.&lt;br /&gt;&lt;br /&gt;메시 셰이더는 오프라인 버텍스 중복 제거에 의존한다. 일반적인 구현은 레인당 하나의 버텍스를 셰이딩하고 이를 온칩 메모리에 출력한다. 8비트 로컬 인덱스 버퍼는 각 삼각형이 어떤 3개의 버텍스를 사용하는지 래스터라이저에 알려준다. 모든 메슐릿 출력은 한 번에 उपलब्ध하고 이미 온칩 저장소에서 변환된 상태이므로, 삼각형 설정 이후에 버텍스를 중복 제거하거나 패킹할 필요가 없다. 이것이 메시 셰이더가 인덱스 중복 제거 하드웨어나 포스트 트랜스폼 캐시를 필요로 하지 않는 이유다. 모든 메시 셰이더 입력은 raw 데이터다. gpuDrawMeshlets 명령 외에는 추가 API 표면이 필요 없다.&lt;br /&gt;&lt;br /&gt;내 예제 메시 셰이더는 128레인 스레드 그룹을 사용한다. Nvidia는 출력 메슐릿당 최대 126개 버텍스와 64개 삼각형을 지원한다. AMD는 256개 버텍스와 128개 삼각형을 지원한다. 셰이더는 초과 레인을 마스킹한다. 삼각형 수가 64개를 넘지 않으므로, 최적의 삼각형 레인 활용을 위해 64레인 스레드 그룹을 선택하고 버텍스 셰이딩을 두 번 반복하는 루프를 사용할 수도 있다. 내 삼각형 페치 로직은 단일 메모리 로드 명령이므로, 그 단계에서 절반의 레인을 낭비하는 것은 큰 문제가 아니다. 대신 버텍스 셰이딩에서 추가적인 병렬성을 선택했다. 최적의 선택은 워크로드와 대상 하드웨어에 따라 달라진다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Common&amp;nbsp;header...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;Vertex&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8x4&amp;nbsp;normal;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8x4&amp;nbsp;tangent;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint16x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Meshlet&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;vertexOffset;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;triangleOffset;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;vertexCount;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;triangleCount;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;Data&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4x4&amp;nbsp;matrixMVP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;Meshlet&amp;nbsp;*meshlets;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;Vertex&amp;nbsp;*vertices;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;uint8x4&amp;nbsp;*triangles;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;CPU&amp;nbsp;code...&lt;/span&gt;&lt;br /&gt;gpuSetPipeline(commandBuffer,&amp;nbsp;graphicsMeshPipeline);&lt;br /&gt;&lt;br /&gt;auto&amp;nbsp;data&amp;nbsp;=&amp;nbsp;myBumpAllocator.allocate&amp;lt;Data&amp;gt;();&lt;br /&gt;data.cpu-&amp;gt;matrixMVP&amp;nbsp;=&amp;nbsp;camera.viewProjection&amp;nbsp;*&amp;nbsp;modelMatrix;&lt;br /&gt;data.cpu-&amp;gt;meshlets&amp;nbsp;=&amp;nbsp;mesh.meshlets;&lt;br /&gt;data.cpu-&amp;gt;vertices&amp;nbsp;=&amp;nbsp;mesh.vertices;&lt;br /&gt;data.cpu-&amp;gt;triangles&amp;nbsp;=&amp;nbsp;mesh.triangles;&lt;br /&gt;&lt;br /&gt;gpuDrawMeshlets(commandBuffer,&amp;nbsp;data.gpu,&amp;nbsp;uvec3(mesh.meshletCount,&amp;nbsp;1,&amp;nbsp;1));&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Mesh&amp;nbsp;shader...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;VertexOut&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;:&amp;nbsp;SV_Position;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float16x4&amp;nbsp;normal;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;[groupsize&amp;nbsp;=&amp;nbsp;(128,&amp;nbsp;1,&amp;nbsp;1)]&lt;br /&gt;void&amp;nbsp;main(uint32x3&amp;nbsp;groupThreadId&amp;nbsp;:&amp;nbsp;SV_GroupThreadID,&amp;nbsp;uint32x3&amp;nbsp;groupId&amp;nbsp;:&amp;nbsp;SV_GroupID,&amp;nbsp;const&amp;nbsp;Data*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Meshlet&amp;nbsp;meshlet&amp;nbsp;=&amp;nbsp;data-&amp;gt;meshlets[groupId.x];&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Meshlet&amp;nbsp;output&amp;nbsp;allocation&amp;nbsp;intrinsics&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VertexOut*&amp;nbsp;outVertices&amp;nbsp;=&amp;nbsp;allocateMeshVertices&amp;lt;VertexOut&amp;gt;(meshlet.vertexCount);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8x3*&amp;nbsp;outIndices&amp;nbsp;=&amp;nbsp;allocateMeshIndices(meshlet.triangleCount);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Triangle&amp;nbsp;indices&amp;nbsp;(3x&amp;nbsp;8&amp;nbsp;bit)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(groupThreadId.x&amp;nbsp;&amp;lt;&amp;nbsp;meshlet.triangleCount)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;outIndices[groupThreadId.x]&amp;nbsp;=&amp;nbsp;triangles[meshlet.triangleOffset&amp;nbsp;+&amp;nbsp;groupThreadId.x].xyz;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Vertices&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(groupThreadId.x&amp;nbsp;&amp;lt;&amp;nbsp;meshlet.vertexCount)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Vertex&amp;nbsp;vertex&amp;nbsp;=&amp;nbsp;data-&amp;gt;vertices[meshlet.vertexOffset&amp;nbsp;+&amp;nbsp;groupThreadId.x];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;=&amp;nbsp;data-&amp;gt;matrixMVP&amp;nbsp;*&amp;nbsp;vertex.position;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;TODO:&amp;nbsp;Normal&amp;nbsp;transform&amp;nbsp;here&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;outVertices[groupThreadId.x]&amp;nbsp;=&amp;nbsp;{&amp;nbsp;.position&amp;nbsp;=&amp;nbsp;position,&amp;nbsp;.normal&amp;nbsp;=&amp;nbsp;normal,&amp;nbsp;.uv&amp;nbsp;=&amp;nbsp;vertex.uv&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버텍스 셰이더와 메시 셰이더 모두 픽셀 셰이더를 사용한다. 래스터라이저는 삼각형의 픽셀 커버리지, HiZ, early depth/스텐실 테스트 결과에 따라 픽셀 셰이더 작업을 생성한다. 하드웨어는 여러 삼각형과 여러 인스턴스를 동일한 픽셀 셰이더 웨이브에 패킹할 수 있다. 픽셀 셰이더 자체는 그다지 특별하지 않다. 오늘날 픽셀 셰이더는 다른 모든 셰이더 타입과 동일한 SIMD 코어에서 실행된다. 다만 몇 가지 특수 입력이 제공된다: 보간된 버텍스 출력, 스크린 위치, 샘플 인덱스와 커버리지 마스크, 삼각형 ID, 삼각형의 앞/뒤 방향 등이다. 이러한 특수 입력은 기존 API와 유사하게 시스템 값(: SV) 시맨틱을 사용해 커널 함수 매개변수로 선언된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Pixel&amp;nbsp;shader...&lt;/span&gt;&lt;br /&gt;const&amp;nbsp;Texture&amp;nbsp;textureHeap[];&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;VertexIn&amp;nbsp;//&amp;nbsp;Matching&amp;nbsp;vertex&amp;nbsp;shader&amp;nbsp;output&amp;nbsp;struct&amp;nbsp;layout&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float16x4&amp;nbsp;normal;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;PixelOut&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float16x4&amp;nbsp;color&amp;nbsp;:&amp;nbsp;SV_Color0;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;PixelOut&amp;nbsp;main(const&amp;nbsp;VertexIn&amp;nbsp;&amp;amp;vertex,&amp;nbsp;const&amp;nbsp;DataPixel*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;texture&amp;nbsp;=&amp;nbsp;textureHeap[data-&amp;gt;textureIndex];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sampler&amp;nbsp;sampler&amp;nbsp;=&amp;nbsp;{.minFilter&amp;nbsp;=&amp;nbsp;LINEAR,&amp;nbsp;.magFilter&amp;nbsp;=&amp;nbsp;LINEAR};&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;color&amp;nbsp;=&amp;nbsp;sample(texture,&amp;nbsp;sampler,&amp;nbsp;vertex.uv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;.color&amp;nbsp;=&amp;nbsp;color&amp;nbsp;};&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 바인딩을 제거하면 버텍스와 픽셀 셰이더를 더 단순하게 사용할 수 있다. 복잡한 데이터 바인딩 API는 모두 64비트 GPU 포인터 하나로 대체된다. 사용자는 각 버텍스 레이아웃마다 PSO 퍼뮤테이션을 만들지 않고도, 유연한 버텍스 페치 코드를 작성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Rasterizer state&lt;/h2&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;173&quot; data-ke-size=&quot;size16&quot;&gt;레거시 API(OpenGL과 DirectX 9)는 모든 셰이더 입력과 래스터라이저 상태를 설정하기 위한 세밀한 명령을 제공했다. 드라이버는 필요할 때 셰이더 파이프라인을 생성해야 했다. 하드웨어 특화 래스터라이저, 블렌더, 입력 어셈블러 명령 패킷은 개별적인 세밀한 상태를 결합한 섀도우 상태(shadow state)로부터 구성되었다. Vulkan 1.0과 DirectX 12는 정반대의 설계를 선택했다. 모든 상태를 사전에 PSO에 베이크했다. 뷰포트, 시저 사각형, 스텐실 값 등 일부 상태만 동적으로 변경할 수 있다. 그 결과 PSO 퍼뮤테이션이 대폭 증가했다.&lt;br /&gt;&lt;br /&gt;PSO 생성은 비용이 크다. GPU 드라이버의 저수준 셰이더 컴파일러를 호출해야 하기 때문이다. PSO 퍼뮤테이션은 상당한 저장 공간과 RAM을 소비한다. PSO 변경은 가장 비용이 큰 상태 변경이다. 일부 벤더가 렌더 상태를 셰이더 마이크로코드에 직접 포함해 얻은 작은 성능 이점은, 파이프라인 생성&amp;middot;바인딩&amp;middot;데이터 관리 비용이 크게 증가하면서 발생한 성능 문제에 의해 상쇄되었다. 진자는 반대쪽으로 너무 많이 흔들렸다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;현대 GPU는 ALU 밀도가 높다. Nvidia와 AMD는 최근 추가 파이프라인을 통해 ALU 처리율을 두 배로 늘렸다. Apple도 M 시리즈 칩에서 fp32 파이프라인을 두 배로 늘렸다. 셰이더 내 상수 치환으로 해결되는 단순 상태는, 추가 ALU 명령 하나가 생기거나 유니폼 레지스터를 하나 더 사용하는 정도의 비용이 들더라도 파이프라인을 복제할 필요가 없다. 오늘날 대부분의 셰이더는 ALU 병목이 아니다. 그 비용은 측정하기 어려울 정도로 작지만, 퍼뮤테이션을 줄이는 이점은 매우 크다. Vulkan 1.3은 올바른 방향으로 나아간 큰 진전이다. 많은 베이크된 PSO 상태를 이제 동적으로 설정할 수 있다.&lt;br /&gt;&lt;br /&gt;만약 더 깊이 살펴보면, 모든 GPU가 래스터라이저와 깊이-스텐실 유닛을 구성하기 위해 명령 패킷을 사용한다는 것을 알 수 있다. 이러한 명령 패킷은 셰이더 마이크로코드에 직접적으로 묶여 있지 않다. 래스터라이저 및 깊이-스텐실 상태를 변경하기 위해 셰이더 마이크로코드를 수정할 필요는 없다. Metal은 별도의 깊이-스텐실 상태 객체와 이를 적용하는 별도의 명령을 갖고 있다. 별도의 상태 객체는 PSO 퍼뮤테이션을 줄이고, 비용이 큰 셰이더 바인딩 호출을 줄인다. Vulkan 1.3의 동적 상태 역시 유사하게 PSO 퍼뮤테이션을 줄이지만, 더 세밀한 방식이다. Metal의 설계는 실제 하드웨어 명령 패킷 구조와 더 잘 맞는다. 더 큰 패킷은 API 비대화와 오버헤드를 줄인다. DirectX 12는 안타깝게도 대부분의 깊이-스텐실 상태를 여전히 PSO에 묶어두고 있다(스텐실 레퍼런스와 깊이 바이어스만 동적 상태다). 우리의 설계에서는 깊이-스텐실 상태를 별도의 객체로 둔다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;GpuDepthStencilDesc&amp;nbsp;depthStencilDesc&amp;nbsp;=&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthMode&amp;nbsp;=&amp;nbsp;DEPTH_READ&amp;nbsp;|&amp;nbsp;DEPTH_WRITE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthTest&amp;nbsp;=&amp;nbsp;OP_LESS_EQUAL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthBias&amp;nbsp;=&amp;nbsp;0.0f,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthBiasSlopeFactor&amp;nbsp;=&amp;nbsp;0.0f,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthBiasClamp&amp;nbsp;=&amp;nbsp;0.0f,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.stencilReadMask&amp;nbsp;=&amp;nbsp;0xff,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.stencilWriteMask&amp;nbsp;=&amp;nbsp;0xff,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.stencilFront&amp;nbsp;=&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.test&amp;nbsp;=&amp;nbsp;OP_ALWAYS,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.failOp&amp;nbsp;=&amp;nbsp;OP_KEEP,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.passOp&amp;nbsp;=&amp;nbsp;OP_KEEP,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthFailOp&amp;nbsp;=&amp;nbsp;OP_KEEP,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.reference&amp;nbsp;=&amp;nbsp;0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.stencilBack&amp;nbsp;=&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.test&amp;nbsp;=&amp;nbsp;COMPARE_ALWAYS,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.failOp&amp;nbsp;=&amp;nbsp;OP_KEEP,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.passOp&amp;nbsp;=&amp;nbsp;OP_KEEP,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthFailOp&amp;nbsp;=&amp;nbsp;OP_KEEP,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.reference&amp;nbsp;=&amp;nbsp;0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;A&amp;nbsp;minimal&amp;nbsp;way&amp;nbsp;to&amp;nbsp;descibe&amp;nbsp;the&amp;nbsp;above&amp;nbsp;(using&amp;nbsp;C++&amp;nbsp;API&amp;nbsp;struct&amp;nbsp;default&amp;nbsp;values):&lt;br /&gt;GpuDepthStencilDesc&amp;nbsp;depthStencilDesc&amp;nbsp;=&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthMode&amp;nbsp;=&amp;nbsp;DEPTH_READ&amp;nbsp;|&amp;nbsp;DEPTH_WRITE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthTest&amp;nbsp;=&amp;nbsp;OP_LESS_EQUAL,&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;GpuDepthStencilState&amp;nbsp;depthStencilState&amp;nbsp;=&amp;nbsp;gpuCreateDepthStencilState(depthStencilDesc);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;176&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;즉시 모드-Immediate mode(desktop) GPU도 알파 블렌더 유닛을 구성하기 위한 유사한 명령 패킷을 가지고 있다. 만약 우리가 DirectX 13을 설계한다면, 단순히 블렌드 상태 객체를 PSO에서 분리하고 끝낼 것이다. 하지만 우리는 크로스 플랫폼 API를 설계하고 있으며, 모바일 GPU에서 블렌딩은 완전히 다르게 동작한다.&lt;br /&gt;&lt;br /&gt;모바일 GPU(TBDR)는 오래전부터 프로그래머블 블렌딩을 지원해왔다. 렌더 타일은 컴퓨트 유닛 근처의 스크래치패드 메모리(groupshared 메모리같은)에 들어가며, 픽셀 셰이더는 이전에 래스터라이즈된 픽셀에 대해 직접적이고 저지연의 읽기+쓰기 접근을 할 수 있다. 대부분의 모바일 GPU에는 고정 기능 블렌딩 하드웨어가 없다. 전통적인 그래픽스 API를 사용할 경우, 드라이버의 저수준 셰이더 컴파일러는 셰이더 끝에 블렌딩 명령을 추가한다. 이는 앞서 설명한 버텍스 페치 코드 생성과 유사하다. 만약 모바일 GPU만을 위한 API를 설계한다면, 버텍스 버퍼를 제거했던 것처럼 블렌드 상태 API도 완전히 제거했을 것이다. 모바일 중심 API는 현재 픽셀의 이전 색상을 효율적으로 얻기 위한 프레임버퍼 페치 intrinsic을 노출한다. 사용자는 원하는 어떤 블렌딩 공식이든 작성할 수 있으며, 순서 독립 투명도 같은 고급 알고리즘을 구현하기 위한 복잡한 공식도 가능하다. 또한 사용자는 PSO 퍼뮤테이션 폭증을 줄이기 위해 일반화된 매개변수화 공식도 작성할 수 있다. 이처럼 데스크톱과 모바일 GPU는 블렌딩과 관련된 파이프라인 퍼뮤테이션을 줄이는 각자의 방법을 가지고 있으며, 제약은 현재의 API에 있다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Vulkan의 서브패스(subpass)는 프레임버퍼 페치를 크로스 플랫폼 API로 감싸기 위해 설계되었다. 이는 Vulkan 설계에서 또 하나의 잘못된 선택이었다. Vulkan은 Mantle에서 단순한 저수준 설계를 계승했지만, OpenGL의 대체재로 설계되었기 때문에 모든 모바일과 데스크톱 GPU 아키텍처를 대상으로 해야 했다. 완전히 다른 두 아키텍처 유형을 동일한 API 아래에서 추상화하는 것은 쉽지 않다. 서브패스는 저수준 API 안에 들어간 고수준 개념이 되었다. 하나의 서브패스는 전체 렌더 패스 체인을 정의할 수 있었지만, 마치 단일 렌더 패스인 것처럼 취급되었다. 서브패스는 드라이버 복잡성을 증가시키고, 셰이더 및 렌더패스 API를 불필요하게 복잡하게 만들었다. 사용자는 복잡한 영속적 멀티 렌더 패스 객체를 사전에 생성하고 이를 셰이더 파이프라인 생성 시 전달해야 했다. 셰이더 파이프라인은 내부적으로 여러 개의 파이프라인(서브패스당 하나)으로 분리되었다. Vulkan은 단지 프레임버퍼 페치 intrinsic을 셰이더 언어에 직접 노출하지 않기 위해 이 모든 복잡성을 추가했다. 설상가상으로 서브패스는 프로그래머블 블렌딩 문제를 해결하기에도 충분하지 않았다. 픽셀 순서는 패스 경계에서만 보장된다. 서브패스는 제한적인 1:1 멀티패스 사용 사례에서만 유용했다. Vulkan 1.3은 서브패스를 폐기하고 &amp;ldquo;동적 렌더링(dynamic rendering)&amp;rdquo;을 도입했다. 이제 사용자는 Metal, DirectX 12, WebGPU처럼 영속적 렌더 패스 객체를 생성할 필요가 없다. 이는 복잡한 프레임워크가 API 설계자에게 매력적으로 보일 수 있지만, 개발자는 단순한 셰이더 intrinsic을 선호한다는 좋은 예다. 게임 엔진은 이미 플랫폼별로 서로 다른 셰이더를 빌드하는 것을 지원한다. Apple의 Metal 예제도 마찬가지다: iOS에서는 프레임버퍼 페치를 사용하고, Mac에서는 전통적인 멀티패스 알고리즘을 사용한다.&lt;br /&gt;&lt;br /&gt;블렌딩과 프레임버퍼 페치에 관한 하드웨어 차이를 추상화할 수 없다는 것은 분명하다. Vulkan 1.0은 이를 시도했고 크게 실패했다. 올바른 해결책은 사용자에게 선택권을 제공하는 것이다. 사용자는 블렌드 상태를 PSO에 포함시킬 수 있다. 이는 모든 플랫폼에서 동작하며, 블렌드 상태와 관련된 파이프라인 퍼뮤테이션 문제를 겪지 않는 셰이더에 적합한 접근이다. 모바일 GPU에서는 내부 드라이버 셰이더 컴파일러가 평소처럼 픽셀 셰이더 끝에 블렌딩 명령을 추가한다. 즉시 모드(데스크톱) GPU(및 일부 모바일 GPU)에서는 사용자가 별도의 블렌드 상태 객체를 사용할 수 있다. 이는 PSO 퍼뮤테이션 수를 줄이고, 전체 파이프라인 변경 없이 블렌드 상태 구성 패킷만 전송하면 되므로 런타임에 블렌드 상태를 더 빠르게 변경할 수 있게 해준다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;GpuBlendDesc&amp;nbsp;blendDesc&amp;nbsp;=&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.colorOp&amp;nbsp;=&amp;nbsp;OP_ONE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.srcColorFactor&amp;nbsp;=&amp;nbsp;FACTOR_SRC_ALPHA,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.dstColorFactor&amp;nbsp;=&amp;nbsp;FACTOR_ONE_MINUS_SRC_ALPHA,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.alphaOp&amp;nbsp;=&amp;nbsp;OP_ONE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.srcAlphaFactor&amp;nbsp;=&amp;nbsp;FACTOR_SRC_ALPHA,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.dstAlphaFactor&amp;nbsp;=&amp;nbsp;FACTOR_ONE_MINUS_SRC_ALPHA,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.colorWriteMask&amp;nbsp;=&amp;nbsp;0xf&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Create&amp;nbsp;blend&amp;nbsp;state&amp;nbsp;object&amp;nbsp;(needs&amp;nbsp;feature&amp;nbsp;flag)&lt;/span&gt;&lt;br /&gt;GpuBlendState&amp;nbsp;blendState&amp;nbsp;=&amp;nbsp;gpuCreateBlendState(blendDesc);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Set&amp;nbsp;dynamic&amp;nbsp;blend&amp;nbsp;state&amp;nbsp;(needs&amp;nbsp;feature&amp;nbsp;flag)&lt;/span&gt;&lt;br /&gt;gpuSetBlendState(commandBuffer,&amp;nbsp;blendState);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모바일 GPU에서는 사용자가 기존처럼 블렌드 상태를 PSO에 포함시킬 수도 있고, 프레임버퍼 페치를 사용해 커스텀 블렌딩 공식을 작성할 수도 있다. 모바일 개발자가 서로 다른 알파 블렌딩 모드에 대해 여러 PSO 퍼뮤테이션을 컴파일하는 것을 피하고 싶다면, 동적 드로우 구조체 입력으로 매개변수화된 일반 공식을 작성하면 된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 216px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 216px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 216px;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Standard&amp;nbsp;percentage&amp;nbsp;blend&amp;nbsp;formula&amp;nbsp;(added&amp;nbsp;automatically&amp;nbsp;by&amp;nbsp;internal&amp;nbsp;shader&amp;nbsp;compiler)&lt;/span&gt;&lt;br /&gt;dst.rgb&amp;nbsp;=&amp;nbsp;src.rgb&amp;nbsp;*&amp;nbsp;src.a&amp;nbsp;+&amp;nbsp;dst.rgb&amp;nbsp;*&amp;nbsp;(1.0&amp;nbsp;-&amp;nbsp;src.a);&lt;br /&gt;dst.a&amp;nbsp;=&amp;nbsp;src.a&amp;nbsp;*&amp;nbsp;src.a&amp;nbsp;+&amp;nbsp;dst.a&amp;nbsp;*&amp;nbsp;(1.0&amp;nbsp;-&amp;nbsp;src.a);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Custom&amp;nbsp;formula&amp;nbsp;supporting&amp;nbsp;all&amp;nbsp;blend&amp;nbsp;modes&amp;nbsp;used&amp;nbsp;by&amp;nbsp;HypeHype&lt;/span&gt;&lt;br /&gt;const&amp;nbsp;BlendParameters&amp;amp;&amp;nbsp;p&amp;nbsp;=&amp;nbsp;data-&amp;gt;blendParameters;&lt;br /&gt;vec4&amp;nbsp;fs&amp;nbsp;=&amp;nbsp;src.a&amp;nbsp;*&amp;nbsp;vec4(p.sc_sa.xxx&amp;nbsp;+&amp;nbsp;p.sc_one.xxx,&amp;nbsp;p.sa_sa&amp;nbsp;+&amp;nbsp;p.sa_one)&amp;nbsp;+&amp;nbsp;dst.rgba&amp;nbsp;*&amp;nbsp;vec4(p.sc_dc.xxx,&amp;nbsp;sa_da);&lt;br /&gt;vec4&amp;nbsp;fd&amp;nbsp;=&amp;nbsp;(1.0&amp;nbsp;-&amp;nbsp;src.a)&amp;nbsp;*&amp;nbsp;vec4(p.dc_1msa.xxx,&amp;nbsp;p.da_1msa)&amp;nbsp;+&amp;nbsp;vec4(p.dc_one.xxx,&amp;nbsp;p.da_one);&lt;br /&gt;dst.rgb&amp;nbsp;=&amp;nbsp;src.rgb&amp;nbsp;*&amp;nbsp;fs.rgb&amp;nbsp;+&amp;nbsp;dst.rgb&amp;nbsp;*&amp;nbsp;fd.rgb;&lt;br /&gt;dst.a&amp;nbsp;&amp;nbsp;=&amp;nbsp;src.a&amp;nbsp;*&amp;nbsp;fs.a&amp;nbsp;+&amp;nbsp;dst.a&amp;nbsp;*&amp;nbsp;fd.a;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;419&quot; data-start=&quot;186&quot; data-ke-size=&quot;size16&quot;&gt;블렌드 상태가 PSO에서 분리되면 일부 자동 데드 코드 최적화를 잃을 가능성이 있다. 사용자가 컬러 출력을 비활성화하고 싶을 때는 전통적으로 블렌드 상태의 colorWriteMask를 사용한다. 블렌드 상태가 PSO에 포함되어 있을 경우, 컴파일러는 이를 기반으로 데드 코드 제거를 수행할 수 있다. 유사한 데드 코드 최적화를 가능하게 하기 위해, 우리는 PSO에 각 컬러 타깃별 writeMask를 둔다.&lt;br /&gt;&lt;br /&gt;듀얼 소스 블렌딩은 픽셀 셰이더에서 두 개의 컬러 출력을 요구하는 특수 블렌드 모드다. 듀얼 소스 블렌딩은 단일 렌더 타깃만 지원한다. 우리의 블렌드 상태는 분리될 수 있으므로, PSO 설명자에 supportDualSourceBlending 필드를 두어야 한다. 이 옵션이 활성화되면, 셰이더 컴파일러는 두 번째 출력이 듀얼 소스 블렌딩용임을 알 수 있다. 출력이 존재하지 않으면 검증 레이어가 오류를 발생시킨다. 두 개의 컬러를 출력하는 픽셀 셰이더는 듀얼 소스 블렌딩 없이도 사용할 수 있지만(두 번째 컬러는 무시됨), 두 개의 컬러를 출력하는 데에는 약간의 비용이 있다.&lt;br /&gt;&lt;br /&gt;PSO에 남는 렌더링 상태는 최소한이다: 프리미티브 토폴로지, 렌더 타깃 및 깊이-스텐실 타깃 포맷, MSAA 샘플 수, 알파 투 커버리지다. 이러한 상태는 생성되는 셰이더 마이크로코드에 영향을 미치므로 PSO에 남아 있어야 한다. 상태 변경 때문에 셰이더 PSO 마이크로코드를 재빌드하는 일은 절대 원하지 않는다. 블렌드 상태가 PSO에 포함된 경우, 그것 역시 PSO에 베이크된다. 이렇게 하면 PSO 생성을 위한 단순한 래스터 상태 구조체만 남게 된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;GpuRasterDesc&amp;nbsp;rasterDesc&amp;nbsp;=&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.topology&amp;nbsp;=&amp;nbsp;TOPOLOGY_TRIANGLE_LIST,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.cull&amp;nbsp;=&amp;nbsp;CULL_CCW,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.alphaToCoverage&amp;nbsp;=&amp;nbsp;false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.supportDualSourceBlending&amp;nbsp;=&amp;nbsp;false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.sampleCount&amp;nbsp;=&amp;nbsp;1`&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthFormat&amp;nbsp;=&amp;nbsp;FORMAT_D32_FLOAT,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.stencilFormat&amp;nbsp;=&amp;nbsp;FORMAT_NONE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.colorTargets&amp;nbsp;=&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RG11B10_FLOAT }, //&amp;nbsp;G-buffer&amp;nbsp;with&amp;nbsp;3&amp;nbsp;render&amp;nbsp;targets&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RGB10_A2_UNORM&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RGBA8_UNORM&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.blendstate&amp;nbsp;=&amp;nbsp;GpuBlendDesc&amp;nbsp;{&amp;nbsp;...&amp;nbsp;} //&amp;nbsp;optional&amp;nbsp;(embedded&amp;nbsp;blend&amp;nbsp;state,&amp;nbsp;otherwise&amp;nbsp;dynamic)&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;A&amp;nbsp;minimal&amp;nbsp;way&amp;nbsp;to&amp;nbsp;descibe&amp;nbsp;the&amp;nbsp;above&amp;nbsp;(using&amp;nbsp;C++&amp;nbsp;API&amp;nbsp;struct&amp;nbsp;default&amp;nbsp;values):&lt;/span&gt;&lt;br /&gt;GpuRasterDesc&amp;nbsp;rasterDesc&amp;nbsp;=&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthFormat&amp;nbsp;=&amp;nbsp;FORMAT_D32_FLOAT,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.colorTargets&amp;nbsp;=&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RG11B10_FLOAT },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RGB10_A2_UNORM&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;.format&amp;nbsp;=&amp;nbsp;FORMAT_RGBA8_UNORM&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Pixel&amp;nbsp;+&amp;nbsp;vertex&amp;nbsp;shader&lt;/span&gt;&lt;br /&gt;auto&amp;nbsp;vertexIR&amp;nbsp;=&amp;nbsp;loadFile(&quot;vertexShader.ir&quot;);&lt;br /&gt;auto&amp;nbsp;pixelIR&amp;nbsp;=&amp;nbsp;loadFile(&quot;pixelShader.ir&quot;);&lt;br /&gt;GpuPipeline&amp;nbsp;graphicsPipeline&amp;nbsp;=&amp;nbsp;gpuCreateGraphicsPipeline(vertexIR,&amp;nbsp;pixelIR,&amp;nbsp;rasterDesc);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Mesh&amp;nbsp;shader&lt;/span&gt;&lt;br /&gt;auto&amp;nbsp;meshletIR&amp;nbsp;=&amp;nbsp;loadFile(&quot;meshShader.ir&quot;);&lt;br /&gt;auto&amp;nbsp;pixelIR&amp;nbsp;=&amp;nbsp;loadFile(&quot;pixelShader.ir&quot;);&lt;br /&gt;GpuPipeline&amp;nbsp;graphicsMeshletPipeline&amp;nbsp;=&amp;nbsp;gpuCreateGraphicsMeshletPipeline(meshletIR,&amp;nbsp;pixelIR,&amp;nbsp;rasterDesc);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;146&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;HypeHype의 Vulkan 셰이더 PSO 초기화 백엔드 코드는 400줄이며, 내가 개발해온 다른 엔진들과 비교해도 상당히 간결한 편이다. 여기서는 단 18줄의 코드로 픽셀 + 버텍스 셰이더를 초기화했다. 읽고 이해하기도 쉽다. 그럼에도 성능 저하는 없다.&lt;br /&gt;&lt;br /&gt;래스터 파이프라인으로 렌더링하는 방식은 컴퓨트 파이프라인과 유사하다. 하나의 데이터 포인터 대신 두 개를 제공한다는 점만 다르다. 커널 엔트리 포인트가 두 개이기 때문이다: 하나는 버텍스 셰이더용, 다른 하나는 픽셀 셰이더용이다. Metal은 버텍스와 픽셀 셰이더에 대해 별도의 데이터 바인딩 슬롯을 가진다. DirectX, Vulkan, WebGPU는 각 바인딩에 대해 가시성 마스크(버텍스, 픽셀, 컴퓨트 등)를 사용한다. 많은 엔진은 동일한 데이터를 버텍스와 픽셀 셰이더에 모두 바인딩한다. DirectX, Vulkan, WebGPU에서는 마스크 비트를 결합할 수 있어 이는 적절한 방식이지만, Metal에서는 바인딩 호출이 두 배로 늘어난다. 우리가 제안하는 두 개의 데이터 포인터 방식은 양쪽의 장점을 모두 가진다. 버텍스와 픽셀 셰이더에서 동일한 데이터를 사용하고 싶다면 동일한 포인터를 두 번 전달하면 된다. 또는 셰이더 단계 간 완전한 분리를 원한다면 서로 다른 데이터 포인터를 제공할 수도 있다. 셰이더 컴파일러는 픽셀과 버텍스 셰이더에 대해 각각 데드 코드 제거 및 상수/스칼라 프리로드 최적화를 수행한다. 데이터 공유든 데이터 중복이든 성능에 악영향을 주지 않는다. 사용자는 자신의 설계에 맞는 방식을 선택하면 된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 1188px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 1188px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 1188px;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Common&amp;nbsp;header...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;Vertex&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint16x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;DataVertex&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4x4&amp;nbsp;matrixMVP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;Vertex&amp;nbsp;*vertices;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;alignas(16)&amp;nbsp;DataPixel&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;color;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;textureIndex;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;CPU&amp;nbsp;code...&lt;/span&gt;&lt;br /&gt;gpuSetDepthStencilState(commandBuffer,&amp;nbsp;depthStencilState);&lt;br /&gt;gpuSetPipeline(commandBuffer,&amp;nbsp;graphicsPipeline);&lt;br /&gt;&lt;br /&gt;auto&amp;nbsp;dataVertex&amp;nbsp;=&amp;nbsp;myBumpAllocator.allocate&amp;lt;DataVertex&amp;gt;();&lt;br /&gt;dataVertex.cpu-&amp;gt;matrixMVP&amp;nbsp;=&amp;nbsp;camera.viewProjection&amp;nbsp;*&amp;nbsp;modelMatrix;&lt;br /&gt;dataVertex.cpu-&amp;gt;vertices&amp;nbsp;=&amp;nbsp;mesh.vertices;&lt;br /&gt;&lt;br /&gt;auto&amp;nbsp;dataPixel&amp;nbsp;=&amp;nbsp;myBumpAllocator.allocate&amp;lt;DataPixel&amp;gt;();&lt;br /&gt;dataPixel.cpu-&amp;gt;color&amp;nbsp;=&amp;nbsp;material.color;&lt;br /&gt;dataPixel.cpu-&amp;gt;textureIndex&amp;nbsp;=&amp;nbsp;material.textureIndex;&lt;br /&gt;&lt;br /&gt;gpuDrawIndexed(commandBuffer,&amp;nbsp;dataVertex.gpu,&amp;nbsp;dataPixel.gpu,&amp;nbsp;mesh.indices,&amp;nbsp;mesh.indexCount);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Vertex&amp;nbsp;shader...&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;VertexOut&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;:&amp;nbsp;SV_Position;&amp;nbsp;//&amp;nbsp;SV&amp;nbsp;values&amp;nbsp;are&amp;nbsp;not&amp;nbsp;real&amp;nbsp;struct&amp;nbsp;fields&amp;nbsp;(doesn't&amp;nbsp;affect&amp;nbsp;the&amp;nbsp;layout)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;VertexOut&amp;nbsp;main(uint32&amp;nbsp;vertexIndex&amp;nbsp;:&amp;nbsp;SV_VertexID,&amp;nbsp;const&amp;nbsp;DataVertex*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Vertex&amp;nbsp;vertex&amp;nbsp;=&amp;nbsp;data.vertices[vertexIndex];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;position&amp;nbsp;=&amp;nbsp;data-&amp;gt;matrixMVP&amp;nbsp;*&amp;nbsp;vertex.position;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;.position&amp;nbsp;=&amp;nbsp;position,&amp;nbsp;.uv&amp;nbsp;=&amp;nbsp;vertex.uv&amp;nbsp;};&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Pixel&amp;nbsp;shader...&lt;/span&gt;&lt;br /&gt;const&amp;nbsp;Texture&amp;nbsp;textureHeap[];&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;VertexIn&amp;nbsp;//&amp;nbsp;Matching&amp;nbsp;vertex&amp;nbsp;shader&amp;nbsp;output&amp;nbsp;struct&amp;nbsp;layout&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x2&amp;nbsp;uv;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;PixelOut&amp;nbsp;main(const&amp;nbsp;VertexIn&amp;nbsp;&amp;amp;vertex,&amp;nbsp;const&amp;nbsp;DataPixel*&amp;nbsp;data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture&amp;nbsp;texture&amp;nbsp;=&amp;nbsp;textureHeap[data-&amp;gt;textureIndex];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sampler&amp;nbsp;sampler&amp;nbsp;=&amp;nbsp;{.minFilter&amp;nbsp;=&amp;nbsp;LINEAR,&amp;nbsp;.magFilter&amp;nbsp;=&amp;nbsp;LINEAR};&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float32x4&amp;nbsp;color&amp;nbsp;=&amp;nbsp;sample(texture,&amp;nbsp;sampler,&amp;nbsp;vertex.uv);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;nbsp;.color&amp;nbsp;=&amp;nbsp;color&amp;nbsp;};&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;2699b663-460e-4e85-891a-cc5743871b0e&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;우리의 목표는 PSO 내부에 남아 있는 상태를 최소화하여 PSO 퍼뮤테이션 폭증을 줄이는 것이었다. 깊이-스텐실 상태는 모든 아키텍처에서 분리할 수 있다. 블렌드 상태 분리는 데스크톱 하드웨어에서는 가능하지만, 대부분의 모바일 하드웨어는 블렌드 방정식을 픽셀 셰이더 마이크로코드 끝에 포함시킨다. 프레임버퍼 페치 intrinsic을 사용자에게 직접 노출하는 것은 Vulkan의 실패한 서브패스 접근보다 훨씬 나은 방법이다. 사용자는 새로운 렌더링 알고리즘을 가능하게 하는 자신만의 블렌드 공식을 작성할 수 있고, PSO 수를 줄이기 위해 일반화된 매개변수화 블렌딩 공식을 만들 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Indirect drawing&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표준 드로우/디스패치 명령은 C/C++ 함수 매개변수를 사용해 스레드 그룹 차원, 인덱스 개수, 인스턴스 개수 등의 인자를 전달한다. 간접 드로우 호출은 이러한 드로우 인자의 소스로 GPU 버퍼 + 오프셋 쌍을 대신 제공할 수 있게 하며, 이는 GPU 주도 렌더링을 가능하게 하는 중요한 기능이다. 우리의 버전은 일반적인 버퍼 객체 + 오프셋 쌍 대신 단일 GPU 포인터를 사용해 API를 약간 더 단순화한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;gpuDispatchIndirect(commandBuffer,&amp;nbsp;data.gpu,&amp;nbsp;arguments.gpu);&lt;br /&gt;gpuDrawIndexedInstancedIndirect(commandBuffer,&amp;nbsp;dataVertex.gpu,&amp;nbsp;dataPixel.gpu,&amp;nbsp;arguments.gpu);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;131&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;우리의 모든 인자는 GPU 포인터다. 데이터와 인자 모두가 간접적이다. 이는 기존 API에 비해 큰 개선이다. DirectX 12, Vulkan, Metal은 간접 루트 인자를 지원하지 않는다. 이를 제공하는 것은 CPU의 몫이다.&lt;/p&gt;
&lt;p data-end=&quot;333&quot; data-start=&quot;133&quot; data-ke-size=&quot;size16&quot;&gt;간접 멀티드로우(MDI)도 지원되어야 한다. 드로우 개수는 GPU 주소에서 가져온다. MDI 파라미터는 다음과 같다: 루트 데이터 배열(GPU 포인터, 버텍스와 픽셀 각각), 드로우 인자 배열(GPU 포인터), 그리고 루트 데이터 배열의 스트라이드(버텍스와 픽셀 각각). 스트라이드가 0이면 동일한 루트 데이터가 각 드로우에 대해 반복 사용됨을 의미한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span&gt;gpuDrawIndexedInstancedIndirectMulti(&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; commandBuffer,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt; dataVertex.gpu, sizeof(DataVertex),&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt; dataPixel.gpu, sizeof(DataPixel),&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt; arguments.gpu,&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt; drawCount.gpu&lt;/span&gt;&lt;br /&gt;&lt;span&gt;);&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;684&quot; data-start=&quot;521&quot; data-ke-size=&quot;size16&quot;&gt;Vulkan의 멀티드로우는 드로우 호출마다 바인딩을 변경할 수 없다. gl_DrawID를 사용해 드로우 데이터 구조체를 담은 버퍼를 인덱싱할 수 있지만, 이는 셰이더에 간접 참조를 추가한다. 텍스처를 가져오기 위해서는 디스크립터 인덱싱이나 새로운 디스크립터 버퍼 확장을 사용해야 한다.&lt;br /&gt;&lt;br /&gt;DirectX 12의 ExecuteIndirect는 사용자가 드로우마다 루트 상수를 수동 설정할 수 있는 구성 가능한 커맨드 시그니처를 제공하지만, 모든 GPU 커맨드 프로세서에서 빠른 경로를 타지는 않는다. ExecuteIndirect Tier 1.1(2024)은 D3D12_INDIRECT_ARGUMENT_TYPE_INCREMENTING_CONSTANT라는 새로운 선택적 카운터 증가 기능을 추가했다. 이는 드로우 ID를 구현하는 데 사용할 수 있다. SM 6.8(2024)은 마침내 SV_StartInstanceLocation을 지원해, 사용자가 간접 드로우 인자에 상수를 직접 포함할 수 있게 했다. SV_InstanceID와 달리 SV_StartInstanceLocation은 전체 드로우 호출에 걸쳐 균일하므로, 인덱스 로드에 대해 최적의 코드 생성(유니폼/스칼라 경로)을 제공한다. 그러나 데이터 페치는 여전히 간접 참조가 필요하다. GPU 생성 루트 데이터는 지원되지 않는다.&lt;br /&gt;&lt;br /&gt;드로우 인자나 루트 데이터를 GPU에서 생성하는 경우, 커맨드 프로세서가 디스패치 완료를 기다리도록 보장해야 한다. 현대 커맨드 프로세서는 지연을 숨기기 위해 명령과 인자를 미리 가져온다(prefetch). 이를 방지하기 위한 플래그를 우리는 배리어에 포함한다. 가장 좋은 방법은 세밀한 배리어를 피하기 위해 모든 드로우 인자와 루트 데이터를 한 번에 업데이트하는 것이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;
&lt;div id=&quot;block-yui_3_17_2_1_1765890239746_148980&quot; data-block-type=&quot;44&quot;&gt;
&lt;div&gt;gpuBarrier(commandBuffer,&amp;nbsp;STAGE_COMPUTE,&amp;nbsp;STAGE_COMPUTE,&amp;nbsp;HAZARD_DRAW_ARGUMENTS);&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;1876&quot; data-start=&quot;1503&quot; data-ke-size=&quot;size16&quot;&gt;간접 셰이더 선택이 없다는 점은 현재 PC 및 모바일 그래픽스 API의 중요한 한계다. 간접 셰이더 선택은 레이 트레이싱과 유사한 멀티 파이프라인으로 구현할 수 있다. Metal은 간접 커맨드 생성도 지원한다(Nvidia는 유사한 Vulkan 확장을 제공한다). 드로우 호출을 효율적으로 건너뛰는 기능은 유용한 부분집합이다. DirectX의 워크 그래프와 CUDA의 동적 병렬성은 셰이더가 필요에 따라 추가 웨이브를 생성할 수 있게 한다. 그러나 이러한 하드웨어 개선에 접근하기 위한 API는 여전히 플랫폼별로 다르고, 여러 셰이더 엔트리 포인트에 흩어져 있다. 명확한 표준화가 없다. 이에 대해서는 후속 글에서 셰이더 프레임워크를 다루며 자세히 설명할 예정이다.&lt;br /&gt;&lt;br /&gt;우리의 제안 설계는 간접 드로잉을 매우 강력하게 만든다. 셰이더 루트 데이터와 드로우 파라미터 모두 GPU에서 간접적으로 제공할 수 있다. 이러한 장점은 멀티드로우를 강화해, 해킹 없이 깔끔하고 효율적인 드로우별 데이터 바인딩을 가능하게 한다. 간접 드로잉과 셰이더 프레임워크의 미래는 후속 글에서 다룰 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1876&quot; data-start=&quot;1503&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Render passes&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;18ef05b8-5e23-470c-97e7-c81003973a78&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;434&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;래스터라이저 하드웨어는 드로잉을 시작하기 전에 렌더링 준비가 되어야 한다. 일반적인 작업에는 렌더 타깃과 깊이-스텐실 뷰 바인딩, 컬러 및 깊이 클리어가 포함된다. 클리어 색상이 변경되면 fast clear eliminate가 발생할 수 있다. 이는 클리어 명령에서 투명하게 처리된다. 모바일 GPU에서는 렌더링 중에 온칩 저장소의 타일이 VRAM으로 저장된다. Vulkan, Metal, WebGPU는 렌더 타깃의 클리어, 로드, 저장을 위해 렌더 패스 추상화를 사용한다. DirectX 12는 최신 Intel(Gen11) 및 Qualcomm(Adreno 630) GPU에서 렌더링을 최적화하기 위해 2018년 업데이트에서 렌더 패스 지원을 추가했다. 렌더 패스 추상화는 눈에 띄는 API 복잡성을 추가하지 않으므로, 현대적인 크로스 플랫폼 API에서 합리적인 선택이다.&lt;br /&gt;&lt;br /&gt;DirectX 12에는 렌더 타깃 뷰와 깊이-스텐실 뷰가 있으며, 이를 저장하기 위한 별도의 디스크립터 힙이 있다. 이는 단지 API 추상화일 뿐이다. 이러한 힙은 드라이버가 할당한 CPU 메모리다. 렌더 타깃과 깊이-스텐실 뷰는 GPU 디스크립터가 아니다. 래스터라이저 API는 바인드리스가 아니다. CPU 드라이버가 명령 패킷을 사용해 래스터라이저를 설정한다. Vulkan과 Metal에서는 기존 텍스처/뷰 객체를 beginRenderPass에 직접 전달한다. 드라이버는 내부적으로 텍스처 객체에서 필요한 정보를 얻는다. 우리가 제안하는 GpuTexture 객체가 이 역할을 수행한다. 래스터라이제이션 출력은 여전히 CPU 측 텍스처 객체가 필요한 주요 이유다. 우리는 텍스처 디스크립터를 GPU 메모리에 직접 작성한다. CPU 측 드라이버는 그것에 접근할 수 없다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;GpuRenderPassDesc&amp;nbsp;renderPassDesc&amp;nbsp;=&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.depthTarget&amp;nbsp;=&amp;nbsp;{.texture&amp;nbsp;=&amp;nbsp;deptStencilTexture,&amp;nbsp;.loadOp&amp;nbsp;=&amp;nbsp;CLEAR,&amp;nbsp;.storeOp&amp;nbsp;=&amp;nbsp;DONT_CARE,&amp;nbsp;.clearValue&amp;nbsp;=&amp;nbsp;1.0f},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.stencilTarget&amp;nbsp;=&amp;nbsp;{.texture&amp;nbsp;=&amp;nbsp;deptStencilTexture,&amp;nbsp;.loadOp&amp;nbsp;=&amp;nbsp;CLEAR,&amp;nbsp;.storeOp&amp;nbsp;=&amp;nbsp;DONT_CARE,&amp;nbsp;.clearValue&amp;nbsp;=&amp;nbsp;0},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.colorTargets&amp;nbsp;=&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{.texture&amp;nbsp;=&amp;nbsp;gBufferColor,&amp;nbsp;.loadOp&amp;nbsp;=&amp;nbsp;LOAD,&amp;nbsp;.storeOp&amp;nbsp;=&amp;nbsp;STORE,&amp;nbsp;.clearColor&amp;nbsp;=&amp;nbsp;{0,0,0,0}},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{.texture&amp;nbsp;=&amp;nbsp;gBufferNormal,&amp;nbsp;.loadOp&amp;nbsp;=&amp;nbsp;LOAD,&amp;nbsp;.storeOp&amp;nbsp;=&amp;nbsp;STORE,&amp;nbsp;.clearColor&amp;nbsp;=&amp;nbsp;{0,0,0,0}},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{.texture&amp;nbsp;=&amp;nbsp;gBufferPBR,&amp;nbsp;.loadOp&amp;nbsp;=&amp;nbsp;LOAD,&amp;nbsp;.storeOp&amp;nbsp;=&amp;nbsp;STORE,&amp;nbsp;.clearColor&amp;nbsp;=&amp;nbsp;{0,0,0,0}}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;gpuBeginRenderPass(commandBuffer,&amp;nbsp;renderPassDesc);&lt;br /&gt;//&amp;nbsp;Add&amp;nbsp;draw&amp;nbsp;calls&amp;nbsp;here!&lt;br /&gt;gpuEndRenderPass(commandBuffer);&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;109&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;바인드리스 렌더 패스, 바인드리스/간접(멀티) 클리어 명령, 간접 시저/뷰포트 사각형(배열) 등이 있으면 좋겠지만, 오늘날 많은 GPU는 여전히 CPU 드라이버가 래스터라이저를 설정해야 한다.&lt;br /&gt;&lt;br /&gt;배리어에 대한 참고 사항: 렌더 패스 시작/종료 명령이 자동으로 배리어를 발생시키지는 않는다. 서로 다른 렌더 타깃에 기록한다면, 사용자는 여러 렌더 패스를 동시에 실행할 수 있다. 래스터 출력 단계(또는 그 이후 단계)와 소비자 단계 사이에 배리어를 두면, 해당 GPU 아키텍처에서 필요할 경우 작은 ROP 캐시가 플러시된다. 렌더 패스 사이에 자동 배리어가 없는 것은 효율적인 깊이 프리패스 구현에 매우 중요하다(ROP 캐시가 불필요하게 플러시되지 않는다).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs6zrz/dJMcaih3vJf/Uk9syz0dw4acyqxCaeHfqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs6zrz/dJMcaih3vJf/Uk9syz0dw4acyqxCaeHfqK/img.png&quot; data-alt=&quot;Claybook의 GPU 기반 점토 시뮬레이션과 레이 트레이싱 기술(Sebastian Aaltonen, GDC 2018): 나는 Unreal Engine 4의 콘솔 배리어 구현(Xbox One, PS4)을 최적화해 렌더 타깃 오버랩이 가능하도록 했다. 배리어로 인한 스톨을 피했다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs6zrz/dJMcaih3vJf/Uk9syz0dw4acyqxCaeHfqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs6zrz%2FdJMcaih3vJf%2FUk9syz0dw4acyqxCaeHfqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1329&quot; height=&quot;748&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Claybook의 GPU 기반 점토 시뮬레이션과 레이 트레이싱 기술(Sebastian Aaltonen, GDC 2018): 나는 Unreal Engine 4의 콘솔 배리어 구현(Xbox One, PS4)을 최적화해 렌더 타깃 오버랩이 가능하도록 했다. 배리어로 인한 스톨을 피했다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Prototype API&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 프로토타입 API는 한 화면에 들어간다: 코드 150줄이다. 이 블로그 글의 제목은 &amp;ldquo;No Graphics API&amp;rdquo;다. 물론 오늘날 그것은 불가능한 목표지만, 우리는 꽤 근접했다. WebGPU는 더 작은 기능 집합을 가지며, 약 2700줄 규모의 API(Emscripten C 헤더)를 제공한다. Vulkan 헤더는 약 20,000줄에 달하지만, 레이 트레이싱과 우리가 아직 지원하지 않는 많은 기능을 포함한다. 우리는 API 복잡성을 줄이면서도 성능을 희생하지 않았다. 이 기능 범위에서는, 우리의 API가 기존 API보다 더 큰 유연성을 제공한다. 2025년 여름 기준으로 완전히 확장된 Vulkan 1.4도 실제로는 동일한 작업을 수행할 수 있지만, 사용하기 훨씬 복잡하고 API 오버헤드도 더 크다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Opaque&amp;nbsp;handles&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;GpuPipeline;&lt;br /&gt;struct&amp;nbsp;GpuTexture;&lt;br /&gt;struct&amp;nbsp;GpuDepthStencilState;&lt;br /&gt;struct&amp;nbsp;GpuBlendState;&lt;br /&gt;struct&amp;nbsp;GpuQueue;&lt;br /&gt;struct&amp;nbsp;GpuCommandBuffer;&lt;br /&gt;struct&amp;nbsp;GpuSemaphore;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Enums&lt;/span&gt;&lt;br /&gt;enum&amp;nbsp;MEMORY&amp;nbsp;{&amp;nbsp;MEMORY_DEFAULT,&amp;nbsp;MEMORY_GPU,&amp;nbsp;MEMORY_READBACK&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;CULL&amp;nbsp;{&amp;nbsp;CULL_CCW,&amp;nbsp;CULL_CW,&amp;nbsp;CULL_ALL,&amp;nbsp;CULL_NONE&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;DEPTH_FLAGS&amp;nbsp;{&amp;nbsp;DEPTH_READ&amp;nbsp;=&amp;nbsp;0x1,&amp;nbsp;DEPTH_WRITE&amp;nbsp;=&amp;nbsp;0x2&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;OP&amp;nbsp;{&amp;nbsp;OP_NEVER,&amp;nbsp;OP_LESS,&amp;nbsp;OP_EQUAL,&amp;nbsp;OP_LESS_EQUAL,&amp;nbsp;OP_GREATER,&amp;nbsp;OP_NOT_EQUAL,&amp;nbsp;OP_GREATER_EQUAL,&amp;nbsp;OP_ALWAYS&amp;nbsp;};&amp;nbsp;&lt;br /&gt;enum&amp;nbsp;BLEND&amp;nbsp;{&amp;nbsp;BLEND_ADD,&amp;nbsp;BLEND_SUBTRACT,&amp;nbsp;BLEND_REV_SUBTRACT,&amp;nbsp;BLEND_MIN,&amp;nbsp;BLEND_MAX&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;FACTOR&amp;nbsp;{&amp;nbsp;FACTOR_ZERO,&amp;nbsp;FACTOR_ONE,&amp;nbsp;FACTOR_SRC_COLOR,&amp;nbsp;FACTOR_DST_COLOR,&amp;nbsp;FACTOR_SRC_ALPHA,&amp;nbsp;...&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;TOPOLOGY&amp;nbsp;{&amp;nbsp;TOPOLOGY_TRIANGLE_LIST,&amp;nbsp;TOPOLOGY_TRIANGLE_STRIP,&amp;nbsp;TOPOLOGY_TRIANGLE_FAN&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;TEXTURE&amp;nbsp;{&amp;nbsp;TEXTURE_1D,&amp;nbsp;TEXTURE_2D,&amp;nbsp;TEXTURE_3D,&amp;nbsp;TEXTURE_CUBE,&amp;nbsp;TEXTURE_2D_ARRAY,&amp;nbsp;TEXTURE_CUBE_ARRAY&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;FORMAT&amp;nbsp;{&amp;nbsp;FORMAT_NONE,&amp;nbsp;FORMAT_RGBA8_UNORM,&amp;nbsp;FORMAT_D32_FLOAT,&amp;nbsp;FORMAT_RG11B10_FLOAT,&amp;nbsp;FORMAT_RGB10_A2_UNORM,&amp;nbsp;...&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;USAGE_FLAGS&amp;nbsp;{&amp;nbsp;USAGE_SAMPLED,&amp;nbsp;USAGE_STORAGE,&amp;nbsp;USAGE_COLOR_ATTACHMENT,&amp;nbsp;USAGE_DEPTH_STENCIL_ATTACHMENT,&amp;nbsp;...&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;STAGE&amp;nbsp;{&amp;nbsp;STAGE_TRANSFER,&amp;nbsp;STAGE_COMPUTE,&amp;nbsp;STAGE_RASTER_COLOR_OUT,&amp;nbsp;STAGE_PIXEL_SHADER,&amp;nbsp;STAGE_VERTEX_SHADER,&amp;nbsp;...&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;HAZARD_FLAGS&amp;nbsp;{&amp;nbsp;HAZARD_DRAW_ARGUMENTS&amp;nbsp;=&amp;nbsp;0x1,&amp;nbsp;HAZARD_DESCRIPTORS&amp;nbsp;=&amp;nbsp;0x2,&amp;nbsp;,&amp;nbsp;HAZARD_DEPTH_STENCIL&amp;nbsp;=&amp;nbsp;0x4&amp;nbsp;};&lt;br /&gt;enum&amp;nbsp;SIGNAL&amp;nbsp;{&amp;nbsp;SIGNAL_ATOMIC_SET,&amp;nbsp;SIGNAL_ATOMIC_MAX,&amp;nbsp;SIGNAL_ATOMIC_OR,&amp;nbsp;...&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Structs&lt;/span&gt;&lt;br /&gt;struct&amp;nbsp;Stencil&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OP&amp;nbsp;test&amp;nbsp;=&amp;nbsp;OP_ALWAYS,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OP&amp;nbsp;failOp&amp;nbsp;=&amp;nbsp;OP_KEEP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OP&amp;nbsp;passOp&amp;nbsp;=&amp;nbsp;OP_KEEP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OP&amp;nbsp;depthFailOp&amp;nbsp;=&amp;nbsp;OP_KEEP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;reference&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;GpuDepthStencilDesc&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DEPTH_FLAGS&amp;nbsp;depthMode&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OP&amp;nbsp;depthTest&amp;nbsp;=&amp;nbsp;OP_ALWAYS;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float&amp;nbsp;depthBias&amp;nbsp;=&amp;nbsp;0.0f;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float&amp;nbsp;depthBiasSlopeFactor&amp;nbsp;=&amp;nbsp;0.0f;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float&amp;nbsp;depthBiasClamp&amp;nbsp;=&amp;nbsp;0.0f;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;stencilReadMask&amp;nbsp;=&amp;nbsp;0xff;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;stencilWriteMask&amp;nbsp;=&amp;nbsp;0xff;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Stencil&amp;nbsp;stencilFront;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Stencil&amp;nbsp;stencilBack;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;GpuBlendDesc&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BLEND&amp;nbsp;colorOp&amp;nbsp;=&amp;nbsp;BLEND_ADD,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FACTOR&amp;nbsp;srcColorFactor&amp;nbsp;=&amp;nbsp;FACTOR_ONE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FACTOR&amp;nbsp;dstColorFactor&amp;nbsp;=&amp;nbsp;FACTOR_ZERO;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BLEND&amp;nbsp;alphaOp&amp;nbsp;=&amp;nbsp;BLEND_ADD;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FACTOR&amp;nbsp;srcAlphaFactor&amp;nbsp;=&amp;nbsp;FACTOR_ONE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FACTOR&amp;nbsp;dstAlphaFactor&amp;nbsp;=&amp;nbsp;FACTOR_ZERO;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;colorWriteMask&amp;nbsp;=&amp;nbsp;0xf;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;ColorTarget&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FORMAT&amp;nbsp;format&amp;nbsp;=&amp;nbsp;FORMAT_NONE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;writeMask&amp;nbsp;=&amp;nbsp;0xf;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;GpuRasterDesc&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TOPOLOGY&amp;nbsp;topology&amp;nbsp;=&amp;nbsp;TOPOLOGY_TRIANGLE_LIST;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CULL&amp;nbsp;cull&amp;nbsp;=&amp;nbsp;CULL_NONE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool&amp;nbsp;alphaToCoverage&amp;nbsp;=&amp;nbsp;false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool&amp;nbsp;supportDualSourceBlending&amp;nbsp;=&amp;nbsp;false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;sampleCount&amp;nbsp;=&amp;nbsp;1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FORMAT&amp;nbsp;depthFormat&amp;nbsp;=&amp;nbsp;FORMAT_NONE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FORMAT&amp;nbsp;stencilFormat&amp;nbsp;=&amp;nbsp;FORMAT_NONE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Span&amp;lt;ColorTarget&amp;gt;&amp;nbsp;colorTargets&amp;nbsp;=&amp;nbsp;{};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GpuBlendDesc*&amp;nbsp;blendstate&amp;nbsp;=&amp;nbsp;nullptr;&amp;nbsp;//&amp;nbsp;optional&amp;nbsp;embedded&amp;nbsp;blend&amp;nbsp;state&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;GpuTextureDesc&lt;br /&gt;{&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TEXTURE&amp;nbsp;type&amp;nbsp;=&amp;nbsp;TEXTURE_2D;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32x3&amp;nbsp;dimensions;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;mipCount&amp;nbsp;=&amp;nbsp;1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;layerCount&amp;nbsp;=&amp;nbsp;1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;sampleCount&amp;nbsp;=&amp;nbsp;1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FORMAT&amp;nbsp;format&amp;nbsp;=&amp;nbsp;FORMAT_NONE;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;USAGE_FLAGS&amp;nbsp;usage&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;GpuViewDesc&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FORMAT&amp;nbsp;format&amp;nbsp;=&amp;nbsp;FORMAT_NONE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;baseMip&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;mipCount&amp;nbsp;=&amp;nbsp;ALL_MIPS;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint16&amp;nbsp;baseLayer&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint16&amp;nbsp;layerCount&amp;nbsp;=&amp;nbsp;ALL_LAYERS;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;GpuTextureSizeAlign&amp;nbsp;{&amp;nbsp;size_t&amp;nbsp;size;&amp;nbsp;size_t&amp;nbsp;align;&amp;nbsp;};&lt;br /&gt;struct&amp;nbsp;GpuTextureDescriptor&amp;nbsp;{&amp;nbsp;uint64[4]&amp;nbsp;data;&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Memory&lt;/span&gt;&lt;br /&gt;void*&amp;nbsp;gpuMalloc(size_t&amp;nbsp;bytes,&amp;nbsp;MEMORY&amp;nbsp;memory&amp;nbsp;=&amp;nbsp;MEMORY_DEFAULT);&lt;br /&gt;void*&amp;nbsp;gpuMalloc(size_t&amp;nbsp;bytes,&amp;nbsp;size_t&amp;nbsp;align,&amp;nbsp;MEMORY&amp;nbsp;memory&amp;nbsp;=&amp;nbsp;MEMORY_DEFAULT);&lt;br /&gt;void&amp;nbsp;gpuFree(void&amp;nbsp;*ptr);&lt;br /&gt;void*&amp;nbsp;gpuHostToDevicePointer(void&amp;nbsp;*ptr);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Textures&lt;/span&gt;&lt;br /&gt;GpuTextureSizeAlign&amp;nbsp;gpuTextureSizeAlign(GpuTextureDesc&amp;nbsp;desc);&lt;br /&gt;GpuTexture&amp;nbsp;gpuCreateTexture(GpuTextureDesc&amp;nbsp;desc,&amp;nbsp;void*&amp;nbsp;ptrGpu);&lt;br /&gt;GpuTextureDescriptor&amp;nbsp;gpuTextureViewDescriptor(GpuTexture&amp;nbsp;texture,&amp;nbsp;GpuViewDesc&amp;nbsp;desc);&lt;br /&gt;GpuTextureDescriptor&amp;nbsp;gpuRWTextureViewDescriptor(GpuTexture&amp;nbsp;texture,&amp;nbsp;GpuViewDesc&amp;nbsp;desc);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Pipelines&lt;/span&gt;&lt;br /&gt;GpuPipeline&amp;nbsp;gpuCreateComputePipeline(ByteSpan&amp;nbsp;computeIR);&lt;br /&gt;GpuPipeline&amp;nbsp;gpuCreateGraphicsPipeline(ByteSpan&amp;nbsp;vertexIR,&amp;nbsp;ByteSpan&amp;nbsp;pixelIR,&amp;nbsp;GpuRasterDesc&amp;nbsp;desc);&lt;br /&gt;GpuPipeline&amp;nbsp;gpuCreateGraphicsMeshletPipeline(ByteSpan&amp;nbsp;meshletIR,&amp;nbsp;ByteSpan&amp;nbsp;pixelIR,&amp;nbsp;GpuRasterDesc&amp;nbsp;desc);&lt;br /&gt;void&amp;nbsp;gpuFreePipeline(GpuPipeline&amp;nbsp;pipeline);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;State&amp;nbsp;objects&lt;/span&gt;&lt;br /&gt;GpuDepthStencilState&amp;nbsp;gpuCreateDepthStencilState(GpuDepthStencilDesc&amp;nbsp;desc);&lt;br /&gt;GpuBlendState&amp;nbsp;gpuCreateBlendState(GpuBlendDesc&amp;nbsp;desc);&lt;br /&gt;void&amp;nbsp;gpuFreeDepthStencilState(GpuDepthStencilState&amp;nbsp;state);&lt;br /&gt;void&amp;nbsp;gpuFreeBlendState(GpuBlendState&amp;nbsp;state);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Queue&lt;/span&gt;&lt;br /&gt;GpuQueue&amp;nbsp;gpuCreateQueue(/*&amp;nbsp;DEVICE&amp;nbsp;&amp;amp;&amp;nbsp;QUEUE&amp;nbsp;CREATION&amp;nbsp;DETAILS&amp;nbsp;OMITTED&amp;nbsp;*/);&lt;br /&gt;GpuCommandBuffer&amp;nbsp;gpuStartCommandRecording(GpuQueue&amp;nbsp;queue);&lt;br /&gt;void&amp;nbsp;gpuSubmit(GpuQueue&amp;nbsp;queue,&amp;nbsp;Span&amp;lt;GpuCommandBuffer&amp;gt;&amp;nbsp;commandBuffers);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Semaphores&lt;/span&gt;&lt;br /&gt;GpuSemaphore&amp;nbsp;gpuCreateSemaphore(uint64&amp;nbsp;initValue);&lt;br /&gt;void&amp;nbsp;gpuWaitSemaphore(GpuSemaphore&amp;nbsp;sema,&amp;nbsp;uint64&amp;nbsp;value);&lt;br /&gt;void&amp;nbsp;gpuDestroySemaphore(GpuSemaphore&amp;nbsp;sema);&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;//&amp;nbsp;Commands&lt;/span&gt;&lt;br /&gt;void&amp;nbsp;gpuMemCpy(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;destGpu,&amp;nbsp;void*&amp;nbsp;srcGpu,);&lt;br /&gt;void&amp;nbsp;gpuCopyToTexture(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;destGpu,&amp;nbsp;void*&amp;nbsp;srcGpu,&amp;nbsp;GpuTexture&amp;nbsp;texture);&lt;br /&gt;void&amp;nbsp;gpuCopyFromTexture(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;destGpu,&amp;nbsp;void*&amp;nbsp;srcGpu,&amp;nbsp;GpuTexture&amp;nbsp;texture);&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;gpuSetActiveTextureHeapPtr(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void&amp;nbsp;*ptrGpu);&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;gpuBarrier(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;STAGE&amp;nbsp;before,&amp;nbsp;STAGE&amp;nbsp;after,&amp;nbsp;HAZARD_FLAGS&amp;nbsp;hazards&amp;nbsp;=&amp;nbsp;0);&lt;br /&gt;void&amp;nbsp;gpuSignalAfter(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;STAGE&amp;nbsp;before,&amp;nbsp;void&amp;nbsp;*ptrGpu,&amp;nbsp;uint64&amp;nbsp;value,&amp;nbsp;SIGNAL&amp;nbsp;signal);&lt;br /&gt;void&amp;nbsp;gpuWaitBefore(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;STAGE&amp;nbsp;after,&amp;nbsp;void&amp;nbsp;*ptrGpu,&amp;nbsp;uint64&amp;nbsp;value,&amp;nbsp;OP&amp;nbsp;op,&amp;nbsp;HAZARD_FLAGS&amp;nbsp;hazards&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;uint64&amp;nbsp;mask&amp;nbsp;=&amp;nbsp;~0);&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;gpuSetPipeline(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;GpuPipeline&amp;nbsp;pipeline);&lt;br /&gt;void&amp;nbsp;gpuSetDepthStencilState(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;GpuDepthStencilState&amp;nbsp;state);&lt;br /&gt;void&amp;nbsp;gpuSetBlendState(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;GpuBlendState&amp;nbsp;state);&amp;nbsp;&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;gpuDispatch(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;dataGpu,&amp;nbsp;uvec3&amp;nbsp;gridDimensions);&lt;br /&gt;void&amp;nbsp;gpuDispatchIndirect(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;dataGpu,&amp;nbsp;void*&amp;nbsp;gridDimensionsGpu);&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;gpuBeginRenderPass(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;GpuRenderPassDesc&amp;nbsp;desc);&lt;br /&gt;void&amp;nbsp;gpuEndRenderPass(GpuCommandBuffer&amp;nbsp;cb);&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;gpuDrawIndexedInstanced(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;vertexDataGpu,&amp;nbsp;void*&amp;nbsp;pixelDataGpu,&amp;nbsp;void*&amp;nbsp;indicesGpu,&amp;nbsp;uint32&amp;nbsp;indexCount,&amp;nbsp;uint32&amp;nbsp;instanceCount);&lt;br /&gt;void&amp;nbsp;gpuDrawIndexedInstancedIndirect(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;vertexDataGpu,&amp;nbsp;void*&amp;nbsp;pixelDataGpu,&amp;nbsp;void*&amp;nbsp;indicesGpu,&amp;nbsp;void*&amp;nbsp;argsGpu);&lt;br /&gt;void&amp;nbsp;gpuDrawIndexedInstancedIndirectMulti(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;dataVxGpu,&amp;nbsp;uint32&amp;nbsp;vxStride,&amp;nbsp;void*&amp;nbsp;dataPxGpu,&amp;nbsp;uint32&amp;nbsp;pxStride,&amp;nbsp;void*&amp;nbsp;argsGpu,&amp;nbsp;void*&amp;nbsp;drawCountGpu);&lt;br /&gt;&lt;br /&gt;void&amp;nbsp;gpuDrawMeshlets(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;meshletDataGpu,&amp;nbsp;void*&amp;nbsp;pixelDataGpu,&amp;nbsp;uvec3&amp;nbsp;dim);&lt;br /&gt;void&amp;nbsp;gpuDrawMeshletsIndirect(GpuCommandBuffer&amp;nbsp;cb,&amp;nbsp;void*&amp;nbsp;meshletDataGpu,&amp;nbsp;void*&amp;nbsp;pixelDataGpu,&amp;nbsp;void&amp;nbsp;*dimGpu);&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Tooling&lt;/h2&gt;
&lt;p data-end=&quot;532&quot; data-start=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;버퍼와 텍스처 객체를 바인딩하지도 않고, 메모리 레이아웃을 명시적으로 설명하는 API도 호출하지 않는 코드를 어떻게 디버그할 수 있을까? C/C++ 디버거는 수십 년 동안 그런 일을 해왔다. 소프트웨어의 메모리 레이아웃을 설명하기 위한 특별한 운영체제 API는 없다. 디버거는 64비트 포인터 체인을 따라갈 수 있고, 컴파일러가 제공하는 디버그 심볼 데이터를 사용할 수 있다. 여기에는 구조체와 클래스의 메모리 레이아웃도 포함된다. CUDA와 Metal은 완전한 64비트 포인터 시맨틱을 갖는 C/C++ 기반 셰이딩 언어를 사용한다. 둘 다 포인터 체인을 문제없이 따라가는 견고한 디버거를 갖고 있다. 텍스처 디스크립터 힙은 그저 GPU 메모리다. 디버거는 이를 인덱싱해 텍스처 디스크립터를 로드하고, 디스크립터 데이터를 보여주며, 텍셀을 시각화할 수 있다. 이런 것들은 Xcode Metal 디버거에서 이미 동작한다. 어떤 GPU 주소의 어떤 구조체 안에 있는 텍스처나 샘플러 핸들을 클릭해도, 디버거가 그것을 시각화해준다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;현대 GPU는 메모리를 가상화한다. 각 프로세스는 자신의 페이지 테이블을 가진다. GPU 캡처에는 자체 가상 주소 공간을 가진 별도의 리플레이어 프로세스가 있다. 리플레이어가 모든 할당을 단순히 다시 재생(replay)한다면, 각 메모리 할당은 서로 다른 GPU 가상 주소를 받게 된다. 레거시 API에서는 GPU 주소를 데이터 구조체에 직접 저장할 수 없었기 때문에 이것이 문제가 되지 않았다. 하지만 현대 API에서는 리플레이어가 정확히 동일한 GPU 가상 메모리 레이아웃을 미러링하도록 강제하는 특수한 리플레이 메모리 할당 API가 필요하다. DX12와 Vulkan BDA에는 이를 위한 공개 API가 있다: RecreateAt과 VkMemoryOpaqueCaptureAddressAllocateInfo. Metal과 CUDA 디버거도 내부의 문서화되지 않은 API를 사용해 같은 일을 한다. RenderDoc 같은 오픈 소스 도구가 동작하려면 공개 API가 더 바람직하다.&lt;br /&gt;&lt;br /&gt;원시 포인터는 보안 문제를 가져오지 않을까? 다른 앱의 메모리를 읽고/쓸 수 있지 않을까? 가상 메모리 때문에 이는 불가능하다. 접근할 수 있는 것은 자기 자신의 메모리 페이지뿐이다. 실수로 오래된 포인터를 쓰거나 오버플로가 발생하면 페이지 폴트가 발생한다. 페이지 폴트는 기존의 버퍼 기반 API에서도 가능하다. DirectX 12와 Vulkan은 스토리지(바이트어드레스/스트럭처드) 버퍼 주소를 클램프하지 않는다. OOB(범위 밖 접근)는 페이지 폴트를 일으킨다. 사용자가 메모리 힙을 해제한 뒤에도 오래된 버퍼/텍스처 디스크립터를 계속 사용해 페이지 폴트를 일으킬 수도 있다. 본질적으로 달라지는 것은 없다. 매핑되지 않은 영역에 접근하면 페이지 폴트가 발생하고 애플리케이션은 크래시한다. 이는 C/C++ 프로그래머에게 익숙한 동작이다. 견고함(robustness)이 필요하다면 ptr + size 쌍을 사용할 수 있다. WebGPU가 정확히 이런 방식으로 구현되어 있다. WebGPU 셰이더 컴파일러(Tint 또는 Naga)는 정점 접근(인덱스 버퍼 값 범위 밖)까지 포함해 각 버퍼 접근마다 추가 클램프 명령을 생성한다. WebGL은 인덱스 버퍼 데이터를 다른 데이터와 함께 셰이딩하는 것을 허용하지 않았다. WebGL은 CPU에서 인덱스를 훑어 검사했는데(그 결과 인덱스 버퍼 업데이트가 매우 느려졌다). 그 당시에는 커스텀 버텍스 페치가 불가능했다. 셰이더가 실행되기도 전에 하드웨어가 페이지 폴트를 내버렸기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;532&quot; data-start=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Translation layers&lt;/h3&gt;
&lt;p data-end=&quot;185&quot; data-start=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;기존 소프트웨어를 실행할 수 있는 능력은 매우 중요하다. ANGLE, Proton, MoltenVK 같은 번역 레이어는 레거시 API의 이식성과 폐기(deprecation) 과정에서 핵심적인 역할을 한다. 이제 DirectX 12, Vulkan, Metal을 우리의 새로운 API로 번역하는 방법을 살펴보자.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;MoltenVK(Vulkan &amp;rarr; Metal 번역 레이어)는 Vulkan의 버퍼 중심 API가 Metal의 64비트 포인터 기반 생태계로 번역될 수 있음을 증명한다. MoltenVK는 Vulkan의 디스크립터 세트를 Metal의 argument buffer로 변환한다. 생성된 argument buffer는 각 버퍼 바인딩당 64비트 GPU 포인터 하나, 각 텍스처 바인딩당 64비트 텍스처 ID 하나를 포함하는 표준 GPU 구조체다. 우리는 더 나은 방식을 사용할 수 있다. 각 디스크립터 세트에 대해 텍스처 힙에 연속된 범위의 텍스처 디스크립터를 할당하고, 각 텍스처 바인딩마다 64비트 텍스처 ID 대신 단일 32비트 베이스 인덱스를 저장하는 것이다. 이는 우리의 API가 Metal과 달리 사용자 관리 텍스처 힙을 가지기 때문에 가능하다.&lt;br /&gt;&lt;br /&gt;MoltenVK는 디스크립터 세트를 Metal API 루트 바인딩 슬롯에 매핑한다. 우리는 최대 8개의 64비트 포인터 필드를 가진 루트 구조체를 생성하고, 각 필드는 디스크립터 세트 구조체를 가리킨다. 루트 상수는 값 필드로 변환되고, 루트 디스크립터(루트 버퍼)는 64비트 포인터로 변환된다. GPU 드라이버가 루트 구조체 필드를 유니폼/스칼라 레지스터에 프리로드한다고 가정하면, 효율성은 동일해야 한다.&lt;br /&gt;&lt;br /&gt;우리 API는 Metal과 같은 64비트 포인터 시맨틱을 사용한다. 셰이더에서의 버퍼 로드/스토어 명령을 번역할 때 MoltenVK가 사용하는 기법을 그대로 적용할 수 있다. MoltenVK는 Vulkan의 buffer device address 확장도 번역 지원한다.&lt;br /&gt;&lt;br /&gt;Proton(DX12 &amp;rarr; Vulkan 번역 레이어)은 DirectX 12 SM 6.6 디스크립터 힙이 Vulkan의 descriptor buffer 확장으로 번역될 수 있음을 증명한다. Proton은 다른 DirectX 12 기능도 Vulkan으로 변환한다. MoltenVK를 통해 Vulkan &amp;rarr; Metal 번역이 가능하다는 점을 이미 보였으므로, 간접적으로 DirectX 12 &amp;rarr; Metal 번역도 가능함이 증명된다. MoltenVK에서 가장 부족한 기능은 SM 6.6 스타일 디스크립터 힙(Vulkan descriptor buffer 확장)이다. Metal은 디스크립터 힙을 사용자에게 직접 노출하지 않는다. 우리가 제안하는 새로운 API는 이러한 제한이 없다. 우리의 디스크립터 힙 시맨틱은 SM 6.6 디스크립터 힙의 상위 집합이며, Vulkan descriptor buffer 확장과도 매우 유사하다. 번역은 직관적이다. Vulkan 확장은 디스크립터 무효화 플래그도 추가하는데, 이는 우리의 HAZARD_DESCRIPTORS와 일치한다. DirectX 12 디스크립터 힙 API 역시 GPU 메모리의 원시 디스크립터 배열 위에 얇은 래퍼일 뿐이므로 번역이 쉽다.&lt;br /&gt;&lt;br /&gt;Metal 4.0을 지원하려면 Metal의 드라이버 관리 텍스처 디스크립터 힙을 구현해야 한다. 이는 우리의 텍스처 힙 위에 단순한 프리리스트를 구현함으로써 가능하다. Metal은 64비트 텍스처 핸들을 사용하는데, 이는 최신 Apple Silicon에서 직접 힙 인덱스로 구현된다. Metal은 셰이더에서 텍스처 핸들을 텍스처처럼 직접 사용할 수 있게 한다. 이는 textureHeap[uint64(handle)]에 대한 문법적 설탕에 불과하다. Metal 텍스처 핸들은 셰이더 번역기를 통해 uint64로 변환되어 동일한 GPU 메모리 레이아웃을 유지한다.&lt;br /&gt;&lt;br /&gt;우리 API는 버텍스 버퍼를 지원하지 않는다. WebGPU 역시 하드웨어 버텍스 버퍼를 사용하지 않지만, 고전적인 버텍스 버퍼 추상화를 구현한다. WGSL 셰이더 번역기(Tint 또는 Naga)는 각 버텍스 스트림에 대해 하나의 스토리지 버퍼 바인딩을 추가하고, 버텍스 셰이더 시작 부분에 버텍스 로드 명령을 생성한다. 커스텀 버텍스 페치는 OOB 동작을 방지하기 위한 클램프 명령을 삽입할 수 있다. 악의적인 웹사이트가 브라우저를 크래시시키는 일은 없다. 우리의 셰이더 번역기 역시 각 버텍스 스트림에 대해 루트 구조체에 64비트 포인터를 추가하고, 해당 레이아웃에 맞는 구조체를 생성하며, 버텍스 셰이더 시작 부분에 버텍스 구조체 로드 명령을 생성한다.&lt;br /&gt;&lt;br /&gt;이로써 DirectX 12, Vulkan, Metal 애플리케이션을 우리의 새로운 API 위에서 실행하기 위한 번역 레이어를 작성하는 것이 가능함을 보였다. WebGPU는 브라우저에서 이러한 API 위에 구현되어 있으므로, WebGPU 애플리케이션도 실행할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;185&quot; data-start=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Min spec hardware&lt;/h3&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Nvidia Turing&lt;/b&gt;(RTX 2000 시리즈, 2018)은 레이 트레이싱, 텐서 코어, 메시 셰이더, 저지연 raw 메모리 경로, 더 크고 빠른 캐시, 스칼라 유닛, 보조 정수 파이프라인 등 미래 지향적인 여러 기능을 도입했다. 공식적인 PCIe ReBAR 지원은 RTX 3000 시리즈와 함께 시작되었지만, 이를 지원하는 비공식 Turing 드라이버도 존재해 하드웨어 자체는 이를 지원할 수 있음을 보여준다. 이 7년 된 GPU는 우리가 필요로 하는 모든 기능을 지원한다. Nvidia는 2025년 가을에 GTX 1000 시리즈 드라이버 지원을 종료했다. 현재 지원 중인 모든 Nvidia GPU는 우리의 새로운 API를 지원할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AMD RDNA2&lt;/b&gt;(RX 6000 시리즈, 2020)는 레이 트레이싱과 메시 셰이더를 통해 Nvidia의 기능 세트에 맞섰다. 그보다 1년 앞서 RDNA 1은 코히어런트 L2$, 새로운 L1$ 레벨, 빠른 L0$, 범용 DCC 읽기/쓰기 경로, fastpath 비필터 로드, 최신 SIMD32 아키텍처를 도입했다. PCIe ReBAR는 &amp;ldquo;Smart Access Memory&amp;rdquo;라는 브랜드명으로 공식 지원된다. 이 5년 된 GPU는 우리가 필요로 하는 모든 기능을 지원한다. AMD는 이미 2021년에 GCN 드라이버 지원을 종료했다. 현재 RDNA 1과 RDNA 2는 버그 수정과 보안 업데이트만 받고 있으며, RDNA 3가 게임 최적화를 받는 가장 오래된 GPU다. 현재 지원되는 모든 AMD GPU는 우리의 API를 지원할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Intel Alchemist / Xe1&lt;/b&gt;(2022)은 SM 6.6 글로벌 인덱서블 힙을 지원한 최초의 Intel 칩이다. 이 칩들은 레이 트레이싱, 메시 셰이더, PCIe ReBAR(외장형), UMA(내장형)도 지원한다. 이 3년 된 Intel GPU들은 우리가 필요로 하는 모든 기능을 지원한다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Apple M1 / A14&lt;/b&gt;(MacBook M1, iPhone 12, 2020)은 Metal 4.0을 지원한다. Metal 4.0은 CPU에 대한 GPU 메모리 가시성을 보장하며(폰과 컴퓨터 모두 UMA), 사용자가 64비트 포인터와 64비트 텍스처 핸들을 GPU 메모리에 직접 기록할 수 있게 한다. Metal 4.0에는 새로운 residency set API가 추가되어, 기존 useResource/useHeap API의 바인드리스 리소스 관리에서의 중요한 사용성 문제를 해결했다. iOS 26은 여전히 iPhone 11을 지원한다. 현재로서는 개발자가 Metal 4.0을 요구하는 앱을 출시할 수 없다. iOS 27에서는 아마도 내년에 iPhone 11 지원이 종료될 가능성이 크다. Mac에서는 Intel Mac 지원을 중단하면 Metal 4.0이 보장된다. M1부터 M5까지 5세대, 5년에 해당한다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ARM Mali-G710&lt;/b&gt;(2021)은 ARM의 첫 번째 현대적 아키텍처다. 새로운 커맨드 스트림 프런트엔드(CSF)를 도입해 드로우 콜 빌딩에 대한 CPU 의존성을 줄이고, 멀티 드로우 간접과 컴퓨트 큐 같은 중요한 기능을 추가했다. 비균일 인덱스 텍스처 샘플링 성능이 크게 향상되었고, AFBC 무손실 압축기는 이제 16비트 부동소수점 타깃을 지원한다. G710은 Vulkan BDA와 descriptor buffer 확장을 지원하며, 향후 드라이버에서 2025년 unified image layout 확장도 지원할 수 있다. Mali-G715(2022)는 레이 트레이싱 지원을 도입했다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Qualcomm Adreno 650&lt;/b&gt;(2019)은 Vulkan BDA, descriptor buffer, unified image layout 확장을 지원하며, 최신 Turnip 오픈소스 드라이버와 함께 16비트 저장/연산, dynamic rendering, 확장 동적 상태를 지원한다. Adreno 740(2022)는 레이 트레이싱을 도입했다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PowerVR DXT&lt;/b&gt;(Pixel 10, 2025)는 PowerVR의 첫 번째 Vulkan descriptor buffer 및 buffer device address 확장 지원 아키텍처다. 또한 64비트 원자 연산, 8비트 및 16비트 저장/연산, dynamic rendering, 확장 동적 상태 및 우리가 요구하는 모든 기능을 지원한다.&lt;/p&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p data-end=&quot;452&quot; data-start=&quot;9&quot; data-ke-size=&quot;size16&quot;&gt;현대 그래픽스 API는 지난 10년간 점진적으로 개선되어 왔다. DirectX 12 출시 6년 후, SM 6.6(2021)는 현대적인 글로벌 텍스처 힙을 도입해 완전한 바인드리스 렌더러 설계를 가능하게 했다. Metal 4.0(2025)과 CUDA는 최소한의 바인딩 API 표면을 갖춘 깔끔한 64비트 포인터 기반 셰이더 아키텍처를 제공한다. Vulkan은 가장 제한적인 표준을 갖고 있지만, buffer device address(2020), descriptor buffer(2022), unified image layouts(2025) 같은 확장을 통해 현대적인 바인드리스 인프라를 지원하게 되었다. 그러나 툴링은 여전히 뒤처져 있다. 현재로서는 우리의 모든 요구를 충족하는 단일 API는 없지만, 각 API의 장점을 결합하면 현대 하드웨어에 최적화된 이상적인 API를 만들 수 있다.&lt;br /&gt;&lt;br /&gt;10년 전, 현대 API는 CPU 주도 바인딩 모델을 기준으로 설계되었다. 새로운 바인드리스 기능은 선택적 기능이나 확장으로 제시되었다. 과감한 단절(clean break)은 사용성을 개선하고 API 비대화와 드라이버 복잡성을 크게 줄일 수 있다. 업계 전체를 새로운 API로 이끄는 것은 매우 어렵다. 하지만 벤더들이 새로운 메이저 API 버전(Vulkan 2.0, DirectX 13)에서 하위 호환성을 과감히 포기하고, 오늘날의 완전한 바인드리스 GPU 아키텍처를 수용하길 기대한다. 새로운 바인드리스 API 설계는 API와 게임 엔진 RHI 사이의 불일치를 해결해 해시 맵과 세밀한 리소스 추적을 제거할 수 있게 한다. Metal 4.0은 이 목표에 근접했지만, 글로벌 인덱서블 텍스처 힙이 아직 없다. 64비트 텍스처 핸들 하나로는 텍스처 범위를 표현할 수 없다.&lt;br /&gt;&lt;br /&gt;HLSL과 GLSL 셰이딩 언어는 20년 이상 전에 1:1 요소 단위 변환 함수(버텍스, 픽셀, 지오메트리, 헐, 도메인 등) 프레임워크로 설계되었다. 메모리 접근은 추상화되어 있고, 포인터를 지원하지 않기 때문에 배열 처리도 번거롭다. 20년이 지났지만 HLSL과 GLSL은 라이브러리 생태계를 구축하는 데 실패했다. 반면 CUDA는 메모리를 직접 노출하고, 새로운 기능(예: AI 텐서 코어)을 intrinsic으로 제공하는 조합 가능한 언어다. CUDA는 폭넓은 라이브러리 생태계를 갖추었고, 이는 Nvidia를 4조 달러 가치 기업으로 끌어올렸다. 우리는 여기서 배워야 한다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;WebGPU 참고 :&amp;nbsp;&lt;/b&gt;WebGPU 설계는 10년 된 Vulkan 1.0 코어를 기반으로 하며 추가적인 제한을 둔다. WebGPU는 바인드리스 리소스, 64비트 GPU 포인터, 영구 매핑 GPU 메모리를 지원하지 않는다. DirectX 11과 Vulkan 1.0의 혼합처럼 보인다. 웹 그래픽스에는 큰 진전이지만, 현대적인 바인드리스 API 기준에는 미치지 못한다. WebGPU에 대해서는 별도의 블로그 글에서 다룰 예정이다. &lt;br /&gt;&lt;br /&gt;내 프로토타입 API는 최신 API들의 장점을 결합했을 때 오늘날 현대 GPU 아키텍처로 무엇이 가능한지를 보여준다. DirectX 11과 Metal 1.0보다 사용하기 쉽고, 동시에 DirectX 12와 Vulkan보다 더 나은 성능과 유연성을 제공하는 API를 만드는 것이 가능하다. 우리는 현대 바인드리스 하드웨어를 받아들여야 한다.&lt;/p&gt;
&lt;p data-end=&quot;452&quot; data-start=&quot;9&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Appendix&lt;/h3&gt;
&lt;p data-end=&quot;452&quot; data-start=&quot;9&quot; data-ke-size=&quot;size16&quot;&gt;모든 예제 코드에서 사용된 간단한 사용자 공간 GPU 범프 할당기다. 임시 할당기 생성자에서 gpuHostToDevicePointer를 한 번 호출한다. GPU 포인터에 대해 표준 포인터 연산(예: 오프셋)을 수행할 수 있다. 기존 Vulkan/DX12 버퍼 API는 별도의 오프셋을 요구한다. 이는 API와 사용자 코드를 단순화한다(포인터 vs 핸들+오프셋 쌍). 실제 제품 수준의 임시 할당기는 오버플로 처리(확장, 플러시 등)를 구현해야 한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;template&amp;lt;typename&amp;nbsp;T&amp;gt;&lt;br /&gt;struct&amp;nbsp;GPUTempAllocation&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T*&amp;nbsp;cpu;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T*&amp;nbsp;gpu;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;struct&amp;nbsp;GPUBumpAllocator&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;*cpu;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint8&amp;nbsp;*gpu;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;offset&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32&amp;nbsp;size;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TempBumpAllocator(uint32&amp;nbsp;size)&amp;nbsp;:&amp;nbsp;size(size)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cpu&amp;nbsp;=&amp;nbsp;gpuMalloc(size);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gpu&amp;nbsp;=&amp;nbsp;gpuHostToDevicePointer(cpu);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TempAllocation&amp;lt;uint8&amp;gt;&amp;nbsp;alloc(int&amp;nbsp;bytes,&amp;nbsp;int&amp;nbsp;align&amp;nbsp;=&amp;nbsp;16)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;offset&amp;nbsp;=&amp;nbsp;alignRoundUp(offset,&amp;nbsp;align);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(offset&amp;nbsp;+&amp;nbsp;bytes&amp;nbsp;&amp;gt;&amp;nbsp;size)&amp;nbsp;offset&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;//&amp;nbsp;Simple&amp;nbsp;ring&amp;nbsp;wrap&amp;nbsp;(no&amp;nbsp;overflow&amp;nbsp;detection)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TempAllocation&amp;lt;uint8&amp;gt;&amp;nbsp;alloc&amp;nbsp;=&amp;nbsp;{&amp;nbsp;.cpu&amp;nbsp;=&amp;nbsp;cpu&amp;nbsp;+&amp;nbsp;offset,&amp;nbsp;.&amp;nbsp;gpu&amp;nbsp;=&amp;nbsp;gpu&amp;nbsp;+&amp;nbsp;offset&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;offset&amp;nbsp;+=&amp;nbsp;bytes;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;alloc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template&amp;lt;typename&amp;nbsp;T&amp;gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T*&amp;nbsp;alloc(int&amp;nbsp;count&amp;nbsp;=&amp;nbsp;1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TempAllocation&amp;lt;uint8&amp;gt;&amp;nbsp;mem&amp;nbsp;=&amp;nbsp;alloc(sizeof(T)&amp;nbsp;*&amp;nbsp;count,&amp;nbsp;alignof(T));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;TempAllocation&amp;lt;T&amp;gt;&amp;nbsp;{&amp;nbsp;.cpu&amp;nbsp;=&amp;nbsp;(T*)mem.cpu,&amp;nbsp;.&amp;nbsp;gpu&amp;nbsp;=&amp;nbsp;(T*)mem.gpu&amp;nbsp;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>Technical Report/Graphics Tech Reports</category>
      <category>API</category>
      <category>bindless</category>
      <category>DirectX</category>
      <category>Graphics</category>
      <category>metal</category>
      <category>Vulkan</category>
      <category>webGPU</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1520</guid>
      <comments>https://illu.tistory.com/1520#entry1520comment</comments>
      <pubDate>Mon, 23 Feb 2026 17:28:24 +0900</pubDate>
    </item>
    <item>
      <title>[번역] State of HLSL : 2026.2</title>
      <link>https://illu.tistory.com/1519</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;원문 : &lt;a href=&quot;https://www.abolishcrlf.org/2026/02/10/HLSLState.html?fbclid=IwZXh0bgNhZW0CMTEAc3J0YwZhcHBfaWQQMjIyMDM5MTc4ODIwMDg5MgABHgl8W9EXMPw9HJ_v2remHvETZ9yj4FOV7sHOUYPX0RQujg9XxwI-cdM8eExH_aem_UDUl1x35x8I2rKGu0ksVmA&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.abolishcrlf.org/2026/02/10/HLSLState.html?fbclid=IwZXh0bgNhZW0CMTEAc3J0YwZhcHBfaWQQMjIyMDM5MTc4ODIwMDg5MgABHgl8W9EXMPw9HJ_v2remHvETZ9yj4FOV7sHOUYPX0RQujg9XxwI-cdM8eExH_aem_UDUl1x35x8I2rKGu0ksVmA&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;22&quot; data-start=&quot;0&quot; data-ke-size=&quot;size23&quot;&gt;HLSL의 현황: 2026년 2월&lt;/h3&gt;
&lt;p data-end=&quot;22&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;아마도 나는 2025년을, GPU 프로그래밍의 미래 방향에 대해 이야기하다가 누군가가 슬그머니 &amp;ldquo;neural(신경망)&amp;rdquo;이라는 단어를 끼워 넣지 않고는 대화를 이어갈 수 없게 된 해로 기억하게 될 것이다. 개인적으로 나는 신경망의 많은 활용 사례에 대해 회의적인 편이지만, 2025년은 특히 실시간 그래픽스 분야에서 꽤 흥미로운 사용 사례들이 주목받기 시작한 해이기도 하다.&lt;br /&gt;&lt;br /&gt;내가 썩 좋아하지는 않는 표현이지만, 이른바 &amp;ldquo;뉴럴 렌더링(neural rendering)&amp;rdquo;의 부상은 2025년을 규정했고, 올해 HLSL을 둘러싼 논의를 지배했다. 하지만 HLSL 세계에서 일어나고 있는 일이 그것뿐만은 아니다. 그러니 먼저 다른 이야기들부터 살펴본 뒤, 다시 이 주제로 돌아오도록 하자.&lt;/p&gt;
&lt;p data-end=&quot;22&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;20&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Clang에서의 HLSL 현황&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;321&quot; data-start=&quot;22&quot; data-ke-size=&quot;size16&quot;&gt;Microsoft와 Google의 HLSL 팀은 Clang 기반 HLSL 구현을 꾸준히 발전시켜 왔다. 현재 Clang은&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt; [RW]Buffer&lt;/b&gt;&lt;/span&gt;와 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;[RW]StructuredBuffer&lt;/b&gt; &lt;/span&gt;리소스 타입을 지원하며, 곧 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;[RW]ByteAddressBuffer&lt;/b&gt;&lt;/span&gt;도 지원할 예정이다. 또한 HLSL 내장 함수(intrinsic functions)에 대한 지원도 계속 확장하고 있다. 이제 막 그래픽스 셰이더 작업을 시작했으며, 여기에는 셰이더 입력/출력, 행렬 데이터 타입, 텍스처 리소스 등 다양한 기능 지원이 포함될 예정이다.&lt;br /&gt;&lt;br /&gt;현재 우리가 추진 중인 작업의 대부분은 DXC와의 기능 동등성(feature parity)을 맞추기 위한 것이다. 하지만 DXC를 넘어 의미 있는 개선을 이루기 위해 투자하고 있는 몇 가지 영역을 강조하고 싶다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1519_1&quot; id=&quot;footnote_link_1519_1&quot; onmouseover=&quot;tistoryFootnote.show(this, 1519, 1)&quot; onmouseout=&quot;tistoryFootnote.hide(1519, 1)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;1&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p data-end=&quot;364&quot; data-start=&quot;279&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;473&quot; data-start=&quot;451&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;더 나은 루트 시그니처 진단 기능&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;733&quot; data-start=&quot;475&quot; data-ke-size=&quot;size16&quot;&gt;올해 Clang에 새롭게 구현된 매우 인상적인 기능 중 하나는 새로운 루트 시그니처 파서이다(이 작업을 진행한 Finn Plummer에게 감사의 인사를 전한다). 루트 시그니처에 대해서는 여러 이유로 많은 불만이 제기되어 왔는데, 그중 하나가 바로 기묘한 문법 파싱 방식이다. 장기적인 루트 시그니처 개선 방안은 아직 로드맵에 포함되어 있지 않지만, Clang의 새로운 파서는 상당히 훌륭하며, 우리 팀이 얼마나 품질에 중점을 두고 있는지를 잘 보여준다.&lt;/p&gt;
&lt;p data-end=&quot;1010&quot; data-start=&quot;735&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업의 핵심 목표 중 하나는 루트 시그니처 파서에서 나오는 진단 메시지를 최대한 정확한 소스 위치 정보와 함께 제공하는 것이었다. 즉, 루트 시그니처에 오류가 있을 경우, 파서가 가능한 한 많은 정보를 제공하여 오류를 쉽게 찾을 수 있도록 하는 것이다. 이를 위해 새로운 루트 시그니처 파서는 Clang의 파싱 유틸리티, 소스 위치 추적, 진단 시스템을 활용하게된다. 그 결과, DXC에서는 제공할 수 없었던 정확한 소스 위치 기반 진단을 Clang에서는 제공할 수 있게 되었다.&lt;br /&gt;&lt;br /&gt;예를 들어, 다음과 같이 루트 시그니처가 지정된 경우 :&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;#define&amp;nbsp;BasicValidation&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s0,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;13),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s1,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;17),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s2,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;13),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s3,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;13),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s4,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;23),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s5,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;13)&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;364&quot; data-start=&quot;279&quot; data-ke-size=&quot;size16&quot;&gt;DXC는 다음과 같은 진단을 제공하며, 이때 소스 위치는 실제 오류가 있는 지점이 아니라 전처리기 지시문이 시작된 줄을 가리킨다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&amp;lt;source&amp;gt;:40:9:&amp;nbsp;error:&amp;nbsp;root&amp;nbsp;signature&amp;nbsp;error&amp;nbsp;-&amp;nbsp;Static&amp;nbsp;sampler:&amp;nbsp;MaxAnisotropy&amp;nbsp;must&amp;nbsp;be&amp;nbsp;in&amp;nbsp;the&amp;nbsp;range&amp;nbsp;[0&amp;nbsp;to&amp;nbsp;16].&amp;nbsp;&amp;nbsp;17&amp;nbsp;specified.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Clang의 새로운 파서는 매크로 정의 내부의 구체적인 위치를 포함해 훨씬 더 많은 문맥 정보를 제공한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&amp;lt;source&amp;gt;:42:4:&amp;nbsp;error:&amp;nbsp;value&amp;nbsp;must&amp;nbsp;be&amp;nbsp;in&amp;nbsp;the&amp;nbsp;range&amp;nbsp;[0,&amp;nbsp;16]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;42&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s1,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;17),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;&amp;lt;source&amp;gt;:45:4:&amp;nbsp;error:&amp;nbsp;value&amp;nbsp;must&amp;nbsp;be&amp;nbsp;in&amp;nbsp;the&amp;nbsp;range&amp;nbsp;[0,&amp;nbsp;16]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;45&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s4,&amp;nbsp;maxAnisotropy&amp;nbsp;=&amp;nbsp;23),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;2&amp;nbsp;errors&amp;nbsp;generated.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;274&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;Clang이 하나가 아니라 두 개의 오류를 출력한 것을 알 수 있을 것이다. 이것은 DXC의 파서와 Clang의 파서 사이의 또 다른 중요한 차이점이다. DXC 파서는 처음 발견한 오류에서 즉시 중단한다. 따라서 루트 시그니처에 여러 오류가 있는 경우, 하나를 수정한 뒤 셰이더를 다시 컴파일해 다음 오류를 확인하는 과정을 반복해야 한다. 반면 Clang의 새로운 파서는 가능한 한 파싱 오류로부터 복구하고, 한 번의 처리로 더 포괄적인 진단 정보를 제공하기 위해 파싱을 계속 시도한다.&lt;br /&gt;&lt;br /&gt;Clang 파서의 견고함과 오류 복구 능력을 보여주기 위해, 때로는 같은 절 안에 여러 오류가 포함된 다음과 같은 루트 시그니처를 살펴보자.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;#define&amp;nbsp;Recovery&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;CBV(b0,&amp;nbsp;reported_diag,&amp;nbsp;flags&amp;nbsp;=&amp;nbsp;skipped_diag),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;DescriptorTable(&amp;nbsp;&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;&amp;nbsp;&amp;nbsp;UAV(u0,&amp;nbsp;reported_diag),&amp;nbsp;&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;&amp;nbsp;&amp;nbsp;SRV(t0,&amp;nbsp;skipped_diag),&amp;nbsp;&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s0,&amp;nbsp;reported_diag,&amp;nbsp;SRV(t0,&amp;nbsp;reported_diag)&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;01f73ed4-6afc-47b0-a691-64370b78aaa3&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;39&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;이 루트 시그니처에 대해 DXC의 파서는 다음과 같은 진단을 제공한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&amp;lt;source&amp;gt;:63:9:&amp;nbsp;error:&amp;nbsp;root&amp;nbsp;signature&amp;nbsp;error&amp;nbsp;-&amp;nbsp;Unexpected&amp;nbsp;token&amp;nbsp;'reported_diag'&lt;br /&gt;#define&amp;nbsp;Recovery&amp;nbsp;\&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;ce899536-53c4-4fe2-8d21-4861ed777d12&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;39&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;반면 Clang의 새로운 파서는 한 번의 처리로 여러 오류를 식별한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;&amp;lt;source&amp;gt;:64:12:&amp;nbsp;error:&amp;nbsp;invalid&amp;nbsp;parameter&amp;nbsp;of&amp;nbsp;CBV&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;64&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;CBV(b0,&amp;nbsp;reported_diag,&amp;nbsp;flags&amp;nbsp;=&amp;nbsp;skipped_diag),&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;&amp;lt;source&amp;gt;:66:14:&amp;nbsp;error:&amp;nbsp;invalid&amp;nbsp;parameter&amp;nbsp;of&amp;nbsp;UAV&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;66&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;&amp;nbsp;&amp;nbsp;UAV(u0,&amp;nbsp;reported_diag),&amp;nbsp;&quot;&amp;nbsp;\&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;&amp;lt;source&amp;gt;:69:22:&amp;nbsp;error:&amp;nbsp;invalid&amp;nbsp;parameter&amp;nbsp;of&amp;nbsp;StaticSampler&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;69&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s0,&amp;nbsp;reported_diag,&amp;nbsp;SRV(t0,&amp;nbsp;reported_diag)&quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;&amp;lt;source&amp;gt;:69:45:&amp;nbsp;error:&amp;nbsp;invalid&amp;nbsp;parameter&amp;nbsp;of&amp;nbsp;SRV&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;69&amp;nbsp;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;StaticSampler(s0,&amp;nbsp;reported_diag,&amp;nbsp;SRV(t0,&amp;nbsp;reported_diag)&quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;4&amp;nbsp;errors&amp;nbsp;generated.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;88&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;Clang의 파서는 파싱 문맥이 불완전할 수 있기 때문에 항상 모든 오류를 감지할 수 있는 것은 아니지만, DXC의 파서보다 훨씬 더 나은 성능을 보인다.&lt;br /&gt;&lt;br /&gt;우리는 이러한 삶의 질 향상이 Clang을 사용자들에게 훨씬 더 나은 도구로 만들어줄 것이라고 믿으며, 이러한 품질 중심의 개선이 실제로 구현되고 있다는 점에 매우 기대하고 있다. 위의 두 예시는 Finn이 만든 Compiler Explorer 데모에서 가져온 것으로, Clang과 DXC의 진단 차이를 매우 잘 보여준다. 더 많은 예시는 해당 데모를 직접 살펴보고 계속 실험해보길 바란다.&lt;/p&gt;
&lt;p data-end=&quot;88&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;333&quot; data-start=&quot;317&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;오프로드 테스트 스위트&lt;/span&gt;&lt;/h4&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;515&quot; data-start=&quot;335&quot; data-ke-size=&quot;size16&quot;&gt;또 다른 큰 투자 영역은 테스트 인프라이다. DXC의 셰이더 실행 테스트 인프라는 Windows에서의 DirectX만 지원하는데, 이는 HLSL을 점점 크로스 플랫폼 언어로 바라보고 있는 상황에서 상당히 큰 제약으로 작용한다. 또한 이 인프라는 DXC에 매우 밀접하게 결합되어 있어 Clang과 함께 사용하기가 쉽지 않다.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1519_2&quot; id=&quot;footnote_link_1519_2&quot; onmouseover=&quot;tistoryFootnote.show(this, 1519, 2)&quot; onmouseout=&quot;tistoryFootnote.hide(1519, 2)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;2&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;942&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cD018H/dJMcahwBNf5/Kgnvkky6JdhAe3yzqeuIQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cD018H/dJMcahwBNf5/Kgnvkky6JdhAe3yzqeuIQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cD018H/dJMcahwBNf5/Kgnvkky6JdhAe3yzqeuIQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcD018H%2FdJMcahwBNf5%2FKgnvkky6JdhAe3yzqeuIQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;601&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;942&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;233&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;이러한 제약을 해결하기 위해 우리는 LLVM에 &lt;b&gt;Offload Test Suite&lt;/b&gt;라는 새로운 테스트 인프라를 구축했다. 이 새로운 인프라는 일부 유틸리티에서 LLVM에 의존하지만, 테스트 실행 자체는 컴파일러와 소스 언어로부터 분리되어 있어 동일한 테스트를 DXC와 Clang 모두에서 실행할 수 있다. 또한 이 인프라는 DirectX, Vulkan, Metal을 지원하여 폭넓은 테스트 커버리지를 제공한다.&lt;br /&gt;&lt;br /&gt;우리는 이 새로운 인프라를 활용해 Clang 컴파일러 구현에 대한 테스트를 확장하는 동시에, Clang으로 컴파일한 셰이더가 DXC로 컴파일했을 때와 동일하게 동작하는지 확인하고 있다. 이를 통해 사용자들이 보다 원활하게 전환할 수 있기를 기대한다.&lt;br /&gt;&lt;br /&gt;이 인프라에 대해 더 알고 싶다면, 나는 지난가을 LLVM Developer Meeting에서 이에 관한 발표를 진행했으며, HLSL 팀이 이를 어떻게 워크플로에 통합했는지도 소개했다.&lt;/p&gt;
&lt;p data-end=&quot;233&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;d14d83cb-1fa1-474d-a49b-5c6438172569&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-end=&quot;13&quot; data-start=&quot;0&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;HLSL 표준화!&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;참고: 나는 HLSL 표준화에 대해 &lt;a href=&quot;https://devblogs.microsoft.com/directx/standardizing-hlsl/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;DirectX 블로그&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;에 글을 썼다. 좀 더 &amp;ldquo;공식적인&amp;rdquo;(유머도 개성도 밈도 없는) 버전을 읽고 싶다면 그쪽을 참고하라. 그렇지 않다면 마음 단단히 먹고 따라오라!&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;114&quot; data-ke-size=&quot;size16&quot;&gt;2026년을 맞으며 HLSL에서 가장 기대하고 있는 변화는 HLSL을 표준화하기 위한 위원회 구성 절차를 시작했다는 점이다. 나는 오픈소스 소프트웨어를 중심으로 커리어를 쌓아왔고, 어떤 종류의 소프트웨어는 결코 독점적이어서는 안 된다고 깊이 믿고 있다. HLSL이 계속 발전하고 번영하기 위해서는 표준화로 나아가는 길이 유일한 해법이라고 생각한다. 여러 번 말해왔지만, 여기서 다시 강조하겠다. HLSL의 미래는 크로스 플랫폼이며 오픈이다.&lt;br /&gt;&lt;br /&gt;이는 개인적으로도 매우 큰 노력의 과정이었다. Microsoft 내부에서 공감대를 얻는 한편, 업계 전반에 걸쳐 파트너십을 강화하기 위해 힘써왔다. Microsoft가 가진 몇 가지 평판을 극복하기 위해 노력하고 있으며, 우리가 이 일에 진지하다는 신호를 보내기 위해 나 자신의 평판도 상당 부분 걸었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;16&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;왜 이런 일을 하는가?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;199&quot; data-start=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;내 경험상, 컴파일러와 프로그래밍 언어는 지나치게 복잡한 데 비해 기업이 충분한 인력을 투입해 오픈소스 대안과 경쟁할 수 있을 만큼의 품질과 규모로 독자적인 컴파일러를 개발&amp;middot;유지할 만큼의 차별화 가치를 제공하지 못한다. 이러한 점은 C++처럼 복잡한 언어에서 특히 두드러지며, HLSL 역시 그 방향으로 점점 나아가고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1jVvc/dJMcai93D1i/RdWlDgQWLtSDuJxdcEdJWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1jVvc/dJMcai93D1i/RdWlDgQWLtSDuJxdcEdJWk/img.png&quot; data-alt=&quot;컴파일러 그까이꺼 얼마나 해? 10불??&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1jVvc/dJMcai93D1i/RdWlDgQWLtSDuJxdcEdJWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1jVvc%2FdJMcai93D1i%2FRdWlDgQWLtSDuJxdcEdJWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;292&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴파일러 그까이꺼 얼마나 해? 10불??&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HLSL에 대한 인력 부족은 우리 팀에 매우 큰 문제였다. 우리는 새로운 셰이더 모델 기능을 지속적으로 공개해야 한다는 막대한 압박을 받아왔지만, 새로운 하드웨어 기능을 노출하는 동시에 사용자의 생산성을 높이기 위해 HLSL 자체를 발전시킬 만큼 충분히 큰 팀을 가져본 적이 없다. 그 결과 여러 단기적인 결정들이 이어졌다. 우리는 지름길을 택했고 막대한 기술 부채를 떠안게 되었는데, 그중 가장 대표적인 사례는 DXC가 10년도 더 지난 LLVM 3.7에 묶여 있다는 점이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU3AQJ/dJMcaioKlXz/HjB2yGBqK5K6PKQ3LVUjo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU3AQJ/dJMcaioKlXz/HjB2yGBqK5K6PKQ3LVUjo0/img.png&quot; data-alt=&quot;LLVM 3.7 : C++ 14 초기 수준, 옛 패스 매니저(legacy pass manager), 벡터화/루프 최적화/인라이닝 등의 알고리즘이 구식, 최신 GPU/CPU 아키텍처에 대한 고려 부족. 10년 넘음... .&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU3AQJ/dJMcaioKlXz/HjB2yGBqK5K6PKQ3LVUjo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU3AQJ%2FdJMcaioKlXz%2FHjB2yGBqK5K6PKQ3LVUjo0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;462&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;700&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LLVM 3.7 : C++ 14 초기 수준, 옛 패스 매니저(legacy pass manager), 벡터화/루프 최적화/인라이닝 등의 알고리즘이 구식, 최신 GPU/CPU 아키텍처에 대한 고려 부족. 10년 넘음... .&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;223&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;냉정한 진실은, 훌륭한 프로그래밍 언어와 컴파일러는 어떤 플랫폼이 갖춰야 할 기본 요건일 뿐, 그것만으로 더 많은 하드웨어나 소프트웨어 라이선스를 판매하게 만들지는 않는다는 점이다. 그렇다고 해서 품질이 나쁜 언어와 컴파일러가 문제가 되지 않는 것은 아니다. 오히려 그것들은 개발자들에게 과도한 부담을 주어 양질의 소프트웨어를 출시하는 능력을 저해하고, 이는 결국 매출에 부정적인 영향을 미친다.&lt;br /&gt;&lt;br /&gt;나는 아직 HLSL 컴파일러가 심각한 부담이 될 만큼 낡고 &amp;ldquo;나쁜&amp;rdquo; 상태라고 보지는 않지만, 그런 방향으로 가고 있는 것은 분명하다. 따라서 이를 반드시 바로잡아야 하며, 그 과정에서 HLSL의 개발 모델을 보다 지속 가능하고 합리적인 자원 투자 구조로 전환해야 한다.&lt;br /&gt;&lt;br /&gt;이 모든 비즈니스식 표현을 한마디로 정리하면 이렇다. 오픈소스를 수용하고, 폭넓은 파트너십을 구축하며, 건강한 커뮤니티를 만들자는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;223&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;492&quot; data-start=&quot;465&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;표준이 사용자에게 어떤 이점을 제공하는가?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;608&quot; data-start=&quot;494&quot; data-ke-size=&quot;size16&quot;&gt;HLSL 자체의 발전과 고품질 툴체인 기능에 충분히 투자하지 못했던 점은 업계에 오래 지속된, 때로는 해결 불가능해 보였던 여러 문제를 낳았다. 그 대표적인 사례가 셰이더 빌드 파이프라인의 복잡성이다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;크로스 플랫폼 애플리케이션의 CPU 코드를 빌드할 때는 일반적으로 애플리케이션 로직의 대부분을 동일한 언어(그리고 종종 동일한 컴파일러)로 처리할 수 있다. 예를 들어 Windows, Linux, macOS, Xbox, PlayStation, Nintendo용 게임을 개발한다면 CPU 코드는 C나 C++로 작성하고 Clang을 컴파일러로 사용할 수 있다. 물론 일부 플랫폼 특화 코드는 존재하겠지만, 대부분의 코드는 쉽게 공유 가능하다. 그러나 GPU 프로그래밍에서는 반드시 그렇지 않다.&lt;br /&gt;&lt;br /&gt;Khronos Group은 구성원과 커뮤니티를 통해 GPU 프로그램을 위한 크로스 플랫폼 파이프라인을 구축하는 데 놀라운 성과를 이루어냈지만, 그 구조는 매우 복잡하다. Khronos의&lt;b&gt;&lt;a href=&quot;https://www.khronos.org/spirv/#spir-ecosystem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; SPIR-V&lt;/a&gt; &lt;/b&gt;생태계 다이어그램을 내가 약간 수정해 DirectX를 추가한 그림을 생각해보라.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2533&quot; data-origin-height=&quot;986&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BWknz/dJMcahwBNun/GV6CVxbdXHDpCOialwEhKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BWknz/dJMcahwBNun/GV6CVxbdXHDpCOialwEhKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BWknz/dJMcahwBNun/GV6CVxbdXHDpCOialwEhKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBWknz%2FdJMcahwBNun%2FGV6CVxbdXHDpCOialwEhKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2533&quot; height=&quot;986&quot; data-origin-width=&quot;2533&quot; data-origin-height=&quot;986&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;243&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;왼쪽에는 선택할 수 있는 소스 언어가 매우 다양하고, 오른쪽에는 실행할 수 있는 대상 런타임이 매우 많다는 점은 인상적이다. 문제는 그 사이에 존재하는 (정보 손실이 발생하는) 번역 단계가 너무 많다는 것이다. 특히 SPIRV-Cross는 많은 셰이더 빌드 파이프라인에서 핵심적인 역할을 하고 있지만, 디버그 정보(최종 실행 코드와 원본 소스 라인의 매핑)를 파괴해 버린다. 그 결과 셰이더 디버깅과 프로파일링이 극도로 어려워진다.&lt;br /&gt;&lt;br /&gt;이러한 생태계 구조는 통합된 툴링의 부재에서 비롯된 것이며, 그로 인해 크로스 플랫폼 게임 엔진들은 각자 복잡한 셰이더 빌드 파이프라인을 구축하게 되었다. 나는 이 분야에서 오랫동안 일해왔지만, 개발자들이 실제로 자사 타이틀의 셰이더를 어떻게 빌드하는지 들을 때마다 여전히 경악하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b28Vf4/dJMcadOqTg4/3fVShY4AjyCKfwHG14hTS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b28Vf4/dJMcadOqTg4/3fVShY4AjyCKfwHG14hTS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b28Vf4/dJMcadOqTg4/3fVShY4AjyCKfwHG14hTS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb28Vf4%2FdJMcadOqTg4%2F3fVShY4AjyCKfwHG14hTS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;404&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;174&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;AAA급 엔진의 셰이더 빌드 파이프라인은 생산성을 유지한다는 명목 아래 모두가 감수해온 복잡한 루브 골드버그 장치&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1519_3&quot; id=&quot;footnote_link_1519_3&quot; onmouseover=&quot;tistoryFootnote.show(this, 1519, 3)&quot; onmouseout=&quot;tistoryFootnote.hide(1519, 3)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;3&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;와 같다. 이 문제를 해결한다고 해서 Microsoft가 Xbox나 Windows 라이선스를 더 많이 판매하게 되는 것은 아니기 때문에, 그동안은 이 문제가 방치되어 왔다. 하지만 이제는 다르다.&lt;br /&gt;&lt;br /&gt;현재 우리는 DXC와 Clang을 사용해 DirectX와 Vulkan용 셰이더를 빌드하는 HLSL 네이티브 빌드 파이프라인을 이미 보유하고 있다. 또한 Metal에 대해서도 비교적 네이티브에 가까운 경로를 갖추고 있는데, 이는 IR에서 IR로 변환하는 Metal Shader Converter를 통해 가능하다. 이 도구는 정확한 디버그 정보를 유지하며, Apple의 네이티브 셰이더 디버깅 및 프로파일링 도구와 함께 HLSL을 사용할 수 있게 해준다(정말 인상적인 성과다!).&lt;br /&gt;&lt;br /&gt;내 진심 어린 바람은 HLSL을 Clang에 통합하는 작업과 병행해 표준화를 추진함으로써, 크로스 플랫폼 지원, 고품질 툴링, 언어 진화를 우선시하는 폭넓은 커뮤니티를 HLSL 중심으로 구축하는 것이다. 우리의 궁극적인 목표는 업계 전반의 파트너십을 형성해 모든 HLSL 사용자가 최고의 툴링을 누릴 수 있도록 하는 것이다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;653&quot; data-start=&quot;631&quot; data-ke-size=&quot;size16&quot;&gt;애플, 소니, 닌텐도 여러분, 함께하자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZzLw1/dJMcaaYwBOL/avAiTucdxJmtBF3LkvtUK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZzLw1/dJMcaaYwBOL/avAiTucdxJmtBF3LkvtUK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZzLw1/dJMcaaYwBOL/avAiTucdxJmtBF3LkvtUK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZzLw1%2FdJMcaaYwBOL%2FavAiTucdxJmtBF3LkvtUK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;428&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-2&quot; data-message-id=&quot;adbc4975-7481-4bd1-bd2d-f42982abaed0&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;27&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;27&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;표준 위원회가 있으면 일이 느려지지 않나?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;359&quot; data-start=&quot;29&quot; data-ke-size=&quot;size16&quot;&gt;대화를 나눌 때 나는 HLSL이 앞으로 어떻게 발전하길 바라는지를 설명하기 위해 종종 &amp;ldquo;신중한(deliberate)&amp;rdquo;이라는 표현을 사용한다. 돌이켜보면, 우리는 새로운 기능의 단기적&amp;middot;장기적 영향을 충분히 숙고하도록 요구하는 틀 없이, 언어를 다소 즉흥적으로 발전시켜온 측면이 있다. 어떤 때는 지나치게 느리게 움직였고, 또 어떤 때는 너무 빠르게 움직였다. 그 결과 유용한 기능 측면에서는 뒤처지면서도, 품질 또한 충분히 확보하지 못하는 상황이 발생했다. 대표적인 사례로, HLSL 2021은 기능 추가보다 버그를 더 많이 만들어냈고, 우리는 그 문제들을 해결하는 데 몇 년을 보내야 했다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPoGdw/dJMcadt8npb/S96MxwvrSyRN3k6d39tzY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPoGdw/dJMcadt8npb/S96MxwvrSyRN3k6d39tzY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPoGdw/dJMcadt8npb/S96MxwvrSyRN3k6d39tzY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPoGdw%2FdJMcadt8npb%2FS96MxwvrSyRN3k6d39tzY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;401&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;297&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;나는 표준 절차를 도입하면 HLSL에 추가(또는 제거)되는 기능에 대해 보다 신중하고 숙고된 접근을 하도록 만드는 구조 안에서 언어를 발전시킬 수 있다고 믿는다. 이 과정은 때로는 그 절차가 없을 때보다 느릴 수 있고, 다른 경쟁 언어들보다 느릴 수도 있다. 하지만 그 대신 더 높은 품질의 결과를 만들어낼 것이며, 그것이 모두에게 최선이라고 생각한다. 또한 국제 표준화 기구 아래에서 이를 추진함으로써, 우리 스스로를 객관적으로 점검하고 성급하고 결함 있는 결정을 내리려는 본능을 억제할 수 있는 틀을 갖게 될 것이라고 본다.&lt;br /&gt;&lt;br /&gt;나는 프로그래밍 언어나 컴파일러에서 &amp;ldquo;빠른 혁신(rapid innovation)&amp;rdquo;이라는 말을 들으면 불편함을 느낀다. 물론 빠른 혁신이 사용자에게 도움이 되는 소프트웨어 분야도 있다. 그러나 사람들이 의존하는 인프라 소프트웨어는 &amp;ldquo;빠르게 움직이고 문제는 나중에 고친다(move fast and break things)&amp;rdquo;는 모델과는 맞지 않는 수준의 안정성과 신뢰성을 요구한다.&lt;br /&gt;&lt;br /&gt;누구도 실험적인 도구를 핵심적인 역할로 프로덕션 코드베이스에 통합하고 싶어하지는 않을 것이다. 이와 같은 맥락에서, HLSL 사용자들 역시 오늘 작성한 코드가 미래에도 예상대로 동작하길 바랄 것이라고 생각한다. 우리가 할 수 있는 최악의 일은 사용자와 그 영향에 대한 고려 없이 HLSL의 의미론에 근본적인 변화를 가하는 것이다. 표준 절차는 사용자들이 목소리를 낼 수 있는 장을 제공하고, 우리가 미래를 향해 HLSL을 발전시키는 과정에서 스스로를 점검할 수 있는 틀을 제공할 것이다.&lt;/p&gt;
&lt;p data-end=&quot;297&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;817&quot; data-start=&quot;794&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;그렇다면 실제로 어떻게 진행되는가?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;1009&quot; data-start=&quot;819&quot; data-ke-size=&quot;size16&quot;&gt;Ecma International 산하에 새롭게 구성된 &lt;b&gt;&lt;a href=&quot;https://ecma-international.org/technical-committees/tc57/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;기술 위원회 57(Technical Committee 57)&lt;/a&gt;&lt;/b&gt;은 HLSL 핵심 언어의 명세화와 표준화를 담당하게 된다. 초기에는 핵심 동작(문법, 기본 데이터 타입, 변환 규칙, 오버로드 해석 등)과 모든 API 대상에 공통적으로 적용되는 제한된 범위의 기능에 초점을 맞출 예정이다.&lt;br /&gt;&lt;br /&gt;위원회가 발전해 나감에 따라, HLSL을 더 나은 언어로 진화시키는 동력을 제공하는 동시에 Microsoft 플랫폼에 종속되지 않는 크로스 플랫폼 표준으로 확립하는 역할을 하게 되기를 기대하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWMXoG/dJMcab4cttG/s0bgh0XsKqmF4dKtepi2kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWMXoG/dJMcab4cttG/s0bgh0XsKqmF4dKtepi2kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWMXoG/dJMcab4cttG/s0bgh0XsKqmF4dKtepi2kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWMXoG%2FdJMcab4cttG%2Fs0bgh0XsKqmF4dKtepi2kK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;334&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;127&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;위원회는 거의 전적으로 공개적으로, 그리고 &lt;b&gt;&lt;a href=&quot;https://github.com/hlsl-tc57&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;GitHub&lt;/a&gt;&lt;/b&gt; 상에서 운영될 예정이지만, 회의 자체는 Ecma 회원과 초청된 전문가에게만 공개된다. 우리는 모든 분들이 우리의 공개 작업을 지켜보고 표준화 과정에 기여해주기를 바란다.&lt;/p&gt;
&lt;p data-end=&quot;127&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;127&quot; data-start=&quot;0&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;뉴럴 렌더링&lt;/b&gt;&lt;/h3&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;347&quot; data-start=&quot;146&quot; data-ke-size=&quot;size16&quot;&gt;이제 &amp;ldquo;뉴럴 렌더링&amp;rdquo; 이야기를 더는 미루기 어렵겠으니 그냥 꺼내보겠다. 개인적으로 나는 이 용어를 싫어한다. 컴파일러와 언어 관점에서 보면 &amp;ldquo;뉴럴 렌더링&amp;rdquo;은 다른 신경망 연산과 본질적으로 다르지 않으며, 결국은 거대한 다차원 행렬에 대한 선형대수 연산에 불과하다는 점을 계속 설명해야 하기 때문이다. 하지만 뭐 어쩌겠는가, 나는 그저 고함치는 늙은이일 뿐이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSD4ND/dJMcadt8nti/UKNpyCUTz4lp15z6klqNA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSD4ND/dJMcadt8nti/UKNpyCUTz4lp15z6klqNA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSD4ND/dJMcadt8nti/UKNpyCUTz4lp15z6klqNA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSD4ND%2FdJMcadt8nti%2FUKNpyCUTz4lp15z6klqNA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;792&quot; height=&quot;525&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;525&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;299&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;지난해부터, 그리고 현재까지도 신경망 연산과 관련해 상당히 큰 작업을 진행해왔다. 작년에는 렌더링 및 컴퓨트 워크로드에서 소규모 신경망 평가를 가능하게 하는 &lt;a href=&quot;https://devblogs.microsoft.com/directx/cooperative-vector/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;D3D12 Cooperative Vector&lt;/a&gt; 기능의 프리뷰를 공개했다. 하지만 가을에 많은 고민 끝에 이 기능이 아직 정식 도입을 하기에 &lt;a href=&quot;https://devblogs.microsoft.com/directx/shader-model-6-9-and-the-future-of-cooperative-vector/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;충분히 성숙하지 않았다&lt;/a&gt;고 판단했다. 이후 우리는 Cooperative Vector의 기능은 물론, 2023년에 프리뷰했지만 SM 6.8에 포함되지는 않았던 &lt;a href=&quot;https://devblogs.microsoft.com/directx/agility-sdk-1-711/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Wave Matrix&lt;/a&gt;의 보다 발전된 대체 기능을 개발하는 데 적극적으로 힘써왔다.&lt;br /&gt;&lt;br /&gt;새로운 기능은 다소 밋밋하게도 &lt;a href=&quot;https://github.com/microsoft/hlsl-specs/blob/main/proposals/0035-linalg-matrix.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Linear Algebra&lt;/a&gt;(줄여서 LinAlg)라고 이름 붙였으며, Cooperative Vector와 Wave Matrix의 기능을 모두 포함한다. 또한 이 기능을 다른 API(즉, Vulkan)와 보다 긴밀히 정렬되도록 설계해, 장차 HLSL을 통해 Vulkan과 DirectX 양쪽에서 사용할 수 있도록 했다(Apple이 보조를 맞춘다면 Metal에서도 가능할 수 있다). 이는 Windows 환경의 브라우저에서 WebGPU가 제안한 &lt;a href=&quot;https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/subgroup_matrix.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Subgroup Matrix&lt;/a&gt; 기능을 구현하는 데에도 활용될 수 있을 것이다.&lt;br /&gt;&lt;br /&gt;GenAI나 LLM에 대해 어떻게 생각하든지(나는 회의적인 편이다), 신경망이 그래픽스 프로그래밍에서 점점 더 많은 유용한 응용을 갖고 있다는 점은 분명하다. 텍스처 압축, 라디언스 캐싱, 패스 트레이싱, 디노이징, 업스케일링 등 신경망을 활용하려는 움직임이 활발하다. 이러한 모든 응용 분야에서 중요한 것은 HLSL이 이러한 알고리즘을 효율적으로 하위 수준으로 변환(lowering)할 수 있어야 한다는 점이며, 그래야 셰이더 작성자가 최신 GPU 하드웨어의 성능을 최대한 활용할 수 있다.&lt;br /&gt;&lt;br /&gt;내가 특히 기대하는 부분은 신경망이 복잡한 함수를 근사할 수 있는 능력이다. 몇 년 안에 행렬 곱셈 및 누적 연산 전용 하드웨어가 저가형 GPU까지 확산되고, 설치 기반 전반에 보급된다면, 함수 근사는 낮은 사양의 하드웨어에서도 허용 가능한 프레임 속도로 더 높은 수준의 렌더링 품질을 구현하는 데 유용한 기법이 될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;299&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1087&quot; data-start=&quot;1080&quot; data-ke-size=&quot;size23&quot;&gt;맺으며&lt;/h3&gt;
&lt;p data-end=&quot;1214&quot; data-start=&quot;1089&quot; data-ke-size=&quot;size16&quot;&gt;여기까지 읽었다면 축하한다. 꽤 장황하게 이야기했으니 여기서는 길게 붙잡지 않겠다. 위에서 길게 설명한 내용에 이미 담겨 있지만, 2026년에 내가 HLSL에서 특히 밀고자 하는 몇 가지 핵심 주제를 분명히 정리해보겠다.&lt;/p&gt;
&lt;h4 data-end=&quot;1236&quot; data-start=&quot;1221&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;크로스 플랫폼과 오픈&lt;/span&gt;&lt;/h4&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;1346&quot; data-start=&quot;1238&quot; data-ke-size=&quot;size16&quot;&gt;HLSL의 미래는 크로스 플랫폼이며 오픈이다. 이는 오픈소스를 의미하고, 로열티 프리 특허 및 지식재산 정책을 갖춘 공개 명세를 의미한다. 그리고 전 세계 누구로부터든 기여를 환영한다는 뜻이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;1128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgniCU/dJMcafZPc1i/kNRsbu0Ehgu6KAtNWPhPQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgniCU/dJMcafZPc1i/kNRsbu0Ehgu6KAtNWPhPQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgniCU/dJMcafZPc1i/kNRsbu0Ehgu6KAtNWPhPQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgniCU%2FdJMcafZPc1i%2FkNRsbu0Ehgu6KAtNWPhPQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;679&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;1128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;18&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;품질, 품질, 그리고 품질&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 속도나 화려함을 위해 품질을 희생해서는 안 된다. 지름길을 택하거나 느슨한 품질 기준을 적용했다가 여러 차례 대가를 치러왔고, 그 피해는 결국 사용자에게까지 이어졌다. 컴파일러 구현이든, 새로운 기능 설계든, 초안 단계의 언어 명세든, HLSL과 관련된 모든 영역에서 더 높은 품질 기준을 확립하기 위해 우리는 많은 노력을 기울여왔다. 앞으로도 이러한 품질에 대한 투자를 지속할 것이며, 그 과정에서 우리를 객관적으로 점검해줄 커뮤니티와 함께해 나갈 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lgmXC/dJMcac9PGhb/IvKYV5w8fdVi9h0kvad50K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lgmXC/dJMcac9PGhb/IvKYV5w8fdVi9h0kvad50K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lgmXC/dJMcac9PGhb/IvKYV5w8fdVi9h0kvad50K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlgmXC%2FdJMcac9PGhb%2FIvKYV5w8fdVi9h0kvad50K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;338&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-end=&quot;22&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;22&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;HLSL은 사용자를 위해 존재한다&lt;/span&gt;&lt;/h4&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;297&quot; data-start=&quot;24&quot; data-ke-size=&quot;size16&quot;&gt;HLSL이 가치 있는 기술인 이유는 그것이 널리 사용되고 있기 때문이다. 우리는 사용자와 적극적으로 소통하고, 그들의 피드백에 응답하며, 그들의 우려 사항을 우선순위에 둘 것이다. 물론 모든 개별 사용자의 요구를 그대로 수용할 수는 없다. 전체 사용자 기반을 아우르는 보다 종합적인 관점이 필요하기 때문이다. 그러나 우리의 중심 동기는 언제나 사용자들이 생산적으로 일할 수 있도록 돕고, 우리의 도구를 활용해 그들의 애플리케이션을 최상의 수준으로 만들 수 있도록 지원하는 데 있어야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QLKxO/dJMcafrZUki/4MDgkDT0BhPVuJH3BvGVjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QLKxO/dJMcafrZUki/4MDgkDT0BhPVuJH3BvGVjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QLKxO/dJMcafrZUki/4MDgkDT0BhPVuJH3BvGVjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQLKxO%2FdJMcafrZUki%2F4MDgkDT0BhPVuJH3BvGVjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;258&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol class=&quot;footnotes&quot;&gt;
    &lt;li id=&quot;footnote_1519_1&quot;&gt;&lt;/p&gt;
&lt;p data-end=&quot;321&quot; data-start=&quot;22&quot; data-ke-size=&quot;size16&quot;&gt;여기서 이야기하는 Clang은 LLVM 프로젝트의 C/C++ 계열 컴파일러 프론트엔드를 이야기 하는 것으로&lt;br /&gt;&amp;nbsp; - &lt;b&gt;LLVM : 다양한 언어를 위한 컴파일러 인프라(백엔드 + 최적화 프레임워크)&lt;br /&gt;&amp;nbsp; - &lt;/b&gt;&lt;b&gt;Clang : LLVM을 사용하는 C, C++, Objective-C 등의 프론트 엔드 컴파일러&lt;br /&gt;&amp;nbsp; - &lt;/b&gt;&lt;b&gt;DXC : Microsoft의 기존 HLSL 컴파일러(DirectX Shader Compiler)&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;364&quot; data-start=&quot;279&quot; data-ke-size=&quot;size16&quot;&gt;최근 Microsoft와 Google은 &lt;b&gt;HLSL을 Clang 기반으로 구현&lt;/b&gt;하고 있으며, 기존 DXC처럼 별도의 전용 컴파일러가 아니라:Clang의 파서, 진단 시스템, 타입 시스템 등을 활용해 HLSL을 하나의 정식 언어 프론트엔드처럼 통합하려는 시도를 진행중이다. 이런 형태로 진행이된다면 Clang의 진단 시스템을 그대로 활용할 수 있는 장점이 있다.(HLSL을 차세대 컴파일러 인프라(LLVM/Clang)에 통합하려는 프로젝트) &lt;a href=&quot;#footnote_link_1519_1&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1519_2&quot;&gt;여기서 말하는 Test Suite는 일종의 테스트 묶음으로 이해하면 된다  &lt;a href=&quot;#footnote_link_1519_2&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_1519_3&quot;&gt; Rube Goldberg는 20세기 초 미국의 만화가. 아주 단순한 일을 하기위해 지나치게 복잡한 프로세스를 가진 장치나 절차를 풍자함 &lt;a href=&quot;#footnote_link_1519_3&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</description>
      <category>Technical Report/Graphics Tech Reports</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1519</guid>
      <comments>https://illu.tistory.com/1519#entry1519comment</comments>
      <pubDate>Sat, 14 Feb 2026 19:56:59 +0900</pubDate>
    </item>
    <item>
      <title>2025 TA Campus 수업 문서 링크</title>
      <link>https://illu.tistory.com/1518</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2025년 컴투스에서 진행된 TA Campus 강의문서링크.&lt;br /&gt;외부 공유를 염두하고 진행했었는데 배포에 시간이 걸렸다(정확히는 내가 너무 바빴다....;;;;;) 뒤늦게라도 공유&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;컴투스온 TA Campus 강연진 후기 : &lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://on.com2us.com/company/ta-campus/&quot;&gt;https://on.com2us.com/company/ta-campus/&lt;/a&gt;&lt;br /&gt;&lt;span&gt;컴투스온 TA Campus 수강 후기 : &lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://on.com2us.com/company/ta-campus2/&quot;&gt;https://on.com2us.com/company/ta-campus2/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;2주차 그래픽스 파이프라인과 셰이더&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1B8Y-ACEsoR-UAoGocXVOqZl496SxdfSEViZ5n9AYWd0/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/1B8Y-ACEsoR-UAoGocXVOqZl496SxdfSEViZ5n9AYWd0/edit?usp=sharing&lt;/a&gt;&lt;span&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;3주차 3D 아트 에셋 최적화&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1nkUH9D1UN3EnxrNBQTOWY6VSeVv2OrE47jzupN7Fd40/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/1nkUH9D1UN3EnxrNBQTOWY6VSeVv2OrE47jzupN7Fd40/edit?usp=sharing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;4주차 플랫폼 소개 및 메모리 대역폭&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1_ZQ6yCFSfbPdJV-HPzb3A6JqGV9pHQkFKP6xOe-SXzQ/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/1_ZQ6yCFSfbPdJV-HPzb3A6JqGV9pHQkFKP6xOe-SXzQ/edit?usp=sharing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;5주차 라이팅 세팅 및 최적화 전략&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/16UN8fk77W9okW4S9-S4JIXsnVpxaOnRShf63NBsLZxE/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/16UN8fk77W9okW4S9-S4JIXsnVpxaOnRShf63NBsLZxE/edit?usp=sharing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;6주차 게임 애니메이션 파이프라인 최적화&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1UEBm5BjnnBqrUpUPvd6hEcEEF-9Gdap7ZxtS8HRtpQo/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/1UEBm5BjnnBqrUpUPvd6hEcEEF-9Gdap7ZxtS8HRtpQo/edit?usp=sharing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;7주차 게임 FX/UI 최적화&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/19cEFAuT5pe74s-SJu2pTVHcUhapIgDCvagJMv7dGk_U/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/19cEFAuT5pe74s-SJu2pTVHcUhapIgDCvagJMv7dGk_U/edit?usp=sharing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;8주차 게임 개발을 위한 최적화&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1vQ6H0vpI-oXKAxdyYd8edLw8lc1Ow5Nt8Hpnf3zcnuc/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/1vQ6H0vpI-oXKAxdyYd8edLw8lc1Ow5Nt8Hpnf3zcnuc/edit?usp=sharing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;9주차 구경해보자 프로파일링&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1lBXoVLpK2Dcg-Ef7JNw8ua6iNt8o2OcSyocgTb1izt0/edit?usp=sharing&quot;&gt;https://docs.google.com/presentation/d/1lBXoVLpK2Dcg-Ef7JNw8ua6iNt8o2OcSyocgTb1izt0/edit?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과제수행해주신 내용들도 좋은데 그거까지 넣음 넘 링크가 많아질듯해서 여기까지만......&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5agmH/dJMcaiPz86X/98ejkEgq7gKnXbdrQZqnkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5agmH/dJMcaiPz86X/98ejkEgq7gKnXbdrQZqnkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5agmH/dJMcaiPz86X/98ejkEgq7gKnXbdrQZqnkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5agmH%2FdJMcaiPz86X%2F98ejkEgq7gKnXbdrQZqnkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1175&quot; height=&quot;560&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Technical Report/Graphics Tech Reports</category>
      <category>TA</category>
      <category>TACampus</category>
      <category>TA실</category>
      <category>컴투스</category>
      <category>테크니컬아트</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1518</guid>
      <comments>https://illu.tistory.com/1518#entry1518comment</comments>
      <pubDate>Tue, 20 Jan 2026 15:40:43 +0900</pubDate>
    </item>
    <item>
      <title>GV70 26년식 짧은 후기</title>
      <link>https://illu.tistory.com/1517</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;차 받고 대략 3주정도 지난 시점에서 800km 정도 타고 다녔는데 몇가지 느끼는 점들을 써본다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9l8eV/dJMcadmWd3P/idQexQ3Zxq5zrpzcuzIS60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9l8eV/dJMcadmWd3P/idQexQ3Zxq5zrpzcuzIS60/img.png&quot; data-alt=&quot;제일 기분좋은건 차 올때까지 기다리는거.... 제네시스 따로 할인이 없어서 카드 캐쉬백 조금 받는걸로 하고 일시불로 결재....&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9l8eV/dJMcadmWd3P/idQexQ3Zxq5zrpzcuzIS60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9l8eV%2FdJMcadmWd3P%2FidQexQ3Zxq5zrpzcuzIS60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;427&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제일 기분좋은건 차 올때까지 기다리는거.... 제네시스 따로 할인이 없어서 카드 캐쉬백 조금 받는걸로 하고 일시불로 결재....&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOcBCT/dJMcabo7EKH/KuA9vuoxjQcKQKbf8Kv22k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOcBCT/dJMcabo7EKH/KuA9vuoxjQcKQKbf8Kv22k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOcBCT/dJMcabo7EKH/KuA9vuoxjQcKQKbf8Kv22k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOcBCT%2FdJMcabo7EKH%2FKuA9vuoxjQcKQKbf8Kv22k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;842&quot; height=&quot;402&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;494&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OzQHR/dJMcagqqTTN/GeMVzBN5UYKyI2EmyKWFQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OzQHR/dJMcagqqTTN/GeMVzBN5UYKyI2EmyKWFQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OzQHR/dJMcagqqTTN/GeMVzBN5UYKyI2EmyKWFQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOzQHR%2FdJMcagqqTTN%2FGeMVzBN5UYKyI2EmyKWFQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;820&quot; height=&quot;494&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;홍대에서 차를 인도 받고 집까지 몰고 왔는데, 도로주행 시험칠때 말곤 도로에서 운전을 안해봐서 걱정이 많았다. 그런데 집까지 운전해서 가지고 와보니 할만했다.(20대때 바이크 몇년 몰아본게 시험칠때도 그렇고 꽤나 도움이 됐던..... 도로주행 연수를 받을까 계속 고민했는데 시간도 안맞고 출퇴근 해보니 할만해서 요샌 그냥 몰고 다닌다. 주차는 여전히 어렵다만.... 회사 주차장은 할만하고 집이 문제)&lt;br /&gt;&lt;br /&gt;26년식이 되면서 후면 배기구가 뒤로 안 뚫리고 아래로 향하는 구조로 바뀌고 차량 모델명, 2WD-AWD 표기 자체가 없어졌다. 깔끔해보여서 이건 나름 만족중. 색상은 우유니화이트로 했는데 26년식에 추가된 베링블루도 괜찮겠다 싶다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;407&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBnQnc/dJMcaiV2rBm/6r7cY533KI9BwxQFViXP71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBnQnc/dJMcaiV2rBm/6r7cY533KI9BwxQFViXP71/img.png&quot; data-alt=&quot;인터넷에 도는 사진 퍼왔는데 요런 느낌. 좀 유니크한 색상이라 맘에 든다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBnQnc/dJMcaiV2rBm/6r7cY533KI9BwxQFViXP71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBnQnc%2FdJMcaiV2rBm%2F6r7cY533KI9BwxQFViXP71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;307&quot; data-origin-width=&quot;407&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인터넷에 도는 사진 퍼왔는데 요런 느낌. 좀 유니크한 색상이라 맘에 든다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵션은 외장은 하나도 안하고 기본에 휠도 18인치 기본휠(이게 연비가 젤 좋단다). AWD를 할지 고민좀 했는데 그냥 이것도 2륜으로.(참고로 GV70은 FR). &lt;b&gt;파노라마 선루프&lt;/b&gt;&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1517_1&quot; id=&quot;footnote_link_1517_1&quot; onmouseover=&quot;tistoryFootnote.show(this, 1517, 1)&quot; onmouseout=&quot;tistoryFootnote.hide(1517, 1)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;1&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;만 추가 했다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;내장옵션은 &lt;b&gt;시그니처 디자인 셀렉션 I&amp;nbsp;&lt;/b&gt; 프로즌 그레이(이거때문에 이차 샀다. I이 170만원 추가고 II가 300만원 추가인데 나파가죽이 좋긴한데 오염이나 관리가 힘들어 보여 야외 주차를 해야하는 상황이라 안했다). 파퓰러 패키지1(26년식에서 옵션이 변경되었다. 2열 컴포트가 빠지고 드라이빙 어시스트 I + HUD였나?) +2열 컴포트 패키지 + 빌트인 캠. HUD(Head Up Display)를 할지 말지 고민을 좀 했는데 모두가 다 하라고 해서 넣었는데 대만족 중이다. 하고나서 아쉬운건 컨비니언스 패키지가 좋아보이긴 하는데.... 가끔 동승하는 부서원들이나 지인들 보면 2열 컴포트 넣긴 잘했나 싶기도 하고....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;583324521_32832917792965874_7968643832042339320_n.jpg&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A9h0r/dJMcabo7ERB/kfk2mGxM76Kmj3kQQZWT0k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A9h0r/dJMcabo7ERB/kfk2mGxM76Kmj3kQQZWT0k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A9h0r/dJMcabo7ERB/kfk2mGxM76Kmj3kQQZWT0k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA9h0r%2FdJMcabo7ERB%2Fkfk2mGxM76Kmj3kQQZWT0k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;1153&quot; data-filename=&quot;583324521_32832917792965874_7968643832042339320_n.jpg&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1153&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시트 커버는 청바지, 블랙진 주로 입는 내입장에서 밝은 가죽은 이염은 무조건 생긴다고 생각하고 바로 주문했다. 아임반 방석+콘솔커버, 시트 후면커버 3가지. 시트 뒷면이 원래 브라운으로 되어있는데 그레이로 통일 하는게 훨씬 이쁜듯. 겸사겸사 더러워지는거 신경안써도 되고...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1049&quot; data-origin-height=&quot;615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sXYKc/dJMcadHcth0/WBGTEN9ne65CTVH1XeDtj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sXYKc/dJMcadHcth0/WBGTEN9ne65CTVH1XeDtj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sXYKc/dJMcadHcth0/WBGTEN9ne65CTVH1XeDtj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsXYKc%2FdJMcadHcth0%2FWBGTEN9ne65CTVH1XeDtj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1049&quot; height=&quot;615&quot; data-origin-width=&quot;1049&quot; data-origin-height=&quot;615&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그외 소소하게 알리에서 악세사리 주문해서 몇개 넣어줬다(컵홀더 받침대)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6a7Ca/dJMcaiV2rME/mDj9s3wH1Dbmstv93Kgy6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6a7Ca/dJMcaiV2rME/mDj9s3wH1Dbmstv93Kgy6K/img.png&quot; data-alt=&quot;개인적으로 가격대비 꽤 만족스러운 보조 손잡이 커버&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6a7Ca/dJMcaiV2rME/mDj9s3wH1Dbmstv93Kgy6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6a7Ca%2FdJMcaiV2rME%2FmDj9s3wH1Dbmstv93Kgy6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;639&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;개인적으로 가격대비 꽤 만족스러운 보조 손잡이 커버&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM3u6j/dJMcajm9Pjk/AR1l6cTr2KKKspgdLIp6Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM3u6j/dJMcajm9Pjk/AR1l6cTr2KKKspgdLIp6Mk/img.png&quot; data-alt=&quot;지현님이 선물해준 방향제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM3u6j/dJMcajm9Pjk/AR1l6cTr2KKKspgdLIp6Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM3u6j%2FdJMcajm9Pjk%2FAR1l6cTr2KKKspgdLIp6Mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;262&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;지현님이 선물해준 방향제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bszflQ/dJMcaaDNBRA/Zkl6tLqg0buPI04QzgRSlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bszflQ/dJMcaaDNBRA/Zkl6tLqg0buPI04QzgRSlK/img.png&quot; data-alt=&quot;드레, 정미니 선물 방향제. 이렇게 총3개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bszflQ/dJMcaaDNBRA/Zkl6tLqg0buPI04QzgRSlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbszflQ%2FdJMcaaDNBRA%2FZkl6tLqg0buPI04QzgRSlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;827&quot; height=&quot;259&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;드레, 정미니 선물 방향제. 이렇게 총3개&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;653&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIG9c2/dJMcai2OeL4/VX0r4U4WJyYgHUp0lU3xi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIG9c2/dJMcai2OeL4/VX0r4U4WJyYgHUp0lU3xi0/img.png&quot; data-alt=&quot;샤오미 마그네틱 거치대. 이거 생각보다 잘 잡아준다. 근데 힘을 좀만 세게 주니 부러질거 같은...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIG9c2/dJMcai2OeL4/VX0r4U4WJyYgHUp0lU3xi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIG9c2%2FdJMcai2OeL4%2FVX0r4U4WJyYgHUp0lU3xi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1151&quot; height=&quot;653&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;653&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;샤오미 마그네틱 거치대. 이거 생각보다 잘 잡아준다. 근데 힘을 좀만 세게 주니 부러질거 같은...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1225&quot; data-origin-height=&quot;667&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vXXSS/dJMcaacGe5n/qgpPtOpPs1gW2UKybkd6k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vXXSS/dJMcaacGe5n/qgpPtOpPs1gW2UKybkd6k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vXXSS/dJMcaacGe5n/qgpPtOpPs1gW2UKybkd6k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvXXSS%2FdJMcaacGe5n%2FqgpPtOpPs1gW2UKybkd6k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1225&quot; height=&quot;667&quot; data-origin-width=&quot;1225&quot; data-origin-height=&quot;667&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;센터페시아 조작패널 마감은 하이그로시라고 하는데 저 기어패널쪽 부분이 손떼가 금방 탄다. 자주 조작하는 부위이기도 하고. 좀 써보다가 이대로는 안되겠다 싶어서 인터넷에서 필름 주문해서 붙였다(카본 패턴). 이거 붙여주니 훨씬 관리하기도 손에 촉감도 좋다.&lt;br /&gt;&lt;br /&gt;그리고 연비..... 출퇴근 평균 50km내외인데 약 6~8km/l 정도 나온다... 연비는 정말 기대하면 안되는 차인듯... 고속 주행조금 하면 10km 가깝게 나오는데 강변북로 주로 타는 아침 저녁 출퇴근때는 답이 안나온다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzfhUX/dJMcabJuu6Z/FEyISIvKIkyZkgxxXUAl21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzfhUX/dJMcabJuu6Z/FEyISIvKIkyZkgxxXUAl21/img.png&quot; data-alt=&quot;눈, 비올때는 조심 또 조심...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzfhUX/dJMcabJuu6Z/FEyISIvKIkyZkgxxXUAl21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzfhUX%2FdJMcabJuu6Z%2FFEyISIvKIkyZkgxxXUAl21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;600&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;눈, 비올때는 조심 또 조심...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;승차감은 꽤나 편하다. 2열에 타본 지인들도 승차감은 만족하는중. 제일 큰건 2열 시트가 뒤로 좀 넘어가는게 큰 듯하다(나도 사기전에 센터장님꺼 타보고 생각보다 뒷자리 괜찮은데? 싶어서 샀던것도 있다) 지하철과 자차 출근시 몸이 느끼는 피로도는 확실히 차가 몸이 좀 더 편하다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;운전은 어라운드뷰, 차선 유지장치, 자세제어장치, HUD, auto hold, 사이드미러 카메라가 들어있어 꽤나 운전하기 편하다. 특히, 순정 네비도 꽤 쓸만하고 HUD에 보여주는 정보량이 차이가 나서 그냥 순정 네비 사용중.(Android Auto 연동해서 다른거 써보니 순정네비보다 자세하게 안나온다)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W0wIH/dJMcabW0PfV/b9VqaUAi5LSFqsIWVr7081/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W0wIH/dJMcabW0PfV/b9VqaUAi5LSFqsIWVr7081/img.png&quot; data-alt=&quot;HDA(Hyundai Driving Assist) 아침 저녁으로 잘 써먹고 있다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W0wIH/dJMcabW0PfV/b9VqaUAi5LSFqsIWVr7081/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW0wIH%2FdJMcabW0PfV%2Fb9VqaUAi5LSFqsIWVr7081%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;415&quot; height=&quot;271&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HDA(Hyundai Driving Assist) 아침 저녁으로 잘 써먹고 있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI0c06/dJMcacn2odm/7pjnwiTzcpXDVMc9pjrXl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI0c06/dJMcacn2odm/7pjnwiTzcpXDVMc9pjrXl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI0c06/dJMcacn2odm/7pjnwiTzcpXDVMc9pjrXl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI0c06%2FdJMcacn2odm%2F7pjnwiTzcpXDVMc9pjrXl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1023&quot; height=&quot;640&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저녁에 키를 가지고 접근하면 웰컴 라이트 띄워주는것도 꽤맘에 드는 부분.(내리고 탈때 시트 포지션 움직이는것도 좋다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;671&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dylaKz/dJMcafdZF5x/iPOmK6IrSlNsCheLaLWk71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dylaKz/dJMcafdZF5x/iPOmK6IrSlNsCheLaLWk71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dylaKz/dJMcafdZF5x/iPOmK6IrSlNsCheLaLWk71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdylaKz%2FdJMcafdZF5x%2FiPOmK6IrSlNsCheLaLWk71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1220&quot; height=&quot;671&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;671&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 차량 인테리어는 밝은톤이 내취향인듯.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1229&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDwZr9/dJMcabWXBRH/62ZppWp6ft4DRHIKxKf0LK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDwZr9/dJMcabWXBRH/62ZppWp6ft4DRHIKxKf0LK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDwZr9/dJMcabWXBRH/62ZppWp6ft4DRHIKxKf0LK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDwZr9%2FdJMcabWXBRH%2F62ZppWp6ft4DRHIKxKf0LK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1229&quot; height=&quot;694&quot; data-origin-width=&quot;1229&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앰비언트 라이트는 바이올렛은 기본톤으로 설정하고 경고할때 붉은색으로 바뀐다. 요게 눈도 편하고 퍼스널 컬러랑도 맞아서 좋은듯&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2mb22/dJMcafdZF9J/Um7QCn6bdURHKLfNpbFSG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2mb22/dJMcafdZF9J/Um7QCn6bdURHKLfNpbFSG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2mb22/dJMcafdZF9J/Um7QCn6bdURHKLfNpbFSG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2mb22%2FdJMcafdZF9J%2FUm7QCn6bdURHKLfNpbFSG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;973&quot; height=&quot;572&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직까지는 주차하다가 사이드 미러 살짝 긁은거 말곤 긁지 않고 잘 버티고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs5EG3/dJMcajm9Pj3/ITzZW24oWFpf60V2PUfwz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs5EG3/dJMcajm9Pj3/ITzZW24oWFpf60V2PUfwz0/img.png&quot; data-alt=&quot;회사 주차장은 주차하기 편하다. 정말...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs5EG3/dJMcajm9Pj3/ITzZW24oWFpf60V2PUfwz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs5EG3%2FdJMcajm9Pj3%2FITzZW24oWFpf60V2PUfwz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;435&quot; height=&quot;500&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;회사 주차장은 주차하기 편하다. 정말...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덧 : 제네시스 혜택은 5년간 소모품 교환 쿠폰, 그리고 프리빌리지 선택(워커힐 숙박권 받을예정), 제네시스 멤버쉽 이정도다(가죽 키 케이스랑 담요 줌)&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol class=&quot;footnotes&quot;&gt;
    &lt;li id=&quot;footnote_1517_1&quot;&gt;꽤 넓게 열린다. 2열에선 이게 꽤나 맘에 드는 모양 &lt;a href=&quot;#footnote_link_1517_1&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</description>
      <category>Diary/2020-2025</category>
      <category>26년식</category>
      <category>genesis</category>
      <category>gv70</category>
      <category>제네시스</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1517</guid>
      <comments>https://illu.tistory.com/1517#entry1517comment</comments>
      <pubDate>Sun, 30 Nov 2025 23:46:31 +0900</pubDate>
    </item>
    <item>
      <title>Shader interpolation modifier</title>
      <link>https://illu.tistory.com/1515</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Unity Live 25년 8월꺼 보다가 재밌어 보여서 정리&lt;br /&gt;링크 : &lt;a href=&quot;https://www.youtube.com/live/ZOlOnXWYQvk?si=yxGyJsz5zDklL-cl&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/live/ZOlOnXWYQvk?si=yxGyJsz5zDklL-cl&lt;/a&gt; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shader Graph Custom Interpolators라는 항목이 새로 들어왔는데 이는 보간기(interpolator)의 보정 설정을 지정할 수 있는 명령이다.&amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.shadergraph@13.1/manual/Custom-Interpolators.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.unity3d.com/Packages/com.unity.shadergraph@13.1/manual/Custom-Interpolators.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rQ4B4/btsQb0iiO3l/zN0o6KxlM0AMj6cj2AQ9ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rQ4B4/btsQb0iiO3l/zN0o6KxlM0AMj6cj2AQ9ZK/img.png&quot; data-alt=&quot;이렇게 Shader Graph Block에서 VS 끝에 노드를 생성하는 방식으로 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rQ4B4/btsQb0iiO3l/zN0o6KxlM0AMj6cj2AQ9ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrQ4B4%2FbtsQb0iiO3l%2FzN0o6KxlM0AMj6cj2AQ9ZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1030&quot; height=&quot;661&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이렇게 Shader Graph Block에서 VS 끝에 노드를 생성하는 방식으로 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4Ppdj/btsQbNiTlWI/GaKncvCjnngbdvf8n5J8bK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4Ppdj/btsQbNiTlWI/GaKncvCjnngbdvf8n5J8bK/img.png&quot; data-alt=&quot;이렇게 Custom interpolator에서 우클릭을 통해 설정할 수 있다. 6.3부터 지원&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4Ppdj/btsQbNiTlWI/GaKncvCjnngbdvf8n5J8bK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4Ppdj%2FbtsQbNiTlWI%2FGaKncvCjnngbdvf8n5J8bK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;496&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이렇게 Custom interpolator에서 우클릭을 통해 설정할 수 있다. 6.3부터 지원&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 HLSL에서는 어떻게 컨트롤 하느냐...&amp;nbsp;&lt;br /&gt;MSDN 문서&amp;nbsp; : &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-struct?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-struct?utm_source=chatgpt.com&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 5가지의 보간기 키워드를 지원한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;linear (기본값) : 원근 보정된 선형 보간 (perspective-correct interpolation)&lt;/li&gt;
&lt;li&gt;noperspective : 원근 보정 없는 선형 보간&lt;/li&gt;
&lt;li&gt;centroid : 삼각형의 내부에서만 샘플링 보장&lt;/li&gt;
&lt;li&gt;nointerpolation : 보간 없이, 가장 가까운 정점 값을 픽셀 셰이더로 전달&lt;/li&gt;
&lt;li&gt;sample : 멀티샘플링(MSAA) 시 샘플 지점 기준으로 보간. Shader model 4.1 이상에서만 사용 가능. 픽셀 중심이 아닌 샘플 위치에서 보간.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* int/uint 타입을 사용할 때 유일하게 유효한 키워드는 &quot;nointerpolation&quot; 만 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;br /&gt;struct&amp;nbsp;v2f&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float4&amp;nbsp;pos&amp;nbsp;:&amp;nbsp;SV_POSITION;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//일반 보간 (기본값, perspective-correct)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float3 normal : NORMAL;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 원근 보정 없는 보간&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;noperspective&amp;nbsp;&lt;/b&gt;float3 normal : TEXCOORD0;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//보간 없이 가장 가까운 정점 값 사용&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nointerpolation&lt;/b&gt; float3 normal : TEXCOORD1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저런 엣지가 두드러지는 스타일의 아트를 만들때 고려해봄직한 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSAA를 사용할때 centorid와 sample 보간 방식이 유용할 수 있다고 하는데 이는 픽셀 커버리지와 샘플링 위치간의 미묘한 차이 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;407&quot; data-start=&quot;379&quot;&gt;하나의 픽셀 안에 MSAA 샘플이 여러 개 있음&lt;/li&gt;
&lt;li data-end=&quot;463&quot; data-start=&quot;408&quot;&gt;하지만 보간된 데이터는 기본적으로 픽셀 중심에서 계산됨 &amp;rarr; &lt;b&gt;샘플 위치와 보간 위치가 다름&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로 인해 &lt;b&gt;픽셀 가장자리(에지) 근처에서 아티팩트&lt;/b&gt;가 생길 수 있고 이를 보간 키워드를 통해 완화할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;917&quot; data-start=&quot;583&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.18605%; text-align: center;&quot;&gt;&lt;b&gt;Modifier&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.9767%; text-align: center;&quot;&gt;&lt;b&gt;동작방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.2791%; text-align: center;&quot;&gt;&lt;b&gt;언제 유용한가?&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%; text-align: center;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;797&quot; data-start=&quot;669&quot;&gt;
&lt;td style=&quot;width: 9.18605%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;682&quot; data-start=&quot;669&quot;&gt;centroid&lt;/td&gt;
&lt;td style=&quot;width: 36.9767%;&quot; data-col-size=&quot;md&quot; data-end=&quot;735&quot; data-start=&quot;682&quot;&gt;픽셀 내부에서 커버되는(coverage) &lt;b&gt;유효한 샘플들의 평균 위치&lt;/b&gt;를 기준으로 보간&lt;/td&gt;
&lt;td style=&quot;width: 36.2791%;&quot; data-col-size=&quot;md&quot; data-end=&quot;780&quot; data-start=&quot;735&quot;&gt;픽셀 경계에 보간 문제가 생길 때 (특히 알파 테스트, 마스크 등 사용 시)&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;797&quot; data-start=&quot;780&quot;&gt;&lt;b&gt;클리핑 오류 방지&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;917&quot; data-start=&quot;798&quot;&gt;
&lt;td style=&quot;width: 9.18605%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;809&quot; data-start=&quot;798&quot;&gt;sample&lt;/td&gt;
&lt;td style=&quot;width: 36.9767%;&quot; data-col-size=&quot;md&quot; data-end=&quot;841&quot; data-start=&quot;809&quot;&gt;&lt;b&gt;MSAA 샘플 위치마다 각각 보간된 값&lt;/b&gt;을 사용&lt;/td&gt;
&lt;td style=&quot;width: 36.2791%;&quot; data-col-size=&quot;md&quot; data-end=&quot;891&quot; data-start=&quot;841&quot;&gt;MSAA가 활성화되어 있고, &lt;b&gt;sample shading&lt;/b&gt;이 필요한 고급 효과에서&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;917&quot; data-start=&quot;891&quot;&gt;더 높은 정확도, &lt;b&gt;성능 부담 증가&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1618&quot; data-start=&quot;1585&quot;&gt;Cutout/AlphaTest 셰이더에서 경계가 깨질 때&lt;/li&gt;
&lt;li data-end=&quot;1668&quot; data-start=&quot;1619&quot;&gt;Deferred Rendering + MSAA 조합 시 (G-buffer 에러 방지)&lt;/li&gt;
&lt;li data-end=&quot;1724&quot; data-start=&quot;1669&quot;&gt;MSAA 환경에서 셰이딩 위치에 민감한 값(normal, UV, tangent 등)을 사용할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그외 위 같은 상황에 유용할 수 있다.(하지만 애시당초 고해상도에서 MSAA 사용하는것 자체가 비용이.......)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sample 키워드의 경우 SV_SampleIndex와 함께 쓰면, 각 MSAA 샘플마다 &lt;b&gt;다른 보간 값&lt;/b&gt;을 받아 정확한 결과를 얻을 수 있지만, 성능이 크게 떨어져서 대부분의 경우 &lt;b&gt;centroid로 충분&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Technical Report/Unity</category>
      <category>HLSL</category>
      <category>interpolator</category>
      <category>Unity</category>
      <category>URP</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1515</guid>
      <comments>https://illu.tistory.com/1515#entry1515comment</comments>
      <pubDate>Fri, 29 Aug 2025 13:53:02 +0900</pubDate>
    </item>
    <item>
      <title>ChinaJoy 2025</title>
      <link>https://illu.tistory.com/1514</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;매우 급하게 결정된 출장. facebook에는 매일 대략의 경험을 공유했지만 한번 몰아서 정리.&lt;br /&gt;업무상 진행된 내용은 공유하지 못하겠지만 그외에 9년만의 상하이는 꽤나 신선했다. 사우나조이라 불렸던 차이나조이도 요새는 많이 좋아졌다고 해서 중국쪽 개발동향도 궁금했었고...&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 링크 기사에 나온 내용중에 상해 날씨에 대한 이야기...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;■&amp;nbsp;&amp;lsquo;사우나조이&amp;rsquo;, 악명 높은 상하이의 날씨는?&lt;/b&gt;&lt;br /&gt;상하이가 얼마나 덥냐고 물어보는 사람들에게 하는 대답이 있다. &amp;ldquo;눈을 감고, 네가 지금까지 살면서 가장 더웠을 때를 떠올려봐. 거기에다가 습기를 10배 더하고, 온도를 10도 가량 높여. 그게 바로 상하이야&amp;rdquo;고 말이다.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://www.gametoc.co.kr/news/articleView.html?idxno=20586&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://www.gametoc.co.kr/news/articleView.html?idxno=20586&lt;/span&gt;&lt;/a&gt; &amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://www.inven.co.kr/webzine/news/?news=161071&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://www.inven.co.kr/webzine/news/?news=161071&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;여튼 기대반 두려움반을 안고 상하이로 이동....(그전에 급하게 출장준비에 TA Campus 마무리에 굉장히 정신없었어서 어떻게 갔는지 기억도 안난다...ㅎ)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;785&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJV50G/btsPZeHcm2c/R3sSGPQ0sAYCGtLSvSkQF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJV50G/btsPZeHcm2c/R3sSGPQ0sAYCGtLSvSkQF0/img.png&quot; data-alt=&quot;모닝캄 라운지 바우처가 이번달 마감이라 3장 남은거중에 두장을 이번에 쓰고 한장은 결국 날리게 됐다. 뭐 sky sky priority pass도 있고 법인카드도 일년에 두번은 라운지 쓸 수 있어서 딱히 라운지 이용 못해서 불편한건 없을듯..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJV50G/btsPZeHcm2c/R3sSGPQ0sAYCGtLSvSkQF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJV50G%2FbtsPZeHcm2c%2FR3sSGPQ0sAYCGtLSvSkQF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1387&quot; height=&quot;785&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;785&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모닝캄 라운지 바우처가 이번달 마감이라 3장 남은거중에 두장을 이번에 쓰고 한장은 결국 날리게 됐다. 뭐 sky sky priority pass도 있고 법인카드도 일년에 두번은 라운지 쓸 수 있어서 딱히 라운지 이용 못해서 불편한건 없을듯..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WfHPh/btsPWZ4WFcQ/DIal6tz4CXnA2Xg4WDraZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WfHPh/btsPWZ4WFcQ/DIal6tz4CXnA2Xg4WDraZ1/img.png&quot; data-alt=&quot;뭔가 마계의 도시 같은 느낌의 하늘&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WfHPh/btsPWZ4WFcQ/DIal6tz4CXnA2Xg4WDraZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWfHPh%2FbtsPWZ4WFcQ%2FDIal6tz4CXnA2Xg4WDraZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1023&quot; height=&quot;578&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뭔가 마계의 도시 같은 느낌의 하늘&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1407&quot; data-origin-height=&quot;797&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qy94G/btsPZ3yhpns/KYm5RloKW3z71Bi6EAGngK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qy94G/btsPZ3yhpns/KYm5RloKW3z71Bi6EAGngK/img.png&quot; data-alt=&quot;가까워질수록 왠지 LA 갈때랑 비슷한 인상을 받았다. 생각해보니 상해로 중국 들어가는건 또 처음이네...까오티엔으로 상해로 와서 나간적은 있어도..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qy94G/btsPZ3yhpns/KYm5RloKW3z71Bi6EAGngK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqy94G%2FbtsPZ3yhpns%2FKYm5RloKW3z71Bi6EAGngK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1407&quot; height=&quot;797&quot; data-origin-width=&quot;1407&quot; data-origin-height=&quot;797&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;가까워질수록 왠지 LA 갈때랑 비슷한 인상을 받았다. 생각해보니 상해로 중국 들어가는건 또 처음이네...까오티엔으로 상해로 와서 나간적은 있어도..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상하이 도시 사이즈는 한국 6배 정도라는데 수도권 전체랑 비교하면 또 그정도 차이는 아니라 하지만 최소 2~3배 정도는 큰 것 같았다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국도 역대급으로 더웠기에 상해도 덥겠구나 했지만 상상 그 이상을 맛보게 된다.(갈때는 그저 오랜만에 출국하는게 좋기만 했던...) 마침&amp;nbsp;&amp;nbsp;작년부터 중국 단기 체류는 비자 면제가 되기도 했어서 여행갈까 했었기에 차라리 잘 되었다 싶었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK4tJ0/btsPVG5O3Ne/XxFjSTKj7O3LJqpy5mRkck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK4tJ0/btsPVG5O3Ne/XxFjSTKj7O3LJqpy5mRkck/img.png&quot; data-alt=&quot;중국 지하철은 난징이나 항저우, 상해 모두 비교적 오래되지 않아 매우 좋다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK4tJ0/btsPVG5O3Ne/XxFjSTKj7O3LJqpy5mRkck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcK4tJ0%2FbtsPVG5O3Ne%2FXxFjSTKj7O3LJqpy5mRkck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1027&quot; height=&quot;581&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;중국 지하철은 난징이나 항저우, 상해 모두 비교적 오래되지 않아 매우 좋다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마침 퇴근시간이고 상하이 도로 상태는 몇번 겪어본 바 지하철로 이동하기로 했다. 가격은 공항 &amp;gt;&amp;gt; 숙소까지 1인당 7위안인가 그쯤 했다(1RMB = 193원. 대략 1인당 1400원이 안된다). 근거리 이동 기본요금은 3위안으로 매우 저렴하다. 4위안 넘기기 쉽지 않음&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7tN5C/btsPZr0esqo/HmN5MD321vLakTbKAQTJnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7tN5C/btsPZr0esqo/HmN5MD321vLakTbKAQTJnk/img.png&quot; data-alt=&quot;googlemap 교통정보가 제공되지 않기 때문에(2015. 16년까지는 됐던거 같은데 여튼 안된다 !!) 고덕지도를 깔아봤는데 이거 생각보다 쓸만했다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7tN5C/btsPZr0esqo/HmN5MD321vLakTbKAQTJnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7tN5C%2FbtsPZr0esqo%2FHmN5MD321vLakTbKAQTJnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;532&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;googlemap 교통정보가 제공되지 않기 때문에(2015. 16년까지는 됐던거 같은데 여튼 안된다 !!) 고덕지도를 깔아봤는데 이거 생각보다 쓸만했다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 고덕지도, 알리페이, didi 앱도 설치하고 갔다(이제 이거3개 없이는 중국에서 움직이는게 거의 불가능하다고 보면 된다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhXJnn/btsPXGRCQyp/bKCKrSp3K7gcQ1DkElZbg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhXJnn/btsPXGRCQyp/bKCKrSp3K7gcQ1DkElZbg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhXJnn/btsPXGRCQyp/bKCKrSp3K7gcQ1DkElZbg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhXJnn%2FbtsPXGRCQyp%2FbKCKrSp3K7gcQ1DkElZbg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;999&quot; height=&quot;582&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1022&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SYY5M/btsPX0I5Tn4/yEbbqPfOesLK2DEyP3YJ21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SYY5M/btsPX0I5Tn4/yEbbqPfOesLK2DEyP3YJ21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SYY5M/btsPX0I5Tn4/yEbbqPfOesLK2DEyP3YJ21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSYY5M%2FbtsPX0I5Tn4%2FyEbbqPfOesLK2DEyP3YJ21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1022&quot; height=&quot;575&quot; data-origin-width=&quot;1022&quot; data-origin-height=&quot;575&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숙소는 SNIEC(Shanghai New International Expo Convention)에서 좀 떨어진 곳. 4성 맞나 싶긴 했지만 그래도 청결한 편이긴 한데 부대시설이 살짝 아쉬운 정도(가격 생각하면....). 보통 차이나조이에선 케리나 히말라야를 잡는데 방이 없었는지 여길 잡아줬다..... 그리고.. 20분을 걸어 다니는 사태가..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRAIE0/btsPZaxFLZe/XANZ0UOgcN1cY2ueAVNxc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRAIE0/btsPZaxFLZe/XANZ0UOgcN1cY2ueAVNxc1/img.png&quot; data-alt=&quot;뭣보다 중국 최대 매력은 맛있는 먹거리들 ~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRAIE0/btsPZaxFLZe/XANZ0UOgcN1cY2ueAVNxc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRAIE0%2FbtsPZaxFLZe%2FXANZ0UOgcN1cY2ueAVNxc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1028&quot; height=&quot;569&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뭣보다 중국 최대 매력은 맛있는 먹거리들 ~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzuS2K/btsPWkIBBRM/C79cKT1BjCud440h4t7ua0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzuS2K/btsPWkIBBRM/C79cKT1BjCud440h4t7ua0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzuS2K/btsPWkIBBRM/C79cKT1BjCud440h4t7ua0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzuS2K%2FbtsPWkIBBRM%2FC79cKT1BjCud440h4t7ua0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;980&quot; height=&quot;573&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;573&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같이 출장온 차석님하고 간단히 저녁. 물가는 많이 올랐지만 서울이 그 사이 미친듯이 올라서 서울 물가의 아직 반도 안되는 느낌이다. (이렇게 우육면 + 양꼬치 + 사이드 해도두사람이&amp;nbsp; 2만원 넘기기 쉽지 않다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;577&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8GK00/btsPXKT1MuH/wHs47Of3WZn2msuMlbF4w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8GK00/btsPXKT1MuH/wHs47Of3WZn2msuMlbF4w0/img.png&quot; data-alt=&quot;이틀차 일정은 업체 기술 미팅&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8GK00/btsPXKT1MuH/wHs47Of3WZn2msuMlbF4w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8GK00%2FbtsPXKT1MuH%2FwHs47Of3WZn2msuMlbF4w0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1021&quot; height=&quot;577&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;577&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이틀차 일정은 업체 기술 미팅&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KBalY/btsPUK1Ygld/bETXktNSkoIe4WxTMYgy3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KBalY/btsPUK1Ygld/bETXktNSkoIe4WxTMYgy3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KBalY/btsPUK1Ygld/bETXktNSkoIe4WxTMYgy3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKBalY%2FbtsPUK1Ygld%2FbETXktNSkoIe4WxTMYgy3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;986&quot; height=&quot;567&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pg9Wz/btsPXy63Q6j/1TSE5kPmS1b5KyM0caYKZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pg9Wz/btsPXy63Q6j/1TSE5kPmS1b5KyM0caYKZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pg9Wz/btsPXy63Q6j/1TSE5kPmS1b5KyM0caYKZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpg9Wz%2FbtsPXy63Q6j%2F1TSE5kPmS1b5KyM0caYKZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1018&quot; height=&quot;578&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정이후에 오늘아니면 돌아다니기 어려울거 같아서 와이탄과 예원 일대를 돌아다녔다. 9년만인데 여전히 화려한데다 금요일 저녁이라 그런지 관광객이 미친듯이 많아서 움직이기도 힘들었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/elanX4/btsPZhKAOIQ/tuYmXjQbBtuVU5xC6zea9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/elanX4/btsPZhKAOIQ/tuYmXjQbBtuVU5xC6zea9K/img.png&quot; data-alt=&quot;사람한테 치여서 걷는것 자체가 힘들었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/elanX4/btsPZhKAOIQ/tuYmXjQbBtuVU5xC6zea9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FelanX4%2FbtsPZhKAOIQ%2FtuYmXjQbBtuVU5xC6zea9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;800&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사람한테 치여서 걷는것 자체가 힘들었다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1349&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zAIhh/btsPYzFzmxu/1P1mMfsVqmXJ1MTMt6AA00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zAIhh/btsPYzFzmxu/1P1mMfsVqmXJ1MTMt6AA00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zAIhh/btsPYzFzmxu/1P1mMfsVqmXJ1MTMt6AA00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzAIhh%2FbtsPYzFzmxu%2F1P1mMfsVqmXJ1MTMt6AA00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1349&quot; height=&quot;750&quot; data-origin-width=&quot;1349&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NwNrl/btsPVFMGUWL/vdCANIegXerBHpiNnfokkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NwNrl/btsPVFMGUWL/vdCANIegXerBHpiNnfokkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NwNrl/btsPVFMGUWL/vdCANIegXerBHpiNnfokkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNwNrl%2FbtsPVFMGUWL%2FvdCANIegXerBHpiNnfokkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1012&quot; height=&quot;574&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 3일차 ChinaJoy 참관. 이미 BTC 티켓은 매진이라 하루는 BTB, 하루는 BTC 둘러보기로 했다. (BTB가 한국이랑 비교해서 엄청 저렴해서 동향 파악겸 둘러보기로 했음)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nWKgX/btsPV3tzfIn/A6rdLQoRX5kovN9s5w2KQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nWKgX/btsPV3tzfIn/A6rdLQoRX5kovN9s5w2KQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nWKgX/btsPV3tzfIn/A6rdLQoRX5kovN9s5w2KQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnWKgX%2FbtsPV3tzfIn%2FA6rdLQoRX5kovN9s5w2KQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;999&quot; height=&quot;576&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입장은 따로 패스를 발급받는게 아닌 등록한 정보를 확인하고 여권 스캔후 안면촬영후에 입장이 진행된다. 지스타때 입장 대기열 생각하면 상당히 간소화된 느낌. 중국이 이런부분에서 디지털화가 상당히 잘 되어있다는걸 새삼 실감....&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wyiVL/btsPYHvFfzj/pM5XB1sxRFXwB33gKEDkx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wyiVL/btsPYHvFfzj/pM5XB1sxRFXwB33gKEDkx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wyiVL/btsPYHvFfzj/pM5XB1sxRFXwB33gKEDkx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwyiVL%2FbtsPYHvFfzj%2FpM5XB1sxRFXwB33gKEDkx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1015&quot; height=&quot;573&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;573&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nqzT9/btsPUUwKxQS/OsZWzTks74MuenPFBIlKOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nqzT9/btsPUUwKxQS/OsZWzTks74MuenPFBIlKOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nqzT9/btsPUUwKxQS/OsZWzTks74MuenPFBIlKOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnqzT9%2FbtsPUUwKxQS%2FOsZWzTks74MuenPFBIlKOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1018&quot; height=&quot;576&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1346&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSpYlV/btsPXTc3bAU/3dD8fw68L4fZR1VwanB4S1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSpYlV/btsPXTc3bAU/3dD8fw68L4fZR1VwanB4S1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSpYlV/btsPXTc3bAU/3dD8fw68L4fZR1VwanB4S1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSpYlV%2FbtsPXTc3bAU%2F3dD8fw68L4fZR1VwanB4S1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1346&quot; height=&quot;760&quot; data-origin-width=&quot;1346&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unity China도 Jerry도 퇴사했었고 Ricahrd 정도 남아있을듯한데 Grow 부스만 있어 아는 얼굴이 안보였다. 아쉽지만 경품만 하나 챙겨서 이동.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GkMVx/btsPZkAbiEZ/FB3iHdGHm2PO4NMmSul4a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GkMVx/btsPZkAbiEZ/FB3iHdGHm2PO4NMmSul4a1/img.png&quot; data-alt=&quot;공주 컨셉의 독특한 러시아 부스. 모바일 광고 플랫폼인거 같은데 소녀소녀, 공주공주했던 부스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GkMVx/btsPZkAbiEZ/FB3iHdGHm2PO4NMmSul4a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGkMVx%2FbtsPZkAbiEZ%2FFB3iHdGHm2PO4NMmSul4a1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1005&quot; height=&quot;578&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공주 컨셉의 독특한 러시아 부스. 모바일 광고 플랫폼인거 같은데 소녀소녀, 공주공주했던 부스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1323&quot; data-origin-height=&quot;745&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJjpYR/btsP03ZmJAX/PpdFtqZWfp0WOxEHAxIqWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJjpYR/btsP03ZmJAX/PpdFtqZWfp0WOxEHAxIqWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJjpYR/btsP03ZmJAX/PpdFtqZWfp0WOxEHAxIqWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJjpYR%2FbtsP03ZmJAX%2FPpdFtqZWfp0WOxEHAxIqWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1323&quot; height=&quot;745&quot; data-origin-width=&quot;1323&quot; data-origin-height=&quot;745&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;744&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwzQTf/btsPZqBjajJ/kKaAxkOnSCY1KgInUNysjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwzQTf/btsPZqBjajJ/kKaAxkOnSCY1KgInUNysjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwzQTf/btsPZqBjajJ/kKaAxkOnSCY1KgInUNysjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwzQTf%2FbtsPZqBjajJ%2FkKaAxkOnSCY1KgInUNysjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1329&quot; height=&quot;744&quot; data-origin-width=&quot;1329&quot; data-origin-height=&quot;744&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnVhzP/btsPXrAtpw8/ELYDqagpkCBxXBEowS8KzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnVhzP/btsPXrAtpw8/ELYDqagpkCBxXBEowS8KzK/img.png&quot; data-alt=&quot;지하철 역에서 나오면 이렇게 행사장 분위기가 느껴진다. 저기 무지막지하게 크다. 코엑스 전체 면적은 한 3~4배를 다 전시장으로 쓰는 느낌&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnVhzP/btsPXrAtpw8/ELYDqagpkCBxXBEowS8KzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnVhzP%2FbtsPXrAtpw8%2FELYDqagpkCBxXBEowS8KzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1027&quot; height=&quot;570&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;지하철 역에서 나오면 이렇게 행사장 분위기가 느껴진다. 저기 무지막지하게 크다. 코엑스 전체 면적은 한 3~4배를 다 전시장으로 쓰는 느낌&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BTB 전체 인상은 AI 관련해서 내용이 있음 좋겠다 싶었는데 그쪽보다는 비지니스 수익화, 광고쪽이 대부분이고 그외 신규 게임 퍼블리싱을 찾기위해 전시하거나 퍼블리싱 사업관련해 게임쪽은 거의 보이지 않았다..... 아쉽&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;602&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/82STq/btsPYAw2bJN/4nEfSgnhZYTV9AAxt4WIy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/82STq/btsPYAw2bJN/4nEfSgnhZYTV9AAxt4WIy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/82STq/btsPYAw2bJN/4nEfSgnhZYTV9AAxt4WIy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F82STq%2FbtsPYAw2bJN%2F4nEfSgnhZYTV9AAxt4WIy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1099&quot; height=&quot;602&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;602&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqJi6Y/btsPZkUtQxy/ksyaH4RJejHevM0xQIwwSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqJi6Y/btsPZkUtQxy/ksyaH4RJejHevM0xQIwwSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqJi6Y/btsPZkUtQxy/ksyaH4RJejHevM0xQIwwSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqJi6Y%2FbtsPZkUtQxy%2FksyaH4RJejHevM0xQIwwSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1010&quot; height=&quot;582&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저녁엔 텐센트 담당자 초대로 선상파티 참여. 실제로 배가 출항할줄 몰랐는데 두시간정도 황푸강을 따라 이동했다. 크루즈 위에서 보는 상하이 야경은 멋져서 여행온다면 타보는걸 추천~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4XcNN/btsPVlOqY1J/O8AWcn4CrerIrPQTWmsnB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4XcNN/btsPVlOqY1J/O8AWcn4CrerIrPQTWmsnB1/img.png&quot; data-alt=&quot;바이주중 최고로 친다는 귀주모태주(마오타이) 한병에 82,999RMB 대충 1,600만원짜리. 1ml 32,000원..... 이걸 대형마트 진열장에서 판다... ㅎ...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4XcNN/btsPVlOqY1J/O8AWcn4CrerIrPQTWmsnB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4XcNN%2FbtsPVlOqY1J%2FO8AWcn4CrerIrPQTWmsnB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;396&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;바이주중 최고로 친다는 귀주모태주(마오타이) 한병에 82,999RMB 대충 1,600만원짜리. 1ml 32,000원..... 이걸 대형마트 진열장에서 판다... ㅎ...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4일차는 BTC를 둘러보게 되었다. 여긴 VIP패스를 끊어서(일반패스 2배 가격. 약 7만원)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1022&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sQuUc/btsPXQfkCW6/8vKG0ZeWquK9PMuvPQR5Zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sQuUc/btsPXQfkCW6/8vKG0ZeWquK9PMuvPQR5Zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sQuUc/btsPXQfkCW6/8vKG0ZeWquK9PMuvPQR5Zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsQuUc%2FbtsPXQfkCW6%2F8vKG0ZeWquK9PMuvPQR5Zk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1022&quot; height=&quot;582&quot; data-origin-width=&quot;1022&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BTB에 비해 사람이 엄청 많았는데 공간도 엄청 크니까 막상 들어가니 그래도 다닐만 했다. 오히려 지스타 한창 사람 몰릴때보다는 좀 여유가 있는 느낌....&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1409&quot; data-origin-height=&quot;795&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4FTBp/btsPXIWAoaX/7FXJFGIZcXlFqL9gxTK92k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4FTBp/btsPXIWAoaX/7FXJFGIZcXlFqL9gxTK92k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4FTBp/btsPXIWAoaX/7FXJFGIZcXlFqL9gxTK92k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4FTBp%2FbtsPXIWAoaX%2F7FXJFGIZcXlFqL9gxTK92k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1409&quot; height=&quot;795&quot; data-origin-width=&quot;1409&quot; data-origin-height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KABuB/btsPVEtvuT9/YrTAaUa1nflyh8KyAJkowk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KABuB/btsPVEtvuT9/YrTAaUa1nflyh8KyAJkowk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KABuB/btsPVEtvuT9/YrTAaUa1nflyh8KyAJkowk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKABuB%2FbtsPVEtvuT9%2FYrTAaUa1nflyh8KyAJkowk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;575&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;575&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boQfR7/btsPWlOjpPD/JGpEqDwsvkHjm9x8ToDkhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boQfR7/btsPWlOjpPD/JGpEqDwsvkHjm9x8ToDkhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boQfR7/btsPWlOjpPD/JGpEqDwsvkHjm9x8ToDkhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboQfR7%2FbtsPWlOjpPD%2FJGpEqDwsvkHjm9x8ToDkhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1020&quot; height=&quot;583&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1333&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o0d2e/btsPXFTLhdC/l6rqotjdFtnhxEn5dl3kCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o0d2e/btsPXFTLhdC/l6rqotjdFtnhxEn5dl3kCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o0d2e/btsPXFTLhdC/l6rqotjdFtnhxEn5dl3kCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo0d2e%2FbtsPXFTLhdC%2Fl6rqotjdFtnhxEn5dl3kCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1333&quot; height=&quot;750&quot; data-origin-width=&quot;1333&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1341&quot; data-origin-height=&quot;754&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceHa9O/btsP0XY9Nre/f3YeoIkDCcJEjS8Z5J7j60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceHa9O/btsP0XY9Nre/f3YeoIkDCcJEjS8Z5J7j60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceHa9O/btsP0XY9Nre/f3YeoIkDCcJEjS8Z5J7j60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceHa9O%2FbtsP0XY9Nre%2Ff3YeoIkDCcJEjS8Z5J7j60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1341&quot; height=&quot;754&quot; data-origin-width=&quot;1341&quot; data-origin-height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B3Ace/btsPXIaUwQq/KSWcD38kCSAjlb6KaAN8tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B3Ace/btsPXIaUwQq/KSWcD38kCSAjlb6KaAN8tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B3Ace/btsPXIaUwQq/KSWcD38kCSAjlb6KaAN8tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB3Ace%2FbtsPXIaUwQq%2FKSWcD38kCSAjlb6KaAN8tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1027&quot; height=&quot;582&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;777&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbLBUl/btsP0fyCsZz/UIlK8NgpPOZBpmdXs9OLdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbLBUl/btsP0fyCsZz/UIlK8NgpPOZBpmdXs9OLdK/img.png&quot; data-alt=&quot;명말 : 공허의 깃털 코스프레&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbLBUl/btsP0fyCsZz/UIlK8NgpPOZBpmdXs9OLdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbLBUl%2FbtsP0fyCsZz%2FUIlK8NgpPOZBpmdXs9OLdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1388&quot; height=&quot;777&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;777&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;명말 : 공허의 깃털 코스프레&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1009&quot; data-origin-height=&quot;599&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nJVBA/btsPVePqpJk/HEQ0vCq3MeDavux7bfpDm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nJVBA/btsPVePqpJk/HEQ0vCq3MeDavux7bfpDm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nJVBA/btsPVePqpJk/HEQ0vCq3MeDavux7bfpDm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnJVBA%2FbtsPVePqpJk%2FHEQ0vCq3MeDavux7bfpDm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1009&quot; height=&quot;599&quot; data-origin-width=&quot;1009&quot; data-origin-height=&quot;599&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;789&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bp54cK/btsPXTi96f1/SFxT68KXddjCnKixR6NWGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bp54cK/btsPXTi96f1/SFxT68KXddjCnKixR6NWGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bp54cK/btsPXTi96f1/SFxT68KXddjCnKixR6NWGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbp54cK%2FbtsPXTi96f1%2FSFxT68KXddjCnKixR6NWGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1392&quot; height=&quot;789&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;789&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1412&quot; data-origin-height=&quot;802&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bILPoa/btsPZ444aog/mRoqbljTgYo91KSpAGIygk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bILPoa/btsPZ444aog/mRoqbljTgYo91KSpAGIygk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bILPoa/btsPZ444aog/mRoqbljTgYo91KSpAGIygk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbILPoa%2FbtsPZ444aog%2FmRoqbljTgYo91KSpAGIygk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1412&quot; height=&quot;802&quot; data-origin-width=&quot;1412&quot; data-origin-height=&quot;802&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일요일이라 그런지 걸그룹 행사가 많았다. 예전 걸스타 보는 느낌 ㅎㅎㅎ. 인플루언서도 많았고&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cldfOy/btsPWoRu7rc/gK5LPK6P6AsIoozYxCxf60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cldfOy/btsPWoRu7rc/gK5LPK6P6AsIoozYxCxf60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cldfOy/btsPWoRu7rc/gK5LPK6P6AsIoozYxCxf60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcldfOy%2FbtsPWoRu7rc%2FgK5LPK6P6AsIoozYxCxf60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;489&quot; height=&quot;706&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rp05x/btsPWdQlehi/2wnffNhWKfGTpNVkqr6lhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rp05x/btsPWdQlehi/2wnffNhWKfGTpNVkqr6lhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rp05x/btsPWdQlehi/2wnffNhWKfGTpNVkqr6lhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frp05x%2FbtsPWdQlehi%2F2wnffNhWKfGTpNVkqr6lhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1017&quot; height=&quot;579&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;797&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PrS7U/btsPZg5XPB6/TYggdbz6NILCus3ftbjX70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PrS7U/btsPZg5XPB6/TYggdbz6NILCus3ftbjX70/img.png&quot; data-alt=&quot;카잔부스의 이 코스프레하시는분은 꽤 유명한 사람이였는지 사람이 엄청 몰렸었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PrS7U/btsPZg5XPB6/TYggdbz6NILCus3ftbjX70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPrS7U%2FbtsPZg5XPB6%2FTYggdbz6NILCus3ftbjX70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;797&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;797&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;카잔부스의 이 코스프레하시는분은 꽤 유명한 사람이였는지 사람이 엄청 몰렸었다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;746&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qca0N/btsP0xfnnVF/1d0pkngJInaYMQYxqxZI10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qca0N/btsP0xfnnVF/1d0pkngJInaYMQYxqxZI10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qca0N/btsP0xfnnVF/1d0pkngJInaYMQYxqxZI10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqca0N%2FbtsP0xfnnVF%2F1d0pkngJInaYMQYxqxZI10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1320&quot; height=&quot;746&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;746&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;627&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mrBgO/btsPYCnL380/gKv2kJGLWKYswzOKWlmMvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mrBgO/btsPYCnL380/gKv2kJGLWKYswzOKWlmMvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mrBgO/btsPYCnL380/gKv2kJGLWKYswzOKWlmMvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmrBgO%2FbtsPYCnL380%2FgKv2kJGLWKYswzOKWlmMvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;817&quot; height=&quot;459&quot; data-origin-width=&quot;627&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검은신화 오공 이후로 중국 콘솔시장이 본격적으로 태동하는 느낌.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TSoKC/btsPZO8OVK9/jkiYjc8ySeKP2dESsY46m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TSoKC/btsPZO8OVK9/jkiYjc8ySeKP2dESsY46m0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TSoKC/btsPZO8OVK9/jkiYjc8ySeKP2dESsY46m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTSoKC%2FbtsPZO8OVK9%2FjkiYjc8ySeKP2dESsY46m0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;820&quot; height=&quot;460&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4mchN/btsPVfOfB8d/QWXZxOZHFfrA10pTfsPuq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4mchN/btsPVfOfB8d/QWXZxOZHFfrA10pTfsPuq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4mchN/btsPVfOfB8d/QWXZxOZHFfrA10pTfsPuq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4mchN%2FbtsPVfOfB8d%2FQWXZxOZHFfrA10pTfsPuq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;785&quot; height=&quot;451&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Phantom&amp;nbsp;Blade&amp;nbsp;Zero&amp;nbsp;:&lt;/b&gt;&amp;nbsp;&lt;a href=&quot;https://youtu.be/ZX1k0z2pPY0?si=WIdyk9-bW08eSLaE&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/ZX1k0z2pPY0?si=WIdyk9-bW08eSLaE&lt;/a&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;중국 무협 스타일 게임. 중국식 무협을 잘 구현했다는 느낌이다. 중국 영화에서 보던 연출같은데 액션에 잘 녹아있는 느낌. 요거 은근히 재미있을거 같단 느낌을 받았다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=ZX1k0z2pPY0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/Fbcy3/hyZysb9l8c/s38Gp6DNjybDmGYjkuOXr0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/desbO7/hyZC4HomL4/CP5INY4Hy0RjS2cgefXVJ0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;600&quot; data-video-height=&quot;338&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;Phantom Blade Zero - Year of the Snake Gameplay Trailer | PS5 Games&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/ZX1k0z2pPY0&quot; width=&quot;600&quot; height=&quot;338&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Lost&amp;nbsp;Soul&amp;nbsp;Aside&amp;nbsp;:&lt;/b&gt;&amp;nbsp;&lt;a href=&quot;https://youtu.be/0EKvNt4bijE?si=y4ceh8i1U6nKIqGk&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/0EKvNt4bijE?si=y4ceh8i1U6nKIqGk&lt;/a&gt; 몇년전에 언리얼4 인디로 꽤 유명했던 영상인데 투자를 받아서 본격적으로 개발을 진행했던 게임이다. 곧 출시를 앞두고 있는듯..... 파판 캐릭터 오마쥬라서 그런지 파판 캐릭터 인상이 강하다.&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=0EKvNt4bijE&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/9gRyJ/hyZzJEz7Is/qk1GrXDc7NmEF738GDYY81/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/dthjGQ/hyZzGOBUmq/W2lNRa7xAtuxh1FX4ks5D0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;600&quot; data-video-height=&quot;338&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;Lost Soul Aside - Pre-Order Trailer | PS5 &amp;amp; PC Games&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/0EKvNt4bijE&quot; width=&quot;600&quot; height=&quot;338&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XEWfm/btsPXm0mKbA/wBLLMN8tQ16OEDYhsXKAKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XEWfm/btsPXm0mKbA/wBLLMN8tQ16OEDYhsXKAKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XEWfm/btsPXm0mKbA/wBLLMN8tQ16OEDYhsXKAKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXEWfm%2FbtsPXm0mKbA%2FwBLLMN8tQ16OEDYhsXKAKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;852&quot; height=&quot;475&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원피스 앰비션. 3:3 모바일에서 캐릭터 대전을 현장에서 진행했는데 나중에 봤던 킹오파 XV보다 이쪽이 더 재밌어 보였다. 모바일 대전 액션과 유명 IP 게임 연출이 꽤 인상적이였다. 중국에서만 출시한거 같은데 찾아보니 한국에서도 apk 파일구해서 꽤 하고 있나봄&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kwJBi/btsPY8temcf/46R1c5JD3Y8nT2Tj0q2Qxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kwJBi/btsPY8temcf/46R1c5JD3Y8nT2Tj0q2Qxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kwJBi/btsPY8temcf/46R1c5JD3Y8nT2Tj0q2Qxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkwJBi%2FbtsPY8temcf%2F46R1c5JD3Y8nT2Tj0q2Qxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;754&quot; height=&quot;428&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;428&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;751&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYwUaG/btsP0llVmCG/NFzK5BaGkueq3oKzXaJtXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYwUaG/btsP0llVmCG/NFzK5BaGkueq3oKzXaJtXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYwUaG/btsP0llVmCG/NFzK5BaGkueq3oKzXaJtXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYwUaG%2FbtsP0llVmCG%2FNFzK5BaGkueq3oKzXaJtXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1343&quot; height=&quot;751&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;751&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p5UlQ/btsPWe9z77U/po2E4xB2lYzqjVzHJWIUE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p5UlQ/btsPWe9z77U/po2E4xB2lYzqjVzHJWIUE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p5UlQ/btsPWe9z77U/po2E4xB2lYzqjVzHJWIUE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp5UlQ%2FbtsPWe9z77U%2Fpo2E4xB2lYzqjVzHJWIUE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;415&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oefCk/btsPXqayFFq/X9kNdD4plHMlgX6V75teb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oefCk/btsPXqayFFq/X9kNdD4plHMlgX6V75teb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oefCk/btsPXqayFFq/X9kNdD4plHMlgX6V75teb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoefCk%2FbtsPXqayFFq%2FX9kNdD4plHMlgX6V75teb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;771&quot; height=&quot;415&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국게임은 붉은사막, 카잔, 데이브더 다이브 정도 출시&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/opp8Y/btsPZc3r8BM/KoT3SQKJbegLtZnOIbSpCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/opp8Y/btsPZc3r8BM/KoT3SQKJbegLtZnOIbSpCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/opp8Y/btsPZc3r8BM/KoT3SQKJbegLtZnOIbSpCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fopp8Y%2FbtsPZc3r8BM%2FKoT3SQKJbegLtZnOIbSpCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1023&quot; height=&quot;575&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;575&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요런 보드게임 전시랑 행사도 있었고...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;798&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ci2Cvw/btsPZoCNwWv/tTq144H1D8jRM8G98jJMa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ci2Cvw/btsPZoCNwWv/tTq144H1D8jRM8G98jJMa0/img.png&quot; data-alt=&quot;스냅드래곤 부스는 엄청 큰데 저게 왕자영요인가...?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ci2Cvw/btsPZoCNwWv/tTq144H1D8jRM8G98jJMa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fci2Cvw%2FbtsPZoCNwWv%2FtTq144H1D8jRM8G98jJMa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1422&quot; height=&quot;798&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;798&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스냅드래곤 부스는 엄청 큰데 저게 왕자영요인가...?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;756&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/28sLe/btsP0sZypvN/Je80DDT8aK1a4upA0Ak4xK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/28sLe/btsP0sZypvN/Je80DDT8aK1a4upA0Ak4xK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/28sLe/btsP0sZypvN/Je80DDT8aK1a4upA0Ak4xK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F28sLe%2FbtsP0sZypvN%2FJe80DDT8aK1a4upA0Ak4xK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1342&quot; height=&quot;756&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;756&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCxvtq/btsPXBCLTMZ/zIIKeDKIe5Y3xLSapgKzwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCxvtq/btsPXBCLTMZ/zIIKeDKIe5Y3xLSapgKzwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCxvtq/btsPXBCLTMZ/zIIKeDKIe5Y3xLSapgKzwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCxvtq%2FbtsPXBCLTMZ%2FzIIKeDKIe5Y3xLSapgKzwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1027&quot; height=&quot;581&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1393&quot; data-origin-height=&quot;812&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XiQxt/btsPZQ6UGct/KYQf1McXD5BrxjT5Fb5Bkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XiQxt/btsPZQ6UGct/KYQf1McXD5BrxjT5Fb5Bkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XiQxt/btsPZQ6UGct/KYQf1McXD5BrxjT5Fb5Bkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXiQxt%2FbtsPZQ6UGct%2FKYQf1McXD5BrxjT5Fb5Bkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1393&quot; height=&quot;812&quot; data-origin-width=&quot;1393&quot; data-origin-height=&quot;812&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1008&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciRNN8/btsPW1BIF6Q/7okVjkQgOufCU74GrGq1X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciRNN8/btsPW1BIF6Q/7okVjkQgOufCU74GrGq1X1/img.png&quot; data-alt=&quot;한화로 약 5,000만원 정도인 스포티한 전기차. 타볼수 있었는데 한번 완충으로 720km 정도 주행가능하다고&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciRNN8/btsPW1BIF6Q/7okVjkQgOufCU74GrGq1X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciRNN8%2FbtsPW1BIF6Q%2F7okVjkQgOufCU74GrGq1X1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1008&quot; height=&quot;579&quot; data-origin-width=&quot;1008&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한화로 약 5,000만원 정도인 스포티한 전기차. 타볼수 있었는데 한번 완충으로 720km 정도 주행가능하다고&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRPKQy/btsPZrzhGPe/U3KMhTHXyJTEzSx0n2osZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRPKQy/btsPZrzhGPe/U3KMhTHXyJTEzSx0n2osZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRPKQy/btsPZrzhGPe/U3KMhTHXyJTEzSx0n2osZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRPKQy%2FbtsPZrzhGPe%2FU3KMhTHXyJTEzSx0n2osZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1019&quot; height=&quot;576&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샤오미랑 BYD 전기차 전시 부스도 있었다(속으로 게임쇼에 참 별게 다 있네 생각을...)&lt;br /&gt;이거랑 별개로 금번에 중국에서 didi로 중국 전기차를 타보고 다들 중국 전기차에 대한 인상이 바뀌었다 하는데 나도 이부분에는 동감이다. 퀄이 너무 좋다.... 개인적으로 솔직히 많이 놀람... (샤오미, 화웨이, BYD )&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;751&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/th76I/btsPXZqVTYq/nvml8zwPnfG7MplLjAGVOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/th76I/btsPXZqVTYq/nvml8zwPnfG7MplLjAGVOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/th76I/btsPXZqVTYq/nvml8zwPnfG7MplLjAGVOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fth76I%2FbtsPXZqVTYq%2Fnvml8zwPnfG7MplLjAGVOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1343&quot; height=&quot;751&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;751&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;751&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DwMLj/btsPYOvPouZ/JPSV8uMj0wiITWwvzYDoHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DwMLj/btsPYOvPouZ/JPSV8uMj0wiITWwvzYDoHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DwMLj/btsPYOvPouZ/JPSV8uMj0wiITWwvzYDoHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDwMLj%2FbtsPYOvPouZ%2FJPSV8uMj0wiITWwvzYDoHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1342&quot; height=&quot;751&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;751&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그리고 부스 한쪽에서 전시중이였던 중국 인디 스팀게임들중에 눈에 띄던 것&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1352&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfroSV/btsPXGd5gbZ/eVtmlfTX8tB3GjtpPw6c3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfroSV/btsPXGd5gbZ/eVtmlfTX8tB3GjtpPw6c3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfroSV/btsPXGd5gbZ/eVtmlfTX8tB3GjtpPw6c3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfroSV%2FbtsPXGd5gbZ%2FeVtmlfTX8tB3GjtpPw6c3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1352&quot; height=&quot;762&quot; data-origin-width=&quot;1352&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwRflp/btsPXIQykEP/cDj2xJjpx3ZKSiPyQLK5sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwRflp/btsPXIQykEP/cDj2xJjpx3ZKSiPyQLK5sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwRflp/btsPXIQykEP/cDj2xJjpx3ZKSiPyQLK5sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwRflp%2FbtsPXIQykEP%2FcDj2xJjpx3ZKSiPyQLK5sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1356&quot; height=&quot;760&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQT4Zb/btsPWrOfbO7/kr7NrOkekZNJ8rZapvmKpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQT4Zb/btsPWrOfbO7/kr7NrOkekZNJ8rZapvmKpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQT4Zb/btsPWrOfbO7/kr7NrOkekZNJ8rZapvmKpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQT4Zb%2FbtsPWrOfbO7%2Fkr7NrOkekZNJ8rZapvmKpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;532&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGrhwZ/btsPW1V3Lx1/F895ySRkBWQj3CeaDSgWPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGrhwZ/btsPW1V3Lx1/F895ySRkBWQj3CeaDSgWPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGrhwZ/btsPW1V3Lx1/F895ySRkBWQj3CeaDSgWPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGrhwZ%2FbtsPW1V3Lx1%2FF895ySRkBWQj3CeaDSgWPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;741&quot; height=&quot;410&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Abyss Rebel : UE4. 이날 만났던 인디 업체중 유일하게 커뮤니케이션이 가능했다(영어가 조금 통함).&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개인적으로 비쥬얼적인 부분은 가장 좋아 보였던 프로젝트. 인게임 전투는 전략 턴제고 톤만 실사지 캐릭터 등신 비율이나 연출이 좀 정적인게 아쉽다. 로비씬은 묵직한 메카닉느낌이 좋아서 프로젝트 퀄이 엄청 좋아보였던 플젝&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;a href=&quot;https://store.steampowered.com/app/3855320/ABYSS_REBEL/?curator_clanid=4777282&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://store.steampowered.com/app/3855320/ABYSS_REBEL/?curator_clanid=4777282&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egRzOg/btsPXtrCtyQ/kTzRkqkiEcKNjBbFw2zKA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egRzOg/btsPXtrCtyQ/kTzRkqkiEcKNjBbFw2zKA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egRzOg/btsPXtrCtyQ/kTzRkqkiEcKNjBbFw2zKA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FegRzOg%2FbtsPXtrCtyQ%2FkTzRkqkiEcKNjBbFw2zKA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;715&quot; height=&quot;411&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVw04t/btsPVE8ojPG/KYvaxriicNSbPSwG9E1IP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVw04t/btsPVE8ojPG/KYvaxriicNSbPSwG9E1IP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVw04t/btsPVE8ojPG/KYvaxriicNSbPSwG9E1IP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVw04t%2FbtsPVE8ojPG%2FKYvaxriicNSbPSwG9E1IP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;530&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Wretch : Divine Ascent : 덱 조합 전투 액션 게임&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Ogopogo 개발. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SapStaR Games&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가 퍼블리셔로 확인&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href=&quot;https://store.steampowered.com/app/3081280/Wretch_Divine_Ascent/&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://store.steampowered.com/app/3081280/Wretch_Divine_Ascent/&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0xxKZ/btsPYz5FR8K/pkWdnWp2TMxkijOJ4vXdl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0xxKZ/btsPYz5FR8K/pkWdnWp2TMxkijOJ4vXdl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0xxKZ/btsPYz5FR8K/pkWdnWp2TMxkijOJ4vXdl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0xxKZ%2FbtsPYz5FR8K%2FpkWdnWp2TMxkijOJ4vXdl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;442&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Antro : inside와 같은 횡스크롤 퍼즐 플랫포머 게임. 스팀 페이지에서 찾아본것보다 현장에서 플레이하면서 봤던 비주얼과 스팀 페이지 영상이랑 비주얼 퀄 차이가 좀 있다. 전시전에 보강을 좀 한것 같음. inside 느낌이 많이 들긴 하는데 카툰 스타일에 톤을 다양한게 쓴게 좀 독특해 보이긴 했다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href=&quot;https://store.steampowered.com/app/1861250/Antro/&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://store.steampowered.com/app/1861250/Antro/&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;568&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVEM8G/btsPV04LdqX/axkHOR4ceAqvLqa5k1W9w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVEM8G/btsPV04LdqX/axkHOR4ceAqvLqa5k1W9w0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVEM8G/btsPV04LdqX/axkHOR4ceAqvLqa5k1W9w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVEM8G%2FbtsPV04LdqX%2FaxkHOR4ceAqvLqa5k1W9w0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1019&quot; height=&quot;568&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;568&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바깥은 더운데다 내부에 따로 쉴곳이 없다보니 이렇게 바닥에 앉아 쉬는 사람이 많았다. 개인적으로 이런건 좀 아쉬운 부분...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFzHx8/btsPZkAgnkI/gJxcaVqS6FCxKUnsXQ4KY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFzHx8/btsPZkAgnkI/gJxcaVqS6FCxKUnsXQ4KY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFzHx8/btsPZkAgnkI/gJxcaVqS6FCxKUnsXQ4KY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFzHx8%2FbtsPZkAgnkI%2FgJxcaVqS6FCxKUnsXQ4KY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;826&quot; height=&quot;447&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 걸어 나오면서 한장. 날씨가 너무 덥다보니 중간중간 외부로 나올때 체력이 빠르게 방전되는 상황..... 이번에 정말 체력의 한계를 많이 느꼈던게...&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;너무 습하고 죽을거 같어... !!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CDnh2/btsPWoxbb6X/M3KkS7dSX9TZ6Zi0H5gbZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CDnh2/btsPWoxbb6X/M3KkS7dSX9TZ6Zi0H5gbZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CDnh2/btsPWoxbb6X/M3KkS7dSX9TZ6Zi0H5gbZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCDnh2%2FbtsPWoxbb6X%2FM3KkS7dSX9TZ6Zi0H5gbZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;663&quot; height=&quot;360&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 정말 체력적으로 힘들었다........ 여름 아닐때 하면 다시 오고 싶긴 하지만....&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;501&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMX54g/btsPVASt9BF/wkBXm23wg2xA8TZcrdpRwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMX54g/btsPVASt9BF/wkBXm23wg2xA8TZcrdpRwK/img.png&quot; data-alt=&quot;zaijien Shanghai~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMX54g/btsPVASt9BF/wkBXm23wg2xA8TZcrdpRwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMX54g%2FbtsPVASt9BF%2FwkBXm23wg2xA8TZcrdpRwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;501&quot; height=&quot;670&quot; data-origin-width=&quot;501&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;zaijien Shanghai~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Diary/2020-2025</category>
      <category>2025</category>
      <category>chinajoy</category>
      <category>차이나조이</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1514</guid>
      <comments>https://illu.tistory.com/1514#entry1514comment</comments>
      <pubDate>Wed, 20 Aug 2025 01:15:44 +0900</pubDate>
    </item>
    <item>
      <title>[번역중]Microflake theory</title>
      <link>https://illu.tistory.com/1513</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2009&quot; data-origin-height=&quot;1118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cG7C6G/btsPhPnxneq/BwP2WqirawIu5401OstNkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cG7C6G/btsPhPnxneq/BwP2WqirawIu5401OstNkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cG7C6G/btsPhPnxneq/BwP2WqirawIu5401OstNkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcG7C6G%2FbtsPhPnxneq%2FBwP2WqirawIu5401OstNkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2009&quot; height=&quot;1118&quot; data-origin-width=&quot;2009&quot; data-origin-height=&quot;1118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;623&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QgN2C/btsPhrN9Mvw/yuH6AHC4A1EKpVfA4rKcO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QgN2C/btsPhrN9Mvw/yuH6AHC4A1EKpVfA4rKcO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QgN2C/btsPhrN9Mvw/yuH6AHC4A1EKpVfA4rKcO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQgN2C%2FbtsPhrN9Mvw%2FyuH6AHC4A1EKpVfA4rKcO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1130&quot; height=&quot;623&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;623&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;276&quot; data-start=&quot;189&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고급 위상 함수 처리와 볼륨에 대한 밉맵핑 기법 소개&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JU3tV/btsPhOCdHuz/bKl9CbbhWQot9qJAghVpWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JU3tV/btsPhOCdHuz/bKl9CbbhWQot9qJAghVpWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JU3tV/btsPhOCdHuz/bKl9CbbhWQot9qJAghVpWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJU3tV%2FbtsPhOCdHuz%2FbKl9CbbhWQot9qJAghVpWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;780&quot; height=&quot;415&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;276&quot; data-start=&quot;189&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;276&quot; data-start=&quot;189&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Rayleigh scattering :&lt;/b&gt; 작은 입자 &amp;rarr; 빛을 고르게 산란&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Mie scattering (소/대 입자) :&lt;/b&gt; 입자가 클수록 전방향으로 강하게 산란됨 (Forward scattering)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 이 차이가 수식의 위상 함수 &lt;span&gt;&lt;span&gt;&amp;rho;(&amp;omega;,&amp;omega;&amp;prime;) &lt;/span&gt;&lt;/span&gt;에 반영됨&lt;/p&gt;
&lt;p data-end=&quot;1458&quot; data-start=&quot;1430&quot; data-ke-size=&quot;size16&quot;&gt;오른쪽 아래 : 위상 함수 또는 산란 분포의 &lt;b&gt;방향성을 시각화&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1519&quot; data-start=&quot;1461&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1483&quot; data-start=&quot;1461&quot;&gt;원형 &amp;rarr; 등방성 (Isotropic)&lt;/li&gt;
&lt;li data-end=&quot;1501&quot; data-start=&quot;1486&quot;&gt;앞쪽 타원 &amp;rarr; 전방 산란&lt;/li&gt;
&lt;li data-end=&quot;1519&quot; data-start=&quot;1504&quot;&gt;뒤쪽 타원 &amp;rarr; 후방 산란&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;rho;(&amp;omega;,&amp;omega;&amp;prime;)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1639&quot; data-start=&quot;1588&quot;&gt;&lt;b&gt;Phase Function&lt;/b&gt;은 광학 매질 내에서 빛이 어떤 방향으로 산란될지를 결정&lt;/li&gt;
&lt;li data-end=&quot;1692&quot; data-start=&quot;1640&quot;&gt;Rayleigh, Henyey-Greenstein, Schlick 등의 다양한 모델이 존재&lt;/li&gt;
&lt;li data-end=&quot;1692&quot; data-start=&quot;1640&quot;&gt;볼륨 내부에서의 라이언스 전달을 설명하며, 위상함수 p는 산란의 방향성과 강도를 결정하는 핵심요소이다.&amp;nbsp;&lt;br /&gt;밉맵핑은 이러한 계산을 효율적으로 하기 위한 렌더링 최적화 기법으로 함께 소개될 예정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;659&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvGZc0/btsPiBPRlju/aFofFSGF7X1Pgb9yTekfy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvGZc0/btsPiBPRlju/aFofFSGF7X1Pgb9yTekfy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvGZc0/btsPiBPRlju/aFofFSGF7X1Pgb9yTekfy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvGZc0%2FbtsPiBPRlju%2FaFofFSGF7X1Pgb9yTekfy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;659&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;659&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;390&quot; data-start=&quot;258&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A Radiative Transfer Framework for Rendering Materials with Anisotropic Structure&lt;/b&gt;&lt;br /&gt;(by Wenzel Jakob et al., Cornell University)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;548&quot; data-start=&quot;406&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;470&quot; data-start=&quot;406&quot;&gt;비등방성 미세 구조(microflakes)를 갖는 재질 (예: 섬유, 머리카락, 카펫) 렌더링 프레임워크&lt;/li&gt;
&lt;li data-end=&quot;510&quot; data-start=&quot;471&quot;&gt;입사광이 재질의 방향성 구조에 따라 &lt;b&gt;비대칭 산란&lt;/b&gt;되도록 모델링&lt;/li&gt;
&lt;li data-end=&quot;548&quot; data-start=&quot;511&quot;&gt;전통적인 등방성(Isotropic) 모델보다 현실적인 표현 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1227&quot; data-origin-height=&quot;498&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCI9rx/btsPiC85UJh/OnXiHzP9B2bDwZKuMizjnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCI9rx/btsPiC85UJh/OnXiHzP9B2bDwZKuMizjnK/img.png&quot; data-alt=&quot;(a) 일반적인 확산형태 / (b) 섬유 방향성에 따라 달라진 하이라이트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCI9rx/btsPiC85UJh/OnXiHzP9B2bDwZKuMizjnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCI9rx%2FbtsPiC85UJh%2FOnXiHzP9B2bDwZKuMizjnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1227&quot; height=&quot;498&quot; data-origin-width=&quot;1227&quot; data-origin-height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(a) 일반적인 확산형태 / (b) 섬유 방향성에 따라 달라진 하이라이트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;289&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwp0BS/btsPh6pkR9u/lj7zeNMvk2LQ9OcdkDhG11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwp0BS/btsPh6pkR9u/lj7zeNMvk2LQ9OcdkDhG11/img.png&quot; data-alt=&quot;미세구조에 따른 광 반응 차이 시각화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwp0BS/btsPh6pkR9u/lj7zeNMvk2LQ9OcdkDhG11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwp0BS%2FbtsPh6pkR9u%2Flj7zeNMvk2LQ9OcdkDhG11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;500&quot; data-origin-width=&quot;289&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;미세구조에 따른 광 반응 차이 시각화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;875&quot; data-start=&quot;769&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;The SGGX Microflake Distribution&lt;/b&gt;&lt;br /&gt;(by Eric Heitz, Jonathan Dupuy, Cyril Crassin, Carsten Dachsbacher)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1084&quot; data-start=&quot;891&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;986&quot; data-start=&quot;891&quot;&gt;&lt;b&gt;SGGX (Spherical Gaussian-GGX) 모델&lt;/b&gt;은 미세 구조(마이크로플레이크)가 임의 방향으로 분포한 &lt;b&gt;볼륨 기반 재질&lt;/b&gt;의 광산란을 정확하게 표현&lt;/li&gt;
&lt;li data-end=&quot;1032&quot; data-start=&quot;987&quot;&gt;미세한 입자의 방향 분포를 통해 &lt;b&gt;헤어, 잎사귀, 구름 등&lt;/b&gt;의 렌더링 개선&lt;/li&gt;
&lt;li data-end=&quot;1084&quot; data-start=&quot;1033&quot;&gt;GGX 기반의 구조적 확장을 통해 &lt;b&gt;볼륨 안에서의 조밀한 방향성 정보&lt;/b&gt;까지 반영 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1379&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UfSNk/btsPgCbIM7J/nuhQIq1IFd3IKiUVXezW3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UfSNk/btsPgCbIM7J/nuhQIq1IFd3IKiUVXezW3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UfSNk/btsPgCbIM7J/nuhQIq1IFd3IKiUVXezW3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUfSNk%2FbtsPgCbIM7J%2FnuhQIq1IFd3IKiUVXezW3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1379&quot; height=&quot;781&quot; data-origin-width=&quot;1379&quot; data-origin-height=&quot;781&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;복잡한 현상을 표현하기 위해 볼륨(volume) 기반 모델을 사용하자&amp;rdquo;&lt;/b&gt;&lt;br /&gt;&amp;rarr; 단순한 위상 함수(phase function)는 세부 묘사 능력이 떨어진다.&lt;/p&gt;
&lt;p data-end=&quot;222&quot; data-start=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존의 간단한 phase function은&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;310&quot; data-start=&quot;223&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;248&quot; data-start=&quot;223&quot;&gt;입사광의 산란을 대칭적이고 단순하게 모델링&lt;/li&gt;
&lt;li data-end=&quot;283&quot; data-start=&quot;249&quot;&gt;예: Isotropic scattering (등방성 산란)&lt;/li&gt;
&lt;li data-end=&quot;310&quot; data-start=&quot;284&quot;&gt;결과적으로 &lt;b&gt;디테일 부족&lt;/b&gt;, 현실감 낮음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;319&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;A Radiative Transfer Framework for Rendering Materials with Anisotropic Structure&quot;&lt;/b&gt;&lt;br /&gt;저자: Wenzel Jakob, Adam Arbree, Jonathan T. Moon, Kavita Bala, Steve Marschner (Cornell University)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;438&quot; data-start=&quot;320&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;357&quot; data-start=&quot;320&quot;&gt;복잡한 비등방성(anisotropic) 구조를 가진 재질을 위해&lt;/li&gt;
&lt;li data-end=&quot;438&quot; data-start=&quot;358&quot;&gt;볼륨 내 마이크로 구조(micro-flakes)를 고려한 방사 전달 모델(radiative transfer framework)을 사용&lt;/li&gt;
&lt;li data-end=&quot;1067&quot; data-start=&quot;1033&quot;&gt;비등방성 재질에 적합한 위상 함수 설계&lt;/li&gt;
&lt;li data-end=&quot;1126&quot; data-start=&quot;1092&quot;&gt;섬유, 카펫, 헤어 등에서 현실적인 광 표현을 가능하게 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1292&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHwKoL/btsPiBPUFAT/DHvxlKkK855CHhY2v1iMek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHwKoL/btsPiBPUFAT/DHvxlKkK855CHhY2v1iMek/img.png&quot; data-alt=&quot;임의의 함수를 위상 함수 &amp;amp;rho;에 사용할 수 있는가?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHwKoL/btsPiBPUFAT/DHvxlKkK855CHhY2v1iMek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHwKoL%2FbtsPiBPUFAT%2FDHvxlKkK855CHhY2v1iMek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1292&quot; height=&quot;419&quot; data-origin-width=&quot;1292&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;임의의 함수를 위상 함수 &amp;rho;에 사용할 수 있는가?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1062&quot; data-start=&quot;1000&quot;&gt;&lt;b&gt;기존 모델 (예: Henyey-Greenstein, Rayleigh 등)&lt;/b&gt; 은 특정 물리적 특성을 근사&lt;/li&gt;
&lt;li data-end=&quot;1118&quot; data-start=&quot;1063&quot;&gt;그러나 &lt;b&gt;복잡한 재질&lt;/b&gt;(예: 섬유, 안개, 피부 등)에서는 단순 위상 함수로 디테일이 손실됨&lt;/li&gt;
&lt;li data-end=&quot;1172&quot; data-start=&quot;1119&quot;&gt;따라서 연구자들은 &lt;i&gt;&lt;span&gt;&lt;span&gt;&amp;rho;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;를 &lt;b&gt;보다 복잡하고 표현력 높은 함수로 바꾸고자&lt;/b&gt; 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qwS76/btsPhu5jG2W/18ulXbBH8Nu7rSDm4Mmn30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qwS76/btsPhu5jG2W/18ulXbBH8Nu7rSDm4Mmn30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qwS76/btsPhu5jG2W/18ulXbBH8Nu7rSDm4Mmn30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqwS76%2FbtsPhu5jG2W%2F18ulXbBH8Nu7rSDm4Mmn30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;517&quot; height=&quot;244&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;물리적 제약 조건 (Physical properties of &amp;rho;) : &lt;/b&gt;임의의 함수를 넣을 수 있는 것처럼 보이지만, 다음 세 가지 물리적 조건을 만족해야만 실제 세계에 기반한 위상 함수가 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;positivity (비음수성) : 위상함수는 음수일 수 없으며, 음의 산란량은 물리적으로 의미 없음&lt;/li&gt;
&lt;li&gt;reciprocity(상호성) : 광학적 역대칭성 보장. 빛이  &amp;prime; &amp;rarr;   방향으로 산란되든,   &amp;rarr;   &amp;prime; 방향으로 산란되든 확률은 동일&lt;/li&gt;
&lt;li&gt;energy conservation(에너지 보존) : 하나의 입사광이 여러 방향으로 퍼질수는 있어도, 총 에너지는 1(입사량 이상)을 넘을수 없다. 일부는 흡수되거나 전달되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1513_1&quot; id=&quot;footnote_link_1513_1&quot; onmouseover=&quot;tistoryFootnote.show(this, 1513, 1)&quot; onmouseout=&quot;tistoryFootnote.hide(1513, 1)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;1&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceIJeW/btsPgwW40Cp/Abzs0GOUIb1OScD9xnp7J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceIJeW/btsPgwW40Cp/Abzs0GOUIb1OScD9xnp7J0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceIJeW/btsPgwW40Cp/Abzs0GOUIb1OScD9xnp7J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceIJeW%2FbtsPgwW40Cp%2FAbzs0GOUIb1OScD9xnp7J0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;989&quot; height=&quot;552&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;480&quot; data-start=&quot;363&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;421&quot; data-start=&quot;363&quot;&gt;기존에는 &amp;sigma;ₛ가 고정된 &lt;b&gt;스칼라 값&lt;/b&gt;이었음 &amp;rarr; 이제는 &lt;b&gt;방향에 따른 함수 &amp;sigma;ₛ(&amp;omega;)&lt;/b&gt; 로 바뀜&lt;/li&gt;
&lt;li data-end=&quot;480&quot; data-start=&quot;422&quot;&gt;이는 &lt;b&gt;매질이 방향에 따라 다르게 산란&lt;/b&gt;시키는 것을 반영함 (예: 나무 섬유, 머리카락, 패브릭)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;638&quot; data-start=&quot;615&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reciprocity (상호성)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;37&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KwAGc/btsPgYGiaG3/q8AyAzKgrPMpqmG2ljN0N0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KwAGc/btsPgYGiaG3/q8AyAzKgrPMpqmG2ljN0N0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KwAGc/btsPgYGiaG3/q8AyAzKgrPMpqmG2ljN0N0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKwAGc%2FbtsPgYGiaG3%2Fq8AyAzKgrPMpqmG2ljN0N0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;254&quot; height=&quot;37&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;37&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;796&quot; data-start=&quot;738&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 방향별 산란 계수를 고려한 상호성(산란 정도가 다르더라도 &lt;b&gt;상호적 성질&lt;/b&gt; 유지해야 함)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;738&quot;&gt;기존 &amp;sigma;ₛ 모든 방향에 대해 일정한 산란 정도&lt;/li&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;738&quot;&gt;개선된 &amp;sigma;ₛ(&amp;omega;) 방향 &amp;omega;에 따라 산란 정도가 달라짐&lt;/li&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;738&quot;&gt;용도 섬유, 헤어, 브러시 등 방향성 구조가 있는 매질 표현에 필수&lt;/li&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;738&quot;&gt;장점 더&amp;nbsp;정밀한&amp;nbsp;anisotropic&amp;nbsp;volume&amp;nbsp;rendering&amp;nbsp;구현&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4lbBC/btsPg7iSzex/dPq1iSNAZkYTVZ3bkyf7V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4lbBC/btsPg7iSzex/dPq1iSNAZkYTVZ3bkyf7V1/img.png&quot; data-alt=&quot;방사선 전달 이론(Radiative Transfer Theory)에서 비구형 입자(non-spherical particles) , 특히 microflakes 의 물리적 의미를 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4lbBC/btsPg7iSzex/dPq1iSNAZkYTVZ3bkyf7V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4lbBC%2FbtsPg7iSzex%2FdPq1iSNAZkYTVZ3bkyf7V1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;908&quot; height=&quot;570&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;방사선 전달 이론(Radiative Transfer Theory)에서 비구형 입자(non-spherical particles) , 특히 microflakes 의 물리적 의미를 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;278&quot; data-start=&quot;158&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Physical interpretation: non-spherical particles (microflakes)&lt;/b&gt;&lt;br /&gt;&amp;rarr; 비구형 입자(편평한 형태의 마이크로 입자)의 산란 특성을 직관적으로 설명&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;358&quot; data-start=&quot;301&quot;&gt;microflake 입자 : 얇고 납작한 형태 (flake = 조각)&lt;/li&gt;
&lt;li data-end=&quot;358&quot; data-start=&quot;301&quot;&gt;&amp;sigma;ₜ (Sigma_t) : Extinction Coefficient (소광 계수)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;358&quot; data-start=&quot;301&quot;&gt;&amp;sigma;ₜ는 광선이 입자와 충돌하거나 흡수될 확률을 의미.&lt;/li&gt;
&lt;li data-end=&quot;358&quot; data-start=&quot;301&quot;&gt;&amp;sigma;ₜ가 클수록 빛이 더 빨리 사라진다 (산란되거나 흡수되기 때문에).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;358&quot; data-start=&quot;301&quot;&gt;입자&amp;nbsp;배열&amp;nbsp;방향 &amp;sigma;ₜ의&amp;nbsp;방향성에&amp;nbsp;결정적&amp;nbsp;영향&lt;/li&gt;
&lt;li data-end=&quot;358&quot; data-start=&quot;301&quot;&gt;렌더링&amp;nbsp;영향 방향에&amp;nbsp;따라&amp;nbsp;빛의&amp;nbsp;감쇠가&amp;nbsp;달라짐&amp;nbsp;&amp;rarr;&amp;nbsp;Anisotropic&amp;nbsp;Volume&amp;nbsp;Rendering&amp;nbsp;구현&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;471&quot; data-start=&quot;446&quot; data-ke-size=&quot;size16&quot;&gt;좌측 그림: &lt;b&gt;high &amp;sigma;ₜ&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;565&quot; data-start=&quot;472&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;492&quot; data-start=&quot;472&quot;&gt;입자들이 수평 방향으로 놓여 있음&lt;/li&gt;
&lt;li data-end=&quot;525&quot; data-start=&quot;493&quot;&gt;좌측에서 입사하는 광선은 많은 입자 표면과 충돌하게 됨&lt;/li&gt;
&lt;li data-end=&quot;565&quot; data-start=&quot;526&quot;&gt;즉, &lt;b&gt;빛의 경로가 입자에 의해 자주 방해받음&lt;/b&gt; &amp;rarr; &amp;sigma;ₜ가 높음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;591&quot; data-start=&quot;567&quot; data-ke-size=&quot;size16&quot;&gt;우측 그림: &lt;b&gt;low &amp;sigma;ₜ&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;679&quot; data-start=&quot;592&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;614&quot; data-start=&quot;592&quot;&gt;입자들이 수직 방향으로 정렬되어 있음&lt;/li&gt;
&lt;li data-end=&quot;654&quot; data-start=&quot;615&quot;&gt;위에서 수직으로 입사하는 광선은 &lt;b&gt;입자 면을 거의 통과&lt;/b&gt;하게 됨&lt;/li&gt;
&lt;li data-end=&quot;679&quot; data-start=&quot;655&quot;&gt;따라서 &lt;b&gt;적은 충돌&lt;/b&gt; &amp;rarr; &amp;sigma;ₜ가 낮음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;645&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmO05I/btsPhQBczox/j1C2Lk5VRKtROzh3JM8Fb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmO05I/btsPhQBczox/j1C2Lk5VRKtROzh3JM8Fb0/img.png&quot; data-alt=&quot;목표 : 입자 분포 및 특성으로부터 &amp;amp;sigma;ₐ(&amp;amp;omega;), &amp;amp;sigma;ₛ(&amp;amp;omega;), &amp;amp;rho;(&amp;amp;omega;, &amp;amp;omega;&amp;amp;prime;)를 도출한다.

미세면 이론과 유사 : NDF 및 미세면 구성으로부터 BSDF 도출&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmO05I/btsPhQBczox/j1C2Lk5VRKtROzh3JM8Fb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmO05I%2FbtsPhQBczox%2Fj1C2Lk5VRKtROzh3JM8Fb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1216&quot; height=&quot;645&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;645&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;목표 : 입자 분포 및 특성으로부터 &amp;sigma;ₐ(&amp;omega;), &amp;sigma;ₛ(&amp;omega;), &amp;rho;(&amp;omega;, &amp;omega;&amp;prime;)를 도출한다.

미세면 이론과 유사 : NDF 및 미세면 구성으로부터 BSDF 도출&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;203&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;입자 분포로부터&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;347&quot; data-start=&quot;204&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;242&quot; data-start=&quot;204&quot;&gt;&lt;b&gt;흡수 계수 (&amp;sigma;ₐ) &lt;/b&gt;: 특정 방향에서 얼마나 빛을 흡수하는지&lt;/li&gt;
&lt;li data-end=&quot;274&quot; data-start=&quot;243&quot;&gt;&lt;b&gt;산란 계수 (&amp;sigma;ₛ) &lt;/b&gt;: 얼마나 빛을 산란시키는지&lt;/li&gt;
&lt;li data-end=&quot;347&quot; data-start=&quot;275&quot;&gt;&lt;b&gt;위상 함수 (&amp;rho;) &lt;/b&gt;: 입사 방향 &amp;omega;&amp;prime;에서 방향 &amp;omega;로 얼마나 산란되는지&lt;br /&gt;이 세 가지 물리량을 유도하는 것이 목표.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZXXl8/btsPiFZVpty/X4nk6xcL1woQL9YYmP8eBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZXXl8/btsPiFZVpty/X4nk6xcL1woQL9YYmP8eBk/img.png&quot; data-alt=&quot;마이크로플레이크 이론 : 입자 분포 및 특성으로부터 &amp;amp;sigma;ₐ(&amp;amp;Omega;), &amp;amp;sigma;ₛ(&amp;amp;Omega;) 및 &amp;amp;rho;(&amp;amp;Omega;, &amp;amp;Omega;&amp;amp;prime;) 도출&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZXXl8/btsPiFZVpty/X4nk6xcL1woQL9YYmP8eBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZXXl8%2FbtsPiFZVpty%2FX4nk6xcL1woQL9YYmP8eBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1249&quot; height=&quot;704&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;704&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;마이크로플레이크 이론 : 입자 분포 및 특성으로부터 &amp;sigma;ₐ(&amp;Omega;), &amp;sigma;ₛ(&amp;Omega;) 및 &amp;rho;(&amp;Omega;, &amp;Omega;&amp;prime;) 도출&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;291&quot; data-start=&quot;235&quot; data-ke-size=&quot;size16&quot;&gt;미세 입자(microflake)의 분포 및 속성을 이용해 다음의 &lt;b&gt;방사 전파 특성&lt;/b&gt;을 계산한다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;414&quot; data-start=&quot;293&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;293&quot;&gt;&lt;b&gt;&amp;sigma;ₐ(&amp;omega;)&lt;/b&gt; : 방향 &amp;omega;에 대한 &lt;b&gt;흡수 계수&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;362&quot; data-start=&quot;328&quot;&gt;&lt;b&gt;&amp;sigma;ₛ(&amp;omega;)&lt;/b&gt; : 방향 &amp;omega;에 대한 &lt;b&gt;산란 계수&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;414&quot; data-start=&quot;363&quot;&gt;&lt;b&gt;&amp;rho;(&amp;omega;, &amp;omega;&amp;prime;)&lt;/b&gt; : 입사 방향 &amp;omega;&amp;prime;에서 산란되어 방향 &amp;omega;로 가는 &lt;b&gt;위상 함수&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;441&quot; data-start=&quot;421&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-end=&quot;441&quot; data-start=&quot;421&quot; data-ke-size=&quot;size16&quot;&gt;입력 요소 (input)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Particle density(입자밀도) &lt;span aria-hidden=&quot;true&quot;&gt;&amp;sigma;p​&lt;/span&gt;&amp;nbsp;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단위 부피당 microflake 입자의 수&lt;/li&gt;
&lt;li&gt;방향에 따라 변하지 않음 (isotropic)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;albedo(알베도) &amp;alpha;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입자가 반사하는 비율 (0~1 사이)&lt;/li&gt;
&lt;li&gt;방향에 따라 변하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;법선 분포 함수 (NDF) D(m)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;microflake의 법선이 방향 m에 분포하는 정도&lt;/li&gt;
&lt;li&gt;마이크로페이스 이론과 유사한 개념&lt;/li&gt;
&lt;li&gt;이 함수는 각 입자의 방향성 구조를 정의함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 요소 (output)&lt;/p&gt;
&lt;p data-end=&quot;795&quot; data-start=&quot;775&quot; data-ke-size=&quot;size16&quot;&gt;위 3가지 입력으로부터 다음을 도출:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;910&quot; data-start=&quot;797&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;833&quot; data-start=&quot;797&quot;&gt;&lt;b&gt;흡수 계수&lt;/b&gt; &lt;span&gt;&lt;span&gt;&amp;sigma;a(&amp;omega;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;870&quot; data-start=&quot;834&quot;&gt;&lt;b&gt;산란 계수&lt;/b&gt; &lt;span&gt;&lt;span&gt;&amp;sigma;s(&amp;omega;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;910&quot; data-start=&quot;871&quot;&gt;&lt;b&gt;위상 함수&lt;/b&gt; &lt;span&gt;&lt;span&gt;&amp;rho;(&amp;omega;,&amp;omega;&amp;prime;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;Note: I present a less general version here for simplicity&amp;rdquo;&lt;br /&gt;해당 설명은 단순화를 위해 방향성 변화를 고려하지 않는 모델로 제한하고 있음을 알립니다. 실제 일반화된 이론은 방향에 따라 변하는 &amp;sigma;, &amp;alpha; 등을 포함합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;633&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brlqx2/btsPjdhB0oQ/xstP1KFnK54nv8eepDOBtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brlqx2/btsPjdhB0oQ/xstP1KFnK54nv8eepDOBtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brlqx2/btsPjdhB0oQ/xstP1KFnK54nv8eepDOBtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbrlqx2%2FbtsPjdhB0oQ%2FxstP1KFnK54nv8eepDOBtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;633&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;633&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 마이크로플레이크는 양면 거울 BRDF를 가진 평평한 이중면(two-sided surface)으로 간주된다.&lt;/p&gt;
&lt;p data-end=&quot;222&quot; data-start=&quot;200&quot; data-ke-size=&quot;size16&quot;&gt;planar&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;293&quot; data-start=&quot;223&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;253&quot; data-start=&quot;223&quot;&gt;입자는 &lt;b&gt;얇고 납작한 평면형 입자&lt;/b&gt;로 모델링됨.&lt;/li&gt;
&lt;li data-end=&quot;293&quot; data-start=&quot;254&quot;&gt;3D 공간에서 &lt;b&gt;정해진 법선 방향&lt;/b&gt;을 가진 &quot;플레이크&quot;로 존재.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;328&quot; data-start=&quot;295&quot; data-ke-size=&quot;size16&quot;&gt;two-sided mirror&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;461&quot; data-start=&quot;329&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;359&quot; data-start=&quot;329&quot;&gt;입자는 &lt;b&gt;거울처럼 빛을 반사하는 성질&lt;/b&gt;을 가짐.&lt;/li&gt;
&lt;li data-end=&quot;414&quot; data-start=&quot;360&quot;&gt;방향 &amp;omega;에서 입사된 광선은 플레이크의 법선 &lt;b&gt;m&lt;/b&gt;을 기준으로 &lt;b&gt;&amp;omega;&amp;prime; 방향으로 반사&lt;/b&gt;됨.&lt;/li&gt;
&lt;li data-end=&quot;461&quot; data-start=&quot;415&quot;&gt;중요한 점: &lt;b&gt;양면 거울&lt;/b&gt;이므로, m과 -m 양쪽 모두 반사에 영향을 미침.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;517&quot; data-start=&quot;463&quot; data-ke-size=&quot;size16&quot;&gt;즉, 단일 면만 반응하는 것이 아니라, 두 방향 모두에서 입사된 빛이 반사될 수 있는 구조.&lt;/p&gt;
&lt;p data-end=&quot;544&quot; data-start=&quot;524&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;544&quot; data-start=&quot;524&quot; data-ke-size=&quot;size16&quot;&gt;BRDF 관점에서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;683&quot; data-start=&quot;545&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;582&quot; data-start=&quot;545&quot;&gt;각 마이크로플레이크는 BRDF(양방향 반사 분포 함수)를 가짐.&lt;/li&gt;
&lt;li data-end=&quot;635&quot; data-start=&quot;583&quot;&gt;이 BRDF는 &lt;b&gt;mirror-like&lt;/b&gt;, 즉 반사만을 고려하는 &lt;b&gt;델타 함수 기반&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;683&quot; data-start=&quot;636&quot;&gt;산란의 방향성은 &lt;b&gt;플레이크의 법선 분포 D(m)&lt;/b&gt; 에 따라 통계적으로 결정됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNUW4Q/btsPjip6xQI/VX6i9HZ5pVkZCQbYrdNf9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNUW4Q/btsPjip6xQI/VX6i9HZ5pVkZCQbYrdNf9K/img.png&quot; data-alt=&quot;Particle 분포와 속성으로 부터 입자밀도, 흡수계수 &amp;amp;sigma;a​ ( &amp;amp;omega; ), 산란계수 &amp;amp;sigma;s(​&amp;amp;omega;), 위상합수를 도출한다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNUW4Q/btsPjip6xQI/VX6i9HZ5pVkZCQbYrdNf9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNUW4Q%2FbtsPjip6xQI%2FVX6i9HZ5pVkZCQbYrdNf9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1272&quot; height=&quot;723&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Particle 분포와 속성으로 부터 입자밀도, 흡수계수 &amp;sigma;a​ ( &amp;omega; ), 산란계수 &amp;sigma;s(​&amp;omega;), 위상합수를 도출한다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;assuming the particles are planar(입자는 평면이라고 가정)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;123&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PsNXb/btsPjBbZG9L/AuCiUPCW6JUqynVF9XOPHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PsNXb/btsPjBbZG9L/AuCiUPCW6JUqynVF9XOPHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PsNXb/btsPjBbZG9L/AuCiUPCW6JUqynVF9XOPHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPsNXb%2FbtsPjBbZG9L%2FAuCiUPCW6JUqynVF9XOPHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;521&quot; height=&quot;123&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;123&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1473&quot; data-start=&quot;1429&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;총 상호작용 계수 &lt;span&gt;&lt;span&gt;&amp;sigma;t(&amp;omega;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1488&quot; data-start=&quot;1474&quot; data-ke-size=&quot;size16&quot;&gt;빛이 입자와 만날 가능성:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1683&quot; data-start=&quot;1564&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1586&quot; data-start=&quot;1564&quot;&gt;&lt;span&gt;&lt;span&gt;D(m) &lt;/span&gt;&lt;/span&gt;: 법선 분포 함수&lt;/li&gt;
&lt;li data-end=&quot;1650&quot; data-start=&quot;1587&quot;&gt;&lt;span&gt;&lt;span&gt;m&amp;sdot;&amp;omega; &lt;/span&gt;&lt;/span&gt;: 방향 &lt;span&gt;&lt;span&gt;&amp;omega;에&lt;/span&gt;&lt;/span&gt;서의 입자의 &lt;b&gt;투영면적&lt;/b&gt; (교차 확률)&lt;/li&gt;
&lt;li data-end=&quot;1683&quot; data-start=&quot;1651&quot;&gt;직관 : 광선이 입자 면에 수직으로 갈수록 만날 확률 &amp;uarr;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FSou9/btsPj1aAlFF/ig0jfOf6UkjR7z5nLvL0IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FSou9/btsPj1aAlFF/ig0jfOf6UkjR7z5nLvL0IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FSou9/btsPj1aAlFF/ig0jfOf6UkjR7z5nLvL0IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFSou9%2FbtsPj1aAlFF%2Fig0jfOf6UkjR7z5nLvL0IK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;551&quot; height=&quot;324&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왼쪽 &lt;/b&gt;: 입사 방향이 &lt;b&gt;입자 방향과 수평&lt;/b&gt;&lt;br /&gt;&amp;rarr; 입자 면에 거의 수직하게 들어옴&lt;br /&gt;&amp;rarr; 입자 투영 면적이 작음&lt;br /&gt;&amp;rarr; 입자와의 교차 확률이 낮음&lt;br /&gt;&amp;rarr; &amp;rarr; &lt;b&gt;긴 free path (자유 평균 경로)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;오른쪽&lt;/b&gt;: 입사 방향이 &lt;b&gt;입자 방향과 수직&lt;/b&gt;&lt;br /&gt;&amp;rarr; 입자 면에 수평하게 들어감&lt;br /&gt;&amp;rarr; 입자 투영 면적이 큼&lt;br /&gt;&amp;rarr; 입자와의 교차 확률이 큼&lt;br /&gt;&amp;rarr; &amp;rarr; &lt;b&gt;짧은 free path&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 입사 방향 &lt;span&gt;&lt;span&gt;&amp;omega;에&lt;/span&gt;&lt;/span&gt;&amp;nbsp;따라 입자들과의 충돌 확률이 다르며, 이는 곧 &lt;b&gt;free path&lt;/b&gt;에 영향을 준다는 걸 보여준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r4EyB/btsPiCDsDwv/6ykKCxqLAjpPpRRKYB8Ig0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r4EyB/btsPiCDsDwv/6ykKCxqLAjpPpRRKYB8Ig0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r4EyB/btsPiCDsDwv/6ykKCxqLAjpPpRRKYB8Ig0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr4EyB%2FbtsPiCDsDwv%2F6ykKCxqLAjpPpRRKYB8Ig0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;233&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1963&quot; data-start=&quot;1906&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1934&quot; data-start=&quot;1906&quot;&gt;산란은 전체 충돌 중 &lt;span&gt;&lt;span&gt;&amp;alpha;\alpha&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;alpha;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;만큼&lt;/li&gt;
&lt;li data-end=&quot;1963&quot; data-start=&quot;1935&quot;&gt;흡수는 나머지 &lt;span&gt;&lt;span&gt;(1&amp;minus;&amp;alpha;)(1 - \alpha)&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;&amp;minus;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;alpha;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2030&quot; data-start=&quot;1965&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; &lt;span&gt;&lt;span&gt;&amp;sigma;t(&amp;omega;)=&amp;sigma;s(&amp;omega;)+&amp;sigma;a(&amp;omega;)&lt;/span&gt;&lt;/span&gt;&amp;nbsp;성립&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1287&quot; data-origin-height=&quot;719&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wX3Sy/btsPkbqLPk2/RMw6PptmmOYTsshxUBkrv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wX3Sy/btsPkbqLPk2/RMw6PptmmOYTsshxUBkrv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wX3Sy/btsPkbqLPk2/RMw6PptmmOYTsshxUBkrv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwX3Sy%2FbtsPkbqLPk2%2FRMw6PptmmOYTsshxUBkrv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1287&quot; height=&quot;719&quot; data-origin-width=&quot;1287&quot; data-origin-height=&quot;719&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위상 함수 &lt;span&gt;&lt;span&gt;&amp;rho;(&amp;omega;,&amp;omega;&amp;prime;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1291&quot; data-start=&quot;1236&quot;&gt;&lt;span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;omega;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 방향으로 입사한 빛이 &lt;span&gt;&lt;span&gt;&amp;omega;&amp;prime;\omega'&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;omega;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;prime;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 방향으로 산란될 확률 밀도&lt;/li&gt;
&lt;li data-end=&quot;1463&quot; data-start=&quot;1292&quot;&gt;&lt;b&gt;핵심 아이디어 &lt;/b&gt;: 거울 반사 조건을 만족하는 법선 벡터 &lt;span&gt;&lt;span&gt;m &lt;/span&gt;&lt;/span&gt;를 찾기 위한 조건 :&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOt1JY/btsPj1BGouc/umA8jkn27W36nRgq3sT0c1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOt1JY/btsPj1BGouc/umA8jkn27W36nRgq3sT0c1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOt1JY/btsPj1BGouc/umA8jkn27W36nRgq3sT0c1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOt1JY%2FbtsPj1BGouc%2FumA8jkn27W36nRgq3sT0c1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;415&quot; height=&quot;80&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1562&quot; data-start=&quot;1465&quot;&gt;따라서, 이 방향을 갖는 마이크로플레이크(입자)가 있을 확률이 &lt;span&gt;&lt;span&gt;D(&amp;sdot;)D(\cdot)&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;sdot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, 그리고 입사 반사 양면 모두 고려해야 하므로 두 개의 &lt;i&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;D&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&amp;nbsp;항이 곱해짐&lt;/li&gt;
&lt;li data-end=&quot;1647&quot; data-start=&quot;1563&quot;&gt;마지막으로 &lt;b&gt;정규화&lt;/b&gt;를 위해 &lt;span&gt;&lt;span&gt;&amp;sigma;s(&amp;omega;)&lt;/span&gt;&lt;/span&gt;로 나누어 줌 &amp;rarr; &lt;b&gt;reciprocity (상호성)&lt;/b&gt; 보장을 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상호성&amp;nbsp;보장&amp;nbsp;조건&amp;nbsp;(Reciprocity&amp;nbsp;Condition)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;38&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kQQl0/btsPjjJT7vT/T53ovYXICfLGL5q0qVcyVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kQQl0/btsPjjJT7vT/T53ovYXICfLGL5q0qVcyVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kQQl0/btsPjjJT7vT/T53ovYXICfLGL5q0qVcyVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkQQl0%2FbtsPjjJT7vT%2FT53ovYXICfLGL5q0qVcyVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;356&quot; height=&quot;55&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;38&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1819&quot; data-start=&quot;1781&quot;&gt;위상 함수는 입출 방향을 바꾸어도 물리적으로 같은 값을 가져야 함&lt;/li&gt;
&lt;li data-end=&quot;1852&quot; data-start=&quot;1820&quot;&gt;이 수식을 만족하도록 &lt;b&gt;&lt;i&gt;&lt;span&gt;&lt;span&gt;&amp;rho;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&amp;nbsp;정의가 설계됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1922&quot; data-start=&quot;1884&quot;&gt;각 미세한 정사각형은 &lt;b&gt;입자들이 분포한 지역 부피&lt;/b&gt;를 보여주며&lt;/li&gt;
&lt;li data-end=&quot;1976&quot; data-start=&quot;1923&quot;&gt;파란 막대기(입자)에 빛이 입사된 뒤 &lt;span&gt;&lt;span&gt;&amp;omega;&amp;prime;\omega'&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;omega;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;prime;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 방향으로 산란되는 것을 시각화&lt;/li&gt;
&lt;li data-end=&quot;2039&quot; data-start=&quot;1977&quot;&gt;이 모든 확률은 &lt;span&gt;&lt;span&gt;D(m)D(m)&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;D&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, &lt;span&gt;&lt;span&gt;&amp;omega;\omega&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;omega;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, &lt;span&gt;&lt;span&gt;&amp;omega;&amp;prime;\omega'&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;omega;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;prime;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;의 상호작용으로 결정됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;719&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N8bJx/btsPkpI4Sld/Tmf9QIFZVYN6ctDD3whPvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N8bJx/btsPkpI4Sld/Tmf9QIFZVYN6ctDD3whPvk/img.png&quot; data-alt=&quot;그림 4는 입사 방향 &amp;amp;omega;i\omega_i&amp;amp;omega;i​ 에 대해 두 가지 입자 법선 분포 와 그에 따른 반사 거동 을 보여준다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N8bJx/btsPkpI4Sld/Tmf9QIFZVYN6ctDD3whPvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN8bJx%2FbtsPkpI4Sld%2FTmf9QIFZVYN6ctDD3whPvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1274&quot; height=&quot;719&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;719&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 4는 입사 방향 &amp;omega;i\omega_i&amp;omega;i​ 에 대해 두 가지 입자 법선 분포 와 그에 따른 반사 거동 을 보여준다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span&gt;&lt;span&gt;&lt;span&gt;NDF는 마이크로플레이크 볼륨의 동작을 결정한다!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;228&quot; data-start=&quot;212&quot; data-ke-size=&quot;size16&quot;&gt;(a) NDF : &lt;span&gt;&lt;span&gt;D(&amp;omega;) = cos⁡^20(v, &amp;omega;)+&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;160&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XHjh3/btsPjhSREfh/KKKmP2NYApCZZJhBGL7TRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XHjh3/btsPjhSREfh/KKKmP2NYApCZZJhBGL7TRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XHjh3/btsPjhSREfh/KKKmP2NYApCZZJhBGL7TRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXHjh3%2FbtsPjhSREfh%2FKKKmP2NYApCZZJhBGL7TRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;279&quot; height=&quot;61&quot; data-origin-width=&quot;160&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;440&quot; data-start=&quot;281&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;317&quot; data-start=&quot;281&quot;&gt;&lt;b&gt;법선 분포가 &lt;span&gt;&lt;span&gt;vv&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;v&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 방향으로 매우 집중&lt;/b&gt;되어 있음&lt;/li&gt;
&lt;li data-end=&quot;344&quot; data-start=&quot;318&quot;&gt;&amp;rarr; 입자들이 모두 수직 방향으로 정렬된 상태&lt;/li&gt;
&lt;li data-end=&quot;440&quot; data-start=&quot;345&quot;&gt;&amp;rarr; 반사 특성이 &lt;b&gt;거칠게 rough한 표면&lt;/b&gt;처럼 동작&lt;br /&gt;&amp;rarr; &lt;span&gt;&lt;span&gt;&amp;omega;i\omega_i&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;omega;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 방향에서 들어온 빛이 NDF 중심 방향 &lt;span&gt;&lt;span&gt;vv&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;v&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;에 대해 대칭 반사됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;495&quot; data-start=&quot;442&quot; data-ke-size=&quot;size16&quot;&gt;오른쪽의 &lt;span&gt;&lt;span&gt;fp&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;는 위상 함수(phase function)에 해당하는 분포.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;519&quot; data-start=&quot;502&quot; data-ke-size=&quot;size16&quot;&gt;(b)&amp;nbsp;NDF: &lt;span&gt;&lt;span&gt;D(&amp;omega;) = sin^⁡20(v, &amp;omega;)+&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;155&quot; data-origin-height=&quot;38&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rhop8/btsPjhSRMeH/l8dlkPE0rzKfMjgYCyT3S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rhop8/btsPjhSRMeH/l8dlkPE0rzKfMjgYCyT3S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rhop8/btsPjhSRMeH/l8dlkPE0rzKfMjgYCyT3S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRhop8%2FbtsPjhSRMeH%2Fl8dlkPE0rzKfMjgYCyT3S0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;265&quot; height=&quot;65&quot; data-origin-width=&quot;155&quot; data-origin-height=&quot;38&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;734&quot; data-start=&quot;572&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;608&quot; data-start=&quot;572&quot;&gt;&lt;b&gt;법선 분포가 &lt;span&gt;&lt;span&gt;vv&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;v&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 방향에서 수직 방향으로 퍼짐&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;661&quot; data-start=&quot;609&quot;&gt;&amp;rarr; 입자들이 &lt;span&gt;&lt;span&gt;vv&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;v&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;를 **섬유 방향(tangent)**으로 가지며 평면에 눕는 형태&lt;/li&gt;
&lt;li data-end=&quot;734&quot; data-start=&quot;662&quot;&gt;&amp;rarr; 이는 &lt;b&gt;섬유(fiber)&lt;/b&gt; 또는 &lt;b&gt;긴 기공을 가진 재료&lt;/b&gt; 같은 형태의 반사를 유도함&amp;rarr; 측면으로 넓게 산란됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1101&quot; data-start=&quot;1053&quot;&gt;NDF &lt;span&gt;&lt;span&gt;D(m)&lt;/span&gt;&lt;/span&gt;는 입자들의 배향 분포를 수학적으로 표현한 것으로,&lt;/li&gt;
&lt;li data-end=&quot;1196&quot; data-start=&quot;1102&quot;&gt;그 분포가 달라지면, 결과적으로 &lt;b&gt;빛이 마이크로플레이크 볼륨 내에서 어떻게 산란되는지&lt;/b&gt; (즉, &lt;span&gt;&lt;span&gt;&amp;rho;(&amp;omega;,&amp;omega;&amp;prime;))&lt;/span&gt;&lt;/span&gt;도 완전히 달라짐&lt;/li&gt;
&lt;li data-end=&quot;1254&quot; data-start=&quot;1197&quot;&gt;실제 재질(예: 머리카락, 흙먼지, 우유, 거친 금속 등)은 이 NDF에 따라 광학적 특성이 달라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWuE6Q/btsPjT4ZDWo/xV2GcZAxqKomc8ZkeVkfDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWuE6Q/btsPjT4ZDWo/xV2GcZAxqKomc8ZkeVkfDK/img.png&quot; data-alt=&quot;어떻게 법선 분포 함수(NDF)를 선택할 것인가?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWuE6Q/btsPjT4ZDWo/xV2GcZAxqKomc8ZkeVkfDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWuE6Q%2FbtsPjT4ZDWo%2FxV2GcZAxqKomc8ZkeVkfDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;712&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;어떻게 법선 분포 함수(NDF)를 선택할 것인가?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;we want the projected area&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;88&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boFtCZ/btsPjJVD3v9/6mhuKxilIUPRx6wr7hudi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boFtCZ/btsPjJVD3v9/6mhuKxilIUPRx6wr7hudi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boFtCZ/btsPjJVD3v9/6mhuKxilIUPRx6wr7hudi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboFtCZ%2FbtsPjJVD3v9%2F6mhuKxilIUPRx6wr7hudi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;88&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;88&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to have closed-form&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;464&quot; data-start=&quot;366&quot;&gt;위 적분식(법선 분포를 따라 투영된 면적)이 &lt;b&gt;닫힌 형태(closed-form)&lt;/b&gt;, 즉 수학적으로 명확하게 계산 가능한 형태이기를 원한다.&lt;/li&gt;
&lt;li data-end=&quot;610&quot; data-start=&quot;468&quot;&gt;이 적분은 산란/흡수 계수인 &lt;span&gt;&lt;span&gt;&amp;sigma;s(&amp;omega;)&lt;/span&gt;&lt;/span&gt;, &lt;span&gt;&lt;span&gt;&amp;sigma;a(&amp;omega;)&lt;/span&gt;&lt;/span&gt; 등의 계산에 핵심적으로 사용되기 때문. 이게 해석적으로 간단하면 &lt;b&gt;렌더링 성능이 향상&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;we want D to be &amp;ldquo;filterable&amp;rdquo; like a normal map&lt;/b&gt;[LEAN, LEADR]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;802&quot; data-start=&quot;704&quot;&gt;우리는 NDF가 &lt;b&gt;필터링 가능&lt;/b&gt;하기를 원한다. 즉, 해상도를 낮추거나 mipmap을 만들 때 &lt;b&gt;부드럽게 평균화&lt;/b&gt;할 수 있어야 한다.&lt;/li&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;804&quot;&gt;&lt;b&gt;참고 논문 &lt;/b&gt;: LEAN, LEADR은 NDF를 필터링 가능한 방식으로 사용하는 논문 이름.&lt;/li&gt;
&lt;li data-end=&quot;977&quot; data-start=&quot;868&quot;&gt;보통 normal map을 사용해 디테일을 표현하는데, 이를 &lt;b&gt;확대/축소해도 물리적으로 자연스러워야&lt;/b&gt; 하듯이, NDF도 비슷한 성질을 갖춰야 한다는 의미.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHPlSE/btsPjIboYbS/nkew9cpWCOeIK9qW1AKKW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHPlSE/btsPjIboYbS/nkew9cpWCOeIK9qW1AKKW1/img.png&quot; data-alt=&quot;SGGX : 표현력, 필터링 가능성, 효율성이 뛰어난 NDF&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHPlSE/btsPjIboYbS/nkew9cpWCOeIK9qW1AKKW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHPlSE%2FbtsPjIboYbS%2Fnkew9cpWCOeIK9qW1AKKW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1179&quot; height=&quot;718&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;718&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SGGX : 표현력, 필터링 가능성, 효율성이 뛰어난 NDF&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1265&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKkDBO/btsPkQsImlH/HD1KcK4VsEhJBjFKKWxqdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKkDBO/btsPkQsImlH/HD1KcK4VsEhJBjFKKWxqdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKkDBO/btsPkQsImlH/HD1KcK4VsEhJBjFKKWxqdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKkDBO%2FbtsPkQsImlH%2FHD1KcK4VsEhJBjFKKWxqdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1265&quot; height=&quot;675&quot; data-origin-width=&quot;1265&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol class=&quot;footnotes&quot;&gt;
    &lt;li id=&quot;footnote_1513_1&quot;&gt; 관련 위상 함수 예시&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1663&quot; data-start=&quot;1265&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 30.5814%;&quot;&gt;&lt;b&gt;위상함수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.9767%;&quot;&gt;&lt;b&gt;상호성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 16.5116%;&quot;&gt;&lt;b&gt;에너지보존&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 40.9302%;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1466&quot; data-start=&quot;1398&quot;&gt;
&lt;td style=&quot;width: 30.5814%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1418&quot; data-start=&quot;1398&quot;&gt;&lt;b&gt;Isotropic&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.9767%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1426&quot; data-start=&quot;1418&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 16.5116%;&quot; data-end=&quot;1440&quot; data-start=&quot;1426&quot; data-col-size=&quot;sm&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;width: 40.9302%;&quot; data-end=&quot;1466&quot; data-start=&quot;1440&quot; data-col-size=&quot;sm&quot;&gt;균일 산란&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1529&quot; data-start=&quot;1467&quot;&gt;
&lt;td style=&quot;width: 30.5814%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1487&quot; data-start=&quot;1467&quot;&gt;&lt;b&gt;Rayleigh&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.9767%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1495&quot; data-start=&quot;1487&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 16.5116%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1509&quot; data-start=&quot;1495&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;width: 40.9302%;&quot; data-end=&quot;1529&quot; data-start=&quot;1509&quot; data-col-size=&quot;sm&quot;&gt;미세 입자 산란 (파장 영향)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1597&quot; data-start=&quot;1530&quot;&gt;
&lt;td style=&quot;width: 30.5814%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1554&quot; data-start=&quot;1530&quot;&gt;&lt;b&gt;Henyey-Greenstein&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.9767%;&quot; data-end=&quot;1558&quot; data-start=&quot;1554&quot; data-col-size=&quot;sm&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 16.5116%;&quot; data-end=&quot;1572&quot; data-start=&quot;1558&quot; data-col-size=&quot;sm&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;width: 40.9302%;&quot; data-end=&quot;1597&quot; data-start=&quot;1572&quot; data-col-size=&quot;sm&quot;&gt;편향 산란 (anisotropy 표현)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1663&quot; data-start=&quot;1598&quot;&gt;
&lt;td style=&quot;width: 30.5814%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1618&quot; data-start=&quot;1598&quot;&gt;&lt;b&gt;Schlick&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.9767%;&quot; data-end=&quot;1626&quot; data-start=&quot;1618&quot; data-col-size=&quot;sm&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 16.5116%;&quot; data-end=&quot;1640&quot; data-start=&quot;1626&quot; data-col-size=&quot;sm&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;width: 40.9302%;&quot; data-end=&quot;1663&quot; data-start=&quot;1640&quot; data-col-size=&quot;sm&quot;&gt;HG의 근사, 계산 단순함&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;a href=&quot;#footnote_link_1513_1&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</description>
      <category>Technical Report/Graphics Tech Reports</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1513</guid>
      <comments>https://illu.tistory.com/1513#entry1513comment</comments>
      <pubDate>Mon, 14 Jul 2025 15:19:17 +0900</pubDate>
    </item>
    <item>
      <title>250627 크래프톤 웨이</title>
      <link>https://illu.tistory.com/1512</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MAfle/btsOUA6MDW8/JsHFwBF4BINOL5UWks65r0/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MAfle/btsOUA6MDW8/JsHFwBF4BINOL5UWks65r0/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MAfle/btsOUA6MDW8/JsHFwBF4BINOL5UWks65r0/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMAfle%2FbtsOUA6MDW8%2FJsHFwBF4BINOL5UWks65r0%2Ftfile.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;2252&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;1권이 나왔을때는 회사의 민감한 내용까지 이렇게 책으로 낸다고...? 라는 주위와 인터넷의 호들갑에 서점에서 서서 대충 훓어보고는 '그냥 게임회사에서 쉬이 보던 이야기인데?' 하고 잊고 있다가 2권이 올초에 나온걸 보고 한번은 읽어야지 하고 동시에 주문했다.(생각해보면 다른업계에서는 게임쪽 이야기가 신선했을수는 있겠다 싶지만...)&lt;br&gt;&lt;br&gt;출퇴근 지하철에서 틈틈히 읽은 소감은 1권은 잘 읽히긴 하는데 뭔가 생각할 만한 화두는 딱히 없었고(아마 테라가 내취향이 아니였던 탓도 있으리...배틀그라운드 이야기의 비중이 그리 크지 않았던것도..)&lt;br&gt;&lt;br&gt;2권이 초반부터 펍지 성공이후 인센티브 책정과 관련된 블루홀 경영진과의 갈등, 성공한 IP를 장기 로드맵을 어떻게 만들어 유지하는지, 어떤 생각으로 드라이브 했는지에 대한 부분은 무척이나 흥미로웠다. 때마침 그즈음에 영문씨가 펍지로 가서 건너 들은 이야기도 생각났고.&lt;br&gt;&lt;br&gt;특히 게임업계에서의 리더십, 조직운영, 조직문화를 만들어갈때 고민해야하는 부분은 나도 우리부서 꾸리면서 또 임원도 되고나니 고민이 많은 부분이라 여기에 대한 이야기는 엄청 흡입력 있게 다가왔다. 그러다보니 슬슬 조직리더 역할을 하는 지인이나 시니어들에게는 한번쯤 읽어보라 권하는중.&lt;br&gt;&lt;br&gt;기억에 남는 문장이 몇개 있었는데 1권에서는 이부분&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/muuhu/btsOV8uBSnz/aFnqz9TA5XQrDHk0u7WFdk/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/muuhu/btsOV8uBSnz/aFnqz9TA5XQrDHk0u7WFdk/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/muuhu/btsOV8uBSnz/aFnqz9TA5XQrDHk0u7WFdk/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmuuhu%2FbtsOV8uBSnz%2FaFnqz9TA5XQrDHk0u7WFdk%2Ftfile.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2048&quot; height=&quot;1153&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1153&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;그라고 마지막은 김창한 대표님 맺음말을 첨부해본다.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HTIyL/btsOWlUOvjG/jNGwKhrent0w25Zo6ovZ2k/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HTIyL/btsOWlUOvjG/jNGwKhrent0w25Zo6ovZ2k/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HTIyL/btsOWlUOvjG/jNGwKhrent0w25Zo6ovZ2k/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHTIyL%2FbtsOWlUOvjG%2FjNGwKhrent0w25Zo6ovZ2k%2Ftfile.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;2252&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;</description>
      <category>Diary/2020-2025</category>
      <category>리더십</category>
      <category>크래프톤웨이</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1512</guid>
      <comments>https://illu.tistory.com/1512#entry1512comment</comments>
      <pubDate>Sat, 28 Jun 2025 01:34:21 +0900</pubDate>
    </item>
    <item>
      <title>GPU Specification compare PS5/XBOX Series X/Adreno/PC</title>
      <link>https://illu.tistory.com/1455</link>
      <description>&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.347%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.8372%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RTX 3070(2020)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS5(2020)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.5752%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SnapDragon865&lt;br /&gt;(2020)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.5533%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GTX650(2012)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.5733%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;XBOX SeriesX&lt;br /&gt;(2020)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.8372%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GPU Name&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GA104(8nm)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Ampere&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Oberon(7nm)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RDNA 2.0&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.5752%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Adreno 650(7nm)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.5533%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GK106(26nm)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Kepler&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.5733%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Scarlett(7nm)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RDNA 2.0&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.8372%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Base Clock&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1500MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1725MHz&lt;br /&gt;(Boost Clock)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2233MHz&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.5752%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;250MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;587MHz&lt;br /&gt;(Boost Clock)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.5533%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1058MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.5733%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1825MHz&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.8372%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Clock&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Size&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Type&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Bus&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Bandwidth&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1750MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;14 Gbps effective&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;8GB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GDDR6&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;256bit&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;448.0 GB/s&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1750MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;14 Gbps effective&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;16GB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GDDR6&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;256bit&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;448.0 GB/s&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.5752%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2750MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;LPDDR4X(or LPDDR5)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;64bit&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;44 GB/s&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.5533%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1250MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1GB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GDDR5&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;128bit&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;80.00 GB/s&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.5733%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1750MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;14 Gbps effective&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;10GB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GDDR6&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;320bit&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;560.0 GB/s&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.8372%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Shading Units&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;TMUs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ROPs&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5888&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;184&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;96&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2304&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;144&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;64&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.5752%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;512&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;24*2&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.5533%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;384&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;32&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;16&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.5733%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3328&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;208&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;64&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.8372%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;Pixel Rate&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;Texture Rate&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;FP16(half)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;FP32(float)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;FP64(double)&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;165.6 GPixel/s&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;317.4 GTexel/s&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;20.31 TFLOPS(1:1)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;20.31 TFLOPS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;317.4 GFLOPS(1:64)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.3256%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;142.9 GPixel/s&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;321.6 GTexel/s&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;20.58 TFLOPS(2:1)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;10.29 TFLOPS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;643.1 GFLOPS(1:16)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 15.5752%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;14.1 GPixel/s&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;28.1 GPixel/s&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;1.3 TFLOPS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;/&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 17.5533%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;8.464 GPixel/s&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;33.86 GTexel/s&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;812.5 GFLOPS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;33.86 GFLOPS(1:24)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 18.5733%;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;116.8 GPixel/s&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;379.6 GTexel/s&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;24.29 TFLOPS(2:1)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;12.15 TFLOPS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;759.2 GFLOPS(1:16)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;911&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSpyRz/btsOaEvockY/BdzYfw9h8cz4IlYw1t1kO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSpyRz/btsOaEvockY/BdzYfw9h8cz4IlYw1t1kO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSpyRz/btsOaEvockY/BdzYfw9h8cz4IlYw1t1kO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSpyRz%2FbtsOaEvockY%2FBdzYfw9h8cz4IlYw1t1kO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;131&quot; height=&quot;131&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;911&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Adreno 830 specifications : &lt;a href=&quot;https://en.wikipedia.org/wiki/Adreno#Adreno_800_series&quot;&gt;https://en.wikipedia.org/wiki/Adreno#Adreno_800_series&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.347%; height: 437px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS5(2020)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS5 Pro(2024)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Snap Dragon&lt;br /&gt;Gen Elite(2024)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RTX 5070(2025)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GPU Name&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Oberon(7nm)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RDNA 2.0&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Viola(4nm)&lt;br /&gt;RDNA 2.0&lt;/td&gt;
&lt;td&gt;Adreno 830(3nm)&lt;br /&gt;Oryon&amp;nbsp;Gen&amp;nbsp;2&lt;/td&gt;
&lt;td&gt;GB205(5nm)&lt;br /&gt;Blackwell 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Base Clock&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2233MHz&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;2170MHz&lt;br /&gt;2350MHz(Boost)&lt;/td&gt;
&lt;td&gt;1100MHz&lt;br /&gt;1200MHz(for Galaxy)&lt;/td&gt;
&lt;td&gt;2325MHz&lt;br /&gt;2515MHz(Boost)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Clock&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Size&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Type&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Memory Bus&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Bandwidth&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1750MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;14 Gbps effective&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;16GB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GDDR6&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;256bit&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;448.0 GB/s&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;225&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0MHz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;18 Gbps effective&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;16GB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GDDR6&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;256bit&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;576.0 GB/s&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;5300MHz&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;12MB(on chip) Shared Meomry&lt;br /&gt;LPDDR5X&lt;br /&gt;64bit&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;84.8 GB/s&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.1956%; height: 144px;&quot;&gt;1750HMz&lt;br /&gt;28 Gbps effective&lt;br /&gt;&lt;br /&gt;12GB&lt;br /&gt;GDDR7&lt;br /&gt;192bit&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;672.0 GB/s&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Shading Units&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;TMUs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ROPs&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2304&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;144&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;64&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;3840&lt;br /&gt;240&lt;br /&gt;64&lt;/td&gt;
&lt;td&gt;1536&lt;br /&gt;/&lt;br /&gt;/&lt;/td&gt;
&lt;td&gt;6144&lt;br /&gt;192&lt;br /&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;Pixel Rate&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;Texture Rate&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;FP16(half)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;FP32(float)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;FP64(double)&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;142.9 GPixel/s&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;321.6 GTexel/s&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;20.58 TFLOPS(2:1)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;10.29 TFLOPS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;643.1 GFLOPS(1:16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;150.4 GPixel/s&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;564.0 GTexel/s&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;36.10 TFLOPS(2:1)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif;&quot;&gt;18.05 TFLOPS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, '돋움', sans-serif; color: #000000;&quot;&gt;1128 GFLOPS(1:16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;/&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;6.7584 TFLOPS(2:1)&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;3.3792 TFLOPS&lt;/b&gt; &lt;/span&gt;&lt;br /&gt;844.8 GFLOPS&lt;/td&gt;
&lt;td style=&quot;width: 20.1956%; height: 118px;&quot;&gt;201.0 GPixel/s&lt;br /&gt;482.3 GTexel/s&lt;br /&gt;&lt;br /&gt;30.87 TFLPOPS)1:1&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 30.87 TFLPOPS&lt;/b&gt; &lt;/span&gt;&lt;br /&gt;482.3 GFLPOPS (1:64)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PS5의 Compute Unit (CU)는 AMD GPU에서 &lt;b&gt;셰이더 연산, 텍스처 처리, 벡터 연산 등을 담당하는 병렬 처리 블록&lt;/b&gt;으NVIDIA의 Streaming Multiprocessor(SM)에 해당하는 구조를 말한다.&amp;nbsp; 셰이딩 연산량, 텍스처 처리량등 병렬처리 성능에 영향을 주는 요소이다. PS5에서는 36개에서 Pro에서 60개로 그 수가 늘어났다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N&lt;span style=&quot;background-color: #f8f8f8; color: #1d1c1d; text-align: left;&quot;&gt;vidia는 tile based rendering으로 전환하고 xclipse랑 이번 adreno 830은 IMR(IMR (Immediate Mode Rendering) 으로 다시 돌아왔다. xclipse야 RDNA 아키텍처 때문인가 싶은데, 애플 A18 바이오닉보다 벤치 성능이 잘 나오는걸보면 이유가 있지 싶은데...(완전 전통방식 그대로는 아닌듯하고 특히 캐쉬 사이즈 변경등 몇몇 이유를 짐작할 부분이 보인다. 이 추세면 5년뒤 10년뒤 포터블 디바이스 시장은 지금과도 꽤 다를듯)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://www.reddit.com/r/hardware/comments/1gqubjv/why_does_the_snapdragon_8_elites_gpu_have_so_much/?rdt=59896&quot;&gt;https://www.reddit.com/r/hardware/comments/1gqubjv/why_does_the_snapdragon_8_elites_gpu_have_so_much/?rdt=59896&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Bandwidth :&lt;/b&gt; GPU와 VRAM(그래픽 메모리) 간의 초당 데이터 전송량(Byte/s)&lt;br /&gt;&amp;nbsp; &amp;rarr; GPU가 처리할 데이터를 메모리에서 얼마나 빠르게 가져올 수 있느냐에 따라 전체 처리 속도가 달라짐.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Bandwidth = Memory Bus Width &amp;times; Memory Clock Speed &amp;times; 2 (DDR) &amp;divide; 8&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Snapdragon 865의 경우 계산으로는 88GB/s이 나오지만 실제 LPDDR4X5의 효율을 반영해 44GB/s으로 표기&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;GDDR3/GDDR4/GDDR5 칩 하나당 32bit interface가 있는데, 2개를 병렬로 연결하면 64bit GDDR5 bus, 4개면 128 bit, 6개면 192 bit, 8개면 256 bit, 12개면 384 bit, 16개면 512 bit. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메모리칩을 하나의 GPU에 연결하기 위해서 PCB설계가 더욱 더 복잡해지고, 메모리 클럭도 떨어지게 된다. 더 높은 메모리 버스 일수록 파워를 더 많이 먹게되고, 발열, 그리고 GPU자체도 메모리 컨트롤러 때문에 커지게 됨. 256과 512비트의 경우 PCB 기판 가격도 고가가 된다. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; GDDR 방식은 메모리 버스를 늘려 대역폭을 확보하는 반면, HBM은 버스폭을 크게 하고 클럭은 낮추는 방식으로 더 높은 대역폭을 달성함. HBM/HBM2 경우 1스택당 1024 bit bus를 제공하여, 적은 클럭으로도 Bandwidth는 크다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Shading Units : &lt;/b&gt;GPU의 계산 유닛 또는 코어에 해당하며 물리, 조명, 그림자등 각종 비주얼 계산에 사용된다. FP32 연산(부동소수점 계산) 단위를 기준으로 GPU FLOPS(연산능력) 계산. Cuda core(Nvidia) /&amp;nbsp; Stream Processor(AMD)&lt;br /&gt;AMD와 Nvidia의 연산방식 차이에 따라 유닛 숫자는 차이날 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;TMU(Texture Mapping Units) : &lt;/b&gt;텍스처(이미지)를 픽셀에 힙히는 작업을 담당하는 유닛&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;688&quot; data-start=&quot;638&quot;&gt;텍스처 좌표 변환, 필터링(Bilinear, Trilinear, Anisotropic)&lt;/li&gt;
&lt;li data-end=&quot;729&quot; data-start=&quot;689&quot;&gt;Mipmapping 처리 (화질 및 성능 최적화용 텍스처 축소 기술)&lt;/li&gt;
&lt;li data-end=&quot;756&quot; data-start=&quot;730&quot;&gt;텍셀(Texel) &amp;rarr; 픽셀(Pixel) 매핑&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Texture Fillrate (텍스처 필레이트)&lt;/b&gt; = TMU 수 &amp;times; GPU 클럭으로 계산되며 이는 초당 몇 개의 텍스처를 처리할 수 있는지를 의미(단위: GTexel/s)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ROPs (Render Output Units / Raster Operations Pipelines) : &lt;/b&gt;렌더링 파이프라인의 최종 출력 처리를 담당하는 유닛. 픽셀을&amp;nbsp;최종&amp;nbsp;이미지로&amp;nbsp;출력하기&amp;nbsp;직전의&amp;nbsp;&quot;마무리&amp;nbsp;작업&quot;&amp;nbsp;수행.&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1129&quot; data-start=&quot;1080&quot;&gt;블렌딩(반투명 처리), Z-buffer(깊이 정보 처리), 스텐실 처리, 안티앨리어싱&lt;/li&gt;
&lt;li data-end=&quot;1158&quot; data-start=&quot;1130&quot;&gt;프레임버퍼로의 출력, 최종 해상도에 맞는 픽셀화&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Pixel Fillrate (픽셀 필레이트)&lt;/b&gt; = ROP 수 &amp;times; GPU 클럭. 초당 출력 가능한 픽셀 수 (단위: GPixel/s)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;렌더링 과정은 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[Shading Units : 계산] &amp;rarr; [TMUs : 텍스처] &amp;rarr; [ROPs : 출력] 순으로 이루어진다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;부동소수점 연산 성능(Floating Point Operations Per Second) :&lt;/b&gt; 초당 부동 소수점 연산 수행 능력을 나태는 지표로 1 GFLOPS는 초당 10억, 1 TFLOPS 1조번 연산능력을 이야기 한다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FLOPS = 연산 유닛 수 &amp;times; 클럭 속도 &amp;times; IPC( Instructions Per Cycle)&lt;/b&gt;&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_1455_1&quot; id=&quot;footnote_link_1455_1&quot; onmouseover=&quot;tistoryFootnote.show(this, 1455, 1)&quot; onmouseout=&quot;tistoryFootnote.hide(1455, 1)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;1&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div&gt;이론상 최대값이므로 실제 성능은 이보다 낮을 수 있음. 보통 FP16연산이 FP32보다 빠르게 처리됨. FP64의 경우 게임용 GPU에서는 매우 느리게 작동한다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GPU 아키텍처마다 정밀도별 유닛 지원 비율이 다르기 때문에 FP16, FP32, FP64의 비율이 다르게 나타난다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;492&quot; data-start=&quot;234&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.8372%;&quot;&gt;&lt;b&gt;연산포맷&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 39.8837%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 9.06977%;&quot;&gt;&lt;b&gt;bit 수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 37.093%;&quot;&gt;&lt;b&gt;용도&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;366&quot; data-start=&quot;298&quot;&gt;
&lt;td style=&quot;width: 13.8372%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;312&quot; data-start=&quot;298&quot;&gt;FP16 (Half)&lt;/td&gt;
&lt;td style=&quot;width: 39.8837%;&quot; data-end=&quot;344&quot; data-start=&quot;312&quot; data-col-size=&quot;sm&quot;&gt;Half Precision Floating Point&lt;/td&gt;
&lt;td style=&quot;width: 9.06977%;&quot; data-end=&quot;352&quot; data-start=&quot;344&quot; data-col-size=&quot;sm&quot;&gt;16bit&lt;/td&gt;
&lt;td style=&quot;width: 37.093%;&quot; data-end=&quot;366&quot; data-start=&quot;352&quot; data-col-size=&quot;sm&quot;&gt;모바일, AI 추론&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;426&quot; data-start=&quot;367&quot;&gt;
&lt;td style=&quot;width: 13.8372%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;382&quot; data-start=&quot;367&quot;&gt;FP32 (Float)&lt;/td&gt;
&lt;td style=&quot;width: 39.8837%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;401&quot; data-start=&quot;382&quot;&gt;Single Precision&lt;/td&gt;
&lt;td style=&quot;width: 9.06977%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;409&quot; data-start=&quot;401&quot;&gt;32bit&lt;/td&gt;
&lt;td style=&quot;width: 37.093%;&quot; data-end=&quot;426&quot; data-start=&quot;409&quot; data-col-size=&quot;sm&quot;&gt;일반 게임, 그래픽 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;492&quot; data-start=&quot;427&quot;&gt;
&lt;td style=&quot;width: 13.8372%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;443&quot; data-start=&quot;427&quot;&gt;FP64 (Double)&lt;/td&gt;
&lt;td style=&quot;width: 39.8837%;&quot; data-end=&quot;462&quot; data-start=&quot;443&quot; data-col-size=&quot;sm&quot;&gt;Double Precision&lt;/td&gt;
&lt;td style=&quot;width: 9.06977%;&quot; data-end=&quot;470&quot; data-start=&quot;462&quot; data-col-size=&quot;sm&quot;&gt;64bit&lt;/td&gt;
&lt;td style=&quot;width: 37.093%;&quot; data-end=&quot;492&quot; data-start=&quot;470&quot; data-col-size=&quot;sm&quot;&gt;과학, 공학, 물리 시뮬레이션 등&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FP16&lt;/b&gt; : AI연산 가속 목적으로만 지원하는 경우가 많음. 전통적인 셰이더 코어(SM, CU)와 별개로 존재. 특정 조건에서만 높은 성능 발휘&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1423&quot; data-start=&quot;1175&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;GPU&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;FP32&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;FP16&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;비율&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1298&quot; data-start=&quot;1231&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1242&quot; data-start=&quot;1231&quot;&gt;RTX 3070&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1257&quot; data-start=&quot;1242&quot;&gt;20.31 TFLOPS&lt;/td&gt;
&lt;td data-end=&quot;1272&quot; data-start=&quot;1257&quot; data-col-size=&quot;sm&quot;&gt;20.31 TFLOPS&lt;/td&gt;
&lt;td data-end=&quot;1298&quot; data-start=&quot;1272&quot; data-col-size=&quot;sm&quot;&gt;1:1 (FP16 연산은 SM에서 처리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1363&quot; data-start=&quot;1299&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1310&quot; data-start=&quot;1299&quot;&gt;RTX 3090&lt;/td&gt;
&lt;td data-end=&quot;1325&quot; data-start=&quot;1310&quot; data-col-size=&quot;sm&quot;&gt;35.58 TFLOPS&lt;/td&gt;
&lt;td data-end=&quot;1355&quot; data-start=&quot;1325&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;71 TFLOPS (Tensor Core)&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1363&quot; data-start=&quot;1355&quot; data-col-size=&quot;sm&quot;&gt;1:2 이상&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1423&quot; data-start=&quot;1364&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1377&quot; data-start=&quot;1364&quot;&gt;Adreno 650&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1397&quot; data-start=&quot;1377&quot;&gt;1.3 TFLOPS (FP32)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1409&quot; data-start=&quot;1397&quot;&gt;미지원 / 미기재&lt;/td&gt;
&lt;td data-end=&quot;1423&quot; data-start=&quot;1409&quot; data-col-size=&quot;sm&quot;&gt;AI용 NPU에서 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1715&quot; data-start=&quot;1517&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;플랫폼&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;설계 목적&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;정밀도 지원&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1631&quot; data-start=&quot;1581&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1591&quot; data-start=&quot;1581&quot;&gt;모바일 SoC&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1606&quot; data-start=&quot;1591&quot;&gt;전력효율, 중간 정밀도&lt;/td&gt;
&lt;td data-end=&quot;1631&quot; data-start=&quot;1606&quot; data-col-size=&quot;sm&quot;&gt;FP16/INT8 위주, FP64 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1670&quot; data-start=&quot;1632&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1641&quot; data-start=&quot;1632&quot;&gt;콘솔 GPU&lt;/td&gt;
&lt;td data-end=&quot;1650&quot; data-start=&quot;1641&quot; data-col-size=&quot;sm&quot;&gt;게임 그래픽&lt;/td&gt;
&lt;td data-end=&quot;1670&quot; data-start=&quot;1650&quot; data-col-size=&quot;sm&quot;&gt;FP32 중점, FP16 일부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1715&quot; data-start=&quot;1671&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1684&quot; data-start=&quot;1671&quot;&gt;서버/과학용 GPU&lt;/td&gt;
&lt;td data-end=&quot;1696&quot; data-start=&quot;1684&quot; data-col-size=&quot;sm&quot;&gt;시뮬레이션, AI&lt;/td&gt;
&lt;td data-end=&quot;1715&quot; data-start=&quot;1696&quot; data-col-size=&quot;sm&quot;&gt;FP64/FP16 병렬성 극대화&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reference :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RTX 3070 : &lt;/span&gt;&lt;a href=&quot;https://www.techpowerup.com/gpu-specs/geforce-rtx-3070.c3674&quot;&gt;https://www.techpowerup.com/gpu-specs/geforce-rtx-3070.c3674&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GTX 650 : &lt;/span&gt;&lt;a href=&quot;https://www.techpowerup.com/gpu-specs/geforce-gtx-650.c894&quot;&gt;https://www.techpowerup.com/gpu-specs/geforce-gtx-650.c894&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PS5 : &lt;/span&gt;&lt;a href=&quot;https://www.techpowerup.com/gpu-specs/playstation-5-gpu.c3480&quot;&gt;https://www.techpowerup.com/gpu-specs/playstation-5-gpu.c3480&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;XBOX Series X : &lt;/span&gt;&lt;a href=&quot;https://www.techpowerup.com/gpu-specs/xbox-series-x-gpu.c3482&quot;&gt;https://www.techpowerup.com/gpu-specs/xbox-series-x-gpu.c3482&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol class=&quot;footnotes&quot;&gt;
    &lt;li id=&quot;footnote_1455_1&quot;&gt; 한번의 클럭 주기당 몇개의 명령어(instruction)을 실행할 수 있는지를 나타내는 성능지표. 주요 게임용 Nvidia/AMD GPU의 IPC 는 2.0으로 추정되나 Snapdragon 865의 경우 4.3정도로 추산됨(이는 AI unit 가속을 포함한 수치로 추정됨. 단순 비교하기 어려움)  &lt;a href=&quot;#footnote_link_1455_1&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</description>
      <category>Technical Report/Graphics Tech Reports</category>
      <category>Adreno</category>
      <category>Bandwidth</category>
      <category>GPU</category>
      <category>ps5</category>
      <category>rops</category>
      <category>shadingunit</category>
      <category>Specification</category>
      <category>TMU</category>
      <category>XBOX</category>
      <author>illu_yun</author>
      <guid isPermaLink="true">https://illu.tistory.com/1455</guid>
      <comments>https://illu.tistory.com/1455#entry1455comment</comments>
      <pubDate>Sat, 24 May 2025 23:27:41 +0900</pubDate>
    </item>
  </channel>
</rss>