OSG粒子系統與陰影-霧效模擬(1)

????????虛擬現實中有很多效果,如雨效、雪效、霧效等,這些都可以通過粒子系統來實現。一個真實的粒子系統的模式能使三維場景達到更好的效果。

????????本章對OSG粒子系統的使用以及生成自定義粒子系統的方法進行了詳細介紹最后還附帶說明了陰影的使用方法。在實時的場景中,陰影是非常重要的,是一個很大的范疇,筆者也沒有深入研究,因此,這里只是簡單介紹一下。

粒子系統

????????粒子系統是一個非常復雜的粒子模擬過程。在 OSG中專門定義了新的名字空間 osgParticle 來處理粒子系統的模擬。

????????osgParticle 能夠高效地模擬粒子系統,生成非常真實的效果。在OSG 預定義的粒子系統中,大部分的粒子系統模擬都采用的是 Billboard 與色彩融合技術生成粒子。Billboard 技術前面已經講到過雖然它還存在很多問題,但是總體來說,效果還是非常不錯的。色彩融合技術就是在渲染的過程中將各種顏色,如頂點顏色、光照顏色、質顏色和紋理顏色等按照 Alpha 值按一定的比例進行融合,以達到真實的效果。在本書自定義的粒子系統示例中,會向讀者展示一個爆炸的效果,當然只是演示一個簡單的技術,如果深入的話,還需要重新定義模塊。

粒子系統的主要模塊

????????當打開粒子系統的文檔時,讀者會發現里面包含很多類,但很多類都是內部操作,在模擬一個粒子系統時,只需要使用其中的一部分就可以完成很好的模擬效果,具體使用的類如圖11-1 所示。

11-1子系統成塊

????????對于一個普通的粒子系統的模擬,可以用圖 11-1 來顯示主要模塊。通過圖 11-1 讓讀者明白一個粒子系統所需要的模塊。下面分別介紹這些模塊。

  • 放射極(osgParticle::Emitter):一個標準放射極(osgParticle::ModularEmitter)包括一個計數器、一個放置器和一個發射器,它為用戶控制粒子系統中多個元素提供了一個標準機制。
  • 粒子系統(osgParticle::ParticleSystem):維護并管理一系列粒子的生成、更新染和銷毀。粒子系統類繼承自Drawable類,用于控制粒子的渲染,因此與其他 Drawable對象的渲染類似,控制其渲染屬性StateAttribute 即可。OSG提供了一個方便的函數以允許用戶控制3個常用的渲染狀態屬性,方法setDefaultAttributes可用于指定材質(或指定為NULL以禁用材質)、允許/禁止附加的圖像融合及允許/禁止光照。
  • 粒子(osgParticle::Particle):粒子系統的基本單元。粒子類同時具有物理屬性圖像屬性,它的形狀可以是任意的點(PONT)、四邊形(QUAD)、四邊形帶(QUADTRIPSTRIP)、六角形(HEXAGON)或線(LINE)。每個粒子都有自己的生命周期,生命周期也就是每個粒子可以存活的秒數,生命周期為負數的粒子可以存活無限長時間。所有的粒子都具有大小(SIZE)、Alpha值和顏色(COLOR)屬性,每組粒子都可以指定其最大和最小值。為了便于粒子生命周期的管理,粒子系統通過改變生命周期的最大和最小值來控制單個粒子的渲染,它會根據已經消耗的時間在最小和最大值之間進行線性插值。
  • 放置器(osgParticle::Placer):設置粒子的初始位置。用戶可以使用預定義的放置器或定義自己的放置器,已經定義的放置器包括點放置器 PointPlacer(所有的粒子從同一點出生)、扇面放置器SectorPlacer(所有的粒子從一個指定中心點、半徑范圍和角度范圍的扇面出生)以及多段放置器MultiSegmentPlacer(用戶指定一系列的點,粒子沿著這些點定義的線段出生)。
  • 發射器 (osgParticle::Shooter):指定粒子的初始速度。RadialShooter 類允許用戶指定一個速度范圍(米/秒)以及弧度值表示的方向,方向由兩個角度指定(theta角是與Z軸的夾角,phi角是與XY平面的夾角)。
  • 計數器 (osgParticle::Counter):控制每一產生的粒子數。RandomRateCounter 類允許用戶指定每幀產生粒子的最大和最小數。
  • 粒子系統更新器(osgParticle::ParticleSystemUpdater):用于自動更新粒子,將其置于場景中時,它會在揀選遍歷中調用所有“存活”粒子的更新方法。
  • 標準編程器(osgParticle::ModularProgram):在單個粒子的生命周期中,用戶可以使用ModularProgram實例控制粒子的位置,ModularProgram需要與Operator對象組合使用。
  • 操作器(osgParticle::Operator):提供了控制粒子在其生命周期中的運動特性的方法。用戶可以改變現有 Operator 類實例的參數或定義自己的 Opcrator 類。OSG提供的Operator類包括AccelOperator(加速度)、AngularAccelOperator(角加速度)、FluidFrictionOperator (空氣阻力或流體操作)以及ForceOperator(壓力)。

????????在OSG中除了這些粒子系統的主要模塊以外,還包含其他的已經定義好的模塊,如osgParticle::ExplosionDebrisEfect(爆炸碎片)、osgParticle::ExplosionEffect (爆炸模擬)、osgParticle::SmokeEfect(煙霧模擬)和 osgParticle::FireEffect(火光模擬)。

????????還有一個比較重要的類osgParticle::PrecipitationEfect,它是OSG定義的新類,用來模擬一些在OSG中已經定義好的粒子系統,如雨效和雪效,使用方法很簡單,可以直接加入到場景中。

???????粒子系統的模擬過程

????????下面將介紹如何模擬一個真實的粒子系統。對于模擬粒子系統的過程可以分為兩種,一是OSG中已經定義好的粒子系統模塊,二是根據需要自定義粒子系統。預定義粒子系統模塊模擬過程如下;

????????(1) 創建預定義粒子系統模塊對象,設置相應的參數。

????????(2) 作為子節點加到場景節點中。從上面列舉的子系統的關系繼承圖中可以看出,它們繼承自osg::Node或osg::Group 節點,因此可以直接作為一個節點加入到場景中。

????????自定義粒子系統模擬過程如下:

????????(1)創建粒子系統(osgParticle::ParticleSystem),并將其加入到場景中,設置相應的屬性,如材質、放射及光照。

????????(2)創建粒子模板(osgParticle::Particle),控制場景中每一個粒子的特性并關聯到粒子系統,設置粒子模板對應的特性,如大小、顏色、生命周期及重量等。

????????(3)創建粒子系統放射器(osgParticle::ModularEmitter),標準的放射器包括計數器(Counter)、放置器(Placer)和發射器(Shooter)3 部分,設置相應的屬性,如位置、形狀、速度和方向等。

????????(4)創建粒子系統編程器對象(osgParticle::Program),控制粒子在聲明周期內的運動。一個標準編程器對象包含各種操作器,如osgParticle::AccelOperator和osgParticle;:FluidFrictionOperator等。

????????(5)創建粒子系統更新器(osgParticle::ParticleSystemUpdater),用于管理每一幀的粒子的屬性如位置、速度和方向等。

????????通過上面的步驟,可以完成一個簡單的粒子系統的模擬。對于一般的需要而言是沒有任何問題的。如果需要更高要求的,可以從shader 開始編寫屬于自己的粒子系統。

???????霧效模示例

????????霧效其實并不是一種粒子系統,只是一種狀態屬性,放在這里來演示,因為它本身很像一種粒子系統。

????????霧效的管理主要是由osg::Fog來控制染的。osg::Fog類直接繼承自osg::StateAttribute類繼承關系圖如圖11-2所示。

圖11-2 osg::Fog 的繼承關系圖

????????從繼承關系圖中可以看到,它繼承自osg::StateAttribute類,因此它同樣可以通過設置狀態模式來控制霧效的開啟或關閉,代碼如下:

  1. root->getOrCreateStateSet()->setAttributeAndModes(fog.get(),osg::StateAttribute::ON);?

????????在OSG中,霧效有兩種模式,可以通過下面的方式來獲取或設置:

  1. void?setMode(Mode?mode)??
  2. Mode?getMode()?const??
  3. enum?Mode??
  4. {??
  5. ????LINEAR?=?GL_LINEAR,//?線性務??
  6. ????EXP?=?GL_EXP,?//全局霧??
  7. ????EXP2?=?GL_EXP2//?全局霧??
  8. };?

????????霧的坐標源也有兩種,可以通過下面的方式來設置或獲取:

  1. void?setFogCoordinateSource(GLint?source)??
  2. GLint?getFogCoordinateSource()?const??
  3. enum?FogCoordinateSource??
  4. {??
  5. ????FOG_COORDINATE?=?GL_FOG_COORDINATE,//霧坐標??
  6. ????FRAGMENTDEPTH?=?GL_FRAGMENT_DEPTH//?眼坐標??
  7. };?

????????霧的坐標源在使用固定管道的頂點處理時,霧效的值可以是眼坐標系中的y坐標值,也可以是經過插值的霧坐標,這是由霧的標源是設置成GL_FRAGMENT_DEPTH還是GL_FOG_COORDINATE決定的,在可編程管線中應用比較多。

????????霧效的特性還有顏色、濃度和起始位置等,可以調用下列類的成員函數來設置相應的特性:

  1. void?setDensity(float?density)//?設置濃度??
  2. float?getDensity()?const??
  3. void?setStart(float?start)//?設置起點??
  4. float?getStart()?const??
  5. void?setEnd(float?end)//?設置終點??
  6. float?getEnd()?const??
  7. void?setColor(const?Vec4?&color)?//?設置霧的顏色??
  8. const?Vec4?&getColor()?const??

????????霧效的特性已經都講了,解釋了霧效可能需要設置所有特性,下面來看一個簡單的示例。

代碼如程序清單11-1 所示。

// 創建霧效
osg::ref_ptr<osg::Fog> createFog(bool m_Linear)
{// 創建Fog對象osg::ref_ptr<osg::Fog> fog = new osg::Fog();// 設置顏色fog->setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0));// 設置濃度fog->setDensity(0.01);// 設置霧效模式為線性霧if (!m_Linear){fog->setMode(osg::Fog::LINEAR);}else// 設置霧效模式為全局零{fog->setMode(osg::Fog::EXP);}// 設置霧效近點濃度fog->setStart(5.0);// 設置霧效遠點濃度fog->setEnd(2000.0);return fog.get();
}void fog_11_1(const string &strDataFolder)
{osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;traits->x = 40;traits->y = 40;traits->width = 600;traits->height = 480;traits->windowDecoration = true;traits->doubleBuffer = true;traits->sharedContext = 0;osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());osg::ref_ptr<osg::Camera> camera = viewer->getCamera();camera->setGraphicsContext(gc.get());camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;camera->setDrawBuffer(buffer);camera->setReadBuffer(buffer);osg::ref_ptr<osg::Group> root = new osg::Group();// 讀取模型string strDataPath = strDataFolder + "lz.osg";osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);root->addChild(node.get());// 啟用霧效root->getOrCreateStateSet()->setAttributeAndModes(createFog(false), osg::StateAttribute::ON);// 優化場景數據osgUtil::Optimizer optimize;optimize.optimize(root.get());viewer->setSceneData(root.get());viewer->realize();viewer->run();
}

????????運行程序,截圖如圖11-3所示

圖11-3 霧效模擬示例截圖

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

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

相關文章

(HAL庫版)freeRTOS移植STMF103

正點原子關于freeRTOS的教程是比較好的&#xff0c;可惜移植的是標準庫&#xff0c;但是我學的是Hal庫&#xff0c;因為開發速度更快&#xff0c;從最后那個修改SYSTEM文件夾的地方開始替換為下面的內容就可以了 5.修改Systick中斷、SVC中斷、PendSV中斷 將SVC中斷、P…

pairplot

Python可視化 | Seaborn5分鐘入門(七)——pairplot - 知乎 (zhihu.com) Seaborn是基于matplotlib的Python可視化庫。它提供了一個高級界面來繪制有吸引力的統計圖形。Seaborn其實是在matplotlib的基礎上進行了更高級的API封裝&#xff0c;從而使得作圖更加容易&#xff0c;不需…

紅黑樹詳解

紅黑樹的概念與性質 前置知識 在學習紅黑樹之前&#xff0c;最好有二叉查找樹和AVL樹的基礎&#xff0c;因為紅黑樹本質就是一種特殊的二叉查找樹&#xff0c;而紅黑樹的操作中需要用到AVL樹中旋轉的相關知識。至于二叉查找樹和AVL樹&#xff0c;可以參考如下兩篇博客&#xf…

oracle安裝的肘腋之疾小合集

#臨時空間指定 export TMP/tmp export TMPDIR/tmp #圖形化顯示框不全 java問題&#xff0c;使用系統自帶的jre ./runInstaller -jreLoc/usr/local/jdk1.7.0_80/ #ins30131 Failed to access the temporary location 給/tmp/CVU*加x權限 #linux桌面太小 xrandr -s 1440x900_60…

Matplotlib圖形注釋_Python數據分析與可視化

Matplotlib圖形注釋 添加注釋文字、坐標變換 有的時候單單使用圖形無法完整清晰的表達我們的信息&#xff0c;我們還需要進行文字進行注釋&#xff0c;所以matplotlib提供了文字、箭頭等注釋可以突出圖形中重點信息。 添加注釋 為了使我們的可視化圖形讓人更加容易理解&#…

vue中父組件直接調用子組件方法

vue2 中&#xff0c;父組件如何調用子組件的方法 在Vue 2中&#xff0c;父組件可以通過使用ref屬性來引用子組件的實例&#xff0c;然后通過該實例調用子組件的方法。 首先&#xff0c;在父組件的模板中&#xff0c;給子組件添加一個ref屬性&#xff1a; <template>&l…

在工業生產環境下,服務器沒有互聯網,如何通過代理自己的電腦上互聯網?

服務器主機是CentOS7操作系統.&#xff0c;服務器的局域網是10.0.6.x網段。我的筆記本的以太網口的局域網ip是也是10.0.6.x&#xff0c;由于這個10.0.6.x的整個局域網是沒有撥號上網的所有無法訪問互聯網。 但是&#xff0c;如果筆記本臉上wifi&#xff0c;wifi的網段是192.168…

長度最小的子數組

給定一個含有 n 個正整數的數組和一個正整數 target 。 找出該數組中滿足其總和大于等于 target 的長度最小的 連續子數組 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其長度。如果不存在符合條件的子數組&#xff0c;返回 0 。 示例 1&#xff1a; 輸入&#x…

MySQL 有多個普通索引時會取哪一個索引?

我們都知道MySQL在查詢時底層會進行索引的優化&#xff0c;假設有兩個普通索引&#xff0c;且where 后面也根據這兩個普通索引查詢數據&#xff0c;那么執行查詢語句時會使用到那個索引&#xff1f; 為了方便演示&#xff0c;新建users表&#xff0c;新建idx_name、idx_city這兩…

前端vue導出PPT,使用pptxgen.js

前言 公司新需求需要導出ppt給業務用&#xff0c;查閱資料后發現也挺簡單的&#xff0c;記錄一下。 如有不懂的可以留言&#xff01;&#xff01;&#xff01; 1.安裝包 npm install pptxgenjs --save2.引入包 在需要使用的文件中引入 import Pptxgenfrom "pptxgenjs&…

Oracle研學-介紹及安裝

一 ORACLE數據庫特點: 支持多用戶&#xff0c;大事務量的事務處理數據安全性和完整性控制支持分布式數據處理可移植性(跨平臺&#xff0c;linux轉Windows) 二 ORACLE體系結構 數據庫&#xff1a;oracle是一個全局數據庫&#xff0c;一個數據庫可以有多個實例&#xff0c;每個…

nodejs+vue+python+PHP+微信小程序-留學信息查詢系統的設計與實現-安卓-計算機畢業設計

1、用戶模塊&#xff1a; 1&#xff09;登錄&#xff1a;用戶注冊登錄賬號。 2&#xff09;留學查詢模塊&#xff1a;查詢學校的入學申請條件、申請日期、政策變動等。 3&#xff09;院校排名&#xff1a;查詢國外各院校的實力排名。 4&#xff09;測試功能&#xff1a;通過入學…

Spring Boot WebSocket 客戶端

介紹 WebSocket 是一種在單個 TCP 連接上進行全雙工通信的協議&#xff0c;它可以提供實時的、雙向的數據傳輸。Spring Boot 提供了對 WebSocket 的支持&#xff0c;我們可以使用 Spring Boot WebSocket 客戶端來連接到 WebSocket 服務器&#xff0c;并進行實時通信。 本文將…

python-選擇排序

選擇排序是一種簡單直觀的排序算法&#xff0c;它的基本思想是每一輪選擇未排序部分的最小元素&#xff0c;然后將其放到已排序部分的末尾。這個過程持續進行&#xff0c;直到整個數組排序完成。(重點&#xff1a;通過位置找元素) 以下是選擇排序的詳細步驟和 Python 實現&…

HarmonyOS應用開發實戰—登錄頁面【ArkTS】

文章目錄 本頁面實戰效果預覽圖一.HarmonyOS應用開發1.1HarmonyOS 詳解1.2 ArkTS詳解二.HarmonyOS應用開發實戰—登錄頁面【ArkTS】2.1 ArkTS頁面源碼2.2 代碼解析2.3 心得本頁面實戰效果預覽圖 一.HarmonyOS應用開發 1.1HarmonyOS 詳解 HarmonyOS(鴻蒙操作系統)是華為公司…

小程序首頁白屏優化,并舉例說明

小程序首頁白屏優化 小程序首頁白屏優化是指在用戶進入小程序首頁時&#xff0c;能夠盡快展示內容&#xff0c;避免出現長時間的白屏加載狀態&#xff0c;提升用戶體驗。以下是一些常見的小程序首頁白屏優化方法&#xff1a; 減少首屏請求&#xff1a;盡量減少首頁需要請求的資…

js粒子效果(一)

效果: 代碼: <!doctype html> <html> <head><meta charset"utf-8"><title>HTML5鼠標經過粒子散開動畫特效</title><style>html, body {position: absolute;overflow: hidden;margin: 0;padding: 0;width: 100%;height: 1…

DELL MD3600F存儲重置管理軟件密碼

注意&#xff1a;密碼清除可能會導致業務秒斷&#xff0c;建議非業務時間操作 針對一臺控制器操作即可&#xff0c;另一控制器會同步操作 重置后密碼為空&#xff01; 需求&#xff1a;重置存儲管理軟件密碼 管理軟件中分配物理磁盤時提示輸入密碼(類似是否了解風險確認操作的提…

華為OD機試 - 二叉樹計算(Java JS Python C)

目錄 題目描述 輸入描述 輸出描述 用例 題目解析 JS算法源碼 Java算法源碼

io.lettuce.core.RedisCommandExecutionException

io.lettuce.core.RedisCommandExecutionException: ERR invalid password ERR invalid password-CSDN博客 io.lettuce.core.RedisCommandExecutionException /** Copyright 2011-2022 the original author or authors.** Licensed under the Apache License, Version 2.0 (the…