::GAME2.TW::臺灣遊戲攻略

華語手機遊戲攻略,遊戲資訊專業網站

3D遊戲引擎的架構設計

Game2遊戲:


Introduction (簡介)

讓咱們談談你如何撰寫一份提供優雅性能的3D引擎。你的引擎需要提供的包括:曲面(curved surfaces)、動態光線(dynamic lighting)、體霧(volumetric fog)、鏡面(mirrors)、入口(portals)、天空體(skyboxes)、節點陰影(vertex shaders) 、粒子系統(particle systems)、靜態網格模型(static mesh models)、網格模型動畫(animated mesh models)。假如你已經知道如何以上所述的所有功能順利工作,你也許便能將那些東東一起置入到一個引擎當中。

等等!在你開始撰寫代碼前你必須先構思一下如何去架構你的引擎。多數來講,你一定是迫切地渴望去製作一個遊戲,但如果你立即投入便開始為你的引擎撰寫代碼後,你一定會覺得非常難受,開發後期你可能會為置入新的特效與控制而不得不多次重寫大量的局部代碼,甚至以失敗而放棄告終。花一點時間好好地為你引擎深謀遠慮一番,這將會為你節省大量時間,也少一點頭痛。你一定不會急切地去架構一個巨型的工程;或許你也會在引擎未完成時而乾脆放棄它,然後去幹的別的什麼事兒。好了,當你掌握學習你所需知識的方式之前,也許你還不能完成那些事兒。將設計真正地完成確實是件美事,為之你會感覺更好,你將為之而耀眼!

讓我們分析一下具備完整功能的3D遊戲引擎的需要哪些基本部件。首先,這為具有相應3D經驗但且還需一些指引的開發者提供了一些信息。這是一些並不難且能快速掌握但是你必須應用的內容條目。為將你的工作更好地進行下去,這裡將對關於“把多大的工作量”與“多少部分”置入一個遊戲引擎給出一個總概。我把這些成分稱為系統(System)、控制台(Console)、支持(Support),渲染/引擎內核(Renderer/Engine Core)、遊戲介質層(Game Interface)、以及工具/數據(Tools/Data) 。

Tools/Data (工具/數據)

在開發過程中,你總是需要一些數據,但不幸的是這並不像寫文本文件或是定義一個立方體那麼簡單。至少,你得需要3d模型編輯器,關卡編輯器,以及圖形程序。你可以通過購買,也可以在網上找一些免費的程序滿足你的開發要求。不幸的是你可能還需要一些更多的工具可你卻根本無法獲得(還不存在呢),這時你只得自己動手去寫。最終你很可能要自行設計編寫一個關卡編輯器,因為你更本不可能獲得你所需。你可能也會編寫一些代碼來為大量的文件打個包,整天面對應付成百上千個文件倒是非常痛苦的。你還必須寫一些轉換器或是插件將3d模型編輯器的模型格式轉換成你自己的格式。你也需要一些加工遊戲數據的工具,譬如可見度估算或是光線貼圖。

一個基本的準則是,你可能要為設計工具而置入比遊戲本身等量甚至更多的代碼。開始你總能找到現成的格式和工具,但是經過一段時間以後你就能認識到你需要你的引擎有很大的特性,然後你就會放棄以前的撰寫方式。

也許目前非常流行利用的第3方工具輔助開發,所以你必須時刻注意你的設計。因為一旦當你將你的引擎發佈為opensouce或是允許修改,那也許在某天中會有某些人來應用你的開發成果,他們將其擴展或者做某些修改。

或許你也應該花大量時間去設計美術,關卡,音效,音樂和實體模型,這就和你設計撰寫遊戲,工具以及引擎一樣。

System (系統)

系統(system)是引擎與機器本身做通信交互的部件。一個優秀的引擎在待平台移植時,它的系統則是唯一需要做主要更改(擴加代碼)的地方。我們把一個系統分為若干個子系統,其中包括:圖形(Graphics)、輸入(Input)、聲音(Sound)、記時器(Timer)、配置(Configuration)。主系統負責初始化、更新、以及關閉所有的子系統。

圖形子系統(Graphics Sub-System)在遊戲裡表現得非常直觀,如果想在屏幕上畫點什麼的話,它(圖形子系統)便乾這事兒。大多數來講,圖形子系統都是利用OpenGL、Direct3D, Glide或是軟件渲染(software rendering)實現。如果能更理想一些,你甚至可以把這些API都給支持了,然後抽像出一個“圖形層”並將它置與實現API之上,這將給了客戶開發人員或是玩家更多的選擇,以獲取最好的兼容性、最佳的表現效果。

輸入子系統(Input Sub-System)需要把各種不同輸入裝置(鍵盤、鼠標、遊戲板[Gamepad],遊戲手柄[Joystick])的輸入觸發做統一的控制接收處理。 (透明處理) 比方說,在遊戲中,系統要檢測玩家的位置是否在向前移動,與其直接地分別檢測每一種輸入裝置,不如通過向輸入子系統發送請求以獲取輸入信息,而輸入子系統才在幕後真正地干活(分別檢測每一種輸入裝置),這一切對於客戶開發人員都是透明的。用戶與玩家可以非常自由地切換輸入裝置,通過不同的輸入裝置來獲取統一的行為將變的很容易。

聲音子系統(sound system)負責載入、播放聲音。該子系統功能非常簡潔明了,但當前很多遊戲都支持3D聲音,實現起來會稍許複雜一些。

3D遊戲引擎中很多出色的表現都是基於“時間系統”(time)的。因此你需要一段時間來為時間子系統(Timer sub-system)好好構思一番。即使它非常的簡單,(遊戲裡)任何東西都是通過時間觸發來做移動變化,但一份合理的設計將會讓你避免為實現而一遍又一遍地撰寫大量雷同的控制代碼……

配置系統(Configuration)位於所有子系統的頂端。它負責讀取配置記錄文件,命令行參數,或是實現修改設置(setup)。在系統初始化以及運行期間,所有子系統都將一直與它保持通訊。切換圖像解析度(resolution),色深(color depth),定義按鈕(key bindings),聲音支持選項(sound support opt​​ions),甚至包括載入遊戲,該系統將這些實現顯得格外的簡單與方便。把你引擎設計得更為可設置化一些,這將為調試與測試帶來更大的方便;玩家與用戶也能很方便地選擇他(她)們喜歡的運行方式。

Console (控制台)

哈!我知道所有人都樂意去更風做一個像Quake那樣的控制台(console)系統。但這的確是一個非常好的想法。通過命令行變量與函數,你就能夠在運行時改變你的遊戲或是引擎的設置,而不需要重啟。開發期間輸出調試信息它將顯得非常的有效。很多時間你都需要測試一系列變量的值,將這些值輸出到控制台上要比運行一個debugger速度顯然要快得多。你的引擎在運行期間,一旦發現了一個錯誤,你不必立即退出程序;通過控制台,你可以做些非常輕便的控制,並將這個錯誤信息打印出來。假如你不希望你的最終用戶看見或是使用該控制台,你可以非常方便地將其disable,我想沒人能看得見它。

Support (支持)

支持系統(Support)在你引擎中任何地方都將被使用到。該系統包含了你引擎中所有的數學成分(點,面,矩陣等),(內)存儲管理器,文件載入器,數據容器(假如你不願自己寫,也可以使用STL)。該模塊任務顯得非常基礎與底層,或許你會將它復用到更多別的相關項目中去。

Renderer/Engine Core (渲染/引擎內核)

哈~是呀,所有的人都熱愛3D圖像渲染!因為這邊有著非常多的不同種類的3D世界渲染方式,可要為各類擁有不同工作方式的3D圖形管道做出一個概要描述也是幾乎不可能的。

不管你的渲染器如何工作,最重要的是將你的渲染器組件製作得基化(based)與乾淨(clean)。

首先可以確定的是你將擁有不同的模塊來完成不同的任務,我將渲染器拆分為以下幾個部份:可見裁減(Visibility)、碰撞檢測與反饋(Collision Detection and Response)、攝像器( Camera)、靜態幾何體(Static Geometry)、動態幾何體(Dynamic Geometry)、粒子系統(Particle Systems)、佈告板(Billboarding)、網格(Meshes)、天空體(Skybox)、光線(Lighting)、霧(Fogging )、節點陰影(Vertex Shading)和輸出(Output)。

其中每一個部分都得需要一個接口來方便地實現改變設置(settings)、位置(position)、方向(orientation)、以及其他可能與系統相關的屬性配置。

即將顯露出來的一個主要缺陷便是“特性臃腫”,這將取決於設計期間你想實現什麼樣的特性。但如不把新特色置入引擎的話,你就會發覺一切都將變的很困難,解決問題的方式也顯得特別遜色。

還有一件有意義的事便是讓所有的三角形[triangles](或是面[faces])最終在渲染管道裡經過同一點。 (並非每次的每個三角形,這裡討論的是三角形列表[triangle lists]、扇形[fans]、帶形[strips]、等) 多花一些工作讓所有物體的格式都能經過相同的光線、霧、以及陰影代碼,這樣就能非常便利地僅通過切換材質與紋理id就使任何多邊形具有不同的渲染效果。

這不會傷及到被大量被渲染繪出的點,但是一旦你不當心,它可能會導致大量的冗餘代碼。

你也許最終便能發現,實現所有這些你所需的極酷效果可能只佔了所有的15%左右的代碼量甚至更少。這是當然的,因為大多數遊戲引擎並不只是圖形表現。

Game Interface (遊戲介質)

一個3D(遊戲)引擎很重要的部分便是——它是一個遊戲引擎。但這並不是一個遊戲。一個真正的遊戲所需的一些組件永遠不要將它包含到遊戲引擎裡。引擎與遊戲製作之間的控制介質能使代碼設計變得更清晰,應用起來也會更舒服。這雖是一些額外的代碼,但它能使遊戲引擎具有非常好重用性,通過設計架夠遊戲邏輯(game logic)的腳本語言(scripting language)也能使開髮變的更方便,也可以將游戲代碼置入庫中。如果你想在引擎本身中嵌入你的遊戲邏輯系統設計的話,大量的問題與大量修改一定會讓你打消復用這個引擎的念頭。

因此,此時你很可能在思考這個問題:聯繫引擎與遊戲的介質層到底提供了什麼。答案就是控制(control)。幾乎引擎的每一個部分都有動態的屬性,而該引擎/遊戲介質層(engine/game layer)提供了一個接口去修改這些動態屬性。它們包括了攝像器(camera)、模型屬性(model properties)、光線(lights)、粒子系統物理(particle system physics)、聲效播放(playing sounds)、音樂播放(playing music)、輸入操作(handling input) 、切換等級(changing levels)、碰撞檢測以及反饋(collision detection and response)、以及2D圖形界面的頂端顯示、標題畫面等相關的東西。基本上來講如果你想讓你的遊戲能優雅的實現這些元素,在引擎中置入這個介質層(interface)是必不可少的。

The Game (遊戲)

在這裡,我無法告訴你如何去寫你的遊戲。這該輪到你發揮啦。如果你已經為你那令人讚異的引擎設計出了一套出色的介質層的話,我想在設計撰寫遊戲過程中一定會輕鬆許多。

3D遊戲引擎設計是一項巨大的軟件工程。一個人獨立完成設計並撰寫也並非不可能​​,但這不只是熬一兩個晚上便能搞定的,你很可能會出寫出幾兆的源代碼量。如果你沒有持久的信念與激情,你很可能無法完成它。

當然,別指望你的第一次嘗試就能寫出完整的引擎,挑一個比較小的項目所需的小規模引擎去實現。按你的方式去努力工作,你就能到達成功。

E文原稿

Introduction

So lets say your writing a 3D game engine that supports a pretty good set of features. Your list of desires includes curved surfaces, dynamic lighting, volumetric fog, mirrors and portals, skyboxes, vertex shaders, particle systems, static mesh models and animated mesh models. If you have a good idea of​​ how all these things work, you can probably start putting these things together into an engine.

But wait! Before you start coding you need to think about what you're going to do with your engine. Most likely, you have aspirations of making a game. If you just jump in and start coding an engine, you' re gonna get burned and end up having to re-write huge portions of the engine multiple times to add effects and control later. A little forethought into engine design will save headaches and time. The thing you don't want to do is aspire to huge projects. You'll end up not finishing it, and moving onto something else. While this is a way to learn everything you need, you won't be completing things. It's good to actually finish projects. You'll feel better for it and you can show off!

Let's take a look at the basic components of a full-featured 3D game engine. First off, this is for those people are reasonably experienced with 3d but need a little direction. These are not hard and fast rules that you must use . It's just what has worked well for me and to give an overview of how much work and how many parts go into a game engine. I call these parts System, Console, Support, Renderer/Engine Core, Game Interface, Game, and Tools /Data.

Tools/Data

During development, you're going to need some data, and unfortunately it's not going to be as easy as writing some text files that define a cube. At the least you will need 3d model editors, level editors, and graphics programs . These things can be bought or you can find a free program online that does the same type of thing. Unfortunately you're probably going to need more tools than this and the software doesn't exist yet. You need to write it. You may end up writing your own level editor if you can't find one that does the things you want. You'll probably need to write some code to pack files into an archive since dealing with and distributing hundreds or thousands of files can be a pain. You'll need to write converters or plug-ins from your 3d model editor format into your own format. You'll need tools to process game data, such as visibility computations or lightmaps.

The basic line is that you'll probably have nearly as much or more code in tools than actual game code. You can find formats and tools that you can use, but sooner or later you'll realize you need some things that are very custom to your engine and you'll end up writing your own anyway.

Although there is a probably a big rush to get tools done just so there are usable, do take care in your coding. Someone may actually try to use, extend or modify your tools one day, especially if you make your engine to be opensource or modifiable.

You should probably be prepared to spend as much time making graphics, levels, sound, music and models as you did writing the game, tools, and engine.

System

System is the part of the engine that communicates with the machine itself. If an engine is written very well the system is the only part that should need major modifications if porting to a different platform. Within the system are several sub-systems . Graphics, Input, Sound, Timer, Configuration. The System is responsible for initializing, updating, and shutting down all these sub-systems.

The Graphics Sub-System is pretty straightforward. If it deals with putting things on the screen, it goes here. One would most likely write this component using OpenGL, Direct3D, Glide, or software rendering. To get even fancier, you could implement multiple API interfaces and put a Graphics Layer on top of them to give users more choice and more chance for compatibility and performance. This is a bit difficult though, especially since not all API's will have the same feature sets.

The Input Sub-System should take all input (Keyboard, Mouse, Gamepad and Joystick) and unify it and allow for abstraction of control. For example, somewhere in the game logic, there will be a need to see if the user wants to move his or her position forward. Rather than doing multiple checks for each type of input, one would make one call to the input sub-system and it would transparently check all devices. This also allows for ease of configuration by the user, and easily having multiple inputs perform the same action.

The sound system is responsible for loading and playing sounds. Pretty straight forward, but most current games support 3D sound and this will make things a little more complex.

Pretty much everything in a 3d game engine (I'm assuming real-time games here…) is based on time. Hence you need some time management routines in the Timer sub-system. This is actually pretty simple, but since anything that moves will move with time, a decent set of ro​​utines will keep you from writing the same code over and over.

The Configuration unit actually sits above all the other sub-systems. It's responsible for reading configuration files, command line parameters, or whatever setup method is used. The other sub-systems query this system when they are initializing and running. This makes it easy to change resolution, color depth, key bindings, sound support opt​​ions, or even the game that gets loaded. Making your engine very configurable just makes it easier to test and allows users to set things up the way they like.

Console

Ok, I know everyone likes to follow the crowd and have a console like Quake. But it's really a good idea. With console variables and functions you can change settings in your game and your engine without restarting it. It's wonderful for outputting debug information while developing. Often times you'll be needing to examine some variables and outputting the to the console is faster and sometimes better than running a debugger. Once your engine is running, if an error occurs, you don't have to quit the application; you can handle it gracefully and just print an error message. If you don't want your end user to see or use the console, its easy to disable it and no one is the wiser that it's still there.

Support

This is a system that is used by pretty much every other system in the engine. This includes all your mathematics routines, (vectors, planes, matrix, etc), memory managers, file loaders, containers (or use STL if you don't roll your own). This stuff is pretty basic and will probably be used in most any project you ever are involved in.

Renderer/Engine Core

Ah yes, everyone loves rendering 3D graphics. Because there are so many different methods of rendering 3D worlds, it's nearly impossible to give a description of a graphics pipeline that works in all situations.

Regardless of how you implement your renderer, the most important thing is to make your renderer component based and clean. Make sure you have distinct modules for different things. The sub-sections that I break the renderer into are sections like Visibility, Collision Detection and Response, Camera, Static Geometry, Dynamic Geometry, Particle Systems, Billboarding, Meshes, Skybox, Lighting, Fogging, Vertex Shading, and Output.

Each one of these sections needs to have an interface that easily allows for changes in settings, position, orientation, or any other setting that may be associated with the system.

One major pitfall to look out for is feature bloat. Decide what you are going to implement at the design stage. If you don't adding new features will start to get hard to do and the solutions will be kludgy.

One thing that is nice and convenient is to have all tr​​iangles (or faces) ultimately pass through the same point in the render pipeline. (Not a triangle at a time, I'm talking about triangle lists, fans, strips, etc.) It takes a bit more work to get everything into a format that can be passed through the same lighting, fogging, and shading code but in the end you'll be happy that any effect that you can do to one polygon can be done to any polygon in your game simply by changing its material/texture id.

It doesn't hurt to have multiple points from which things are drawn, but it can lead to redundant code if you're not careful.

You'll eventually find out that all those cool effects that you wanted to implement will be 15% or less of the total code you end up writing. That's right, m​​ost of a game engine is not graphics.

Game Interface

The most important part of a 3D game engine is that it is a game engine. It is not a game. The actual game should never have components that are put into the game engine. Having a thin layer between the engine and the game makes for cleaner code and ease of use. It's a little extra code, but it also makes a game engine very reusable and it becomes much easier to use a scripting language for game logic, or put the game code in a library. If you embed any of your game logic in the engine itself, don't plan on reusing it later without lots of problems and modifications.

So you're probably wondering what this layer between the engine and game provides. The answer is control. For each part of the engine that has any dynamic properties, the engine/game layer provides an interface to modify it. Some things in this category include the camera, model properties, lights, particle system physics, playing sounds, playing music, handling input, changing levels, collision detection and response, and placement of 2D graphics for a heads up display, title screen or whatever. Basically if you want your game to be able to do it, there must be an interface into the engine to do it.

The Game

Well, at this point, I can't tell you how to write your game. That's up to you. You've spent a while writing this amazing engine with a great interface that will make your game writing process less stressing.

3D game engines are huge software projects. A single person can write one, but it's not an overnight process. You're probably going to have more than a few megabytes of source code. If you're not motivated to finish it , you won't.

Also don't expect to write a full engine on your first try. Pick a small project that has small requirements in the engine. Work your way up. You'll get there.

遊戲網誌:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系