光照解耦和重照明

項目地址:

GitHub - NJU-3DV/Relightable3DGaussian: [ECCV2024] 可重新照明的 3D 高斯:使用 BRDF 分解和光線追蹤的實時點云重新照明

可優化參數

gaussians.training_setup(opt)

if is_pbr::?direct_env_light.training_setup(opt)

光照解耦

update_visibility

分塊處理高斯

對每個高斯體,采樣?sample_num?個入射方向,計算每個方向的可見性(是否被遮擋)、方向向量、該方向在球面上的面積權重,并將這些結果保存下來

?fibonacci_sphere_sampling斐波那契球面采樣

輸出

  1. incident_dirs:每個點/法線的?sample_num?個采樣方向(單位向量),用于模擬不同角度的入射光。
  2. ?normals?是?[N,?3],則輸出?incident_dirs?是?[N,?sample_num,?3]
  3. incident_areas:每個采樣方向的面積權重(都相同),用于積分時加權。
  4. incident_dirs形狀[N, sample_num, 1]

在?fibonacci_sphere_sampling?代碼中,采樣方向是圍繞每個高斯體的法線方向生成的:

  • 首先在?z?軸方向上生成均勻分布的球面采樣(fibonacci?sphere)。
  • 然后通過旋轉,把這些方向對齊到每個高斯體的法線方向(rotation_between_z(normals))。
  • 如果?random_rotate=True,還會加上一個隨機旋轉,使得每個高斯體的采樣方向分布更加均勻、隨機。

rotation_matrix?=?rotation_between_z(normals)

incident_dirs?=?rotation_matrix?@?z_samples

  • 這里?rotation_matrix?是針對每個高斯體的法線單獨計算的。
  • 所以?incident_dirs?是每個高斯體獨立的一組方向。

render(is_training=true)

render_pkg = render_fn(viewpoint_cam, gaussians, pipe, background,opt=opt, is_training=True, dict_params=pbr_kwargs, iteration=iteration)pbr_kwargs['sample_num'] = pipe.sample_num#64pbr_kwargs["env_light"] = direct_env_light

高斯增加優化屬性

  1. _base_color:表面基礎色(反射率/漫反射色),PBR渲染的核心屬性。
  2. _roughness:表面粗糙度,影響高光和反射的模糊程度。
  3. _incidents_dc/incidents_rest:每個高斯體的入射光照分布(用球諧函數表示),用于高效地近似全局光照。
  4. _visibility_dc/visibility_rest:每個高斯體的可見性分布(同樣用球諧函數表示),用于陰影和遮擋的近似。
 first_iter = gaussians.create_from_ckpt(args.checkpoint, restore_optimizer=True)

?初始化這些屬性為0

環境光照(IBL - Image-Based Lighting)??

  • ?模擬全局光照?:環境貼圖存儲了來自各個方向的環境光強度與顏色,為物體表面提供非直接光照(如漫反射、鏡面反射)。
  • ?PBR 材質依賴?:在基于物理的渲染中,環境貼圖是計算材質反射、折射的基礎輸入(如金屬高光、玻璃透射)

PBR最終像素顏色和渲染方程Rendering equation

?參考徹底看懂PBR/BRDF方程 - 張亞坤的文章 - 知乎
https://zhuanlan.zhihu.com/p/158025828

?base_color:點云的“固有色”。

?pbr:這個點在當前光照、視角、材質等條件下,真實應該呈現出來的顏色。

pbr?:最終像素顏色(Lambert 漫反射 + GGX 鏡面反射)

輸出結果brdf_color和extra_results

    extra_results = {"incident_dirs": incident_dirs,"incident_lights": incident_lights,"local_incident_lights": local_incident_lights,"global_incident_lights": global_incident_lights,"incident_visibility": incident_visibility,"diffuse_light": diffuse_light,"specular": specular,}

基于物理的渲染方程(PBR)??:

其中:

? ? f_d = base_color[:, None] / np.pi

? ? f_s = GGX_specular(normals, viewdirs, incident_dirs, roughness, fresnel=0.04)

  • Lo?:出射光(最終顏色)
  • fdiffuse?:漫反射 BRDF
  • fspecular?:鏡面反射 BRDF
  • Li?:入射光強度
  • n?ωi?:?余弦項?(法線與入射光方向的點積)

diffuse_light = transport.mean(dim=-2):: 表示表面接收到的總光照強度

rasterizer結果

變量名說明典型形狀
num_rendered渲染的高斯點總數標量/int
num_contrib每像素有貢獻的高斯點數[H, W]
rendered_image渲染出的RGB圖像[3, H, W]
rendered_opacity渲染出的不透明度圖[1, H, W]
rendered_depth渲染出的深度圖[1, H, W]
rendered_feature渲染出的特征圖(多通道)[C, H, W]
rendered_pseudo_normal渲染出的偽法線圖[3, H, W]
rendered_surface_xyz渲染出的表面3D坐標[3, H, W]
weights高斯點對像素的貢獻權重[N, H, W]
radii高斯點在屏幕上的半徑[N]

render輸出results

feature和rendered_image、rendered_pbr

   if is_training:features = torch.cat([depths, depths2, brdf_color, normal, base_color, roughness, extra_results["diffuse_light"], extra_results["incident_visibility"].mean(-2)], dim=-1)else:features = torch.cat([depths, depths2, brdf_color, normal, base_color, roughness,extra_results["diffuse_light"], extra_results["specular"], extra_results["incident_lights"].mean(-2),extra_results["local_incident_lights"].mean(-2),extra_results["global_incident_lights"].mean(-2),extra_results["incident_visibility"].mean(-2)], dim=-1)

?在gaussian_renderer\neilf.py里的render_view

?在gaussian_renderer\r3dg_rasterization.py中

num_rendered, num_contrib, color, opacity, depth, feature, normal, surface_xyz, weights, radii, geomBuffer, binningBuffer, imgBuffer = _C.rasterize_gaussians(*args)

在r3dg-rasterization\ext.cpp中

?在r3dg-rasterization\rasterize_points.cu中

return std::make_tuple(
rendered, n_contrib, out_color, out_opacity, out_depth, out_feature, out_normal, out_surface_xyz, out_weights, radii, geomBuffer, binningBuffer, imgBuffer);

與 下圖一一對應

num_rendered, num_contrib, color, opacity, depth, feature, normal, surface_xyz, weights, radii, geomBuffer, binningBuffer, imgBuffer = _C.rasterize_gaussians(*args)

在r3dg-rasterization\cuda_rasterizer\forward.cu中?

rendered_image:是通過球諧函數(Spherical?Harmonics, SH)渲染得到的圖像,即上圖中的out_color

rendered_pbr:是通過物理基礎渲染(Physically Based Rendering, PBR)得到的圖像,即上圖中的out_feature(對應render_feature)中的一部分

pbr = rendered_pbr
rendered_pbr = pbr * rendered_opacity + (1 - rendered_opacity) * bg_color[:, None, None]

out_feature(對應render_feature)由features加權得出,rendered_pbr對應由brdf_color加權

   if is_training:features = torch.cat([depths, depths2, brdf_color, normal, base_color, roughness, extra_results["diffuse_light"], extra_results["incident_visibility"].mean(-2)], dim=-1)else:features = torch.cat([depths, depths2, brdf_color, normal, base_color, roughness,extra_results["diffuse_light"], extra_results["specular"], extra_results["incident_lights"].mean(-2),extra_results["local_incident_lights"].mean(-2),extra_results["global_incident_lights"].mean(-2),extra_results["incident_visibility"].mean(-2)], dim=-1)

重照明relighting.py

?文件路徑變量
scene_config_file
路徑:{args.config}/transform.json
作用:場景的空間變換配置文件,通常描述每個子場景或物體的變換矩陣(如平移、旋轉、縮放)。
traject_config_file
路徑:{args.config}/trajectory.json
作用:相機軌跡配置文件,通常描述渲染時相機的運動路徑、每一幀的相機參數等。
light_config_file
路徑:{args.config}/light_transform.json
作用:光源軌跡或光照變換配置文件,描述光源的位置、方向、變化等(如果有動態光照)。

為什么可以實現

 if iteration % args.save_interval == 0 or iteration == args.iterations:#5000print("\n[ITER {}] Saving Gaussians".format(iteration))scene.save(iteration)

在運行script\run_nerf.sh后?保存高斯各屬性在output/NeRF_Syn/hotdog/neilf/point_cloud/iteration_40000/point_cloud.ply類似路徑,在configs\nerf_syn_light\transform.json中保存各場景路徑和transform矩陣

?在scene_composition中加載ply文件,

relighting.py?的流程:讀取高斯體模型(如?.ply?文件);讀取環境光照(如?.hdr?文件;讀取相機參數;用渲染器(如?render_fn_dict['neilf'])直接渲染圖片。

只要有一個已經擬合好的3D場景(高斯體參數),可以隨時改變光照條件(比如換環境貼圖),然后用渲染器重新渲染出不同光照下的圖片。這就是重照明。因為場景的幾何和材質參數已經在訓練階段學好了,渲染時只需要前向推理(forward),不需要再優化參數。

?`scene_composition`

功能

scene_composition?的作用是:
將多個場景(或點云)的高斯體模型合成為一個整體高斯體模型,并做必要的初始化。

具體流程如下:

  1. 遍歷?scene_dict,為每個子場景加載高斯體點云(.ply?文件),并應用相應的變換(transform),把每個子場景的點云(高斯體)通過指定的?4x4?變換矩陣變換到全局坐標系,。

  2. 把所有加載好的高斯體模型合成為一個大模型(調用?GaussianModel.create_from_gaussians)。

  3. 對合成后的模型做一些初始化(如可見性、入射光參數等)。

  4. 返回合成后的高斯體模型。


輸入

  • scene_dict: dict

    • 字典格式,key 是場景名,value 是一個字典,包含:

      • "path":點云文件路徑(.ply)

      • "transform":4x4 的變換矩陣(list 或 array)

  • dataset: ModelParams

    • 數據集參數對象,至少包含?sh_degree?等高斯體模型初始化所需參數。


輸出

  • gaussians_composite: GaussianModel

    • 合成后的高斯體模型對象,包含所有子場景的點云和參數,已經應用了各自的變換,并做了初始化。


代碼流程簡述

  1. 加載每個子場景的高斯體模型并變換

    for scene in scene_dict:gaussians = GaussianModel(dataset.sh_degree, render_type="neilf")gaussians.load_ply(scene_dict[scene]["path"])torch_transform = torch.tensor(scene_dict[scene]["transform"], device="cuda").reshape(4, 4)gaussians.set_transform(transform=torch_transform)gaussians_list.append(gaussians)
    
  2. 合成所有高斯體模型

    gaussians_composite = GaussianModel.create_from_gaussians(gaussians_list, dataset)
    
  3. 初始化可見性和入射光參數

    n = gaussians_composite.get_xyz.shape[0]
    gaussians_composite._visibility_rest = (torch.nn.Parameter(torch.cat([gaussians_composite._visibility_rest.data,torch.zeros(n, 5 ** 2 - 4 ** 2, 1, device="cuda", dtype=torch.float32)],dim=1).requires_grad_(True)))
    gaussians_composite._incidents_dc.data[:] = 0
    gaussians_composite._incidents_rest.data[:] = 0
    
  4. 返回合成后的模型

    return gaussians_composite
    

總結

  • 功能:合成多個高斯體點云為一個整體,并初始化相關參數。

  • 輸入:場景字典(含路徑和變換)、數據集參數。

  • 輸出:合成后的高斯體模型對象(GaussianModel)。

render(is_training=false)

render_kwargs = {"pc": gaussians_composite,"pipe": pipe,"bg_color": background,"is_training": False,"dict_params": {"env_light": light,"sample_num": args.sample_num,#384},"bake": args.bake}
with torch.no_grad():render_pkg = render_fn(viewpoint_camera=custom_cam, **render_kwargs)

在?render_view?函數中,is_training?參數為 True 或 False 時,渲染流程和輸出內容有明顯區別is_training?為 True 時,流程更高效、特征更精簡、用于訓練和損失計算;為 False 時,流程更全面、特征更豐富、用于推理、評估和可視化。

主要體現在以下幾個方面:


1.?BRDF 計算方式不同

  • is_training=True
    • 直接對所有點一次性調用?rendering_equation,效率高,適合訓練時的批量處理。
    • 代碼片段:
      if is_training:brdf_color, extra_results = rendering_equation(base_color, roughness, normal.detach(), viewdirs, incidents,direct_light_env_light, visibility_precompute=pc._visibility_tracing, incident_dirs_precompute=pc._incident_dirs, incident_areas_precompute=pc._incident_areas)
      
  • is_training=False
    • 為了節省顯存,采用分塊(chunk)處理,每次只處理一部分點,適合測試/推理時大規模渲染。
    • 代碼片段:
      else:chunk_size = 100000brdf_color = []extra_results = []for i in range(0, means3D.shape[0], chunk_size):_brdf_color, _extra_results = rendering_equation(...)brdf_color.append(_brdf_color)extra_results.append(_extra_results)brdf_color = torch.cat(brdf_color, dim=0)extra_results = {k: torch.cat([_extra_results[k] for _extra_results in extra_results], dim=0) for k in extra_results[0]}torch.cuda.empty_cache()
      

2.?特征拼接內容不同

  • is_training=True

    • 拼接的特征較少,只包含訓練所需的內容。

    • 代碼片段:
      features = torch.cat([depths, depths2, brdf_color, normal, base_color, roughness, extra_results["diffuse_light"], extra_results["incident_visibility"].mean(-2)], dim=-1)
      
  • is_training=False

    • 拼接的特征更豐富,包含更多渲染細節,便于評估和可視化。

    • 代碼片段:
      features = torch.cat([depths, depths2, brdf_color, normal, base_color, roughness,extra_results["diffuse_light"], extra_results["specular"], extra_results["incident_lights"].mean(-2),extra_results["local_incident_lights"].mean(-2),extra_results["global_incident_lights"].mean(-2),extra_results["incident_visibility"].mean(-2)], dim=-1)
      

3.?輸出的特征拆分不同

  • is_training=True

    • rendered_feature?只拆分出訓練所需的特征(如 base_color、roughness、diffuse、visibility)。

  • is_training=False

    • rendered_feature?拆分出更多特征(如 specular、lights、local_lights、global_lights 等),便于評估和可視化。


4.?環境光相關輸出不同

  • is_training=False

    • 還會輸出?render_envpbr_envenv_only?等環境光相關的渲染結果,便于評估不同光照下的表現。

  • is_training=True

    • 這些環境光相關的輸出不會被計算,節省計算資源。


5.?損失計算

  • is_training=True

    • 會進一步調用?calculate_loss?計算損失和訓練日志。

  • is_training=False

    • 不計算損失,只輸出渲染結果。


總結表

is_training

主要用途

BRDF計算

特征拼接

輸出內容

損失計算

評估/可視化

True

訓練

一次性

精簡

精簡

False

推理/評估

分塊

豐富

豐富


render輸出results

評估?

  • train.py?的評估是為了訓練過程中的監控和調優,通常和訓練流程綁定。
  • eval_nvs.py?是專門為獨立評測和論文展示設計的,方便單獨運行和批量評測。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/912793.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/912793.shtml
英文地址,請注明出處:http://en.pswp.cn/news/912793.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Kafka 運維與調優篇:構建高可用生產環境的實戰指南

🛠? Kafka 運維與調優篇:構建高可用生產環境的實戰指南 導語:在生產環境中,Kafka集群的穩定運行和高性能表現是業務成功的關鍵。本篇將深入探討Kafka運維與調優的核心技術,從監控管理到性能優化,再到故障排…

AR 地產互動沙盤:為地產沙盤帶來變革?

在科技飛速發展的今天,AR(增強現實)技術應運而生,為解決傳統地產沙盤的困境提供了全新的思路和方法。AR 技術,簡單來說,是一種將計算機生成的虛擬信息與真實環境相融合的技術。它通過攝像頭、傳感器等設備獲…

端到端自動駕駛系統關鍵技術

一、感知決策一體化模型架構 單一神經網絡整合全流程 端到端神經網絡能夠直接將傳感器輸入映射為控制輸出,消除了傳統模塊化架構中感知、規劃、控制等獨立模塊之間的割裂。傳統架構中,感知模塊負責識別環境信息,決策模塊根據感知結果進行路…

Vue Vue-route (2)

Vue 漸進式JavaScript 框架 基于Vue2的學習筆記 - Vue-route重定向和聲明式導航 目錄 Vue-route路由 重定向 首頁默認訪問 不存在匹配 聲明式導航 路由原理 使用示例 自定義class類 Tag設置 版本4路由 改變 示例 總結 Vue-route路由 重定向 首頁默認訪問 希望訪…

Mabl 基于云端的智能化自動化測試平臺

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】 【測試經驗】 【人工智能】 【Python】 </

Linux/Dog

Dog Enumeration nmap 第一次掃描發現系統對外開放了22、80端口&#xff0c;端口詳細信息如下 ┌──(kali?kali)-[~/Desktop/vegetable/HTB] └─$ nmap -sC -sV -p 22,80 -oA nmap 10.10.11.58 Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-26 03:36 EDT Nmap s…

青少年編程與數學 02-022 專業應用軟件簡介 01 設計與創意類軟件:Adobe Creative Cloud

青少年編程與數學 02-022 專業應用軟件簡介 01 設計與創意類軟件&#xff1a;Adobe Creative Cloud **一、Adobe公司介紹**&#xff08;一&#xff09;Adobe的創立與早期發展&#xff08;二&#xff09;Adobe的市場地位與影響力&#xff08;三&#xff09;Adobe的創新文化 **二…

【亞馬遜防關聯攻略】多店鋪運營如何做好環境隔離?

在亞馬遜跨境電商中&#xff0c;多店運營的最大風險是賬號關聯。亞馬遜規定&#xff0c;同一賣家在同一站點只能擁有一個店鋪。平臺會通過多種方式追蹤注冊信息、設備和網絡環境等&#xff0c;如果發現關聯因素&#xff0c;所有關聯賬號可能被批量封禁&#xff0c;這會導致資金…

She‘s Coming !

#好書推薦《一本書講透汽車功能安全&#xff1a;標準詳解與應用實踐》 #功能安全應用指南 #功能安全實踐參考寶典 Finally, shes coming ! 她來得有點晚&#xff0c;但 “好飯不怕晚”。 她就是剛出爐的新書《一本書講透汽車功能安全&#xff1a;標準詳解與應用實踐》 京東…

如何用廢棄電腦變成服務器搭建web網站(公網訪問零成本)

文章目錄 &#x1f4bb; 如何用廢棄電腦變成服務器搭建 Web 網站&#xff08;公網訪問零成本&#xff09;一、背景與目標? 本文目標&#xff1a; 二、準備工作&#xff08;軟硬件需求&#xff09;&#x1f9f1; 1. 硬件需求&#x1f9f0; 2. 軟件環境準備 三、快速搭建一個 Fl…

〔從零搭建〕指標體系平臺部署指南

&#x1f525;&#x1f525; AllData大數據產品是可定義數據中臺&#xff0c;以數據平臺為底座&#xff0c;以數據中臺為橋梁&#xff0c;以機器學習平臺為中層框架&#xff0c;以大模型應用為上游產品&#xff0c;提供全鏈路數字化解決方案。 ?杭州奧零數據科技官網&#xf…

Vue3 中watch和computed

Vue 3 中 computed 與 watch 深度解析 在 Vue 3 組合中&#xff0c;響應式工具的類型安全使用至關重要。以下是詳細說明 一、watch 偵聽器 1. 基礎類型監聽 <template><div>實際參數1{{count}}</div><div><button click"count">點…

.NET測試工具Parasoft dotTEST:全兼容RMS的測試解決方案

隨著項目規模擴大&#xff0c;需求管理變得復雜&#xff0c;如何高效追溯需求與測試的關聯性成為一大挑戰。Parasoft dotTEST 提供了一套強大的需求追溯解決方案&#xff0c;不僅能自動關聯單元測試結果與需求&#xff0c;還能兼容幾乎所有需求管理系統&#xff08;RMS&#xf…

基于Jeecgboot3.8.1的vue3版本前后端分離的flowable流程管理平臺

初步遷移完成了基于jeecgboot3.8.1的vue3版本的前后端流程管理平臺,基于flowable6.8.0,同時支持bpmn流程設計器與仿釘釘流程設計器。 功能類似于3.6.3,但增加了一些以下功能: 1、支持多租戶 2、支持并行網關的任意跳轉、退回與駁回 3、流程表達式 這里流程表達式定義四…

IP 限流 vs. URI 限流

背景&#xff1a; 昨天調程序的時候遇到了一個 BUG&#xff0c;前端無法將文件正確傳給后端&#xff0c;后端報錯 EOFException&#xff08;EOF 代表 End Of File&#xff09;就是在程序嘗試從一個數據流中讀取數據時&#xff0c;發現已經到達了數據流的末尾&#xff0c;但它卻…

2025年Java常見面試題(持續更新)

數據庫事務特性。原子性、一致性、隔離性、持久性如何防止SQL注入&#xff1a;使用#不要使用$符號&#xff1b;對所有的入參做校驗&#xff1b;使用存儲過程&#xff1b;執行預處理語句和參數化查詢&#xff1b;最低權限原則&#xff1b;微服務拆分的原則&#xff1a;微服務的拆…

Spring AI ——在springboot應用中實現基本聊天功能(ChatModel)

文章目錄 前言項目版本依賴引入配置key信息編寫測試接口注入ChatModel并普通返回注入ChatModel并流式返回自定義模型對象并直接返回總結前言 在Spring AI 中,CchatClient 是一個所有大模型通用性的調用方式,對絕大多數大模型的功能點都具備封裝和見解調用性。 但這一點在部…

78、系統工程生命周期階段及方法

一、系統工程生命周期的七大階段 系統工程生命周期涵蓋從概念萌芽到系統退役的全過程&#xff0c;通常分為以下七個階段&#xff0c;每個階段具有明確目標與核心任務&#xff1a; 1.探索性研究階段 目標&#xff1a;識別利益相關者需求&#xff0c;探索技術可行性。任務&…

二十九、【用戶體驗篇】個人中心:用戶資料展示與密碼修改

二十九、【用戶體驗篇】個人中心:用戶資料展示與密碼修改 前言準備工作第一部分:后端實現 - 個人中心 API1. 修改 `UserDetailSerializer` 以支持密碼修改2. 在 `api/views.py` 中添加 `UserMeView` 和 `PasswordChangeView`3. 注冊個人中心相關 API 路由4. 后端初步測試第二…

STEP-BACK PROMPTING:退一步:通過抽象在大型語言模型中喚起推理能力

摘要 我們提出了 STEP-BACK PROMPTING&#xff0c;這是一種簡單的提示技術&#xff0c;可以讓LLM進行抽象&#xff0c;從包含具體細節的實例中推導出高層次概念和第一性原理。利用這些概念和原理來引導推理過程&#xff0c;LLM在朝向正確解答路徑上顯著提升了推理能力。我們在…