目錄
- 前言
- NeRF
- 神經輻射場
- 體渲染
- 連續體渲染
- 體渲染離散化
- 方法
- 位置編碼
- 分層采樣
- 體渲染推導公式(1)到公式(2)
- 部分代碼解讀
- 相機變換(重要!)
- Mip-Nerf
- To do
- Instant-NGP
- To do
前言
NeRF是NeRF系列的開山之作,將三維場景隱式的表達為神經網絡的權重用于新視角合成。
MipNeRF和Instant NGP分別代表了NeRF的兩個研究方向,前者是抗鋸齒,代表著渲染質量提升方向;后者是采用多分辨率哈希表用于加速NeRF的訓練與推理速度。

NeRF
Title:NeRF: Representing Scenes asNeural Radiance Fields for View Synthesis
Code:nerf-pytorch
From:ECCV 2020 Oral - Best Paper Honorable Mention
神經輻射場
輻射場可以理解光線場,給定多張帶有相機內外參的二維圖片,從攝像機出發,引出到每一個像素的光線,通過對這條光線經歷過的空間點的顏色 c c c和體密度體密度 σ \sigma σ進行累積,以得到二維圖片上像素點的顏色,從而實現端到端訓練。在這個過程中,沒有顯式的三維結構,如點云、體素或者Mesh,而是通過神經網絡的權重 F θ F_{\theta} Fθ?將三維場景連續的存儲起來,通過空間位置(三維點 [ x , y , z ] [x,y,z] [x,y,z])和視角方向(球坐標系下的極角和方位角 [ θ , ? ] [\theta,\phi] [θ,?])作為查詢條件,查詢出給定攝像機下的光線所經過的空間點顏色 c c c和體密度 σ \sigma σ,通過**體渲染(Volume Rendering)**得到該條光線對應像素點的顏色。
體渲染

沿著視角方向的光線上的點P可以用上圖來表示,盡管論文中提到視角方向是使用 θ , ? \theta,\phi θ,?來表示的,但代碼中還是使用單位向量 d d d來表示的。
連續體渲染
體渲染實際上就是將視線r上所有的點通過某種方式累計投射到圖像上形成像素顏色 C ( r ) C(r) C(r)的過程:
C ( r ) = ∫ t n t f T ( t ) σ ( r ( t ) ) c ( r ( t ) , d ) d t where? T ( t ) = exp ? ( ? ∫ t n t σ ( r ( s ) ) d s ) (1) {C}(\boldsymbol{r})=\int_{t_n}^{t_f} T(t) \sigma(\boldsymbol{r}(t)) \boldsymbol{c}(\boldsymbol{r}(t), \boldsymbol{d}) dt \\ \text{where } T(t)=\exp \left(-\int_{t_n}^t \sigma(\boldsymbol{r}(s)) d s\right)\tag{1} C(r)=∫tn?tf??T(t)σ(r(t))c(r(t),d)dtwhere?T(t)=exp(?∫tn?t?σ(r(s))ds)(1)
其中, c ( r ( t ) , d ) \boldsymbol{c}(\boldsymbol{r}(t), \boldsymbol{d}) c(r(t),d)為三維點 r ( t ) r(t) r(t)從 d d d這個方向看到的顏色值; σ ( r ( t ) ) \sigma(\boldsymbol{r}(t)) σ(r(t))為體密度函數,反映的是該三維點的物理材質吸收光線的能力; T ( t ) T(t) T(t)反映的是射線上從 t n t_n tn?到 t t t的累積透射率。tn和tf首先確定了nerf的邊界,而不至于學習到無窮遠;其次避免了光心到近景范圍內無效采樣。
直觀上理解σ,可以解釋為每個三維點吸收光線的能力,光經過該點,一部分被吸收,一部分透射,光的強度(可以理解為 T ( t ) T(t) T(t)) 在逐漸減小,當光強為0時,后面的三維點即便可以吸收顏色,也不會對像素顏色有貢獻。指數函數保證了隨著σ的累積,光的強度從1逐漸減為0。
體渲染離散化
其實就是函數離散化的形式,將tn到tf拆分成N個均勻的分布空間,從每個區間中隨機選取一個樣本ti:
t i ~ U [ t n + i ? 1 N ( t f ? t n ) , t n + i N ( t f ? t n ) ] i 從1到N t_i \sim \mathcal{U}\left[t_n+\frac{i-1}{N}\left(t_f-t_n\right), t_n+\frac{i}{N}\left(t_f-t_n\right)\right] \quad i \text{ 從1到N} ti?~U[tn?+Ni?1?(tf??tn?),tn?+Ni?(tf??tn?)]i?從1到N
然后將連續體渲染公式離散化:
C ^ ( r ) = ∑ i = 1 N T i ( 1 ? exp ? ( ? σ i δ i ) ) c i where? T i = exp ? ( ? ∑ j = 1 i ? 1 σ j δ j ) (2) \hat{C}(\mathbf{r})=\sum_{i=1}^N T_i\left(1-\exp \left(-\sigma_i \delta_i\right)\right) \mathbf{c}_i \quad \tag 2 \\ \text{where } T_i=\exp \left(-\sum_{j=1}^{i-1} \sigma_j \delta_j\right) C^(r)=i=1∑N?Ti?(1?exp(?σi?δi?))ci?where?Ti?=exp(?j=1∑i?1?σj?δj?)(2)
where T i = exp ? ( ? ∑ j = 1 i ? 1 σ j δ j ) T_i=\exp \left(-\sum_{j=1}^{i-1} \sigma_j \delta_j\right) Ti?=exp(?∑j=1i?1?σj?δj?)
其中, δ i = t i + 1 ? t i \delta_i=t_{i+1}-t_i δi?=ti+1??ti? 表示相鄰采樣點之間的距離
但均勻采樣有明顯的問題, 比如體密度較大的點如果在兩個采樣點之間,那么永遠不可能采樣到。從上圖中可看出,左半張代表均勻采樣,右半張代表真實分布,左邊由于表面兩側被采樣到,只能反應這個區間內可能存在表面,但估計的σ不一定準確。
作者提出了分層采樣來試圖解決這個問題。
方法
位置編碼
網絡結構由如上圖所示全連接網絡組成,輸入x,d分別分三維點的空間位置和視線方向。該三維點的體密度只與空間位置相關,顏色還和視角相關。
γ ( p ) = ( sin ? ( 2 0 π p ) , cos ? ( 2 0 π p ) , ? , sin ? ( 2 L ? 1 π p ) , cos ? ( 2 L ? 1 π p ) ) \gamma(p)=\left(\sin \left(2^0 \pi p\right), \cos \left(2^0 \pi p\right), \cdots, \sin \left(2^{L-1} \pi p\right), \cos \left(2^{L-1} \pi p\right)\right) γ(p)=(sin(20πp),cos(20πp),?,sin(2L?1πp),cos(2L?1πp))
還可以注意到γ(x)和γ(d)分別是對位置坐標和方向坐標的位置編碼(標準正余弦位置編碼),這是由于單純坐標只能體現低頻信息,位置編碼可以有效的區分開兩個距離很近的坐標(即低頻接近但高頻編碼分開【但或許也有問題,離得特別近的兩個點或許低頻信息也不相似,私以為mipnerf考慮三維點鄰域的區間,在一定程度上可以緩解】),從而幫助網絡學習到高頻幾何和紋理細節。如下圖所示,視角信息有效反應高光信息,位置編碼有助于恢復高頻細節。
分層采樣
除了上述提到的均勻采樣可能導致i真實表面難以正好采樣到,還有均勻采樣帶來了很多無意義空間的無效采樣,簡單來說,只有空氣的地方沒必要進行采樣,或者被遮擋區域(可見性問題,不可見區域也沒必要采樣,需要提前判斷累積透射率是否為降為0)。
首先均勻采樣可以得到crose color,wi可以理解為同條射線被采樣的 N c N_c Nc?個三維點顏色的權重:
C ^ c ( r ) = ∑ i = 1 N c w i c i , w i = T i ( 1 ? exp ? ( ? σ i δ i ) ) \widehat{C}_c(\mathbf{r})=\sum_{i=1}^{N_c} w_i c_i, \quad w_i=T_i\left(1-\exp \left(-\sigma_i \delta_i\right)\right) C c?(r)=i=1∑Nc??wi?ci?,wi?=Ti?(1?exp(?σi?δi?))
根據均勻采樣點的權重值歸一化后按重要性重新采樣得到新的 n f n_f nf?個位置
w ^ i = w i / ∑ j = 1 N c w j \widehat{w}_i=w_i / \sum_{j=1}^{N_c} w_j w i?=wi?/j=1∑Nc??wj?
最后損失函數可以表示為:
L = ∑ r ∈ R [ ∥ C ^ c ( r ) ? C ( r ) ∥ 2 2 + ∥ C ^ f ( r ) ? C ( r ) ∥ 2 2 ] \mathcal{L}=\sum_{\mathbf{r} \in \mathcal{R}}\left[\left\|\widehat{C}_c(\mathbf{r})-C(\mathbf{r})\right\|_2^2+\left\|\widehat{C}_f(\mathbf{r})-C(\mathbf{r})\right\|_2^2\right] L=r∈R∑?[ ?C c?(r)?C(r) ?22?+ ?C f?(r)?C(r) ?22?]
這里為什么選用兩個網絡來分別做粗糙采樣和精細采樣,參考大佬【
】。crose網絡是用于均勻采樣的,包含更多的是低頻信息的查詢,而fine網絡用于重要性采樣,適用于三維點高頻細節的查詢,兩個網絡起到了類似濾波器的作用。
「待做實驗驗證!!!Todo」
體渲染推導公式(1)到公式(2)
首先,光線通過區間 [ 0 , t + d t ) [0, t+d t) [0,t+dt) 的概率:
光線通過區間 [ 0 , t + d t ) [0, t+d t) [0,t+dt) 的概率:
T ( t + d t ) = T ( t ) ? ( 1 ? d t ? σ ( t ) ) \begin{aligned} \mathcal{T}(t+d t) & =\mathcal{T}(t) \cdot(1-d t \cdot \sigma(t)) \end{aligned} T(t+dt)?=T(t)?(1?dt?σ(t))?
可以得到
T ( t + d t ) ? T ( t ) d t ≡ T ′ ( t ) = ? T ( t ) ? σ ( t ) \begin{aligned} \frac{\mathcal{T}(t+d t)-\mathcal{T}(t)}{d t} & \equiv \mathcal{T}^{\prime}(t)=-\mathcal{T}(t) \cdot \sigma(t) \end{aligned} dtT(t+dt)?T(t)??≡T′(t)=?T(t)?σ(t)?
1 ? T ( t ) 1-\mathcal{T}(t) 1?T(t) 為光線在區間 [ 0 , t ) [0, t) [0,t) 被終止的累積分布函數(CDF);
T ( t ) σ ( t ) \mathcal{T}(t) \sigma(t) T(t)σ(t) 為其對應的概率密度函數 (PDF)
其中, T ( t ) \mathcal{T}(t) T(t) 為光線通過區間 [ 0 , t ) [0, t) [0,t) 透射率,也就是沒被終止的概率,從1->0; σ ( t ) \sigma(t) σ(t) 為體密度函數; d t ? σ ( t ) d t \cdot \sigma(t) dt?σ(t) 為光線在 [ t , t + d t ) [t, t+d t) [t,t+dt) 區間被吸收的概率,也就是被終止概率。
T ′ ( t ) = ? T ( t ) ? σ ( t ) T ′ ( t ) T ( t ) = ? σ ( t ) ∫ a b T ′ ( t ) T ( t ) d t = ? ∫ a b σ ( t ) d t log ? T ( t ) ∣ a b = ? ∫ a b σ ( t ) d t T ( a → b ) ≡ T ( b ) T ( a ) = exp ? ( ? ∫ a b σ ( t ) d t ) \begin{aligned} \mathcal{T}^{\prime}(t) & =-\mathcal{T}(t) \cdot \sigma(t) \\ \frac{\mathcal{T}^{\prime}(t)}{\mathcal{T}(t)} & =-\sigma(t) \\ \int_a^b \frac{\mathcal{T}^{\prime}(t)}{\mathcal{T}(t)} d t & =-\int_a^b \sigma(t) d t \\ \left.\log \mathcal{T}(t)\right|_a ^b & =-\int_a^b \sigma(t) d t \\ \mathcal{T}(a \rightarrow b) \equiv \frac{\mathcal{T}(b)}{\mathcal{T}(a)} & =\exp \left(-\int_a^b \sigma(t) d t\right) \end{aligned} T′(t)T(t)T′(t)?∫ab?T(t)T′(t)?dtlogT(t)∣ab?T(a→b)≡T(a)T(b)??=?T(t)?σ(t)=?σ(t)=?∫ab?σ(t)dt=?∫ab?σ(t)dt=exp(?∫ab?σ(t)dt)?
T ( a → b ) \mathcal{T}(a \rightarrow b) T(a→b) 表示光線通過 a a a 到 b b b 區間沒被終止的概率,假設 [ a , b ) [a,b) [a,b) 共享 a a a點體密度和顏色
C = ∫ 0 D T ( t ) ? σ ( t ) ? c ( t ) d t + T ( D ) ? c b g C=\int_0^D \mathcal{T}(t) \cdot \sigma(t) \cdot \mathbf{c}(t) d t+\mathcal{T}(D) \cdot \mathbf{c}_{\mathrm{bg}} C=∫0D?T(t)?σ(t)?c(t)dt+T(D)?cbg?
c b g c_{b g} cbg? 表示背景色彩
C ( a → b ) = ∫ a b T ( a → t ) ? σ ( t ) ? c ( t ) d t = σ a ? c a ∫ a b T ( a → t ) d t = σ a ? c a ∫ a b exp ? ( ? ∫ a t σ ( u ) d u ) d t = σ a ? c a ∫ a b exp ? ( ? σ a u ∣ a t ) d t = σ a ? c a ∫ a b exp ? ( ? σ a ( t ? a ) ) d t = σ a ? c a ? exp ? ( ? σ a ( t ? a ) ) ? σ a ∣ a b = c a ? ( 1 ? exp ? ( ? σ a ( b ? a ) ) ) \begin{aligned} \boldsymbol{C}(a \rightarrow b) & =\int_a^b \mathcal{T}(a \rightarrow t) \cdot \sigma(t) \cdot \mathbf{c}(t) d t \\ & =\sigma_a \cdot \mathbf{c}_a \int_a^b \mathcal{T}(a \rightarrow t) d t \\ & =\sigma_a \cdot \mathbf{c}_a \int_a^b \exp \left(-\int_a^t \sigma(u) d u\right) d t \\ & =\sigma_a \cdot \mathbf{c}_a \int_a^b \exp \left(-\left.\sigma_a u\right|_a ^t\right) d t \\ & =\sigma_a \cdot \mathbf{c}_a \int_a^b \exp \left(-\sigma_a(t-a)\right) d t \\ & =\left.\sigma_a \cdot \mathbf{c}_a \cdot \frac{\exp \left(-\sigma_a(t-a)\right)}{-\sigma_a}\right|_a ^b \\ & =\mathbf{c}_a \cdot\left(1-\exp \left(-\sigma_a(b-a)\right)\right)\end{aligned} C(a→b)?=∫ab?T(a→t)?σ(t)?c(t)dt=σa??ca?∫ab?T(a→t)dt=σa??ca?∫ab?exp(?∫at?σ(u)du)dt=σa??ca?∫ab?exp(?σa?u∣at?)dt=σa??ca?∫ab?exp(?σa?(t?a))dt=σa??ca???σa?exp(?σa?(t?a))? ?ab?=ca??(1?exp(?σa?(b?a)))?
T ( a → c ) = = exp ? ( ? [ ∫ a b σ ( t ) d t + ∫ b c σ ( t ) d t ] ) = exp ? ( ? ∫ a b σ ( t ) d t ) exp ? ( ? ∫ b c σ ( t ) d t ) = T ( a → b ) ? T ( b → c ) \begin{aligned} \mathcal{T}(a \rightarrow c)= & =\exp \left(-\left[\int_a^b \sigma(t) d t+\int_b^c \sigma(t) d t\right]\right) \\ & =\exp \left(-\int_a^b \sigma(t) d t\right) \exp \left(-\int_b^c \sigma(t) d t\right) \\ & =\mathcal{T}(a \rightarrow b) \cdot \mathcal{T}(b \rightarrow c)\end{aligned} T(a→c)=?=exp(?[∫ab?σ(t)dt+∫bc?σ(t)dt])=exp(?∫ab?σ(t)dt)exp(?∫bc?σ(t)dt)=T(a→b)?T(b→c)?
T n = T ( t n ) = T ( 0 → t n ) = exp ? ( ? ∫ 0 t n σ ( t ) d t ) = exp ? ( ∑ k = 1 n ? 1 ? σ k δ k ) \mathcal{T}_n=\mathcal{T}\left(t_n\right)=\mathcal{T}\left(0 \rightarrow t_n\right)=\exp \left(-\int_0^{t_n} \sigma(t) d t\right)=\exp \left(\sum_{k=1}^{n-1}-\sigma_k \delta_k\right) Tn?=T(tn?)=T(0→tn?)=exp(?∫0tn??σ(t)dt)=exp(k=1∑n?1??σk?δk?)
C ( t N + 1 ) = ∑ n = 1 N ∫ t n t n + 1 T ( t ) ? σ n ? c n d t = ∑ n = 1 N ∫ t n t n + 1 T ( 0 → t n ) ? T ( t n → t ) ? σ n ? c n d t = ∑ n = 1 N T ( 0 → t n ) ∫ t n t n + 1 T ( t n → t ) ? σ n ? c n d t = ∑ n = 1 N T ( 0 → t n ) ? ( 1 ? exp ? ( ? σ n ( t n + 1 ? t n ) ) ) ? c n \begin{aligned} \boldsymbol{C}\left(t_{N+1}\right) & =\sum_{n=1}^N \int_{t_n}^{t_{n+1}} \mathcal{T}(t) \cdot \sigma_n \cdot \mathbf{c}_n d t \\ & =\sum_{n=1}^N \int_{t_n}^{t_{n+1}} \mathcal{T}\left(0 \rightarrow t_n\right) \cdot \mathcal{T}\left(t_n \rightarrow t\right) \cdot \sigma_n \cdot \mathbf{c}_n d t \\ & =\sum_{n=1}^N \mathcal{T}\left(0 \rightarrow t_n\right) \int_{t_n}^{t_{n+1}} \mathcal{T}\left(t_n \rightarrow t\right) \cdot \sigma_n \cdot \mathbf{c}_n d t \\ & =\sum_{n=1}^N \mathcal{T}\left(0 \rightarrow t_n\right) \cdot\left(1-\exp \left(-\sigma_n\left(t_{n+1}-t_n\right)\right)\right) \cdot \mathbf{c}_n\end{aligned} C(tN+1?)?=n=1∑N?∫tn?tn+1??T(t)?σn??cn?dt=n=1∑N?∫tn?tn+1??T(0→tn?)?T(tn?→t)?σn??cn?dt=n=1∑N?T(0→tn?)∫tn?tn+1??T(tn?→t)?σn??cn?dt=n=1∑N?T(0→tn?)?(1?exp(?σn?(tn+1??tn?)))?cn??
T ( 0 → t n ) ? ( 1 ? exp ? ( ? σ n ( t n + 1 ? t n ) ) ) \mathcal{T}\left(0 \rightarrow t_n\right) \cdot\left(1-\exp \left(-\sigma_n\left(t_{n+1}-t_n\right)\right)\right) T(0→tn?)?(1?exp(?σn?(tn+1??tn?)))表示光線正好在 t N + 1 t_{N+1} tN+1?位置的顏色的權重(**透射率*該點的顏色吸收率=該點顏色的貢獻率,對應代碼中的weights,代碼中的 α \alpha α指代 1 ? e x p ( ? σ ? δ ) ? ? 1-exp(-\sigma*\delta)** 1?exp(?σ?δ)??)
C ( t N + 1 ) = ∑ n = 1 N T n ? ( 1 ? exp ? ( ? σ n δ n ) ) ? c n , where T n = exp ? ( ∑ k = 1 n ? 1 ? σ k δ k ) \boldsymbol{C}\left(t_{N+1}\right)=\sum_{n=1}^N \mathcal{T}_n \cdot\left(1-\exp \left(-\sigma_n \delta_n\right)\right) \cdot \mathbf{c}_n, \quad \\ \text{where} \quad \mathcal{T}_n=\exp \left(\sum_{k=1}^{n-1}-\sigma_k \delta_k\right) C(tN+1?)=n=1∑N?Tn??(1?exp(?σn?δn?))?cn?,whereTn?=exp(k=1∑n?1??σk?δk?)
部分代碼解讀
相機變換(重要!)
-
關于nerf相機方向的解讀
-
關于llff格式數據使用的NDC空間解讀
簡單來說就是針對不同種類的數據在不同的空間進行計算,如360度合成數據lego(直接從相機坐標系變換到世界坐標系下)或者無界數據llff(NDC空間能將近遠景范圍限制在0-1之間)