【Virtual Globe 渲染技術筆記】6 著色

著色(Shading)

曲面細分只是地球渲染的第一步。接下來是著色——通過模擬光線與材質的相互作用,計算每個像素的最終顏色。本節先回顧基礎的光照與紋理映射,再講解虛擬地球特有的經緯網格夜景燈光效果。


6.1 光照(Lighting)

我們從最簡“直通”著色器(Listing 1)開始,逐步加入漫反射與鏡面反射。

/*----------------List 1----------------------*/
// Vertex shader
in vec4 position;
uniform mat4 ce_modelViewPerspectiveMatrix;void main()
{gl_Position = ce_modelViewPerspectiveMatrix * position ;
}// Fragment shader
out vec3 fragmentColor;
void main() {fragmentColor = vec3(0.0, 0.0, 0.0);
}
  • 頂點著色器
    使用自動變量 ce_modelViewPerspective 把頂點坐標變換到裁剪空間。
    此時球體全黑。
    在這里插入圖片描述

  • 光源位置
    采用“眼旁點光源”:光源放在相機位置,仿佛用戶提著一盞燈。
    為簡化,光照計算在世界坐標系完成(示例僅有一個坐標系)。

  • 逐像素光照
    在片元著色器計算 Phong 光照,可消除因插值導致的高光鋸齒,也便于后續紋理特效。

漫反射
粗糙表面散射光線,強度僅與入射角有關:
Idiffuse=max?(n^?l^,0) I_{\text{diffuse}} = \max(\hat{\mathbf n}\cdot \hat{\mathbf l},0) Idiffuse?=max(n^?l^,0)
其中 n^\hat{\mathbf n}n^ 為法線,l^\hat{\mathbf l}l^ 為光源方向。
球面法線可直接歸一化世界坐標得到;橢球需用 GeodeticSurfaceNormal

鏡面反射
光滑表面產生高光,強度與視線方向有關:
Ispec=(r^?v^)α,r^=2(n^?l^)n^?l^ I_{\text{spec}} = \left(\hat{\mathbf r}\cdot \hat{\mathbf v}\right)^\alpha,\quad \hat{\mathbf r}=2(\hat{\mathbf n}\cdot\hat{\mathbf l})\hat{\mathbf n}-\hat{\mathbf l} Ispec?=(r^?v^)α,r^=2(n^?l^)n^?l^
指數 α\alphaα 決定高光銳利度。
最終光照:
I=kdIdiffuse+ksIspec+ka I = k_dI_{\text{diffuse}} + k_sI_{\text{spec}} + k_a I=kd?Idiffuse?+ks?Ispec?+ka?

實現見 Listing 2(頂點)與 Listing 3(片元)。

/*-----------Listing 2--------------------*/
// Vertex shader for diffuse and specular lighting.
in vec4 position;
out vec3 worldPosition;
out vec3 positionToLight;
out vec3 positionToEye;uniform mat4 ce_modelViewPerspectiveMatrix;
uniform vec3 ce_cameraEye;
uniform vec3 ce_cameraLightPosition;void main()
{gl_Position = ce_modelViewPerspectiveMatrix * position;worldPosition = position.xyz;positioinToLight = ce_cameraLightPosition - worldPosition;positionToEye = ce_cameraEye - worldPosition;
}
/*-----------Listing 3--------------------*/
// Final Phong-lighting fragment shader.
in vec3 worldPosition;
in vec3 positionToLight;
in vec3 positionToEye;
out vec3 fragmentColor;uniform vec4 ce_diffuseSpecularAmbientShininess;float LightIntensity(vec3 normal, vec3 toLight, vec3 toEye, vec4 diffuseSpecularAmbientShininess)
{vec3 toReflectedLight = reflect(-toLight, normal);float diffuse = max(dot(toLight, normal), 0.0);float specular = max(dot(toReflectedLight, toEye), 0.0);specular = pow(specular, diffuseSpecularAmbientShininess.w);return (diffuseSpecularAmbientShininess.x * diffuse) + (diffuseSpecularAmbientShininess.y * specular) + diffuseSpecularAmbientShininess.z;
}void main()
{vec3 normal = normalize(worldPosition);float intensity = LightIntensity(normal, normalize(positionToLight), normalize(positionToEye), ce_diffuseSpecularAmbientShininess);fragmentColor = vec3(intensity, intensity, intensity);
}

6.2 紋理映射(Texturing)

光照體現曲率,但地球真正魅力來自高分辨率影像。本節講解逐像素計算紋理坐標(假設紋理一次性裝入顯存,且 float 精度足夠)。
在這里插入圖片描述

  • 世界影像通常 2:1 寬高比,WGS84 坐標。

  • 給定片元法線 n=(nx,ny,nz)∈[?1,1]\mathbf n=(n_x,n_y,n_z)\in[-1,1]n=(nx?,ny?,nz?)[?1,1],計算 (s,t)∈[0,1](s,t)\in[0,1](s,t)[0,1]
    s=atan2(ny,nx)2π+0.5,t=arcsin?nzπ+0.5. \begin{aligned} s &= \frac{\text{atan2}(n_y,n_x)}{2\pi}+0.5,\\[2pt] t &= \frac{\arcsin n_z}{\pi}+0.5. \end{aligned} st?=2πatan2(ny?,nx?)?+0.5,=πarcsinnz??+0.5.?
    該公式把經緯度映射到紋理空間(Listing 4.11)。

  • 光照×顏色:
    finalColor=texture(uday,(s,t))×I \text{finalColor} = \text{texture}(u_{\text{day}},(s,t)) \times I finalColor=texture(uday?,(s,t))×I
    (圖 4.11(c))

極點問題
紋理極區像素密度過高,過濾反而加劇失真。
EVE Online 采用“平面+球面”混合投影;也可改用立方體貼圖避免極點拉伸,但在每個立方體面的邊界處會引入輕微的畸變。


6.3 CPU / GPU 權衡

方案優點缺點
逐片元 計算法線/紋理坐標節省顯存;無插值誤差;代碼簡潔;無 IDL 特殊處理GPU 反三角函數精度/速度低
逐頂點 計算并存儲頂點著色器簡單;一次計算多次使用頂點數據翻倍;頂點插值導致 IDL 紋理跳變(下圖)

在這里插入圖片描述


6.4 經緯網格(Latitude-Longitude Grid)

幾乎所有虛擬地球都可疊加經緯網(圖 4.13)。常見做法:

  • CPU 生成折線;
  • 緩存網格,視角移動時復用;
  • 根據縮放級別動態增減分辨率(LOD)。

片元著色器方案
優點:

  • 無 CPU 計算;
  • 無額外顯存/帶寬;
  • 無 Z-fighting;
  • 無需額外 Pass。

缺點:

  • 單 Pass 渲染耗時稍長;
  • 受 32-bit float 精度限制;
  • 文字標注需額外處理。

實現要點

  • 通過紋理坐標 (s,t) 判斷是否在網格線附近;
  • dFdx/dFdy 獲得屏幕空間梯度,實現像素恒定線寬(Listing 4);
  • 支持不同顏色、線寬、淡入淡出、抗鋸齒及線型。
/*------------------------Listing 4-------------------------------*/
void main()
{vec3 normal = GeodeticSurfaceNormal(worldPosition, u_globeOneOverRadiiSquared);vec2 textureCoordinate = ComputeTextureCoordinates(normal);vec2 distanceToLine = mod(textureCoordinate, u_gridResolution);vec2 dx = abs(dFdx(textureCoordinate));vec2 dy = abs(dFdy(textureCoordinate));vec2 dF = vec2(max(dx.s, dy.s), max(dx.t, dy.t)) * u_gridLineWidth;if (any(lessThan(distanceToLine, dF))){fragmentColor = vec3(1.0, 0.0, 0.0);}else{float intensity = LightIntensity(normal,normalize(positionToLight),normalize(positionToEye),ce_diffuseSpecularAmbientShininess);fragmentColor = intensity * texture(ce_texture0, textureCoordinate).rgb;}
}

LOD 控制
根據相機高度分段設置 u_gridResolution

  • 定義高度區間 → 網格分辨率映射表;
  • 利用時間連續性,優先檢查上一區間,查找幾乎 O(1)。
    在這里插入圖片描述

6.5 夜景燈光(Night Lights)

虛擬地球常在背陽面顯示城市燈光——經典多重紋理應用:
白天紋理 + 夜間燈光紋理,按太陽照射角度混合。

片元著色器流程

  • 頂點著色器傳入太陽位置 og_sunPosition
  • 新增 uniform:
    • u_dayTexture, u_nightTexture
    • u_blendDuration 過渡時長
    • u_blendDurationScale = 1/(2u_blendDuration)(預計算)
  • 片元著色器:
    1. 計算漫反射因子 d=max?(n^?l^,0)d = \max(\hat{\mathbf n}\cdot\hat{\mathbf l},0)d=max(n^?l^,0)
    2. d>ublendDurationd > u_{\text{blendDuration}}d>ublendDuration?:用白天紋理 + Phong 光照。
    3. d<?ublendDurationd < -u_{\text{blendDuration}}d<?ublendDuration?:用夜間紋理,無光照。
    4. 介于兩者之間:線性混合晝夜顏色。
      在這里插入圖片描述

性能實驗

  • 僅看晝面 vs 僅看夜面:夜面幀率更高(夜間紋理分辨率低且無光照計算)。
  • 游戲常用技巧:用紋理圖集 + 旋轉/鏡像,少量紋理即可產生豐富夜景變化(EVE Online)。

多重紋理其他應用

  • 云層紋理
  • 水面高光貼圖(gloss map)
    早期硬件不支持多重紋理時,STK 采用多 Pass 實現夜景。

參考:

  • Cozi, Patrick; Ring, Kevin. 3D Engine Design for Virtual Globes. CRC Press, 2011.

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

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

相關文章

OpenCV Python——圖像拼接(一)(圖像拼接原理、基礎知識、單應性矩陣 + 圖像變換 + 拼接)

1 圖像拼接基礎知識1.1 特征匹配 原理及代碼示例1.2 單應性矩陣 原理及代碼示例2 圖像拼接&#xff08;一&#xff09;&#xff08;直接拼接&#xff09;3 圖像拼接&#xff08;二&#xff09;&#xff08;單應性矩陣 圖像變換 拼接&#xff09;3.1 單應性矩陣函數3.2 拼接函…

Git 中切換到指定 tag

在 Git 中切換到指定 tag&#xff08;比如 v1.22.1&#xff09;的正確做法如下&#xff1a;1?? 查看已有的 taggit tag會列出所有可用的版本&#xff0c;比如&#xff1a;v1.21.0 v1.22.0 v1.22.1 v1.23.02?? 切換到指定 taggit checkout tags/v1.22.1 -b v1.22.1解釋&…

rust 從入門到精通之變量和常量

變量和常量 隨著軟件系統安全的重要性與日俱增, rust這門集聚高并發, 安全, 適配云環境的編程語言在市場上得到了越來越高的認可和關注。但其復雜的機制使其難以學習。且其很多特性對于其他語言是全新的&#xff0c;這加劇了學習的困難程度。教程主要針對rust基礎進行講解, 雖然…

2508C++,支持rdma通信的高性能rpc庫

原文 [重磅]支持rdma通信的高性能的rpc庫–yalantinglibs.coro_rpc yalantinglibs的coro_rpc是基于C20的協程的高性能的rpc庫,提供了簡潔易用的接口,讓用戶幾行代碼就可實現rpc通信,現在coro_rpc除了支持tcp通信之外還支持了rdma通信(ibverbs). 通過簡單示例來感受一下rdma通…

FastAPI + React:現代 Web 前后端分離開發的全棧實踐指南

一、為什么選 FastAPI React&#xff1f; 性能&#xff1a;FastAPI 基于 Starlette Uvicorn&#xff0c;QPS 與 Node/Go 同級&#xff0c;實測 3 倍于 Flask&#xff1b;React 虛擬 DOM 代碼分割&#xff0c;首屏 < 1.2 s。效率&#xff1a;FastAPI 內置 Swagger/OpenAPI…

嵌入式硬件篇---電平轉換電路

電平轉換電路是電子電路中用來實現不同電壓信號之間轉換的關鍵電路&#xff0c;比如把 3.3V 的信號轉換成 5V&#xff0c;或者把 5V 轉換成 1.8V&#xff0c;確保不同電壓的芯片、模塊能正常通信。下面用通俗易懂的方式介紹幾種常見的電平轉換電路&#xff1a;一、電阻分壓電路…

SAP ABAP IS SUPPLIED

效果 此謂詞表達式用于檢查過程的某個形式參數“para”是否已賦值或被請求使用。如果在調用時實際參數被賦值給了該形式參數&#xff0c;則該表達式為真。 這種關系表達式僅能在函數模塊和方法中使用。而對于“para”而言&#xff0c;所有可選的形參都可以進行指定。 加上“NOT…

視頻內容提取與AI總結:提升學習效率的實用方法

文章目錄1、前言2、方法介紹2.1 B站視頻處理方案2.2 通用視頻處理方案2.3 AI內容總結3、實際效果4、使用建議5、技術發展趨勢6、總結&#x1f343; 作者介紹&#xff1a;25屆雙非本科網絡工程專業&#xff0c;阿里云專家博主&#xff0c;專注于 AI 原理、AI 應用開發、AI 產品設…

JVM 面試精選 20 題

目錄1. 什么是 JVM、JDK 和 JRE&#xff1f;它們之間的關系是什么&#xff1f;2. Java 內存區域&#xff08;運行時數據區&#xff09;有哪些&#xff1f;3. 說說你對 JVM 垃圾回收機制的理解。4. 常用的垃圾回收算法有哪些&#xff1f;5. 什么是 Minor GC、Major GC 和 Full G…

CMIP6 氣候模式核心特性解析

在全球氣候變化研究中&#xff0c;CMIP6&#xff08;第六次耦合模式比較計劃&#xff09;的氣候模式是關鍵工具。以下從研發背景與核心能力角度&#xff0c;解析五類主流模式的技術特點與適用場景。 一、主流模式技術特性 1. CanESM5/CanESM5-1&#xff08;加拿大環境與氣候變…

【牛客刷題】BM63 跳臺階:三種解法深度解析(遞歸/DP動態規劃/記憶化搜索)

文章目錄 一、題目介紹 1.1 題目描述 1.2 示例 二、算法設計思路 2.1 核心問題分析 2.2 斐波那契數列關系 三、流程圖 解法1:遞歸法(自頂向下) 解法2:動態規劃(自底向上) 解法3:記憶化搜索(遞歸優化) 解法4: 優化DP流程(推薦) 四、解法實現 五、復雜度分析對比 六、…

《解構WebSocket斷網重連:指數退避算法的前端工業級實踐指南》

WebSocket作為客戶端與服務器雙向通信的核心載體,支撐著從在線協作、金融行情到即時通訊等各類高實時性場景。然而,網絡環境的動態變化—從用戶設備的Wi-Fi與蜂窩網絡切換,到公共網絡的臨時擁塞,再到服務器的短暫重啟—都可能導致WebSocket連接中斷,進而引發數據傳輸停滯、…

醫療潔凈間的“隱形助手”:富唯智能復合機器人如何重塑手術器械供應鏈

當手術刀片在無影燈下傳遞時&#xff0c;0.01mm的抓取偏差可能意味著感染風險——而富唯智能復合機器人以0.02mm的重復定位精度與99.999%無菌操作的硬實力&#xff0c;正成為高端醫療產線中替代人力的關鍵技術支點。一、醫療上下料的三大痛點&#xff1a;精度、潔凈與連續性1.毫…

《設計模式》工廠方法模式

1.工廠方法模式&#xff08;Factory Method&#xff09;定義 定義一個用于創建對象的接口&#xff0c;讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。 1.1 UML圖&#xff1a; 主要有4個對象&#xff1a; 抽象工廠&#xff08;Abstract Creator&#xf…

冒泡排序——簡單理解和使用

閱前聲明&#xff1a;如果想直接了解冒泡排序的簡化思想&#xff0c;請跳至文章尾部在介紹之前&#xff0c;我們先看一個用到該功能的實戰訓練&#xff08;本人也是從中開始認識到冒泡排序這個函數定義&#xff09;對于小白來說&#xff0c;我的思路如下&#xff1a;1.題目中涉…

AI應用商業化加速落地 2025智能體爆發與端側創新成增長引擎

今年以來&#xff0c;人工智能 (AI) 正在進入從算力投入到云服務消耗再到商業化收入&#xff0c;最終回到算力再投入的良性循環&#xff0c;而 AI 應用的起量正是推動這一飛輪效應的關鍵。7 月 31 日&#xff0c;國務院常務會議審議通過了《關于深入實施 “人工智能 ” 行動的意…

Pytest測試框架基礎及進階

Pytest測試框架基礎# Pytest測試框架介紹# Pytest是Python一款三方測試框架&#xff0c;用于編寫和運行單元測試、集成測試和功能測試。Pytest測試框架具有簡單、靈活、易于擴展等特點&#xff0c;被廣泛應用于Python項目的測試工作中。 Pytest主要特點&#xff1a; 簡單易用…

航空裝備先進加工工藝與制造技術論壇——2025成都航空裝備展

300參展企業 11500㎡展區面積 7大專業展區 12000觀眾規模15同期會議 160發言嘉賓 5000參會嘉賓 100媒體報道航空工業飛速發展&#xff0c;先進加工工藝與制造技術成為了支撐航空裝備性能提升、質量保障和產能優化的核心基石。為探索前沿技術路徑、凝聚行業創新力量&#xff0c;…

為什么品牌更愿意為新品打廣告?

品牌資源向新品廣告傾斜&#xff0c;可以說是市場上的普遍現象。尤其對于沒有明星產品的品牌而言&#xff0c;新品推廣時企業的重要曝光節點。下面就讓我們一同來了解下&#xff0c;為什么品牌更愿意為新品打廣告。一、市場需求更充分新品廣告往往承擔著市場教育的功能&#xf…

電子電氣架構 --- 關于整車信息安全的一些思考

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…