锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 銆銆濡備笅鏄渶鏂板叕甯冪殑涓孌?#8220;CryEngine 3”寮曟搸鍒朵綔FPS娓告垙鍦板浘瑙嗛錛屼粠鍒朵綔鍒版紨紺轟粎闀?鍒嗛挓錛岀湅浜嗚浜虹灎鐩粨鑸岋紝鍞忓槝涓嶅凡銆?/p>
Introduction
Hidden surface removal is among the biggest problems when writing a 3D engine.
I struggled with it since the very beginning of writing 3D engines and still have no satisfactory solution to it. The ideal visibility detection scheme would allow unlimited data, extremely dynamic worlds and would have zero overdraw. The first 3d engine which implements these three demands still has to be written.
The Z buffer for example allows dynamical worlds and even crossing faces, but it suffers from immense overdraw. The BSP-tree on the other hand, if well implemented, has no overdraw at all but needs that much pre-processing that dynamical worlds are a definite nono.
It wasn't until recently i first heard of the octree, and I must admit i was struck by it's simplicity. I never actually implemented this structure and therefore I will present no pseudo code at all. This explanation is merely an attempt to make it more clear to people who have never heard of it. Besides, if you really understand the structure, then implementation is a piece of cake.
The Octree Structure
Our virtual world or level is actually nothing more then a soup of polygons. Some of you people might have thrown in a couple of curves and voxels but most of it will be polygons. Here it is:
Fig 1. Our little level.
In the picture I just built a simple level containing no more than 250 polys. Now imagine a cube surrounding the world like in the next image:
Fig. 2. Our little level surrounded by a cube.
Now it isn't hard to see that this cube can be divided into eight smaller cubes, hence the name octree. Take a look at this picture:
Fig 3. Our little level with the surrounding cube subdivided.
Call the larger cube the parent and the smaller cubes the children. On their turn subdivide each children into eight smaller cubes, and you will notice we are creating a tree where each node has eight children.
There is still one little problem left. When should we stop dividing cubes into smaller ones? There are two possible solutions. The first one is to stop when a cube has some size smaller then a fixed number. The second one is more common. You might have noticed that every child has less polygons then it's parent. The trick is to stop subdividing when the number of polygons in a cube is smaller then some fixed number.
Creating The Octree
Trees are recursion, recursion is trees. It is as simple as that. If you have a correct definition of you cubeNode it is very easy to create an octree recursively. First of all you check all polygons against the boundarys of the cube. This is very simple cause these boundaries are all axis aligned. This means that the cube has six plane equations, which are:
Where Q is the position of one corner of the cube. This are very easy equations and the all parent polygons can very easily be checked against them.
It could occur that a polygon crosses a cube boundary. Again two possible solution are at hand. First of all we could clip the polygon against the cube, which is simple, because of the axis aligned boundarys. On the other hand we could put the polygon in all cubes it is in. This means that some cubes can contain the same polygons. In order to prevent us from drawing one poly more than one time we should have a flag on each polygon which will be set if the poly is drawn for the first time.
The implementation of an octree is very straight forward. I haven't done it myself yet, but I will soon. It is all matter of recursion. In order to construct a tree, the first thing you should think of is recursion. Whether we are talking about binary trees, quad trees or octrees, it doesnt matter, just build the darn thing recursively. So have a class definition of one cubeNode and put the creation of the tree in it's constructor. In this constructor you will call the constructor itself for smaller cubes.
The Purpose Of The Octree
An octree is actually nothing more then a data structure. It can be used for very different things. It is not only handy for visibility detection but also for collision detection, realtime shadows and many more things. The most important thing to understand about octrees is that if a parent is not important then it's children aren't either. Let's makes this a little bit more clear with an example.
We will do this in 2d, which therefore resembles a quadtree, but with some imagination it can very easily be extended to 3d. Here we test the cubes (squares) against the viewing frustrum. Take a look at the next picture:
Fig 4. An octree from the top and a viewing frustrum.
In this picture a colored square that has one color was dumped without checking it錕絪 children. As you can see some squares had to be checked all the way to the final node, but some large squares could be dumped at once. The colored squares are the ones that are outside the viewing frustrum and the greyscale ones are the one inside the viewing frustrum. As you can see this is actually a worst case scenario because the viewing frustrum crosses the middle of the surrounding square and therefore all the four children have to be checked.
You could also apply the octree to many other things. Collision detection for example. Just check in which cube your bounding sphere or box is and you will only have to check against those faces. There are many more examples.
Conclusion
There is already a lot written about octrees. I tried to give my view on them in the hope somebody might read this. As you can see octrees are way easier to implement than BSP-trees (although some disagree) while offering a better structure. The main point about an octrees is that when a parent is discarded so are it's children. Actually that is all there is to it.
Code clean, play Goldeneye and go vegetarian.
Jaap Suter a.k.a .........
璇戞枃錛?br>1銆佸紩璦錛?span class=English>Introduction錛?br>銆銆闅愰潰縐婚櫎鏄啓3D寮曟搸鏃跺欐渶澶х殑闂涔嬩竴銆?br>銆銆Hidden surface removal is among the biggest problems when writing a 3D engine.
銆銆鍦ㄦ垜鍐?D寮曟搸鐨勫紑濮嬮樁孌靛氨寮濮嬪拰瀹冩枟浜夊茍涓斾竴鐩存病鏈夋弧鎰忕殑瑙e喅鏂規硶銆傜悊鎯崇殑鍙媯嫻嬫柟妗堝簲褰撳仛鍒板厑璁革紙浣跨敤錛夋棤闄愮殑鏁版嵁銆佸ぇ鍔ㄦ佺殑涓栫晫鍜岄浂閲嶇敾銆傜涓嫻佺殑3D寮曟搸涓鐩村湪榪芥眰瀹炵幇榪?涓姹傘?br>銆銆I struggled with it since the very beginning of writing 3D engines and still have no satisfactory solution to it. The ideal visibility detection scheme would allow unlimited data, extremely dynamic worlds and would have zero overdraw. The first 3d engine which implements these three demands still has to be written.
銆銆Z buffer鍏佽鍔ㄦ佷笘鐣屼互鍙婂嵆浣挎槸浜ゅ弶鐨勯潰錛屼絾鏄緱蹇嶅彈澶ч噺鐨勯噸鐢匯傚彟涓鏂歸潰錛孊SP鏍戝鏋滆兘澶熻寰堝ソ鐨勫疄鐜幫紝鍙互閬垮厤閲嶇敾錛屼絾鏄畠闇瑕佸ぇ閲忕殑棰勫鐞嗚綆楄屼笖涓嶉傚悎鍔ㄦ佷笘鐣屻?br>銆銆The Z buffer for example allows dynamical worlds and even crossing faces, but it suffers from immense overdraw. The BSP-tree on the other hand, if well implemented, has no overdraw at all but needs that much pre-processing that dynamical worlds are a definite nono.
銆銆鐩村埌鏈榪戞垜絎竴嬈″惉璇翠簡鍏弶鏍戯紙Octree錛夛紝鎴戝繀欏繪壙璁ゆ垜琚畠鐨勭畝鏄撴?#8220;鐙犵嫚鍦版墦浜嗕竴涓嬪効”銆傛垜浠庢潵娌℃湁鐪熸鍦板幓瀹炵幇榪欎釜緇撴瀯錛屽洜姝ゆ垜涓嶄細鍘誨疄鐜頒竴浜涗唬鐮併傝繖涓В閲婂彧鏄兂璁╀粠娌℃湁鍚榪囧叓鍙夋爲鐨勪漢鎰熷埌鏇存竻鏅版槗鎳傘傚鏋滀綘鐪熺殑浜嗚В浜嗚繖涓粨鏋勶紙Octree錛夛紝瀹炵幇瀹冨彧鏄竴涓皬鎰忔濄?br>銆銆It wasn't until recently i first heard of the octree, and I must admit i was struck by it's simplicity. I never actually implemented this structure and therefore I will present no pseudo code at all. This explanation is merely an attempt to make it more clear to people who have never heard of it. Besides, if you really understand the structure, then implementation is a piece of cake.
2銆佸叓鍙夋爲鐨勭粨鏋?/strong>錛?span class=English>The Octree Structure錛?br>銆銆鎴戜滑鐨勫疄闄?#8216;涓栫晫’鎴栬呰鏄叧鍗″彧涓嶈繃鏄竴浜涘杈瑰艦銆備綘浠垨璁稿湪鍏朵腑鍔犲叆浜嗕竴浜涙洸闈紙Curves錛夊拰Voxels錛堝湴褰㈠疄鐜版柟娉曠殑涓縐嶏級錛屼絾鏄ぇ澶氭暟涔熼兘鏄杈瑰艦銆?br>銆銆Our virtual world or level is actually nothing more then a soup of polygons. Some of you people might have thrown in a couple of curves and voxels but most of it will be polygons. Here it is:
鍥?
銆銆鍥?錛氭垜浠璁$殑灝忓瀷鍏沖崱銆?br>銆銆Fig 1. Our little level.
銆銆鍦ㄨ繖寮犲浘鐗囦腑鎴戝緩绔嬩簡涓涓笉瓚呰繃250涓杈瑰艦鐨?#8216;鍏沖崱’銆傜幇鍦ㄦ兂璞℃湁涓涓寘鍥翠簡榪欎釜涓栫晫鐨勭珛鏂逛綋錛屽儚涓嬩竴寮犲浘鐗囬偅鏍楓?br>銆銆In the picture I just built a simple level containing no more than 250 polys. Now imagine a cube surrounding the world like in the next image:
鍥?
銆銆鍥?錛氭垜浠璁$殑鍏沖崱琚竴涓珛鏂逛綋鎵鍖呭洿鐫銆?br>銆銆Fig. 2. Our little level surrounded by a cube.
銆銆鐜板湪涓嶉毦鐪嬪嚭榪欎釜绔嬫柟浣撳彲浠ヨ鍏瓑鍒嗕負鍏釜灝忎簺鐨勭珛鏂逛綋錛屾墍浠ユ墠鍙叓鍙夋爲銆傜湅鐪嬭繖寮犲浘錛?br>銆銆Now it isn't hard to see that this cube can be divided into eight smaller cubes, hence the name octree. Take a look at this picture:
鍥?
銆銆鍥?錛氬鍥寸粫鐫鍏沖崱鐨勭珛鏂逛綋榪涜緇嗗垎銆?br>銆銆Fig 3. Our little level with the surrounding cube subdivided.
銆銆澶х偣鍎跨殑榪欎釜绔嬫柟浣撹鍙仛‘鐖朵翰’灝忎簺鐨勭珛鏂逛綋鍙仛‘瀛╁瓙’銆傚鐞嗘瘡涓?#8216;瀛╁瓙’鐨勬椂鍊欙紝鍐嶄負鏇村皬鐨勫叓涓珛鏂逛綋錛屼綘浼氬彂鐜版垜浠湪鍒涘緩涓涓瘡涓妭鐐規湁鍏釜瀛愯妭鐐癸紙瀛╁瓙錛夌殑鏍戙?br>銆銆Call the larger cube the parent and the smaller cubes the children. On their turn subdivide each children into eight smaller cubes, and you will notice we are creating a tree where each node has eight children.
銆銆榪樻湁涓涓皬闂銆備粈涔堟椂鍊欐垜浠緇撴潫緇嗗垎鐨勮繃紼嬪憿錛熸湁涓や釜鍙鐨勮В鍐蟲柟娉曘傜涓涓槸褰撲竴涓珛鏂逛綋鐨勫昂瀵稿凡緇忔瘮涓涓瀹氱殑鍥哄畾鍊煎皬鐨勬椂鍊欍傜浜屼釜鏇存櫘閫氥備綘鍙互娉ㄦ剰鍒版瘡涓?#8216;瀛╁瓙’閮芥瘮浠栫殑‘鐖朵翰’鏈夋洿灝戠殑澶氳竟褰€傝繖灝辨槸璇達細褰撲竴涓珛鏂逛綋鍖呭惈鐨勫杈瑰艦鏁伴噺姣斾竴涓瀹氱殑鍥哄畾鍊煎皯鐨勬椂鍊欏仠姝㈢粏鍒嗐?br>銆銆There is still one little problem left. When should we stop dividing cubes into smaller ones? There are two possible solutions. The first one is to stop when a cube has some size smaller then a fixed number. The second one is more common. You might have noticed that every child has less polygons then it's parent. The trick is to stop subdividing when the number of polygons in a cube is smaller then some fixed number.
3銆佸垱寤哄叓鍙夋爲錛?span class=English>Creating The Octree錛?br>銆銆鏍戞槸閫掑綊鐨勶紝閫掑綊鐨勬槸鏍戙傚氨閭d箞綆鍗曘傚鏋滀綘姝g‘鐨勫畾涔変簡浣犵殑绔嬫柟浣撹妭鐐癸紝閭d箞閫掑綊鍦板垱寤轟竴涓叓鍙夋爲鏄緢瀹規槗鐨勩傞鍏堬紝媯鏌ユ墍鏈夌殑澶氳竟褰紙澶氳竟褰笂浣嶇疆鏈澶栭潰鐨勭偣浣滀負錛夌珛鏂逛綋鐨勮竟鐣屻傝繖寰堢畝鍗曞洜涓烘墍鏈夎竟鐣岄兘鏄拰鍧愭爣杞村鍏剁殑銆傝繖鎰忓懗鐫绔嬫柟浣撴湁鍏釜騫抽潰鏂圭▼錛屽垎鍒槸錛?br>銆銆Trees are recursion, recursion is trees. It is as simple as that. If you have a correct definition of you cubeNode it is very easy to create an octree recursively. First of all you check all polygons against the boundarys of the cube. This is very simple cause these boundaries are all axis aligned. This means that the cube has six plane equations, which are:
銆銆鍦ㄨ繖閲孮鏄珛鏂逛綋涓涓《瑙掔殑浣嶇疆銆傝繖鏄釜寰堢畝鍗曠殑鏂圭▼錛岃屼笖鎵鏈夌殑鐖朵翰澶氳竟褰㈠彲浠ュ鏄撳湴鐢ㄨ繖浜涙柟紼嬫潵媯嫻嬨?br>銆銆WhereQ is the position of one corner of the cube. This are very easy equations and the all parent polygons can very easily be checked against them.
銆銆涓涓杈瑰艦絀胯繃浜嗕竴涓珛鏂逛綋杈圭晫榪欐牱鐨勪簨鎯呮槸浼氬彂鐢熺殑銆傚啀涓嬈★紝鏈変袱涓В鍐蟲柟妗堝彲鐢ㄣ傞鍏堟垜浠彲浠ユ部鐫绔嬫柟浣撳壀鍒囪繖涓杈瑰艦錛岃繖涔熸槸寰堢畝鍗曠殑錛屽洜涓猴紙绔嬫柟浣撶殑錛夎竟鐣屾槸涓庡潗鏍囪醬瀵歸綈鐨勩傝繕鏈夛紝鎴戜滑鍙互鎶婁竴涓杈瑰艦鏀懼湪鎵鏈夊畠鎵鍦ㄧ殑绔嬫柟浣撻噷闈€傝繖灝辨剰鍛崇潃涓浜涚珛鏂逛綋鍙兘鍖呭惈鐫鍚屼竴涓杈瑰艦銆備負浜嗛槻姝㈤噸鐢諱竴涓杈瑰艦錛屾垜浠簲褰撳湪姣忎竴涓杈瑰艦涓婂仛涓涓爣璁幫紝褰撳杈瑰艦絎竴嬈¤鐢葷殑鏃跺欙紝璁劇疆榪欎釜鏍囪錛堝綋鐒剁敾涔嬪墠涔熻媯鏌ヨ繖涓爣璁板暒錛屼笉榪囪偗瀹氬獎鍝嶆晥鐜囥?br>銆銆It could occur that a polygon crosses a cube boundary. Again two possible solution are at hand. First of all we could clip the polygon against the cube, which is simple, because of the axis aligned boundarys. On the other hand we could put the polygon in all cubes it is in. This means that some cubes can contain the same polygons. In order to prevent us from drawing one poly more than one time we should have a flag on each polygon which will be set if the poly is drawn for the first time.
銆銆瀹炵幇涓涓叓鍙夋爲鏄緢綆鍗曟槑浜嗙殑浜嬫儏錛屾垜榪樻病鏈夎嚜宸卞仛榪囷紝浣嗘槸鎴戜笉涔呬細鍋氱殑銆傚彧涓嶈繃鏄掑綊鑰屽凡銆備負浜嗘瀯閫犱竴涓爲錛岀涓浠朵綘璇ユ兂鐨勪簨鎯呭氨鏄掑綊銆備笉綆℃垜浠璁虹殑鏄簩鍙夈佸洓鍙夎繕鏄叓鍙夋爲錛岄兘娌℃湁鍖哄埆錛岄兘鏄掑綊鐨勬柟娉曘傛墍浠ュ畾涔変竴涓珛鏂逛綋鑺傜偣鐨勭被錛屽湪鏋勯犲嚱鏁伴噷闈㈠啓涓婂垱寤烘爲鐨勪唬鐮併傚湪榪欎釜鏋勯犲嚱鏁伴噷闈紝浣犱細璋冪敤鍒版洿灝忕珛鏂逛綋鐨勬瀯閫犲嚱鏁般?br>銆銆The implementation of an octree is very straight forward. I haven't done it myself yet, but I will soon. It is all matter of recursion. In order to construct a tree, the first thing you should think of is recursion. Whether we are talking about binary trees, quad trees or octrees, it doesnt matter, just build the darn thing recursively. So have a class definition of one cubeNode and put the creation of the tree in it's constructor. In this constructor you will call the constructor itself for smaller cubes.
4銆佸叓鍙夋爲鐨勭敤閫?/strong>錛?span class=English>The Purpose Of The Octree錛?br>銆銆涓涓叓鍙夋爲瀹為檯涓婂氨鏄竴涓暟鎹粨鏋勩傚畠鍙互鐢ㄥ仛涓嶅悓鐨勪簨鎯呫備笉浠呬粎瀵逛簬‘鍙媯嫻?#8217;鏉ヨ寰堟柟渚匡紝榪樻湁瀹炴椂闃村獎浠ュ強鍏跺畠鏂歸潰銆傜悊瑙e叓鍙夋爲榪囩▼涓渶閲嶈鐨勪簨鎯呮槸錛氬鏋滀竴涓?#8216;鐖朵翰’鑺傜偣鏄?#8216;娌$敤’鐨勶紝閭d箞浠栫殑‘瀛╁瓙’鑺傜偣涔熷悓鏍楓傝鎴戜滑涓句釜渚嬪瓙璁╁畠鏇存竻妤氥?br>銆銆An octree is actually nothing more then a data structure. It can be used for very different things. It is not only handy for visibility detection but also for collision detection, realtime shadows and many more things. The most important thing to understand about octrees is that if a parent is not important then it's children aren't either. Let's makes this a little bit more clear with an example.
銆銆鎴戜滑鐢?D鏉ヨ〃紺哄畠錛岃繖鏍峰氨寰堝儚涓涓洓鍙夋爲錛屼絾鏄兂璞′竴涓嬪畠涔熷彲浠ュ緢瀹規槗鐨勬墿灞曞埌3D涓娿傚湪榪欓噷鎴戜滑娌跨潃瑙嗛敟錛?span class=English>viewing frustrum錛夋嫻嬬珛鏂逛綋錛堟鏂瑰艦錛夈?br>銆銆We will do this in 2d, which therefore resembles a quadtree, but with some imagination it can very easily be extended to 3d. Here we test the cubes (squares) against the viewing frustrum. Take a look at the next picture:
鍥?
銆銆鍥?錛氶《閮ㄨ閿ュ唴鐨勫叓鍙夋爲銆?br>銆銆Fig 4. An octree from the top and a viewing frustrum.
銆銆鍦ㄨ繖涓浘鐗囦腑錛屽僵鑹茬殑姝f柟褰㈡槸娌℃湁錛堟病蹇呰錛夋嫻嬪畠鐨?#8216;瀛╁瓙’鐨勩傚氨鍍忎綘鐪嬪埌鐨勯偅鏍蜂竴浜涙鏂瑰艦錛堢伆鑹茬殑涓浜涳級琚嫻嬬洿鍒版渶緇堣妭鐐癸紝浣嗘槸涓浜涘ぇ鐨勬鏂瑰艦鍙娑備簡涓縐嶉鑹層傞偅浜涘僵鑹茬殑姝f柟褰㈠氨鏄秴鍑轟簡瑙嗛敟鑼冨洿鐨勶紝鐏拌壊鐨勬槸鍦ㄨ閿ヨ寖鍥村唴鐨勩傚氨鍍忎綘鐪嬪埌鐨勯偅鏍鳳紝榪欑‘瀹炴槸鏈緋熺硶鐨勪竴縐嶆儏鍐碉紝鍥犱負瑙嗛敟絀胯繃浜嗗寘鍥存鏂瑰艦鐨勪腑澶紝鎵浠ユ墍鏈夌殑鍥涗釜‘瀛╁瓙’閮藉緱琚嫻嬨?br>銆銆In this picture a colored square that has one color was dumped without checking it鎶?children. As you can see some squares had to be checked all the way to the final node, but some large squares could be dumped at once. The colored squares are the ones that are outside the viewing frustrum and the greyscale ones are the one inside the viewing frustrum. As you can see this is actually a worst case scenario because the viewing frustrum crosses the middle of the surrounding square and therefore all the four children have to be checked.
銆銆浣犲彲浠ュ簲鐢ㄥ叓鍙夋爲鍒板緢澶氬埆鐨勫湴鏂廣備緥濡傜鎾炴嫻嬨傚彧媯鏌ヤ綘鐨勭鎾炵悆鎴栬呯鎾炵洅瀛愭墍鍦ㄧ殑绔嬫柟浣擄紝鑰屼笖鍙渶瑕佹嫻嬮偅浜涢潰銆傝繕鏈夋洿澶氱殑渚嬪瓙銆?br>銆銆You could also apply the octree to many other things. Collision detection for example. Just check in which cube your bounding sphere or box is and you will only have to check against those faces. There are many more examples.
5銆佺粨璁?/strong>錛?span class=English>Conclusion錛?br>銆銆鍏充簬鍏弶鏍戝凡緇忓啓浜嗗緢澶氫簡銆傛垜璁炬硶琛ㄨ堪鑷繁瀵瑰畠鐨勭湅娉曪紝騫朵笖甯屾湜鏈変漢浼氳鍒板畠銆傚氨鍍忎綘鐪嬪埌鐨勯偅鏍鳳紝褰撴彁渚涘ソ鐨勭粨鏋勭殑鏃跺欙紝鍏弶鏍戞瘮BSP鏍戞洿瀹規槗瀹炵幇錛堟湁浜烘寔寮傝錛夈備富瑕佺殑涓鐐規槸錛氬綋涓涓?#8216;鐖朵翰’鑺傜偣琚涪寮冪殑鏃跺欙紝浠栫殑‘瀛╁瓙’鑺傜偣涔熷悓鏍瘋涓㈠純銆傚疄闄呬笂榪欏氨鏄叏閮ㄣ?br>銆銆There is already a lot written about octrees. I tried to give my view on them in the hope somebody might read this. As you can see octrees are way easier to implement than BSP-trees (although some disagree) while offering a better structure. The main point about an octrees is that when a parent is discarded so are it's children. Actually that is all there is to it.
銆銆Code clean, play Goldeneye and go vegetarian. Jaap Suter a.k.a .........
// -------------------------------
// Cel Shading Section
// -------------------------------
vertex_program Ogre/CelShadingVP cg
{
source Example_CelShading.cg
entry_point main_vp
profiles vs_1_1 arbvp1
default_params
{
param_named_auto lightPosition light_position_object_space 0 param_named_auto eyePosition camera_position_object_space
param_named_auto worldViewProj worldviewproj_matrix
param_named shininess float 10
}
}
fragment_program Ogre/CelShadingFP cg
{
source Example_CelShading.cg
entry_point main_fp
profiles ps_1_1 arbfp1 fp20
}
material Examples/CelShading
{
technique
{
pass
{
vertex_program_ref Ogre/CelShadingVP
{
// map shininess from custom renderable param 1
param_named_auto shininess custom 1
// 緇堜簬鐭ラ亾param_named_auto絎笁涓弬鏁扮殑浣滅敤浜嗭紝鐢ㄤ簬緇欑▼搴忎腑璧嬪肩殑绱㈠紩
sub->setCustomParameter(CUSTOM_SHININESS, Vector4(
}
fragment_program_ref Ogre/CelShadingFP
{
// map diffuse from custom renderable param 2
param_named_auto diffuse custom 2
// map specular from custom renderable param 2
param_named_auto specular custom 3
}
texture_unit
{
texture cel_shading_diffuse.png 1d
tex_address_mode clamp
filtering none
}
texture_unit
{
texture cel_shading_specular.png 1d
tex_address_mode clamp
filtering none
}
texture_unit
{
texture cel_shading_edge.png 1d
tex_address_mode clamp
filtering none
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////涓嬮潰鏄?span>cg鏂囦歡
////////////////////////////////////////////////////////////////////////////////
/* Cel shading vertex program for single-pass rendering
In this program, we want to calculate the diffuse and specular
ramp components, and the edge factor (for doing simple outlining)
For the outlining to look good, we need a pretty well curved model.
*/
void main_vp(float4 position : POSITION,
float3 normal : NORMAL,[U1]
// outputs
out float4 oPosition : POSITION,
out float diffuse : TEXCOORD0,
out float specular : TEXCOORD1,
out float edge : TEXCOORD2,[U2]
// parameters
uniform float3 lightPosition, // object space錛氫笘鐣屽潗鏍囩郴
uniform float3 eyePosition, // object space
uniform float4 shininess,
uniform float4x4 worldViewProj)
{
// calculate output position
oPosition = mul(worldViewProj, position);
// calculate light vector
float3 N = normalize(normal);
float
// Calculate diffuse component
diffuse = max(dot(N, L) , 0);
// Calculate specular component
float3 E = normalize(eyePosition - position.xyz);
float3 H = normalize(L + E);
specular = pow(max(dot(N, H), 0), shininess[U3] );
// Mask off specular if diffuse is 0
if (diffuse == 0) specular = 0;
// Edge detection, dot eye and normal vectors
edge = max(dot(N, E), 0); // 娉曠嚎涓庤綰垮鉤琛岀殑鐐硅涓烘槸鏍囪繙錛岀粰浜堥粦鑹叉矡杈?/span>
}
void main_fp(float diffuseIn : TEXCOORD0,
float specularIn : TEXCOORD1,
float edge : TEXCOORD2,
out float4 colour : COLOR,
uniform float4 diffuse,
uniform float4 specular,
uniform sampler1D diffuseRamp,
uniform sampler1D specularRamp,
uniform sampler1D edgeRamp[U5] )
{
// Step functions from textures
diffuseIn = tex1D(diffuseRamp, diffuseIn).x;
specularIn = tex1D(specularRamp, specularIn).x;
edge = tex1D(edgeRamp, edge).x;
colour = edge * ((diffuse * diffuseIn) +
(specular * specularIn));
}
[U1]榪欓噷鏄?/span>GPU浼犺繘鏉ョ殑錛?/span>POSITION錛氶《鐐瑰潗鏍囷紝NORMAL娉曠嚎錛屽幓鐪嬬湅hlsl鐨勮鎰忓畾涔?/span>
[U2]out閮芥槸杈撳嚭鍙傛暟錛屾敼鍙樹粬浠殑鍊艱緭鍑轟箣鍚庤ps鑾峰彇
[U3]鍗?/span>m涓嬫爣gls錛屼負鏉愭枡鐨勫厜娉藉害
[U4]寰楀埌鐨勬槸vs涓?/span>out鍑烘潵鐨勫?/span>
[U5]浠?/span>texture_unit涓緱鍒幫紝欏哄簭鏍規嵁瀹氫箟鐨勯『搴?/span>texture_unit
{
texture cel_shading_diffuse.png 1d
tex_address_mode clamp
filtering none
}
texture_unit
{
texture cel_shading_specular.png 1d
tex_address_mode clamp
filtering none
}
texture_unit
{
texture cel_shading_edge.png 1d
tex_address_mode clamp
filtering none
}
1錛屽浐瀹氱潃鑹?span>(constant shading)
鍥哄畾鐫鑹叉牴鏈笉鑰冭檻鍏夌収妯″瀷錛屽彧鏄牴鎹杈瑰艦棰滆壊鐨勭儲寮曟垨RGB鍊肩粯鍒跺畠銆?/span>
PS:鍩烘湰宸茬粡琚父鎴忔窐姹幫紝澶畝鍗曠殑鐫鑹叉ā鍨?/span>
2錛屾亽瀹氱潃鑹詫紙flat shding錛?/span>
瀵逛簬姣忎釜澶氳竟褰㈠彧闇瑕佹牴鎹竴涓《鐐規墽琛屽厜鐓ц綆楋紝鐒跺悗鏍規嵁璁$畻緇撴灉瀵規暣涓杈瑰艦榪涜鐫鑹詫紝榪欏氨鏄亽瀹氱潃鑹詫紝涔熺О涓洪潰鐗囩潃鑹?span>(faceted shading)錛屽浜庣敱騫抽潰緇勬垚鐨勫杈瑰艦榪欑鏂規硶鏄彲琛岀殑錛堢珛鏂逛綋錛夛紝浣嗗浜庣敱鏇查潰緇勬垚鐨勫杈瑰艦榪欑鐫鑹叉柟寮忎細鍑虹幇闈炰綘鎯寵鐨勭粨鏋?span>.
3錛?span>Gougraud鐫鑹?/span>
銆銆瀵逛簬欏剁偣涔嬮棿鐨勫儚绱犲奸噰鐢ㄤ袱涓《鐐逛箣闂寸殑鎻掑艱綆楁潵紜畾錛岄《鐐逛箣闂寸殑棰滆壊榪囨浮鑷劧錛屾覆鏌撴晥鏋滀篃姣旇緝騫蟲粦,娌℃湁鎭掑畾鐫鑹查偅鏍風獊鍏銆?/span>
4錛?span>Phong鐫鑹?/span>
銆銆涓?span>Gougraud鐫鑹茬被浼鹼紝涓嶈繃浼樼偣鍦ㄤ簬榪樺姣忎釜鍍忕礌榪涜浜嗘硶綰跨殑鎻掑鹼紝瀵逛簬闀滈潰鍙嶅皠鏁堟灉姣旇緝濂姐?/span>
鍑瑰嚫鏄犲皠Bump Mapping | ![]() |
銆銆鍑瑰嚫鏄犲皠鍜岀汗鐞嗘槧灝勯潪甯哥浉浼箋傜劧鑰岋紝綰圭悊鏄犲皠鏄妸棰滆壊鍔犲埌澶氳竟褰笂錛岃屽嚬鍑告槧灝勬槸鎶婄矖緋欎俊鎭姞鍒板杈瑰艦涓娿傝繖鍦ㄥ杈瑰艦鐨勮瑙変笂浼氫駭鐢熷緢鍚稿紩浜虹殑鏁堟灉銆傛垜浠彧闇瑕佹坊鍔犱竴鐐逛俊鎭埌鏈潵闇瑕佷嬌鐢ㄥぇ閲忓杈瑰艦鐨勭墿浣撲笂銆傞渶瑕佹敞鎰忕殑鏄繖涓墿浣撴槸騫崇殑錛屼絾鏄畠鐪嬭搗鏉ュ嵈鏄矖緋欎笉騫崇殑銆傝鎴戜滑鏉ョ湅鐪嬪乏杈圭殑閭d釜绔嬫柟浣撱傚鏋滀綘寰堣繎鍦拌瀵熷畠鏃訛紝浣犱細鍙戠幇瀹冧笂闈㈢殑寰堝緇嗚妭銆傚畠鐪嬭搗鏉ュソ鍍忔槸鐢辨垚鍗冧笂涓囦釜澶氳竟褰㈡瀯鎴愮殑錛屽叾瀹炲畠鍙槸鐢?涓煩褰㈡瀯鎴愩備綘鎴栬浼氶棶錛?#8220;榪欏拰綰圭悊鏄犲皠鏈変粈涔堜笉鍚岋紵”瀹冧滑鐨勪笉鍚屼箣澶勫湪浜庘斺斿嚬鍑告槧灝勬槸涓縐嶈礋璐e厜鏂瑰悜鐨勭汗鐞嗘槧灝勩?br>
錛?錛夊嚬鍑告槧灝勮儗鍚庣殑鍘熺悊
銆銆璁╂垜浠潵鐪嬬湅涓涓矖緋欑殑琛ㄩ潰銆?br>銆銆銆銆
銆銆浠庤繙澶勭湅錛屼綘鍒ゆ柇榪欎釜鐗╀綋鏄矖緋欑殑鐨勫敮涓璇佹嵁鏄湪瀹冭〃闈笂涓嬬殑浜害鏈夋敼鍙樸備綘鐨勫ぇ鑴戣兘澶熻幏寰楄繖浜涗寒鏆椾笉涓鐨勫浘妗堜俊鎭紝鐒跺悗鍒ゆ柇鍑哄畠浠槸琛ㄩ潰涓湁鍑瑰嚫鐨勯儴浣嶃?/p>
銆銆閭d箞浣犱篃璁鎬細闂細鎴戞槸鎬庝箞鐭ラ亾鍝簺鐐硅浜紝鍝簺鐐硅鏆楀憿錛熻繖涓嶉毦銆傜粷澶у鏁頒漢鐢熸椿鍦ㄨ繖鏍蜂竴縐嶇幆澧冧笅鈥斺旇繖涓幆澧冪殑澶у鏁板厜婧愭潵鑷笂鏂癸紙璇戣呮敞錛氭瘮濡傜櫧澶╀富瑕佺殑鍏夋潵鑷お闃籌紝澶滄櫄涓昏鐨勫厜鏉ヨ嚜澶╄姳鏉夸笂鐨勬棩鍏夌伅錛夈傛墍浠ュ悜涓婂劇殑鍦版柟灝變細鏇翠寒錛岃屽悜涓嬪劇殑鍦版柟灝變細鏇存殫銆傛墍浠ヨ繖縐嶇幇璞′嬌浣犵殑鐪肩潧鐪嬪埌涓涓墿浣撲笂浜殫鍖哄煙鏃訛紝鍙互鍒ゆ柇鍑哄畠鐨勫嚬鍑告儏鍐點傜浉瀵逛寒鐨勫潡琚垽鏂槸闈㈠悜涓婄殑錛岀浉瀵規殫鐨勫潡琚垽鏂槸闈㈠悜涓嬬殑銆傛墍浠ユ垜鍙渶瑕佺粰鐗╀綋涓婄殑綰挎潯綆鍗曞緱涓婅壊銆?br>
銆銆濡傛灉浣犳兂瑕佹洿澶氱殑璇佹嵁錛岃繖閲岃繕鏈変竴騫呭嚑涔庣浉鍚岀殑鍥撅紝涓嶅悓浜庡墠鐨勬槸瀹冩棆杞簡180搴︺傛墍浠ュ畠鏄墠涓騫呭浘鍊掕漿鐨勫浘鍍忋傞偅浜涘厛鍓嶇湅璧鋒潵鏄嚬榪涘幓鐨勫尯鍩燂紝鐜板湪鐪嬭搗鏉ユ槸鍑稿嚭鏉ョ殑浜嗐?br>銆銆銆銆
銆銆榪欎釜鏃跺欎綘鐨勫ぇ鑴戝茍娌℃湁琚畬鍏ㄦ楠楋紝浣犺剳涓瓨鐣欑殑瑙嗚鍗拌薄浣夸綘浠嶇劧鏈夎兘鍔涘垽鏂嚭榪欐槸鍓嶄竴騫呭浘錛屽彧鏄畠鐨勫厜婧愬彉浜嗭紝鏄粠灝忓線涓婄収鐨勪綘鐨勫ぇ鑴戝彲鑳藉己榪у湴鍒ゆ柇鍑哄畠鏄涓騫呭浘銆備簨瀹炰笂錛屼綘鍙濮嬬粓鐩潃瀹冿紝騫朵笖鍔姏鍦版兂鍍忕潃鍏夋槸浠庡彸涓嬫柟鍚戠収灝勭殑錛屼綘灝變細鐞嗚В瀹冩槸鍑圭殑錛堣瘧鑰呮敞錛氬洜涓烘棩甯哥敓媧葷殑涔犳儻錛屼綘浼氬緢瀹規槗鎶婅繖浜涘浘褰㈠垽鏂垚鍑稿嚭鐨勫浘褰紝浣嗘槸鍥犱負鏈変簡涓婁竴騫呭鐓у浘鐨勫嵃璞★紝浣犲彲鑳芥墠浼氱壒鍒敞鎰忓埌榪欎簺鍥懼潡鍏跺疄榪樻槸鍑瑰叆鐨勶紝鍙槸鍒ゆ柇鏂規硶涓嶇鍚堟垜浠棩甯哥敓媧諱範鎯紝鍥犱負榪欐椂澶у鏁板厜涓嶆槸浠庝笂鏂圭収灝勶紝鑰屾槸浠庝笅寰涓婄収灝勶級銆?br>
錛?錛変粈涔堟槸鍑瑰嚫鍥撅紙Bump Map錛?/strong>
銆銆鍑瑰嚫鍥懼拰綰圭悊鍥懼緢鐩鎬技銆備絾鏄笉鍚岀殑鏄紝鍑瑰嚫鍥懼寘鍚殑涓嶆槸棰滆壊淇℃伅錛岃屾槸鍑瑰嚫淇℃伅銆傛渶閫氬父鐨勬柟娉曟槸閫氳繃瀛樺偍楂樺害鍊煎疄鐜般傛垜浠鐢ㄥ埌涓涓伆鑹茬殑綰圭悊鍥撅紝鐏拌壊鐨勪寒搴︿綋鐜板嚭姣忎釜鐐瑰垎鍒嚫鍑哄灝戯紙瑙佸彸鍥撅級銆傝繖灝辨槸涓涓潪甯告柟渚跨殑淇濆瓨鍑瑰嚫鍥劇殑鏂規硶錛岃屼笖榪欑鍥懼緢瀹規槗鍒朵綔銆傝繖鍓浘鍏蜂綋鍙堟槸鎬庢牱琚覆鏌撳櫒浣跨敤鐨勫憿錛熶綘鎺ョ潃寰涓嬬湅灝變細鏄庣櫧浜嗐?br>
銆銆褰撶劧錛屼綘騫朵笉涓瀹氳鎶婅嚜宸卞眬闄愪簬榪欎簺綆鍗曠殑鍥懼艦錛屼綘鍙互鎵╁睍錛岀敤瀹冩潵鍋氭湪鏉愶紝鍋氱煶澶達紝鍋氳劚浜嗘紗鐨勫闈紝鍋氫換浣曚綘鎯沖仛鐨勭墿浣撱?br>銆銆銆銆
錛?錛夐偅涔堝畠鏄庝箞宸ヤ綔鐨?/strong>
銆銆鍑瑰嚫鏄犲皠鏄ˉ鑹叉覆鏌撴妧鏈紙Phong Shading Technique錛夌殑涓欏規墿灞曪紝鍙槸鍦ㄨˉ鑹叉覆鏌撻噷錛屽杈瑰艦琛ㄩ潰涓婄殑娉曠嚎灝嗚鏀瑰彉錛岃繖涓悜閲忕敤鏉ヨ綆楄鐐圭殑浜害銆傚綋浣犲姞鍏ヤ簡鍑瑰嚫鏄犲皠錛屾硶綰垮悜閲忎細鐣ュ井鍦版敼鍙橈紝鎬庝箞鏀瑰彉鍒欏熀浜庡嚬鍑稿浘銆傛敼鍙樻硶綰垮悜閲忓氨浼氭敼鍙樺杈瑰艦鐨勭偣鐨勯鑹插箋傚氨榪欎箞綆鍗曘?br>
銆銆鐜板湪錛屾湁鍑犵鏂規硶鏉ヨ揪鍒拌繖涓洰鐨勶紙璇戣呮敞錛氳繖涓洰鐨勬寚鏀瑰彉娉曠嚎鍚戦噺錛夈傛垜騫舵病鏈夊疄闄呯紪鍐欒ˉ鑹叉覆鏌撳拰鍑瑰嚫鏄犲皠鐨勭▼搴忥紝浣嗘槸鎴戝湪榪欓噷灝嗕粙緇嶄竴縐嶆垜鍠滄鐨勬柟娉曟潵瀹炵幇錛?br>
銆銆鐜板湪鎴戜滑闇瑕佸皢鍑瑰嚫鍥句腑鐨勯珮搴︿俊鎭漿鎹㈡垚琛ヨ壊娓叉煋鐢ㄥ埌鐨勬硶綰跨殑璋冭妭淇℃伅銆傝繖涓仛璧鋒潵涓嶉毦錛屼絾鏄В閲婅搗鏉ユ瘮杈冭垂鍔層?br>
銆銆銆銆
銆銆濂界殑錛屾垜浠幇鍦ㄥ皢鍑瑰嚫浣嶅浘鐨勪俊鎭漿鎹㈡垚涓浜涘皬鍚戦噺鈥斺斾竴涓悜閲忓搴斾簬涓涓偣銆傝鐪嬪乏杈逛竴鍓斁澶х殑鍑瑰嚫鍥俱傜浉瀵逛寒鐨勭偣姣旂浉瀵規殫鐨勭偣鏇翠負鍑稿嚭銆傜湅娓呮浜嗗悧錛熺幇鍦ㄨ綆楁瘡涓偣鐨勫悜閲忥紝榪欎簺鍚戦噺琛ㄥ緛浜嗘瘡涓偣鐨勫炬枩鎯呭喌錛岃鐪嬩笅鍥劇殑鎻忕粯銆傚浘涓孩鑹插皬鍦嗙偣琛ㄧず鍚戦噺鏄悜涓嬬殑錛?br>銆銆銆銆
銆銆鏈夊緢澶氳綆楀悜閲忕殑鏂規硶錛屼笉鍚岀殑鏂規硶綺劇‘搴︿笉鍚岋紝浣嗘槸閫夋嫨浠涔堟柟娉曡鍙栧喅浜庝綘鎵瑕佹眰鐨勭簿紜害鏄釜浠涔堝眰嬈°傛渶閫氬父鐨勬柟娉曟槸鍒嗗埆璁$畻姣忎釜鐐逛笂X鍜孻鐨勫炬枩搴︼細
銆銆x_gradient = pixel(x-1, y) - pixel(x+1, y)
銆銆y_gradient = pixel(x, y-1) - pixel(x, y+1)
鍦ㄥ緱鍑轟簡榪欎袱涓炬枩搴﹀悗錛屼綘灝卞彲浠ヨ綆楀杈瑰艦鐐圭殑娉曠嚎浜嗐?br>銆銆銆銆
銆銆榪欓噷鏈変竴涓杈瑰艦錛屽浘涓婄粯鍑轟簡瀹冪殑涓鏉℃硶綰垮悜閲忊斺攏銆傞櫎姝わ紝榪樻湁涓ゆ潯鍚戦噺錛屽畠浠皢鐢ㄦ潵璋冭妭璇ョ偣娉曠嚎鍚戦噺銆傝繖涓ゆ潯鍚戦噺蹇呴』涓庡綋鍓嶈娓叉煋鐨勫杈瑰艦鐨勫嚬鍑稿浘瀵歸綈錛屾崲鍙ヨ瘽璇達紝瀹冧滑瑕佷笌鍑瑰嚫鍥句嬌鐢ㄥ悓涓縐嶅潗鏍囪醬銆備笅杈圭殑鍥懼垎鍒槸鍑瑰嚫鍥懼拰澶氳竟褰紝涓ゅ壇鍥鵑兘鏄劇ず浜哢銆乂涓ゆ潯鍚戦噺錛堣瘧鑰呮敞錛氫篃灝辨槸騫抽潰2D鍧愭爣鐨勪袱鏉¤醬錛夛細銆銆銆銆
銆銆鐜板湪浣犲彲浠ョ湅鍒拌璋冭妭鍚庣殑鏂版硶綰垮悜閲忎簡銆傝繖涓皟鑺傚叕寮忓緢綆鍗曪細
銆銆New_Normal = Normal + (U * x_gradient) + (V * y_gradient)
鏈変簡鏂版硶綰垮悜閲忓悗錛屼綘灝卞彲浠ラ氳繃琛ヨ壊娓叉煋鎶鏈綆楀嚭澶氳竟褰㈡瘡涓偣鐨勪寒搴︿簡
|
銆銆鐜板湪鏍規帴鐐瑰瓨鍌ㄤ簡涓栫晫涓殑鍏ㄩ儴欏剁偣銆傝繖鏄紝浠栬繕鏄笉鑳界粰鎴戜滑浠諱綍濂藉錛屽洜涓轟粬榪樹細鐢繪墍鏈夌殑涓滆タ銆傛垜浠兂鎶婅繖涓帴鐐瑰垎鎴?涓儴鍒嗐備竴嬈★紝鎴戜滑鍒掑垎鏃訛紝鏈?涓珛鏂逛綋鍖呭惈閭f渶鍒濈殑鏍規帴鐐圭殑绔嬫柟浣撱傞偅鎰忓懗鐫鏈?涓珛鏂逛綋鍦ㄤ笂闈紝4涓珛鏂逛綋鍦ㄤ笅闈€傝鐪嬩笅鍥撅細
|
銆銆璁頒綇鍥句腑榛勮壊杞粨綰挎病鏈夈?br>銆銆鎴戜滑鍒氬垰鎶婅繖涓笘鐣屽垎鎴?涓儴鍒嗐傛兂璞′竴涓嬪鏋滄垜浠湁2錛?錛?涓儴鍒嗭紝鎴戜滑鐨勪笘鐣屽皢鏄庢牱錛熸垜浠殑鎽勮薄鏈哄湪涓栫晫鐨勪腑闂達紝鍚戠潃鍚庨潰闈犲彸鐨勮钀姐傚鏋滀綘鐪嬭繖浜涚嚎錛屼綘灝嗘敞鎰忓埌鍦∣CTREE涓?涓粨鐐逛腑鐨勭4涓傝繖浜涚粨鐐瑰寘鍚?涓悗闈㈢殑欏跺拰搴曠粨鐐廣傝繖鎰忓懗鐫鎴戜滑鍙敤鐢誨瓨鍌ㄥ湪榪欎簺緇撶偣涓殑欏剁偣銆?/font>
|
銆銆鎴戜滑濡備綍媯嫻嬪嚭鎴戜滑瑕佺敾鐨勭粨鐐癸紵濡傛灉浣犲榪囩牬鐗囨嫞閫夛紙frustum culling),榪欏皢鏄緢綆鍗曠殑銆備綘鑳藉緱鍒拌繖浜涚牬鐗囩殑澶у皬騫舵嫻嬫瘡涓粨鐐癸紝鐪嬩粬鏄惁琚埅鏂垨鍦ㄤ綘鐨勮瑙夌牬鐗囦腑銆傛湁涓涓叧浜庣牬鐗囨嫞閫夌殑鏁欑▼鍦?a >http://www.gametutorials.com. 濡傛灉涓涓珛鏂逛綋鎴柇鐮寸墖錛屾垜浠氨灝嗙敾榪欎簺緇撶偣銆傚湪榪欎釜渚嬪瓙涓紝鎴戜滑鍒囩殑鏁伴噺鏄垜浠渶瑕佺敾鐨?0%銆傝浣忥紝榪欏彧鏄垜浠笘鐣屼腑鐨勪竴涓儴鍒嗐傞儴鍒嗚秺澶氾紝鎴戜滑灝卞皢瓚婄簿紜傚綋鐒訛紝鎴戜滑涓嶄細闇瑕佸お澶氱殑鐐廣備笅闈紝鎴戜滑鏉ョ湅涓涓嬩笅闈㈢殑鍥撅細
|
銆銆鍦ㄤ笂闈㈣繖騫呭浘涓紝浣犲皢鍙戠幇璁稿鐨勪笉鍚屻傝繖涓緥瀛愪腑錛屼笉鏄湪鍘熷鐨?涓珛鏂逛綋鐨勬瘡涓涓粨鐐逛腑寤虹珛8涓柊鐨勭珛鏂逛綋銆傚師濮嬬殑8涓粨鐐圭殑欏跺拰搴曢潰娌℃湁緇嗗垎銆備綘鎬繪槸鎶婁竴涓粨鐐瑰垎鎴?涓垨鏇村鐨勭粨鐐癸紝浣嗘槸錛屽鏋滃湪榪欎釜闈㈡病鏈変笁瑙掑艦鍙互瀛樺偍錛屾垜浠皢蹇借榪欎釜緇撶偣騫朵笉緇欎粬鍒嗛厤鍐呭瓨銆傚鏋滄垜浠繘涓姝ョ殑緇嗗垎錛屾洿澶氱殑緇撶偣灝嗗艦鎴愬師濮嬬殑涓栫晫銆傚鏋滄垜浠彉鎹㈠埌鍙︿竴涓儴鍒嗭紝閭g珛鏂逛綋灝嗙浉浼肩殑鍙樻崲銆備負浜嗚鏄庤繖涓鐐癸紝璇風湅鍥撅細
![]() |
![]() |
銆銆鍦ㄥ浘涓紝鏈変袱涓悆錛屼絾鏄柟鍚戠浉鍙嶃傛敞鎰忓乏杈圭殑閮ㄥ垎錛屼粬灝嗛偅涓栫晫鍒嗘垚2涓粨鐐癸紝涓嶆槸8涓傝繖鏄洜涓虹悆鍙2涓粨鐐廣傝鐪嬪彸杈圭殑鐞冩槸涓嶆槸鍜屽乏杈圭殑寰堢浉浼箋傝繖騫呭浘鍛婅瘔鎴戜滑錛氬彧鏄劇ず闇瑕佺殑閮ㄥ垎緇撶偣銆傚鏋滄病鏈変笁瑙掑艦鍗犵敤絀洪棿錛岀粨鐐瑰皢涓嶄細寤虹珛銆?br>
浣曟椂鍋滄緇嗗垎
銆銆鐜板湪錛屾垜浠槑鐧戒簡濡備綍緇嗗垎錛屼絾鏄垜浠篃闇瑕佺煡閬撴庢牱鍋滄緇嗗垎銆傛湁璁稿鐨勬柟娉曪細
銆銆1銆傚鏋滃綋鏃剁殑涓夎褰㈡暟閲忓皯浜庢垜浠畾涔夌殑鏈澶х殑涓夎褰㈡暟閲忥紝鎴戜滑鍙互鍋滄緇嗗垎褰撳墠鐨勭粨鐐廣備婦涓緥瀛愶紝鎴戜滑瀹氫箟涓夎褰㈢殑鏈澶ф暟閲忎負100銆傝繖鎰忓懗鐫鎴戜滑鍦ㄧ粏鍒嗙粨鐐逛箣鍓嶏紝瑕佹嫻嬩竴涓嬪綋鍓嶄笁瑙掑艦鐨勬繪暟閲忔槸鍚﹀皬浜庢垨絳変簬鎴戜滑瀹氫箟鐨勬渶澶ф暟閲忥紝鐒跺悗鍐嶅仛鍐沖畾銆傚鏋滄暟閲忓皯浜庢垨絳変簬錛屾垜浠皢鍋滄緇嗗垎騫舵寚瀹氳繖浜涗笁瑙掑艦鍒伴偅涓粨鐐廣傝娉ㄦ剰鎴戜滑浠庝笉鎸囧畾浠諱綍涓夎褰㈠埌浠諱綍緇撶偣錛岄櫎闈炰粬鏄湯緇撶偣銆傚鏋滄垜浠垝鍒嗕竴涓粨鐐癸紝鎴戜滑涓嶈兘瀛樺偍涓夎褰㈠埌閭d釜緇撶偣錛屼絾鏄彲浠ュ瓨鍌ㄥ湪浠栫殑瀛愮粨鐐規垨浠栦滑鐨勫瓙緇撶偣涓紝鐢氳嚦鍒頒粬浠殑瀛愪腑錛岀瓑絳夈傚綋鎴戜滑澶嶄範浜嗘庢牱鐢?C鏍戝悗錛屽皢浼氭湁鏇村鐨勪簡瑙c?br>
銆銆2銆傚彟涓涓柟娉曟槸鍦ㄥ仠姝㈢粏鍒嗘椂錛岀湅鎴戜滑鏄惁緇嗗垎鐨勬暟鐩槸鍚﹁秴榪囦簡緇嗗垎鐨勬爣鍑嗐備緥濡傦紝鎴戜滑鍙互鍏堝緩绔嬬粏鍒嗙殑鏍囧噯涓?0錛屽鏋滅粏鍒嗙殑鏁伴噺澶т簬榪欎釜鏍囧噯錛屾垜浠皢鍋滄騫舵寚瀹氳繖浜涘湪绔嬫柟浣撲腑榪欎釜闈㈢殑欏剁偣鍒伴偅涓粨鐐廣傚綋鎴戜滑璇?#8220;澶т簬榪欎釜鏍囧噯”灝辨剰鍛崇潃緇嗗垎鐨勬暟閲忔湁11涓?br>
銆銆3銆傛渶鍚庣殑鏂規硶鏄湅緇撶偣鏁版槸鍚﹁秴榪囩粨鐐瑰彉閲忓畾涔夋椂鐨勫箋備緥濡傦紝鎴戜滑璁劇疆緇撶偣鍙橀噺鐨勫間負500銆傛瘡嬈★紝鎴戜滑寤虹珛涓涓粨鐐癸紝鐩稿簲鐨勭粨鐐規暟澧炲姞1銆傜劧鍚庡湪鎴戜滑姣忔寤虹珛鍙︿竴涓粨鐐規椂錛屾嫻嬩竴涓嬫垜浠綋鍓嶇殑緇撶偣鏁版槸鍚﹁秴榪囩粨鐐瑰彉閲忋傚鏋滅粨鐐規暟涓?01錛屾垜浠皢涓嶄細緇嗗垎榪欎釜緇撶偣錛屼絾鏄寚瀹氫粬鐨勫綋鍓嶉《鐐圭粰浠栥傛垜鑷繁鐢?1鍜?鐨勬柟娉曪紝浣嗘槸1鍜?涔熷緢濂斤紝鍥犱負浣犲彲浠ユ祴璇曚笉鍚岀殑緇嗗垎鐨勬爣鍑嗐?br>
銆
鎬庢牱鐢籓CTREE
銆銆OCTREE寤虹珛鍚庯紝鎴戜滑灝卞彲浠ョ敾鎴戜滑闇瑕佺殑緇撶偣銆傞偅浜涚珛鏂逛綋涓嶆槸鍏ㄩ儴鍖呭惈鍦ㄦ垜浠殑瑙嗚涓殑錛屽彧鏈変竴閮ㄥ垎銆傝繖灝辨槸鎴戜滑涓轟粈涔堣璁$畻姣忎釜緇撶偣鐨勪笁瑙掑艦鐨勬暟閲忥紝濡傛灉鎴戜滑鍙渶瑕佷竴涓粨鐐逛腑鐨勪竴閮ㄥ垎錛岃繖鏍鋒垜浠氨涓嶉渶瑕佺敾鎴愬崈涓婁竾涓笁瑙掑艦銆傛垜浠粠鏍圭洰褰曞紑濮嬬敾OCTREE銆傚浜庢瘡涓粨鐐歸兘瀛樺偍鐫涓涓腑蹇冪偣銆傝繖鏄潪甯稿ソ鐨勶紝姣斿鍦ㄤ笅闈㈣繖涓嚱鏁頒腑錛?br>
銆銆//榪欎釜鍑芥暟鍙栬蛋绔嬫柟浣擄紙X錛孻錛孼錛夌殑涓績鐐瑰拰浠栫殑澶у皬錛坵idth/2)
銆銆bool CubeInFrustum(float x,float y,float z,float size);
銆銆榪欎釜鍑芥暟榪斿洖true or false,鏄敱绔嬫柟浣撴槸鍚﹀湪鐮寸墖涓喅瀹氱殑銆傚鏋滅珛鏂逛綋鍦ㄧ牬鐗囦腑錛屾垜浠皢媯嫻嬫墍鏈変粬鐨勭粨鐐癸紝鐪嬩粬浠槸鍚﹀湪鐮寸墖涓紝鍚﹀垯鎴戜滑灝嗗拷綰︽爲涓殑鏁翠釜鍒嗘灊銆傚綋鎴戜滑寰楀埌浜嗙牬鐗囦腑鐨勭粨鐐癸紝浣嗘槸娌℃湁浠諱綍緇撶偣鍦ㄤ粬涓嬮潰銆傛垜浠兂鐢葷殑欏剁偣瀛樺偍鍦ㄦ湯緇撶偣涓傝浣忥紝鍙湁鏈粨鐐規湁欏剁偣瀛樺偍銆傜湅涓嬮潰鐨勫浘錛?/font>
|
銆銆鏈夐槾褰辯殑绔嬫柟浣撴槸鍦ㄧ牬鐗囦腑銆傜櫧鑹茬殑绔嬫柟浣撲笉鏄湪鐮寸墖涓傝繖閲屾樉紺轟簡緇嗗垎鐨?灞傘?br>
OCTREE 涓殑鍐茬獊
銆銆OCTREE 涓嶆槸鐢ㄤ簬娓叉煋錛屼絾鏄敤浜庡啿紿佹嫻嬪緢濂姐傞殢鐫娓告垙鐨勫彂灞曪紝鍐茬獊媯嫻嬩篃鍦ㄦ敼鍙橈紝浣犲皢涓嶅緱涓嶅湪娓告垙涓栫晫涓繍鐢ㄨ嚜宸辯殑綆楀紡媯嫻嬩綘鐨勮鑹叉垨鐩爣鏄惁鍐茬獊銆備笅闈㈡槸涓浜涘啿紿佹嫻嬬殑渚嬪瓙錛?br>銆銆1銆備綘灝嗗緩绔嬩竴涓嚱鏁板厑璁鎬綘杞?D絀洪棿涓殑鐐瑰埌浣犵殑OCTREE騫惰繑鍥炲湪榪欎釜鐐瑰懆鍥寸殑欏剁偣銆備綘灝嗚漿閫掔殑閭d釜鐐規槸浣犵殑瑙掕壊鍜岀洰鏍囩殑涓績鐐廣傝繖铏界劧鍙互宸ヤ綔涓绔椂闂達紝浣嗗鏋滆繖涓偣闈犺繎涓涓珛鏂逛綋鐨勮竟鏃跺憿錛熶綘鐨勮鑹叉垨鐩爣鍙兘鍜屽彟涓涓珛鏂逛綋鐨勯《鐐圭浉鍐茬獊銆備負浜嗚В鍐寵繖涓棶棰橈紝浣犲皢鍋氫竴浜涗簨鎯呫備綘鍙互杞掕鑹?鐩爣鐨勫崐寰勬垨涓瀹氱殑絀洪棿錛岀劧鍚庢嫻嬪崐寰勬垨涓瀹氱殑絀洪棿鏄惁鍜屽懆鍥寸殑緇撶偣鐩稿啿紿併傝繖鐢變綘鐨勮鑹?鐩爣鐨勫艦鐘跺喅瀹氥備笅闈㈡槸涓浜涘吀鍨嬬殑鍑芥暟錛?br>
銆銆//榪欎釜鍑芥暟鍙栬蛋瑙掕壊/鐩爣錛圶錛孻錛孼錛夌殑涓績鐐瑰茍榪斿洖闈犺繎浠栫殑欏剁偣
銆銆CVector3 *GetVerticesFromPoint(float x,float y,float z);
銆銆//榪欎釜鍑芥暟鍙栬蛋瑙掕壊/鐩爣錛圶錛孻錛孼錛夌殑涓績鐐瑰拰鍗婂緞錛岀劧鍚庤繑鍥炲拰浠栧啿紿佺殑緇撶偣涓殑欏剁偣
銆銆CVector3 *GetVerticesFromPointAndRadius(float x,float y,float z,float radius);
銆銆//榪欎釜鍑芥暟鍙栬蛋瑙掕壊/鐩爣錛圶錛孻錛孼錛夌殑涓績鐐瑰拰绔嬫柟浣撶殑澶у皬錛岀劧鍚庤繑鍥炲拰浠栧啿紿佺殑緇撶偣涓殑欏剁偣
銆銆CVector3 *GetVerticesFromPointAndCube(float x,float y,float z,float size);
銆銆鎴戠浉淇′綘鏈夋洿濂界殑鏂規硶蹇熺殑媯嫻嬶紝鍦ㄨ繖閲屽彧鏄粰浣犱竴鐐瑰熀紜銆?br>
鎬葷粨
銆銆榪欑瘒鏁欑▼鍙槸緇欎綘璁叉埅濡備綍寤虹珛鑷繁鐨凮CTREE銆傚叧浜庤繖綃囨枃绔犱腑鐨勪唬鐮佸湪www.gametutorials.com錛屾垜甯屾湜榪欑瘒鏂囩珷瀵逛綘鏈夌敤銆?br>
涓枃璇戣咃細antking
http://akinggame.gameres.com
榪欑瘒鏂囩珷鐨勮嫳鏂囩増鍦?a >http://www.gametutorials.com/Tutorials/OpenGL/Octree.htm
Ben Humphrey (DigiBen)
Game Programmer
DigiBen@GameTutorials.com
Co-Web Host of www.GameTutorials.com