2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第十二章 燈光、背景與天空包
本章目的 討論簡單的BasicEffect的燈光實作方式 2D背景圖形 立方體天空箱與半圓形天空包的實作方式
3D光源著色的運算
光源的元素 環境光(Ambient) 擴散光(Diffuse) 反射光(Specular)
質料(Material) 環境光(Ambient) 擴散光(Diffuse) 反射光(Specular) 反射光的反應強度 自發光(Emissive)
3D光源著色元素成分的對應方式
環境光 環境光是代表場景周遭的光源來源,每一個光源都可以設定它對環境光的貢獻度。 在實際的場景上,環境光是周遭物件相互反射光源所形成的亮度,但是在程式實作上,卻是很難即時的去完成這麼複雜的運算。 所以在程式實作上就簡化了環境光源形成的原因,而將環境光的形成歸功給每一個單一光源。
實際的環境光形成方式
簡化的環境光運算方式
擴散光 擴散光是均勻反射的光線成分,與相機的觀測角度無關,只需要考量光源的方向與頂點的法向量
夾角相對於擴散光的貢獻度 當光源的反方向與頂點的法向量的角度愈小,光源的擴散光的貢獻度就愈大;反之,當角度愈大光源的擴散光的貢獻度就愈小;如果角度等於或大於90度該頂點就不接受光源的擴散光
反射光 反射光(Specular) 是朝特定方向反射的光線成分,其目的是要呈現物件表面上的亮點,當然亮點是和觀測的角度有關的,也就是和相機的向量是有關的。 其計算方式是先以頂點的法向量為中心線計算出以光線的反射向量 再以反射向量和相機的向量計算出該頂點具有多少反射光的顏色
BasicEffect 的質料設定 BasicEffect effect; .... \\對環境光的接受度是紅色10%、綠色20%、藍色30% effect.AmbientLightColor = new Vector3(0.1f, 0.2f, 0.3f); effect.DiffuseColor = new Vector3(0, 0, 1); effect.SpecularColor = new Vector3(0.5f, 0.6f, 0.7f); \\自發光是紅色的 effect.EmissiveColor = new Vector3(1, 0, 0); \\反射光的強度是10 effect.SpecularPower = 10;
BasicEffect 的光源設定 內定的光源 effect.EnableDefaultLighting(); 白色光源 射往(-1,-1,-1)方向 帶有些許的環境光 自設的光源 至多三個 可設定方向、擴散光(Diffuse)和反射光(Specular)
BasicEffect 的光源設定 BasicEffect effect; effect.DirectionalLight0.Enabled = true; \\ 第一個有向光 \\ 對擴散光的貢獻度是紅色100%、綠色100%、藍色100% effect.DirectionalLight0.DiffuseColor = new Vector3(1,1,1); \\方向是射向(-1,-1,-1) effect.DirectionalLight0.Direction = new Vector3(-1.0f, -1.0f, -1.0f); \\對反射光的貢獻度是紅色50%、綠色50%、藍色50% effect.DirectionalLight0.SpecularColor=new Vector3(0.5f,0.5f,0.5f); Similarly, we can define Light1, LIght2.
範例一:使用BasicEffic呈現燈光效果 W、S:相機在X軸的旋轉角度控制 A、D:相機在Y軸的旋轉角度控制 Z、X:相機的遠近距離控制 空白鍵:相機回歸初始狀態
範例一:使用BasicEffic呈現燈光效果 protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here foreach (ModelMesh mesh in myModel.Meshes) { // 設定網格的呈現效果 (世界、觀測、投影矩陣) foreach (BasicEffect effect in mesh.Effects) { effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateScale(0.04f); effect.View = camera.view; effect.Projection = camera.projection; effect.EnableDefaultLighting(); // 有向光 白光 (-1,-1,-1) 射過去,有 環境光 \\質料設定 effect.AmbientLightColor = new Vector3(0.5f, 0.5f, 0.5f); effect.DiffuseColor = new Vector3(0, 0, 1); // 1. effect.EmissiveColor = new Vector3(1, 0, 0); effect.SpecularColor = new Vector3(1.0f, 1.0f, 1.0f); effect.SpecularPower = 10; // 2. effect.PreferPerPixelLighting = true; \\像素打光設定 } // 畫出在 模型 中的 某一個 網格 mesh.Draw(); } axis.View = camera.view; axis.Projection = camera.projection; base.Draw(gameTime); } }
範例一:使用BasicEffic呈現燈光效果 試著將//1和//2兩個comment個別或一起刪除,觀其效果 // 1. effect.EmissiveColor = new Vector3(1, 0, 0); // 2. effect.PreferPerPixelLighting = true; \\像素打光設定 Exercise: 使用第十二章範例一中的打結甜甜圈當一個固定的PC: (1)光源點固定, 設計相機經由自動或手動繞行此PC一圈,經由不同的角度觀察打結的甜甜圈。 (2) 相機固定,設計一移動的光源(如太陽)經由自動或手動繞行此PC一圈,觀察來自不同方向的光源對PC的景觀產生的變化。
立體紋理圖
立體的紋理圖的相對位置
2 x 2 x 2立方體的座標位置
The End