<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>渲染Pass学习 on wanfeng</title>
        <link>https://sdpyy1.github.io/tags/%E6%B8%B2%E6%9F%93pass%E5%AD%A6%E4%B9%A0/</link>
        <description>Recent content in 渲染Pass学习 on wanfeng</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <copyright>爱喝东方树叶</copyright>
        <lastBuildDate>Mon, 24 Nov 2025 11:14:58 +0800</lastBuildDate><atom:link href="https://sdpyy1.github.io/tags/%E6%B8%B2%E6%9F%93pass%E5%AD%A6%E4%B9%A0/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Cluster Based Lighting</title>
        <link>https://sdpyy1.github.io/p/cluster-based-lighting/</link>
        <pubDate>Mon, 24 Nov 2025 11:14:58 +0800</pubDate>
        
        <guid>https://sdpyy1.github.io/p/cluster-based-lighting/</guid>
        <description>&lt;h1 id=&#34;cluster-based-lighting&#34;&gt;Cluster Based Lighting
&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;这里只介绍原理，实现篇放在游戏引擎开发实践（GPU-Driven）中&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;将相机视锥体分为若干簇，并为仅为每个簇分配若干有效的光源，可以避免大量无效的光照计算&lt;/p&gt;
&lt;p&gt;在着色阶段的流程则比较简单。首先根据像素坐标计算像素所属 Cluster，然后遍历该 Cluster 的 “有效光源” 列表，逐一计算光照&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;分簇&#34;&gt;分簇
&lt;/h2&gt;&lt;p&gt;&lt;img src=&#34;https://sdpyy1.github.io/v2-022d9a1c88aee7b022fb48107491dc1c_1440w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;img&#34;
	
	
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ComputerShader中每个线程一个簇，XY上分簇，Z上进行切分，每个簇就对应XYZ&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;https://sdpyy1.github.io/v2-cdaa1cb1e8cbd9a82b46a019111615a2_1440w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;img&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;所以执行时就是 &lt;code&gt;command-&amp;gt;Dispatch(  1, 1, LIGHT_CLUSTER_DEPTH);&lt;/code&gt;  LIGHT_CLUSTER_DEPTH就是Z坐标划分次数&lt;/p&gt;
&lt;p&gt;在Shader中进行每个Group的在XY上进行划分。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-glsl&#34; data-lang=&#34;glsl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define THREAD_SIZE_X LIGHT_CLUSTER_WIDTH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define THREAD_SIZE_Y LIGHT_CLUSTER_HEIGHT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#define THREAD_SIZE_Z 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;layout&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;local_size_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;THREAD_SIZE_X&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;local_size_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;THREAD_SIZE_Y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;local_size_z&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;THREAD_SIZE_Z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;uvec3&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gID&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gl_GlobalInvocationID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xyz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// 获得的就是每个簇的索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;接下来要找每个簇对应的视锥体范围的角点坐标&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://sdpyy1.github.io/v2-d0ed99d9b69cb4fceb9eeeb26be29ef6_1440w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;img&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;根据上边的信息可以屏幕空间上每个簇的角点UV，下面顺序是  屏幕UV-&amp;gt;NDC-&amp;gt;View，最终目的是拿到每个簇在View下的每个角点的坐标（转到世界坐标计算也行）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://sdpyy1.github.io/v2-81d582026a88713d0c0e464b0da760c1_1440w.jpg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;img&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;求交光照剔除&#34;&gt;求交光照剔除
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;在每个簇中遍历场景中的所有光源范围，如果光源范围覆盖到了这个簇的位置，就把这个光源的索引信息存储到这个簇的信息中，具体怎么存就看具体光源是怎么管理的了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;求交可以简单的判断簇的角点在不在光源位置内，或者用簇做一个包围盒，用包围盒与光源的球形包围盒进行求交运算来判断该光源是否会影响当前簇&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
