游戏web编程入门经典里面有哪些经典或者很酷的算法

计算机图形学(22)
我挑一些有趣的算法,希望尽量提及相关算法在游戏中的应用。光栅化(图片来自维基百科)全局光照阴影场景管理动画/物理碰撞测试人工智能(中午吃饭时间写不完,后补)参考[1] Bresenham, Jack E. &Algorithm for computer control of a digital plotter.&&IBM Systems journal&4.1 (1965): 25-30.&[2] Bresenham, Jack. &A linear algorithm for incremental digital display of circular arcs.&Communications of the ACM&20.2 (1977): 100-106.&[3] Catmull, Ed, and Alvy Ray Smith. &3-D transformations of images in scanline order.&&ACM SIGGRAPH Computer Graphics. Vol. 14. No. 3. ACM, 1980.&[4] Pineda, Juan. &A parallel algorithm for polygon rasterization.&&ACM SIGGRAPH Computer Graphics. Vol. 22. No. 4. ACM, 1988.&[5] Sloan, Peter-Pike, Jan Kautz, and John Snyder. &Precomputed radiance transfer for real-time rendering in dynamic, low-frequency lighting environments.&&ACM Transactions on Graphics (TOG). Vol. 21. No. 3. ACM, 2002.&[6] Chen, Hao, and Xinguo Liu. &Lighting and material of Halo 3.&&ACM SIGGRAPH 2008 Games. ACM, 2008.&[7] Mittring, Martin. &Finding next gen: Cryengine 2.&&ACM SIGGRAPH 2007 courses. ACM, 2007.&[8] Ritschel, Tobias, Thorsten Grosch, and Hans-Peter Seidel. &Approximating dynamic global illumination in image space.&&Proceedings of the 2009 symposium on Interactive 3D graphics and games. ACM, 2009.&[9] Kaplanyan, Anton. &Light propagation volumes in cryengine 3.&&ACM SIGGRAPH Courses&7 (2009): 2.&[10] Kaplanyan, Anton, and Carsten Dachsbacher. &Cascaded light propagation volumes for real-time indirect illumination.&&Proceedings of the 2010 ACM SIGGRAPH symposium on Interactive 3D Graphics and Games. ACM, 2010.&[11] Crassin, Cyril, et al. &Interactive indirect illumination using voxel cone tracing.&Computer Graphics Forum. Vol. 30. No. 7. Blackwell Publishing Ltd, 2011.&[12] Crow, Franklin C. &Shadow algorithms for computer graphics.&&ACM SIGGRAPH Computer Graphics. Vol. 11. No. 2. ACM, 1977.&[13] Heidmann, Tim. &Real shadows, real time.&&Iris Universe&18 (1991): 28-31.[14] Carmack, John, &e-mail to Mark Kilgard on Shadow Volume&, 23 May 2000.&[15] Zhang, Fan, et al. &Parallel-split shadow maps for large-scale virtual environments.&&Proceedings of the 2006 ACM international conference on Virtual reality continuum and its applications. ACM, 2006.[16] Zhang, Fan, Hanqiu Sun, and Oskari Nyman. &Parallel-split shadow maps on programmable gpus.&&GPU Gems&3 (2007): 203-237.&[17] Dimitrov, Rouslan. &Cascaded shadow maps.&&Developer Documentation, NVIDIA Corp&(2007).&[18] Donnelly, William, and Andrew Lauritzen. &Variance shadow maps.&Proceedings of the 2006 symposium on Interactive 3D graphics and games. ACM, 2006.&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:523016次
积分:9268
积分:9268
排名:第1929名
原创:372篇
转载:57篇
评论:124条
(3)(1)(5)(4)(3)(14)(4)(2)(8)(4)(2)(6)(5)(6)(4)(18)(12)(7)(2)(10)(10)(4)(13)(25)(22)(10)(11)(21)(4)(7)(12)(28)(57)(27)(7)(14)(23)(7)(7)(1)我挑一些有趣的算法,希望尽量提及相关算法在游戏中的应用。&br&&br&&b&光栅化&/b&&br&&ul&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Bresenham%2527s_line_algorithm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Bresenham's line algorithm&i class=&icon-external&&&/i&&/a& [1]:经典的绘画直线算法,后来还可以稍作修改用于绘画圆弧[2],都不用三角函数或除数,只需用整数加法、减法和乘法。 &/li&&/ul&&img src=&/b7cb85217babb238ac6c_b.jpg& data-rawwidth=&592& data-rawheight=&401& class=&origin_image zh-lightbox-thumb& width=&592& data-original=&/b7cb85217babb238ac6c_r.jpg&&&br&&ul&&li&Perspective-Correct Texture Mapping [3]:透视正确的光栅化纹理贴图算法是1980才出现的。第一代Quake引擎引入后,才开始支持不垂直的墙、不水平的地面天花。&/li&&/ul&&img src=&/24681fdb28cfc1e4342f_b.jpg& data-rawwidth=&1000& data-rawheight=&352& class=&origin_image zh-lightbox-thumb& width=&1000& data-original=&/24681fdb28cfc1e4342f_r.jpg&&(图片来自维基百科)&br&&br&&ul&&li&Polygon Rasterization with Edge Function [4]:Bresenham算法如果用来画多边形,两个多边形的共边会被重绘。后来发明了使用简单的edge function去解决这个问题,而且适合并行的硬件实现。现在的GPU都是使用这个算法。&/li&&/ul&&img src=&/bc6a762cbbfeb_b.jpg& data-rawwidth=&492& data-rawheight=&368& class=&origin_image zh-lightbox-thumb& width=&492& data-original=&/bc6a762cbbfeb_r.jpg&&&br&&br&&b&全局光照&/b&&br&&ul&&li&Precomputed Radiance Transfer (PRT) with Spherical Harmonics(SH)[5]:储存静态环境对于各个方向光源的漫反射数据,可以实现动态低频光源的全局光照效果。这种表示方式非常神奇。Halo 3也使用到这种技术[6]。&/li&&/ul&&img src=&/4225d10efdd85cb81c6ef6fe855b14a3_b.jpg& data-rawwidth=&694& data-rawheight=&295& class=&origin_image zh-lightbox-thumb& width=&694& data-original=&/4225d10efdd85cb81c6ef6fe855b14a3_r.jpg&&&br&&ul&&li&Screen-space Ambient Occlusion (SSAO)[7]:Crytek提出的首个屏幕空间环境光遮蔽算法,之后引来大量的研究及改进算法。也有用类似的概念去做近距离的反射,如SSDO[8]。&/li&&/ul&&img src=&/1faa1a94f23aa9b4b1eb_b.jpg& data-rawwidth=&798& data-rawheight=&316& class=&origin_image zh-lightbox-thumb& width=&798& data-original=&/1faa1a94f23aa9b4b1eb_r.jpg&&&br&&ul&&li&Light Propagation Volume (LPV)[9]:Crytek提出的首个动态全局光照算法,不需要预计算。但要在体积数据中计算传播,性能较慢,所以之后再优化成 Cascaded LPV [10]。&br&&/li&&/ul&&img src=&/cda20e301ccbaa6d3b823b22_b.jpg& data-rawwidth=&1198& data-rawheight=&377& class=&origin_image zh-lightbox-thumb& width=&1198& data-original=&/cda20e301ccbaa6d3b823b22_r.jpg&&&br&&ul&&li&Voxel Cone Tracing [11]:也是不需要预计算的动态全局光照算法。把场景动态生成层阶式的体素数据(像mipmap那样的pre-filtering),从光源视角计算直接光照,然后逐像素追踪这组数据获取非直接光照。结果比LPV精确,也可以做到光泽反射(glossy reflection)。&/li&&/ul&&img src=&/a5bc6edfaf47c2be14ba70_b.jpg& data-rawwidth=&1086& data-rawheight=&333& class=&origin_image zh-lightbox-thumb& width=&1086& data-original=&/a5bc6edfaf47c2be14ba70_r.jpg&&&br&&b&阴影&/b&&br&&ul&&li&Shadow Volume [12]:阴影体积是1977年发表的阴影技术,在屏幕空间光栅化阴影体积,可准确判断每个屏幕像素是否在阴影之内。可以处理平行光源和点光源的阴影。1991年[13]讲述如何用stencil buffer来实现此算法,适合在图形加速硬件(当时还没有所谓GPU)上使用。但很多人发现,如果摄像机在阴影体积内,就会出错。在年有多人发现一种解决方法,需要把John Carmack在2000年的电邮[14]中提及这个想法,后来成为2004年《毁灭战士3(Doom 3)》引擎的重要特徵,因他把这项技术发扬光大,即使他非首个发明人,此项技术通常被称为Carmack's Reverse。&/li&&/ul&&img src=&/c0aefec2d7cab_b.jpg& data-rawwidth=&461& data-rawheight=&346& class=&origin_image zh-lightbox-thumb& width=&461& data-original=&/c0aefec2d7cab_r.jpg&&&br&&br&&ul&&li&Parallel Split Shadow Map (PSSM) [15][16] / Cascaded Shadow Map(CSM)[17]:虽然Shadow Volume很吸引,但它需要大量的内存频宽,而且通常不能实现软阴影。后来大部分游戏改为使用Shadow Map(阴影贴图),这更适合GPU,并且可以通过多次采样(Percentage Closer Filtering, PCF)来实现软阴影。然而,阴影贴图也有许多问题,例如远近景物都采用同一张纹理,就会令到近景的精度不足,出现锯齿。2006年香港中文大学的博士生Fan Zhang等人发表了一种 PSSM 算法 [15],为不同距离的场景渲染多张阴影贴图,在采样的时候按距离决定使用那一张。这个方法的变种CSM,在切割上和PSSM有点差异,被广泛使用于现时大部分游戏引擎中。&/li&&/ul&&img src=&/dba24fba68e2ff8eb5a5ab819c50a1a5_b.jpg& data-rawwidth=&511& data-rawheight=&327& class=&origin_image zh-lightbox-thumb& width=&511& data-original=&/dba24fba68e2ff8eb5a5ab819c50a1a5_r.jpg&&&br&&ul&&li&Variance Shadow Map(VSM)[18]:之前谈到用PCF做软阴影,它的坏处就是要做多次采样。那么可否把阴影贴图直接模糊化来实现软阴影?答案是否定的。但是在2006年有学者发表了VSM,它是一种用统计方式来逼近软阴影的效果。 &a href=&/question//answer/& class=&internal&&如何推导方差阴影贴图(variance shadow map, VSM) ? - Milo Yip 的回答&/a&&/li&&/ul&&img src=&/6bb2fb0efc1d_b.jpg& data-rawwidth=&856& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&856& data-original=&/6bb2fb0efc1d_r.jpg&&&br&&b&场景管理&/b&&br&&ul&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Binary_space_partitioning& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Binary Space Partitioning&i class=&icon-external&&&/i&&/a& (BSP)&br&&/li&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Portal_rendering& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Portal rendering&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Quadtree& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Quadtree&i class=&icon-external&&&/i&&/a&、&a href=&///?target=http%3A//en.wikipedia.org/wiki/Octree& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Octree&i class=&icon-external&&&/i&&/a&:&a href=&/question//answer/?group_id=696704& class=&internal&&游戏场景管理的八叉树算法是怎样的? - Milo Yip 的回答&/a&&/li&&li&Potential Visibility Set (PVS)&/li&&li&Occlusion Culling by Software Rasterization&/li&&/ul&&br&&b&动画/物理&/b&&br&&ul&&li&Particle System&/li&&li&Smoothed Particle Hydrodynamics(SPH)&/li&&li&Curl Noise&/li&&li&Dual Quaternion Skinning&/li&&/ul&&br&&b&碰撞测试&/b&&br&&ul&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Hyperplane_separation_theorem& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Hyperplane separation theorem&i class=&icon-external&&&/i&&/a& (或称separating axis theorem/SAT):凸形状相交测试的基本原理。在&a href=&/question//answer/& class=&internal&&怎样判断平面上一个矩形和一个圆形是否有重叠? - Milo Yip 的回答&/a&中,其实背后也是使用了SAT。&br&&/li&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Gilbert%25E2%Johnson%25E2%Keerthi_distance_algorithm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Gilbert-Johnson-Keerthi distance algorithm&i class=&icon-external&&&/i&&/a& (GJK距离算法):计算两个凸形状的距离(可用于相交测试)&br&&/li&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Sweep_and_prune& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sweep and prune&i class=&icon-external&&&/i&&/a&:用于broad phase碰撞检测,找出物体AABB是否相交。对于时空上连续的物体运动,算法最坏O(n^2)、最好O(n)。&br&&/li&&/ul&&br&&b&人工智能&/b&&br&&ul&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Minimax& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Minimax&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Alpha%25E2%beta_pruning& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Alpha-Beta Pruning&i class=&icon-external&&&/i&&/a&&br&&/li&&li&A* path finding&/li&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Dijkstra%2527s_algorithm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dijkstra's algorithm&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Finite-state_machine& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Finite-state machine&i class=&icon-external&&&/i&&/a&&br&&/li&&li&Behavior Tree&/li&&/ul&&br&(中午吃饭时间写不完,后补)&br&&br&&b&参考&/b&&br&&br&[1] Bresenham, Jack E. &Algorithm for computer control of a digital plotter.& &i&IBM Systems journal&/i& 4.1 (1965): 25-30. &a href=&///?target=http%3A//www.cse.iitb.ac.in/%7Eparagc/teaching/2011/cs475/papers/bresenham_line.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&cse.iitb.ac.in/~paragc/&/span&&span class=&invisible&&teaching/2011/cs475/papers/bresenham_line.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[2] Bresenham, Jack. &A linear algorithm for incremental digital display of circular arcs.& &i&Communications of the ACM&/i& 20.2 (1977): 100-106. &a href=&///?target=http%3A//www.cse.iitb.ac.in/%7Eparagc/teaching/2014/cs475/papers/bresenham_circle.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&cse.iitb.ac.in/~paragc/&/span&&span class=&invisible&&teaching/2014/cs475/papers/bresenham_circle.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[3] Catmull, Ed, and Alvy Ray Smith. &3-D transformations of images in scanline order.& &i&ACM SIGGRAPH Computer Graphics&/i&. Vol. 14. No. 3. ACM, 1980. &a href=&///?target=http%3A///Papers/CG/2pass80.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/Papers/CG/2&/span&&span class=&invisible&&pass80.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[4] Pineda, Juan. &A parallel algorithm for polygon rasterization.& &i&ACM SIGGRAPH Computer Graphics&/i&. Vol. 22. No. 4. ACM, 1988. &a href=&///?target=http%3A//people.csail.mit.edu/ericchan/bib/pdf/p17-pineda.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&people.csail.mit.edu/er&/span&&span class=&invisible&&icchan/bib/pdf/p17-pineda.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[5] Sloan, Peter-Pike, Jan Kautz, and John Snyder. &Precomputed radiance transfer for real-time rendering in dynamic, low-frequency lighting environments.& &i&ACM Transactions on Graphics (TOG)&/i&. Vol. 21. No. 3. ACM, 2002. &a href=&///?target=http%3A//www1.cs.columbia.edu/%7Eravir/6998/papers/p527-sloan.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&www1.cs.columbia.edu/~r&/span&&span class=&invisible&&avir/6998/papers/p527-sloan.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[6] Chen, Hao, and Xinguo Liu. &Lighting and material of Halo 3.& &i&ACM SIGGRAPH 2008 Games&/i&. ACM, 2008. &a href=&///?target=http%3A///wordpress/media/08-Chen-Lighting_and_Material_of_Halo3.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/wordp&/span&&span class=&invisible&&ress/media/08-Chen-Lighting_and_Material_of_Halo3.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[7] Mittring, Martin. &Finding next gen: Cryengine 2.& &i&ACM SIGGRAPH 2007 courses&/i&. ACM, 2007. &a href=&///?target=http%3A///wordpress/media/2012/10/Chapter8-Mittring-Finding_NextGen_CryEngine2.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/wordp&/span&&span class=&invisible&&ress/media/2012/10/Chapter8-Mittring-Finding_NextGen_CryEngine2.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[8] Ritschel, Tobias, Thorsten Grosch, and Hans-Peter Seidel. &Approximating dynamic global illumination in image space.& &i&Proceedings of the 2009 symposium on Interactive 3D graphics and games&/i&. ACM, 2009. &a href=&///?target=https%3A//people.mpi-inf.mpg.de/%7Eritschel/Papers/SSDO.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&people.mpi-inf.mpg.de/~&/span&&span class=&invisible&&ritschel/Papers/SSDO.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[9] Kaplanyan, Anton. &Light propagation volumes in cryengine 3.& &i&ACM SIGGRAPH Courses&/i& 7 (2009): 2. &a href=&///?target=http%3A///download/Light_Propagation_Volumes.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/download/Lig&/span&&span class=&invisible&&ht_Propagation_Volumes.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[10] Kaplanyan, Anton, and Carsten Dachsbacher. &Cascaded light propagation volumes for real-time indirect illumination.& &i&Proceedings of the 2010 ACM SIGGRAPH symposium on Interactive 3D Graphics and Games&/i&. ACM, 2010. &a href=&///?target=http%3A//www.vis.uni-stuttgart.de/%7Edachsbcn/download/lpv.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&vis.uni-stuttgart.de/~d&/span&&span class=&invisible&&achsbcn/download/lpv.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[11] Crassin, Cyril, et al. &Interactive indirect illumination using voxel cone tracing.&&i&Computer Graphics Forum&/i&. Vol. 30. No. 7. Blackwell Publishing Ltd, 2011. &a href=&///?target=https%3A///sites/default/files/publications/GIVoxels-pg2011-authors.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/sit&/span&&span class=&invisible&&es/default/files/publications/GIVoxels-pg2011-authors.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[12] Crow, Franklin C. &Shadow algorithms for computer graphics.& &i&ACM SIGGRAPH Computer Graphics&/i&. Vol. 11. No. 2. ACM, 1977. &a href=&///?target=http%3A//excelsior.biosci.ohio-state.edu/%7Ecarlson/history/PDFs/crow-shadows.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&excelsior.biosci.ohio-state.edu&/span&&span class=&invisible&&/~carlson/history/PDFs/crow-shadows.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[13] Heidmann, Tim. &Real shadows, real time.& &i&Iris Universe&/i& 18 (1991): 28-31.&br&[14] Carmack, John, &e-mail to Mark Kilgard on Shadow Volume&, 23 May 2000. &a href=&///?target=http%3A//web.archive.org/web/35/http%3A///attach/6832& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&web.archive.org/web/200&/span&&span class=&invisible&&//attach/6832&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[15] Zhang, Fan, et al. &Parallel-split shadow maps for large-scale virtual environments.& &i&Proceedings of the 2006 ACM international conference on Virtual reality continuum and its applications&/i&. ACM, 2006.&br&[16] Zhang, Fan, Hanqiu Sun, and Oskari Nyman. &Parallel-split shadow maps on programmable gpus.& &i&GPU Gems&/i& 3 (2007): 203-237. &a href=&///?target=http%3A//http./GPUGems3/gpugems3_ch10.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GPU Gems 3 - Chapter 10. Parallel-Split Shadow Maps on Programmable GPUs&i class=&icon-external&&&/i&&/a&&br&[17] Dimitrov, Rouslan. &Cascaded shadow maps.& &i&Developer Documentation, NVIDIA Corp&/i& (2007). &a href=&///?target=http%3A//www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%2520Computer%2520Graphics/cascaded_shadow_maps.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&cse.chalmers.se/edu/yea&/span&&span class=&invisible&&r/2011/course/TDA361/Advanced%20Computer%20Graphics/cascaded_shadow_maps.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&[18] Donnelly, William, and Andrew Lauritzen. &Variance shadow maps.&&i&Proceedings of the 2006 symposium on Interactive 3D graphics and games&/i&. ACM, 2006. &a href=&///?target=http%3A//www.punkuser.net/vsm/vsm_paper.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&punkuser.net/vsm/vsm_pa&/span&&span class=&invisible&&per.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&
我挑一些有趣的算法,希望尽量提及相关算法在游戏中的应用。 光栅化
[1]:经典的绘画直线算法,后来还可以稍作修改用于绘画圆弧[2],都不用三角函数或除数,只需用整数加法、减法和乘法。 Perspective-Correct Texture Mapping …
之前在公司内做的培训计划中,基础内容大概有以下这些:&br&&br&三维几何学基础:&br&&ol&&li&三维坐标系统&br&&/li&&li&点与矢量&br&&/li&&li&矩阵与几何变换&br&&/li&&li&四元数与三维旋转&br&&/li&&/ol&&br&实时渲染管道:&br&&ol&&li&应用阶段(场景管理、可见性剔除、分组排序、提交图元)&br&&/li&&li&几何阶段(顶点着色、图元组装、面向剔除、三角形裁剪、透视除法、视区变换)&br&&/li&&li&光栅化阶段(扫瞄转换、scissor/stencil/alpha 测试、alpha 混合)&br&&/li&&/ol&&br&游戏中的光照与阴影:&br&&ol&&li&实时光照分类(正向渲染、延迟渲染、Tile 正向/延迟渲染)&/li&&li&局部光照中的光源(环境光、方向光、点光、聚光、cookie)&br&&/li&&li&阴影(平面阴影、阴影体积、阴影贴图、PCF、VSM、CSM)&br&&/li&&li&全局光照(光照贴图、幅照度环境贴图、球谐函数)&br&&/li&&/ol&&br&材质着色原理与实践:&br&&ol&&li&材质反射模型(渲染方程、BRDF、Lambertian、Phong、Blinn-Phong)&br&&/li&&li&材质着色器编程(环境光、环境遮蔽、发光物体、贴图采样、环境贴图、法线贴图、轮廓光、纹理坐标动画)&br&&/li&&li&特殊着色器(卡通渲染、Kajiya-Kay、??)&br&&/li&&/ol&&br&由浅入深可先看[1],然后[2]。数学方面可参考[3]。&br&&br&[1] 《游戏引擎架构》,叶劲峰译,电子工业出版社,2014&br&[2] Akenine-M?ller, Tomas, Eric Haines, and Naty Hoffman. Real-time rendering Third Edition, CRC Press, 2008.&br&[3] Lengyel, Eric. Mathematics for 3D game programming and computer graphics. Cengage Learning, 2012.
之前在公司内做的培训计划中,基础内容大概有以下这些: 三维几何学基础: 三维坐标系统 点与矢量 矩阵与几何变换 四元数与三维旋转 实时渲染管道: 应用阶段(场景管理、可见性剔除、分组排序、提交图元) 几何阶段(顶点着色、图元组装、面向剔除、三角形…
实现个简单的固定渲染管线软渲染器不算复杂,大家都说了那么多了,我来个更短的吧,差不多700行代码就可以搞定了。之所以很多人用 D3D用的很熟,写软渲染却坑坑洼洼,主要是现在大部分讲图形的书,讲到透视投影时就是分析一下透视变换矩阵如何生成,顶点如何计算就跳到其他讲模型或者光照的部分了。&br&&br&因为今天基本上是直接用 D3D 或者 OGL,真正光栅化的部分不了解也不影响使用,所以大部分教材都直接跳过了一大段,摄像机坐标系如何转换?三角形如何生成?CVV边缘如何检测?四维坐标如何裁剪?边缘及步长如何计算?扫描线该如何绘制?透视纹理映射具体代码该怎么写?framebuffer zbuffer 到底该怎么用?z-test 到底是该 test z 还是 w 还是 1/z 还是 1/w ?这些都没讲。&br&&br&早年培训学生时候,我花两天时间写的一个 DEMO,今天拿出来重新调整注释一下,性能和功能当然比不过高大上的 Salviar。但一般来讲,工程类项目代码不容易阅读,太多边界情况和太多细节优化容易让初学者迷失,这个 mini3d 的项目不做任何优化,主要目的就是为了突出主干:&br&&br&源代码:&a href=&///?target=https%3A///skywind3000/mini3d& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&skywind3000/mini3d · GitHub&i class=&icon-external&&&/i&&/a&&br&可执行:&a href=&///?target=http%3A//www.skywind.me/mw/images/c/c8/Mini3d.7z& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&skywind.me/mw/images/c/&/span&&span class=&invisible&&c8/Mini3d.7z&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&操作方式:左右键旋转,前后键前进后退,空格键切换模式,ESC退出。&br&&br&&b&特性介绍:&/b&&br&&ul&&li&单个文件:源代码只有一个 mini3d.c,单个文件实现所有内容,易阅读。&br&&/li&&li&独立编译:没有任何第三方库依赖,没有复杂的工程目录。&br&&/li&&li&模型标准:标准 D3D 坐标模型,左手系 + WORLD/VIEW/PROJECTION 三矩阵&br&&/li&&li&简单裁剪:简单 CVV 裁剪&br&&/li&&li&纹理支持:最大支持 1024 x 1024 的纹理&br&&/li&&li&深度缓存:使用深度缓存判断图像前后&/li&&li&透视贴图:透视纹理映射以及透视色彩填充&br&&/li&&li&实现精简:渲染部分只有 700行, 模块清晰,主干突出。&br&&/li&&li&详细注释:主要代码详细注释&br&&/li&&/ul&&br&&b&截图效果:&/b&&br&&br&透视纹理映射&br&&img src=&/6c43d3fdfc195ed35fe788_b.png& data-rawwidth=&816& data-rawheight=&638& class=&origin_image zh-lightbox-thumb& width=&816& data-original=&/6c43d3fdfc195ed35fe788_r.png&&&br&色彩填充&br&&img src=&/be90d1cc702e84a7df4e6ce_b.png& data-rawwidth=&816& data-rawheight=&638& class=&origin_image zh-lightbox-thumb& width=&816& data-original=&/be90d1cc702e84a7df4e6ce_r.png&&&br&线框图&br&&img src=&/17de0efb5d341de3e7dba28d2d0c3066_b.png& data-rawwidth=&816& data-rawheight=&638& class=&origin_image zh-lightbox-thumb& width=&816& data-original=&/17de0efb5d341de3e7dba28d2d0c3066_r.png&&&br&&b&阅读要求:&/b&&br&&ul&&li&看过并了解 D3D / OGL的矩阵变换。&br&&/li&&li&用 D3D / OGL 完成过简单程序。&/li&&/ul&&br&&b&实现说明:&/b&&br&&ul&&li&transform:实现坐标变换,和书本手册同&br&&/li&&li&vertex: 如何定义顶点?如何定义边?如何定义扫描线?如何定义渲染主体(trapezoid)?&br&&/li&&li&device: 设备,如何 projection,如何裁剪和归一化,如何切分三角形,如何顶点排序?&br&&/li&&li&trapezoid:如何生成 trape,如何生成边,如何计算步长,如何计算扫描线&br&&/li&&li&scanline:如何绘制扫描线,如何透视纠正,如何使用深度缓存,如何绘制&br&&/li&&/ul&&br&&b&基础练习:先前给学生的作业&/b&&br&&ul&&li&增加背面剔除&/li&&li&增加简单光照&/li&&li&提供更多渲染模式&/li&&li&实现二次线性差值的纹理读取&/li&&/ul&&br&&b&扩展练习:给有余力的学生&/b&&br&&ul&&li&推导并证明程序中用到的所有几何知识&/li&&li&优化顶点计算性能&br&&/li&&li&优化 draw_scanline 性能&/li&&li&从 BMP/TGA 文件加载纹理&br&&/li&&li&载入 BSP 场景并实现漫游&/li&&/ul&&br&&b&其他内容&/b&&br&&br&当年还用不了 D3D 和 OGL ,开发游戏,做图形实现软件渲染是必备技能,当年机型差,连浮点数都用不了,要用定点数来计算,矩阵稍不注意就越界了。计算透视纠正还是一个比较昂贵的工作,更多游戏使用仿射纹理绘制,只是把离屏幕近的多边形切割成更小的三角形,让人看起来没有那么明显。即便到了 Quake 年代,计算 1/z 的除法也只是四个点才算一次(经过精确计算CPU周期,绘制四个点时下一个点的 1/z刚好算完),Quake 的四个点内也还是仿射纹理绘制。。。。&br&&br&那时显卡没普及,光软件渲染器的优化就是一个无底洞,今天有了 OGL/D3D和显卡,人的精力才能充分集中在更高层次的场景组织、层次细节、动态光照等功能上。然而有空的时候,花个一周时间坐下来了解一下这部分的大概原理,推导所用到的数学模型,也能帮助大家更好的理解底层运行机制,写出更加优化的代码来。&br&&br&PS:光线跟踪版本的软件渲染,考虑光照的话,简单实现起来差不多 500 行,比这个要简单一些。各位有兴趣也可以尝试一下,就是简单渲染个立方体足够了。&br&&br&----------&br&更新:8.12 有朋友跟我说他加上了光照(支持同时N个平行光源)和二次线性插值,效果还行:&br&&img src=&/37dc745ad78c03a9d602c9_b.png& data-rawwidth=&816& data-rawheight=&638& class=&origin_image zh-lightbox-thumb& width=&816& data-original=&/37dc745ad78c03a9d602c9_r.png&&
实现个简单的固定渲染管线软渲染器不算复杂,大家都说了那么多了,我来个更短的吧,差不多700行代码就可以搞定了。之所以很多人用 D3D用的很熟,写软渲染却坑坑洼洼,主要是现在大部分讲图形的书,讲到透视投影时就是分析一下透视变换矩阵如何生成,顶点如…
&b&历史方面:&/b&&br&&br&《大话西游》用的脚本语言是微软的JScript(JavaScript的一种方言),维护不便bug多,受系统IE版本的影响兼容性差。所以2002年网易开发《大话西游II》时,决定在客户端内嵌别的脚本语言。当时该项目技术负责人云风认为要挑不出名的语言,让做外挂的人搞不懂(《大话西游》一代被外挂《月光宝盒》搞死了),于是就选择了Lua 4.0。&br&&br&云风在九十年代就开发游戏引擎并建设个人网站(&a href=&///?target=http%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&云风工作室&i class=&icon-external&&&/i&&/a&),在游戏开发领域声望高。网易《大话西游II》是首个在市场上取得成功的国产网络游戏。所以后来国内游戏开发行业纷纷受此影响采用Lua.&br&&br&&b&技术方面:&/b&&br&&br&现在,2013年,Lua和其他流行脚本语言Python、JavaScript各分秋色:&br&&ul&&li&语言规范精简、运行时库小。其创始人称Lua是穿过针孔的语言(&a href=&///?target=http%3A//queue.acm.org/detail.cfm%3Fid%3D1983083& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Passing a Language through the Eye of a Needle&i class=&icon-external&&&/i&&/a&),他加入的任何语言特性都能用C API简单的调用。&/li&&li&易于创建受限环境,C语言一端可以控制暴露给Lua脚本的任何功能。我猜这也是《魔兽世界》的插件语言选用Lua的原因。&/li&&li&性能方面,虽然仍然比Python快,但不如V8(谷歌的JavaScript实现)。&/li&&li&&b&协程&/b&对于编写并行逻辑,非常有用。而Python、JavaScript都不支持协程,只有StacklessPython、call/cc等方言支持类似功能。&br&&/li&&li&Lua的&b&元表&/b&很有用。不过我听说Python也支持类似的功能。JavaScript的&b&原型链&/b&则只是元表功能的十分之一左右吧。&/li&&li&Lua支持&b&弱引用&/b&。对于上层逻辑用处不大。但对于底层引擎管理资源,超级有用。JavaScript不支持弱引用;Python支持。&/li&&li&Lua有个非官方实现,Luajit,性能不错。&/li&&/ul&但是回到2002年,Lua和JScript相比,优势很大。&br&&ul&&li&与C/C++交互方便。Lua的C API简洁正交,而JScript的COM接口臃肿繁杂。&/li&&li&高性能。Lua虚拟机实现简单高效,比起JScript,又快又省内存。&/li&&li&开源。云风为了防外挂,后来修改了《大话西游II》的Lua字节码格式,让官方的Lua虚拟机无法兼容《大话西游II》的Lua字节码。如果采用不开源的JScript,就不可能自己修改虚拟机和编译器了。&/li&&/ul&不过很遗憾,《大话西游II》的Lua 4.0并不支持协程。&br&&br&------------------------------------------------------------------------&br&&br&最后我想说,开发游戏并不一定要脚本语言。C/C++这类&b&低级语言&/b&写逻辑太不方便,脚本语言能弥补这个缺陷。但如果你的项目主要语言不是C/C++,而是D、Java、Scala、Haskell、Go、C#、F#等性能接近C/C++的&b&高级语言&/b&,那么你就不需要额外的脚本语言。王垠写过&a href=&///?target=http%3A//.cn/s/blog_5d90e82f0101jv17.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&什么是“脚本语言”&i class=&icon-external&&&/i&&/a&,和我的看法基本相同。&br&&br&当然还有Haxe这种既可以编译成脚本语言,也可以编译成C++的古怪语言来捣蛋。
历史方面: 《大话西游》用的脚本语言是微软的JScript(JavaScript的一种方言),维护不便bug多,受系统IE版本的影响兼容性差。所以2002年网易开发《大话西游II》时,决定在客户端内嵌别的脚本语言。当时该项目技术负责人云风认为要挑不出名的语言,让做外…
&a href=&///?target=http%3A///& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&&/span&&span class=&invisible&&/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&game programning patterns能帮助你。amazon五星好评,web版免费,厚道良心,亚马逊5星好评。&br&&br&&img data-rawwidth=&750& data-rawheight=&1334& src=&/c743ec674e4c0176d60e_b.png& class=&origin_image zh-lightbox-thumb& width=&750& data-original=&/c743ec674e4c0176d60e_r.png&&
game programning patterns能帮助你。amazon五星好评,web版免费,厚道良心,亚马逊5星好评。
吐槽第一名答案, &a data-hash=&0effe9e423faad125fa9c6a& href=&///people/0effe9e423faad125fa9c6a& class=&member_mention& data-editable=&true& data-title=&@Vinjn张静& data-tip=&p$b$0effe9e423faad125fa9c6a& data-hovercard=&p$b$0effe9e423faad125fa9c6a&&@Vinjn张静&/a& 回答的 $1 gesture recognizer 是比较好的解法。&br&&br&洒家也有一个类似的算法,借鉴了原始手写ocr的思路来实现的。其实是写在 $1 gesture recognizer 之前的,但没有 $1 gesture recognizer 归纳得好,作者jacob还是我偶像。&br&&br&&a href=&///?target=http%3A//haojian.github.io/gesture_recognition/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Realtime Gesture recognition&i class=&icon-external&&&/i&&/a&&br&&br&把所有的笔画定义了个8个方向,然后将B的笔画可以分解成一个字符串。然后当人在触摸屏上画出一个符号时,也将它分解成8个方向的字符串,最后比较两个字符串的距离就能判断出和不同符号的近似度。&br&&img src=&/5c8f99d6dfe803d783e215e131cb9f10_b.jpg& data-rawwidth=&527& data-rawheight=&167& class=&origin_image zh-lightbox-thumb& width=&527& data-original=&/5c8f99d6dfe803d783e215e131cb9f10_r.jpg&&&br&实现起来也很简单,第一步去噪,因为不同触摸屏的采样频率不同。&br&&img src=&/cd33fdcf5a5f58b1c15ad0ffbf44300a_b.jpg& data-rawwidth=&376& data-rawheight=&188& class=&content_image& width=&376&&&br&&br&第二步把去噪后的数据转换成方向序列,把之前得到的点换成方向序列,并把方向序列归纳到之前定义的8个方向中去。&br&&img src=&/cd33fdcf5a5f58b1c15ad0ffbf44300a_b.jpg& data-rawwidth=&376& data-rawheight=&188& class=&content_image& width=&376&&&br&第三步把连续一致的方向合并。&br&&img src=&/dd4e09658bfd902a0b72cb_b.jpg& data-rawwidth=&263& data-rawheight=&156& class=&content_image& width=&263&&&br&第四步把小片段的移动略去,最后就能得出其实是画了一个凹的形状。&br&&img src=&/e8f5cd42c_b.jpg& data-rawwidth=&470& data-rawheight=&170& class=&origin_image zh-lightbox-thumb& width=&470& data-original=&/e8f5cd42c_r.jpg&&&br&这个算法的厉害之处是可以实时识别,画到一半也能判断出来。&br&&a href=&///?target=http%3A//haojian.github.io/gesture_recognition/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Realtime Gesture recognition&i class=&icon-external&&&/i&&/a& 源代码和demo都在上面了。&br&&br&&br&&br&===============&br&吐槽时间。。。。&br&刚写完论文累死了,来吐槽。。。。&br&原来大家都觉得第一名不靠谱,怎么木有人把我顶上去!我眼红着那300多票呢!&br&&br&我来告诉你为什么第一名不靠谱,&br&&br&首先ocr拿来做gesture recognition是不对滴!&br&ocr是一个比gesture recognition更难的问题,因为ocr得到的是一张图片,所有点并没有时间戳,而手势识别时,每一下移动是有时间戳的,所以是知道“怎么画出来”这个额外信息的。&br&&br&其次ocr不是这么解释的。&br&ocr问题的重点是怎么选择特征,比如知名的uci 数据集就有以下这些特征量:&br&&div class=&highlight&&&pre&&code class=&language-text&&
1. lettr capital letter (26 values from A to Z)
2. x-box horizontal position of box (integer)
3. y-box vertical position of box (integer)
4. width width of box
height of box
6. onpix total # on pixels
7. x-bar mean x of on pixels in box (integer)
8. y-bar mean y of on pixels in box (integer)
9. x2bar mean x variance
10. y2bar mean y variance
11. xybar mean x y correlation
12. x2ybr mean of x * x * y
13. xy2br mean of x * y * y
14. x-ege mean edge count left to right (integer)
15. xegvy correlation of x-ege with y (integer)
16. y-ege mean edge count bottom to top (integer)
17. yegvx correlation of y-ege with x (integer)
&/code&&/pre&&/div&&br&最后贝叶斯讲得也不好。&br&&br&感觉挑小朋友刺也挺不要脸的,其实我就是眼红那300多票。。。
吐槽第一名答案,
回答的 $1 gesture recognizer 是比较好的解法。 洒家也有一个类似的算法,借鉴了原始手写ocr的思路来实现的。其实是写在 $1 gesture recognizer 之前的,但没有 $1 gesture recognizer 归纳得好,作者jacob还是我偶像。
首先澄清引擎这个概念。 &a data-hash=&8da5e5ee5fb135e453d0& href=&///people/8da5e5ee5fb135e453d0& class=&member_mention& data-tip=&p$b$8da5e5ee5fb135e453d0& data-hovercard=&p$b$8da5e5ee5fb135e453d0&&@kubisoft&/a&提到引擎只会带来更出色的画面、更细腻的动画,是不全面的。这么说的话只是说到了“渲染引擎”而已。一个游戏,还有物理引擎、AI引擎等很重要的几个引擎。而所谓的引擎,很大的程度上,是一个”专注于某个功能的模块“。软件中有很多的模块,为什么只有渲染、物理等才被成为引擎,跟汽车的引擎一样,因为这个模块可能比较核心,在所有的组件中功能更有决定性,所以才被叫做引擎。有人可能会说,现在的游戏,决定性的是游戏的内容、逻辑,那为什么没有逻辑引擎这个说法。这个的关键之处在于,逻辑不能成为一个很通用的模块。所以,才没有逻辑引擎这个说法。&br&&br&另外,严格的说来,引擎和解决方案是两个概念,对unity3d来说,即使官方也用engine的字眼,但是,如果硬要用引擎(engine)和解决方案(solution)来区分,那么其实unity3d更是一个solution,而不是engine。因为它本身包含了很多的engine(渲染、物理、AI、audio等),在这些engine的周围,又集成了一个团度协作需要的各种工具(动画、材质、物理、场景编辑器,以及打包发布工具等等)。相对而言,ogre更偏重是一个纯粹的engine:它只负责渲染。另外一个很好的案例是现在的cocos2d-x,原先它只是一个engine,后来它开始出编辑器了,那么慢慢就演变成一个完整的解决方案(现在显然还没有到这个级别)。&br&&br&然后回到题目,回答是:直接写。甚至现在还有很多的公司还是直接写。基于OpenGL或者Direct3D,自己写场景的解析器,自己写渲染器。为了跟美术和策划合作,至少还得写一个场景编辑器,后来发现老是手工改材质配置非常繁琐或者是容易出错,就需要再写个材质编辑器。后来又发现缺个啥,再写个什么。如果完完整整都写下来,那么写出来的这些个工具,就成了一套完整的3d引擎了。现实中,有的游戏很小,根本不需要那么多的工具。有些公司很小,没有那么多的协作,或者各个力量都很牛,打开个文本编辑点东西不是什么问题,那么也就没有那么多的工具。因为最终目的是出游戏内容,而不是周边工具。&br&&br&而游戏引擎,只是有人发现了这是个市场,所以专门针对内容开发团队做了相应的产品:保证他们可以协同,保证他们可以用不是很技术的方式产生高质量的内容,保证他们,如广告中所说”让开发团队只需要专注于内容的开发“。但是因为3d游戏引擎最好的卖点就是渲染,所以会比较注重渲染这一块的技术。
首先澄清引擎这个概念。 提到引擎只会带来更出色的画面、更细腻的动画,是不全面的。这么说的话只是说到了“渲染引擎”而已。一个游戏,还有物理引擎、AI引擎等很重要的几个引擎。而所谓的引擎,很大的程度上,是一个”专注于某个功能的模块“。软…
&p&如果你看不明白原帖中的ECS(似乎很多人有这个反应),我觉得其实是很正常的,尤其是从开始写代码到今天只接触过OOP的人,而OW本身是一个很宏大的项目,你没法很好的去理解这个例子,假如你真的有兴趣了解ECS,那么我给你们举个很简单的例子,以及说一下ECS的基本Motif(调性):&/p&&p&首先是规则区别,我还是要重复一个Key(我记得似乎在别的帖子说过):&/p&&p&1,OOP的核心思想是:我是什么——我是一个角色对象,我是一个子弹对象。&/p&&p&2,ECS的核心思想是:我有什么——我有render,我有move,我有motion。&/p&&p&就拿子弹和角色来说,如果我们是一个很简单的射击游戏,或者是Top-Down-Shooter的,或者更简单直白的,FC上的坦克相信都知道吧?&/p&&p&如果用OOP的方式做,它里面有角色(坦克)对象和子弹对象,伪代码&/p&&p&class tank {&/p&&p&//这里仅说一些有代表性的,就不细节设计了&/p&&p&public tank()&/p&&p&public Vector2 move(direction) //有一个move方法来移动坦克,在这个方法里面,我们根据面向、速度等因素来让坦克的坐标发生位移,同时我们让坦克的动作发生了变化。注意:我们把坦克的渲染其实也放在了这里,所谓的渲染包括了移动时候播放的动画等。&/p&&p&public bullet fire() //我们通过这个来让坦克开火,产生子弹&/p&&p&public void kill()
//我们通过这个来让坦克在HP小于等于0的时候死亡。&/p&&p&}&/p&&p&class bullet {&/p&&p&public bullet(){}&/p&&p&public Vector2 move(direction) //子弹也会根据方向移动,这毫无疑问。注意,我们把子弹的渲染也放在了这里,所谓渲染包括了子弹移动的时候贴出他的位置。&/p&&p&public void hit() //子弹命中了什么东西之后要调用这个,用来消除子弹。&/p&&p&}&/p&&p&我相信不用写game,大多人也知道这个game要怎么写,毕竟这么简单的游戏。&/p&&br&&p&那么我们来看看ECS是怎么做这个的?伪代码&/p&&p&moveComponent{&/p&&p&enum direction
//移动方向,不做进一步解释了&/p&&p&float moveSpeed //移动速度,我想你也明白&/p&&p&}&/p&&p&positionComponent{&/p&&p& //位于地图的坐标,不解释了&/p&&p&&/p&&p&}&/p&&p&function moveSystem(entities){ //这个system只关心带有positionComponent和moveComponent的entity,所以entities里面的所有entity都必然有个moveComponent和positionComponent&/p&&p&for (entity in entities){&/p&&p&
这里就不详细写了,执行的事情就是根据moveComponent中的direction和moveSpeed,为positionComponent中的x,y重新赋值。&/p&&p&}&/p&&p&}&/p&&p&renderComponent{&/p&&p& //贴图的信息,可以是资源名,等等,老做游戏了你应该理解这个&/p&&p&}&/p&&p&function renderSystem(entities){&/p&&p&//这个系统的工作,就是根据自己关心的带有positionComponent和renderComponent的对象,来进行渲染工作。&/p&&p&}&/p&&p&collisionComponent{&/p&&p& //FC的坦克大战中,所有的子弹和坦克,其实都是矩形的。&/p&&p& //可以理解为阵营,同一阵营的互相忽略碰撞,当然写在这里面并不是最好的方案,具体要看需求,目前的需求下这还算凑合。&/p&&p&hitEntities: array&entity&; //用于记录碰撞到的entity&/p&&p&}&/p&&p&tankComponent{&/p&&p&//证明这是一个tank,并且记录坦克需要的数据&/p&&p&int hp&/p&&p&}&/p&&p&bulletComponent{&/p&&p&//证明这是一个子弹,并记录子弹需要的信息&/p&&p&int power&/p&&p&bool hitSomeThing&/p&&p&}&/p&&p&function collisionSystem(entities){&/p&&p&//这个system关心的是collisionComponent和positionComponent,他的工作就是根据position和collisionComponent.rect来判断2个entity是否碰撞,如果碰撞,则将彼此加入到对方的collisionComponent.hitEntities数组中去。&/p&&p&}&/p&&p&function damageSystem(entities){&/p&&p&//这是一个很有意思的system,他只关心带有collisionComponent,然后会根据collisionComponent.hitEntities中的entity提供的信息配合被捕捉的entity的其他component(比如tankComponent和bulletComponent)进行特殊处理。&/p&&p&//这个system的工作之一:如果这个entity并没有tankComponent,同时还没有bulletComponent,for循环执行continue,检查下一个entity。&/p&&p&//如果这个entity拥有tankComponent,证明这是坦克,则遍历collisionComponent.hitEntities,根据其中带有bulletComponent的entity进行处理,你可以同时销毁他们全部,并且都对这个坦克进行伤害,也可以根据被认为是子弹(带有bulletComponent的entity)的个数特殊处理,比如被3个子弹命中则hp提高10000等,根据设计需求来实现。&/p&&p&//值得注意的是:即使entity.tankComponent.hp&=0,也不由我来进行下一步操作,我就是一个damageSystem,我负责的就是damage(造成伤害),造成伤害的后果,管我鸟事儿。&/p&&p&}&/p&&p&function tankDestroySystem(entities){&/p&&p&//我只关心带有tankComponent的entity,我的任务是如果entity.tankComponent.hp&=0,则将他们杀死。&/p&&p&}&/p&&p&function bulletDestroySystem(entities){&/p&&p&//和tankDestroySystem差不多,但我只负责对bulletComponent.hitSomeThing==true的对象进行dispose()&/p&&p&}&/p&&p&这就是一个典型的ECS的游戏写法,他没有坦克对象,子弹对象,但是他有坦克和子弹&/p&&p&tankEntity = entities.new()&/p&&p& .add(new positionComponent(x,y))&/p&&p& .add(new renderComponent(xxxx))&/p&&p& .add(new collisionComponent(rect(x,x,x,x), y)&/p&&p& .add(new tankComponent(x))&/p&&p&bulletEntity = entities.new()&/p&&p& .add(new positionComponent(x,y))&/p&&p& .add(new renderComponent(xxxx))&/p&&p& .add(new collisionComponent(rect(x,x,x,x), y)&/p&&p& .add(new bulletComponent(x))&/p&&p&你会发现,子弹和坦克唯一的区别就是一个是子弹,一个是坦克。你可能要问,为什么没有moveComponent?因为moveComponent只有在移动的时候才需要添加上去,当移动完毕,就可以把它移除掉,这对于效率来说,还算是一种优化。&/p&&br&&p&到这里,我们是不是可以思考另外一个问题——在一个3岁小孩子眼里,画出来的羊和活着的羊有什么区别?区别就是:活着的羊会动,他有motionComponent和moveComponent。当然话题收回来,现在,我们发现游戏中还没有设计地形,对,没有地形玩什么?&/p&&p&OOP方式:&/p&&p&class ObstacleGrid{&/p&&p&//tilebased游戏,地图格当然不能没有,当然这种游戏需要的只是会阻挡的地形格子信息而已。&/p&&p& //贴图资源&/p&&p& //能否被子弹击穿&/p&&p&Vector2 //位置&/p&&p&.....&/p&&p&public void break() //被子弹销毁了&/p&&p&}&/p&&p&看起来加一个对象不复杂,但是当地图上有了这些obstacleGrids之后,你要在game中coding什么呢?很多,比如坦克移动的时候,你不能穿越他,再比如子弹命中他的时候……等等等等。&/p&&br&&p&ECS方式,我们要做的事情很清晰:&/p&&p&wallComponent{&/p&&p&//证明我是阻挡地形,别在意名字的细节……&/p&&p&&/p&&p&}&/p&&p&function obstacleSystem(entities){&/p&&p&//这个system关心的,只有带有wallComponent和collisionComponent的entity,根据collisionComponent.hitEntities进行对应的处理,相信你动动脑子能想明白。&/p&&p&//这里有一个独特与oop的地方,如果我(墙壁entity)阻挡了坦克或者子弹,我要做的是对对方entity.remove(moveComponent),导致对方不能发生移动。&/p&&p&}&/p&&p&阻挡地形:&/p&&p&obstacleGrid = entities.new()
.add(new positionComponent(x,y))
.add(new renderComponent(xxxx))
.add(new collisionComponent(rect(x,x,x,x), y)
.add(new wallComponent(x))&/p&&p&看到这里,发现为啥他和子弹和坦克如此接近?是不是能突然冒出一个有意思的想法?如果策划说了,我的阻挡地形也会移动!是不是OOP很懵逼?但ECS就很好处理了?&/p&&br&&p&以上是一个简单的思路上的例子,区别了ECS和OOP,ECS中你说一点耦合不存在可能吗?是可能的,system之间是否必须耦合(其实必须优先执行aSystem再执行bSystem就可以认为是耦合)取决于你的programming和对业务的理解能力。当然,我想说的是,请看&/p&&br&&img src=&/v2-0bf7aec698eb9caaf0c85b67c6774162_b.png& data-rawwidth=&586& data-rawheight=&295& class=&origin_image zh-lightbox-thumb& width=&586& data-original=&/v2-0bf7aec698eb9caaf0c85b67c6774162_r.png&&&p&是不是符合Component中没有任何行为?no functions&/p&&p&是不是符合没有状态?任何system都不关心游戏状态&/p&&p&第三个、第四个因为业务简单就没有体现出来&/p&&p&最后一个是不是system之间互不关心?当然!&/p&&br&&p&所以,请认真的去理解ECS的特性和好处,不要轻易的做出危险的类比!&/p&&br&&p&算了,吐槽就去掉吧,还是讲讲道理。&/p&
如果你看不明白原帖中的ECS(似乎很多人有这个反应),我觉得其实是很正常的,尤其是从开始写代码到今天只接触过OOP的人,而OW本身是一个很宏大的项目,你没法很好的去理解这个例子,假如你真的有兴趣了解ECS,那么我给你们举个很简单的例子,以及说一下ECS…
自己用VC2008和Lua写的一个游戏框架,结构应该说比较美观吧,相信不会让大家失望,下载地址为:&br&百度网盘:&a class=& wrap external& href=&///?target=http%3A///safecheck/index%3Furl%3Dx%2BZ5mMbGPAvVIlwZePSt0B3tEqEFWbC4tOatFxkC6cJI1peNSaRIJIG5NsZMw//Sd3VltQggDPXnyRS070PNi0MAOwARMgUce5YN%2B3aVQRLufBvgCExtCoMagrMTXUrAisIRR3ehEMN2Pah4egTNMg%3D%3D& target=&_blank& rel=&nofollow noreferrer&&/s/1sjILNrR&i class=&icon-external&&&/i&&/a&&br&GitHub:&a href=&///?target=https%3A///LikeUSummer/GamePainter& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GitHub - LikeUSummer/GamePainter: A repository to store my game framework&i class=&icon-external&&&/i&&/a&&br&也许下面的回答还是不能说清楚lua到底哪点好,哪点适合游戏制作,但是下载查看这个具体的程序后相信会慢慢喜欢它的*_^&br&&img data-rawheight=&658& data-rawwidth=&1013& src=&/88a91ac03a3ac0c096d1fd55ce952401_b.jpg& class=&origin_image zh-lightbox-thumb& width=&1013& data-original=&/88a91ac03a3ac0c096d1fd55ce952401_r.jpg&&&br&以前一直听别人说lua在游戏领域如何流行,但是在网上搜索许多,也只是见到一些文章介绍,于是最终决定自
己来写一个,宿主引擎和脚本框架都从零开始写,在构思和动手制作了几个月后,终于完成了这个完整框架,相信下载使用的同学一定会对这个引擎,以及我已编写好的部分Lua框架模块感到满意,当然如有不足之处也只管指出哈。&br&这个框架的宿主程序(引擎)是用VC2008开发的,运行效率较高(极限测试可装载几百兆大地图,上百活动游戏对象等),这个宿主程序负责绘图,声音,操作消息传递
等基本内容,并向lua提供接口,参数简单,函数名好记;而游戏的上层实现则全部由lua脚本完成;&br&对windows开发熟悉的同学肯定都知道
MFC库对winAPI完善的封装,使得窗口编程中许多重复的事情不必再亲自去处理,根据共性和不同点从基类往下派生,使得结构很清晰,代码重用性很高;
这里正是借鉴了这一思路,先总结游戏程序的共性,从逻辑上把游戏划分成若干模块,确定框架,再充分利用lua的表结构,模拟派生和继承等面向对象特性,然
后把诸如地图,角色,怪物,动画,界面控件等写成lua模块,通过约定一些同名接口来规范协调一些有关联的模块,方便世界管理器统一管理
(world.lua),这样在制作不同游戏时只需要通过搭配已有模块和派生一些新模块或写新模块,即可完成一个确定的新游戏,当然我还会不断更新lua
框架模块,而大家如有新作品也欢迎分享出来哦
&br&这是框架使用截图:&br&&img data-rawheight=&489& data-rawwidth=&700& src=&/61eaab144cf0c593e406adea_b.jpg& class=&origin_image zh-lightbox-thumb& width=&700& data-original=&/61eaab144cf0c593e406adea_r.jpg&&这是用它做的游戏与小应用截图:&br&&img data-rawheight=&650& data-rawwidth=&1006& src=&/428f3afa24a4e0af7568afbf1374af03_b.jpg& class=&origin_image zh-lightbox-thumb& width=&1006& data-original=&/428f3afa24a4e0af7568afbf1374af03_r.jpg&&&img data-rawheight=&658& data-rawwidth=&1013& src=&/88a91ac03a3ac0c096d1fd55ce952401_b.jpg& class=&origin_image zh-lightbox-thumb& width=&1013& data-original=&/88a91ac03a3ac0c096d1fd55ce952401_r.jpg&&下面这个是一个网络搜索实验:&br&&img data-rawheight=&400& data-rawwidth=&580& src=&/af65baaa34e9bdbfdca846a_b.png& class=&origin_image zh-lightbox-thumb& width=&580& data-original=&/af65baaa34e9bdbfdca846a_r.png&&&br&下面是一个信息浏览工具:&br&&img data-rawheight=&750& data-rawwidth=&1288& src=&/0d1c538cd6aae0a2c25d066_b.png& class=&origin_image zh-lightbox-thumb& width=&1288& data-original=&/0d1c538cd6aae0a2c25d066_r.png&&以上截图都是用这个框架开发的,希望大家能喜欢,也真的希望能有更多人了解并喜欢上lua语言&br&--------------------------&br&最后在这里打个小广告吧,是一个原创的数学软件,类似matlab的simulink,个人编写和更新了十余版本,这是最新版,下载地址为:&br&&a href=&///?target=http%3A///s/1eQEPWJo& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/s/1eQEPWJ&/span&&span class=&invisible&&o&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&欢迎有兴趣的朋友们试用,感谢您的支持哦(软件详情也可以看我在知乎的另一个回答) 日
自己用VC2008和Lua写的一个游戏框架,结构应该说比较美观吧,相信不会让大家失望,下载地址为: 百度网盘: GitHub: 也许下面的回答还是不能说…
谢邀&br&&br&不嘲讽,只说事实。&br&&br&问这种问题的人,新手,一般见识短,见得少,玩得少,又毫无执行能力,不懂流程,也不会计算成本。&br&&br&拍脑袋一想,觉得自己想法太牛逼了,简直天赐灵感。&br&&br&岂不知你想的东西,别人十几年前就做过了,而且做的非常好,出了好几代,经典ip,一系列衍生周边。&br&&br&&br&仔细一看你说的这路数,这不TMD是fate吗?&br&&br&你有虚渊玄那编剧的本事吗?能自己码代码吗?会用哪种引擎?能自己设计角色吗?你能自己设计核心玩法吗?&br&&br&这些都没有不要紧,你有钱吗?&br&&br&希望这种无价值低于入门门槛的提问越来越少。
谢邀 不嘲讽,只说事实。 问这种问题的人,新手,一般见识短,见得少,玩得少,又毫无执行能力,不懂流程,也不会计算成本。 拍脑袋一想,觉得自己想法太牛逼了,简直天赐灵感。 岂不知你想的东西,别人十几年前就做过了,而且做的非常好,出了好几代,经典…
上一行右方有玄机。
上一行右方有玄机。
上图喽~&br&&img src=&/a20fe575ab0fac56dd9c53_b.jpg& data-rawwidth=&553& data-rawheight=&419& class=&origin_image zh-lightbox-thumb& width=&553& data-original=&/a20fe575ab0fac56dd9c53_r.jpg&&&br&这是这十几天写的soft pipeline渲染的立方体&br&&img src=&/6dbdb206d6d351d591c82b96c4d98a10_b.jpg& data-rawwidth=&498& data-rawheight=&395& class=&origin_image zh-lightbox-thumb& width=&498& data-original=&/6dbdb206d6d351d591c82b96c4d98a10_r.jpg&&黑色三角形是鼠标点选效果,嗯,精确度高高?~&br&&img src=&/ef0b56f91b16e4f7db88e_b.jpg& data-rawwidth=&566& data-rawheight=&445& class=&origin_image zh-lightbox-thumb& width=&566& data-original=&/ef0b56f91b16e4f7db88e_r.jpg&&左面三角形使用透视纹理映射,右面的是线性映射,还是左面的给力啊(尼玛,计算量翻了好几倍啊~!)&br&为了感谢大家的谬赞,来~小的们,把新出炉的干货给各位兄台抬上来~&br&(1)&a href=&///?target=http%3A//blog.csdn.net/popy007/article/category/640562& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&blog.csdn.net/popy007/a&/span&&span class=&invisible&&rticle/category/640562&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&
这大牛把几个关键的矩阵用初中生都能看懂的数学知识给推!!倒!!了!!受益良多啊。唯一的一点点小遗憾是没有把CVV裁剪介绍一下,导致在顶点乘以透视矩阵后,进行投影操作之前出现了一段真空期,下面提到的《计算机图形学(opengl版)》说明了这个问题。但是大牛的光环还是那么耀眼!&br&(2)目前我看到的介绍流水线的资料中,在推导摄像机矩阵时,基本上没有提到一个很重要的线性代数上的基本概念,如下:&br&
world coordinate
是世界坐标系
&br&&p&  coordinate frame 是局部坐标系 也叫坐标架 类似于物体坐标系,或者摄像机坐标。&/p&&p& 
第一部分:这里用到得一个线性代数里的概念 叫做
过度矩阵: 从一个坐标基 到 另个一坐标基之间有一个过度矩阵
如 从坐标基A到坐标基B
有个过度矩阵C
则有 A*C = B 。如果有一个向量在世界坐标系下的坐标为a,有两在世界坐标系下的坐标基(coordinate frame)A和B,且从A到B的过度矩阵为C,a在A和B两个坐标基下的坐标是a‘和b‘。那么有&/p&&p&a = A*a‘ = B*b‘
由 A*C=B 带入得
A*a‘ = B*b‘=A*C *b‘
其中 A为可逆矩阵 有 a‘ = C*b‘。这样就得到了两个在不同坐标基,且由A可逆还可知C = B*(A-1)。(A-1)时A矩阵的逆。&/p&&p&&a href=&///?target=http%3A///BlackWalnut/articles/4194956.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/BlackWalnut&/span&&span class=&invisible&&/articles/4194956.html&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&
第二部分在上面的链接里,由于公式编辑不下来,看着太疼了。&/p&&p&
上面数学知识的重要性在于,给定任意一个向量可以快速构建一个坐标系。。。。。。用途有多广?!?!?!你把它用在物体绕任意轴旋转上试试,你把它用在摄像机坐标系推导上试试,你把它用在求射线和三角形焦点上试试(搜搜这个吧《Fast Minimum Storage Ray Triangle Intersection》),你把它用在normal map上试试(据说可以,我回头看看,嘻嘻~),当然,你要是发现其他用途也私信一下我,嘿嘿。&/p&&p&要不是考研!!这个定理我踏马也发现不了啊!!线性代数老师压根就没有提过!!话说那天我懒洋洋的看着数二数三不考,数一要考的线性代数部分,看到这个定理后,突然感觉比雷劈轻,比电击爽的一丝电流在大脑里蔓延。。。。。。我靠~我找的你好苦啊!!!&/p&&p&
得了~就这么多吧,今天刚把xcode上的和glsl相关的代码写完,明天开始研究光照,随后更新光照部分,手头已经有两本书了,不过学习思路还是不太明朗。回头聊~&/p&&br& -----------------------------------这东西真叫分割线???------------------------------------------&br&谢(没人)邀。。。。。&br&学3D开发也有两三年了,弯路走了不少就当给大家提个醒吧。&br&3D图形学刚开始学的时候最难的部分其实是渲染流水线,要搞清楚流水线每一步做了什么,用到了那些矩阵,以及矩阵背后的数学原理还真是要了亲命。折腾了死去活来好久以后,发现好书就那么几本:&br&1.《3D数学基础:图形与游戏开发》
这个可以当参考手册使用&br&2.《3D游戏编程大师技巧》
很多人说它过时了,但是让你徒手写个流水线,我还没有发现比这本代码更完整,系统的书。不过这本书的缺点是,透视变换和投影变换完全是乱七八糟的一大坨坨!下面这本书就好很多。&br&3.《计算机图形学(opengl版)》第三版
最近才发现的,目前中文网站上所有关于3D流水线叙述比较热门的博客,帖子基本上都能从这本书上找到出处,很系统,也基本完整,概念,术语,图例等等也比较到位,有些不太清楚的地方可以上网查查,基本上没有什么太大的遗漏。&br&4.红宝书&br&以下所有前提都要求你明白简单的线性代数运算,比如向量和矩阵的左右乘法,矩阵转置,正交矩阵的逆矩阵等于其转置矩阵等等。&br&如果你不知道3D是啥,建议从红宝书开始。&br&如果对3D有一定了解,会一点opengl,建议从《计算机图形学(opengl版)》开始,跟着徒手写一个渲染流水出来,写的过程中,《计算机图形学(opengl版)》里面有数学原理的介绍不太完整的,查查《3D数学基础:图形与游戏开发》相关章节,不知道具体数据结构怎么设计的,查查《3D游戏编程大师技巧》。&br&这个阶段,如果最后能写出来一个软的光栅化流水线,渲染出来线框就算成功。这是我的学习过程,可能对于不同的人,学习过程不太相同,但是,3D渲染流水线上关于几何变换的东西,这三本书都包含的差不多了。&br&关于光照部分,我这个寒假想研究一下,主要是shader的使用,已经有几本资料了,我看看了再来更新吧。&br&好吧。。。。。我回答这个问题的原因是有没有人能帮我回答一下&br&&a href=&/question/& class=&internal&&点经过透视矩阵变化后得到齐次坐标,经行裁剪时w分量的含义? - 数学&/a&&br&这个问题啊!!!急死人了都!!很多资料都“巧妙”(还是我傻傻的没有看见)避开了这个问题!!!三天了!!代码改了十几次!!!猜的,蒙的,算的都试了个遍!!流水线就差这一小步!!还让不让人开心的写代码了!!!快摔啤酒瓶了都!!!&br&----------------------------------------------------他们管这东西叫分割线---------------------------------------------------&br&那个问题解决了,是我的疏忽,给大家带来了麻烦,很抱歉。答案我就写在那个问题下面了。
啊哈哈~ 上图喽~ 这是这十几天写的soft pipeline渲染的立方体 黑色三角形是鼠标点选效果,嗯,精确度高高?~ 左面三角形使用透视纹理映射,右面的是线性映射,还是左面的给力啊(尼玛,计算量翻了好几倍啊~!) 为了感谢大家的谬赞,来~小的们,把新…
主要是要动手。建议是C++学一下,不用学的很深入,然后数据结构看一下,看到树就可以了,树和图可以留到以后看,之前的链表堆栈队列都看掉,争取自己写出来。然后学下SDL,这个包很容易学,看网上的教程几天就学会了,然后接下来就是从最傻逼的游戏开始写。我的过程是贪吃蛇--&乒乓--&打砖块,现在忙了没写下去了,都快忘记了,之后规划的路径是Galaxia--&警察抓小偷--&简单的2d scroll游戏--&简单的2d rpg引擎,最终目标是看懂博德之门的那个开源引擎,自己写2d RPG,因为我对三维的兴趣不大所以就不准备学。&br&&br&其实这里头都是有学习点的:贪吃蛇是练手,顺便学习简单的动画;乒乓是学最简单的碰撞检测+物理;打砖块是学稍微精细一点的碰撞检测+第一个商业游戏(这玩意写得好的确可以卖,但是我们的目的就是练手);Galaxia是学习简单的AI和Sprite表,这是第一个Sprite数量比较大的游戏;警察抓小偷是学习更复杂一点的AI,和简单的关卡编辑器;2d scroll游戏就是学习scroll的;简单的2d rpg引擎,这里我的规划是类似创世纪3这样的引擎就足够了,这里能学到的东西就很多了,但是最主要的是,这是第一次我要做一个完整的游戏引擎,以及所有的工具,包括更复杂的关卡编辑器、试验一下简单的脚本(物品掉落,比如说)。&br&&br&推荐几个链接,我觉得完全足够了。&br&&a href=&///?target=http%3A//lazyfoo.net/tutorials/SDL/index.php& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Lazy Foo' Productions&i class=&icon-external&&&/i&&/a& (SDL + C++的教程,作者连怎么配置环境都手把手的交给我们了,每天学个两节很快就下来了,等学完了基本上我上头那个列表也写完了)&br&&a href=&///?target=http%3A//www.aaroncox.net/tutorials/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&2D Game Programming Tutorials with SDL&i class=&icon-external&&&/i&&/a& (同样是SDL+C++的教程,但是这里头有好几个游戏的源代码,开始写游戏的话,C++学好了,然后写一个月游戏应该就能看懂这里所有的源代码了,好处是他上来就告诉你游戏引擎要有怎么样的架构)&br&&br&最后看下entity driven engine的知识吧,如果你要写比较复杂的游戏的话。当然如果要写3d的话要看的就更多了,我的建议其实也很简单,就是比照着游戏发展史来,比如说你可以先上Wolf3d这样的游戏,当然不是比照它的源代码,而是实现类似的功能。&br&&br&C++的教程就不给了,其实随便挑本英文经典的教程,不用看完,看到面向对象,知道继承大概是个什么样子,就成了。细节部分慢慢追究,总体来说我觉得每天花五六个小时(真心不多,写程序很容易沉浸在里头的,五六个小时是为了保证生活质量,我去年夏天自学的时候往往一天十个小时)看一个月绝对就看完了,然后看数据结构。为什么看数据结构呢,因为第一这是游戏编程里头很重要的一部分,数据结构设计的不好将来你会呵呵呵的,第二,你之前学C++恐怕没写过什么正经的代码,学数据结构可以大量的练习算法,而且最主要的,熟悉常用的数据结构。我觉得学到树就够了,最多把树学完就足够了,这也就是一个月的时间最多了。最后要注意,从一开始就要写比较专业的代码,这个你去网上搜索下就好了,包括一些书上可能不会说到的东西,比如说最新版C++里头我记得有智能指针。我C++其实都是自学的,所以也不知道是不是有什么库要学,蛮多流行的库但是我不知道游戏编程是否要用到,你还是去问下比较好。&br&&br&接下来就是大量的写游戏。写游戏要注意了,从一开始就要搞明白引擎的构架,否则将来要吃亏。我上头给的两个网站都是挺好的,教给你简单的架构,但是最好找个业内的人问一下,因为内容有些老了,而且如果你志在三维游戏的话,一开始有人推荐的那本游戏引擎架构我觉得蛮好的,虽然我看不懂但是翻了下觉得看完应该足够了。&br&&br&然后就没啥了吧,反正就是慢慢写,也别着急。如果有机会去业内肯定要去的,因为能学到很多。但是怎么说呢,如果你和我一样不想写大型的三维游戏(二维角色扮演游戏其实也很大型,不过相对三维来说还是容易点),那么靠网上问人也差不多了。但是有机会进去肯定要去一下的,还能赚钱。如果去不了公司,就多看看源代码,网上实在是太多了,看看行家是怎么写的,同一个游戏同一个功能他为什么这么写,想不明白直接发信嘛,搞IT的人一般都挺热心的。
主要是要动手。建议是C++学一下,不用学的很深入,然后数据结构看一下,看到树就可以了,树和图可以留到以后看,之前的链表堆栈队列都看掉,争取自己写出来。然后学下SDL,这个包很容易学,看网上的教程几天就学会了,然后接下来就是从最傻逼的游戏开始写。…
&p&&a class=&member_mention& href=&///people/ac4ff950d524bf65dae902e463bd7223& data-hash=&ac4ff950d524bf65dae902e463bd7223& data-hovercard=&p$b$ac4ff950d524bf65dae902e463bd7223&&@猴与花果山&/a&童鞋已经阐述了ECS的主要概念。此文主要从技术和工程角度简单探讨游戏行业中设计模式的演变历史和ECS的意义。&/p&&h2&综述&/h2&&p&&i&设计模式产生的动机,往往源于尝试解决一些存在的问题。游戏开发领域技术架构的宏观目标,大体包括以下目标:&/i&&/p&&ul&&li&&b&适合快速迭代。&/b&无论是上线前的敏捷开发流程还是上线后根据市场反馈的调整,迭代都是基本需求。&/li&&li&&b&易于保证产品质量。&/b&良好的架构,可以降低 Bug 和 Crash 出现概率。&/li&&li&&b&开发效率。&/b&重要性不必多说。即使是更重视游戏质量的公司,越高的开发效率也有助于更短的时间打造出质量更高的游戏。&/li&&li&&b&运行效率。&/b&大部分游戏对实时响应和运行流畅度都有很高的要求,同时游戏中又存在大量吃性能的模块(比如渲染、物理、AI等)。&/li&&li&&b&协作扩展性。&/b&能够在开发团队扩张时尽可能无痛,同时方便支持美术、策划、音效等非程序同事的开发需求。&/li&&/ul&&p&&br&&/p&&p&&i&现代 Entity Component System 的概念,以及对游戏开发领域的意义:&/i&&/p&&ul&&li&&b&Entity:&/b&代表游戏中的实体,是 Component 的容器。本身并无数据和逻辑。&/li&&li&&b&Component:&/b&代表实体“有什么”,一个或多个 Component 组成了游戏中的逻辑实体。只有数据,不涉及逻辑。&/li&&li&&b&System:&/b&对 Component 集中进行逻辑操作的部分。一个 System 可以操作一类或多类 Component。同一个 Component 在不同的 System 中,可以关联不同的逻辑。&/li&&/ul&&p&ECS 并非《守望先锋》所独有和原创,事实上近年来以 ECS 为基础架构逐渐成为国际游戏开发领域的主流趋势。&/p&&p&采用 ECS 的范式进行开发,思路上跟传统的开发模式有较大的差别:&/p&&ul&&li&Entity 是个抽象的概念,并不直接映射为具体的事物:比如可以不存在 Player 类,而是由多个相关 Component 所组成的 Entity 代表了 Player。如 Entity { MovementComponent, RenderComponent, StateMachineComponent, ... } 等等。&/li&&li&行为通过对 Component 实施操作来表达。比如简单重力系统的实现,可以遍历所有 Movement Component 实施位移,而不是遍历所有 玩家、怪物、场景物件,或者它们统一的基类。&/li&&li&剥离数据和行为,数据存储于 Component 中,而 Component 的相关行为,和涉及多个 Component 的交互和耦合,由 System 进行实施。&/li&&/ul&&p&ECS 框架,至少有以下优点:&/p&&ul&&li&&b&模式简单&/b&。如果还是觉得复杂,推荐看看 GoF 的《设计模式》。&/li&&li&&b&概念统一。&/b&不再需要庞大臃肿的 OOP 继承体系和大量中间抽象,有助于迅速把握系统全貌。同时,统一的概念也有利于实现**数据驱动**(后面会提到)。&/li&&li&&b&结构清晰。&/b&Component 即数据,System 即行为。Component 扁平的表达有助于实现 Component 间的正交。而封装数据和行为的做法,不仔细设计就会导致 Component 越来越臃肿。&/li&&li&&b&容易组合,高度复用。&/b&Component 具有高度可插拔、可复用的特性。而 System 主要关心的是 Component 而不是 Entity,通过 Component 来组装新的 Entity,对 System 来说是无痛的。&/li&&li&&b&扩展性强。&/b&增加 Component 和 System,不需要对原有代码框架进行改动。&/li&&li&&b&利于实现面向数据编程(DOP)。&/b&对于游戏开发领域来说,面向数据编程是个很重要的思路。天然亲和数据驱动的开发模式,有助于实现以编辑器为核心的工作流程。&/li&&li&&b&性能更好优化。&/b&接上条,相比 OOP 来说,DOP 有更大的性能优化空间。(详见后面章节)&/li&&/ul&&p&若要了解为何会出现 ECS 这样的模式,以及它所试图解决的问题,需要考虑一下历史进程:&/p&&h2&演化路径&/h2&&h2&简单粗暴的上个世纪开发模式&/h2&&p&注重于实现相关算法、功能和逻辑,代码只要能实现功能就行,怎么直观怎么来。比如&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&k&&class&/span& &span class=&nc&&Player&/span& &span class=&p&&{&/span&
&span class=&kt&&int&/span& &span class=&n&&hp&/span&&span class=&p&&;&/span&
&span class=&n&&Model&/span&&span class=&o&&*&/span& &span class=&n&&model&/span&&span class=&p&&;&/span&
&span class=&kt&&void&/span& &span class=&nf&&move&/span&&span class=&p&&();&/span&
&span class=&kt&&void&/span& &span class=&nf&&attack&/span&&span class=&p&&();&/span&
&span class=&p&&};&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&类似这样完全没有或很少架构设计的代码,在项目规模增大后,很快变得臃肿、难以扩展和维护。&/p&&h2&OOP 设计模式的泛滥 案例:OGRE&/h2&&div class=&highlight&&&pre&&code class=&language-text&&设计模式是语言表达能力不足的产物。 —— 某程序员
&/code&&/pre&&/div&&p&那么,作为他山之石,GoF 基于 Java 提出的设计模式,能否有效解决游戏开发领域的问题?&/p&&p&大家还记得当年国内风靡一时的游戏引擎 OGRE 么?&/p&&p&&a href=&///?target=http%3A//blog.csdn.net/xoyojank/article/details/2146435& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OGRE中用到的设计模式 - 逍遥剑客 - 博客频道 - CSDN.NET&i class=&icon-external&&&/i&&/a&&/p&&p&&a class=&member_mention& href=&///people/37aea7374636aae4def311& data-hash=&37aea7374636aae4def311& data-hovercard=&p$b$37aea7374636aae4def311&&@逍遥剑客&/a& &/p&&p&OGRE 总有那么些学院派的味道,试图通过设计模式的广泛使用,来提高代码的可维护性和可扩展性。&/p&&p&然而,个人对游戏开发领域大规模使用 OOP 设计模式的看法:&/p&&ul&&li&设计模式的六大原则大部分仍值得遵循。&/li&&li&基于 Java 实现的设计模式,未必适合其它语言和领域。想想 C# 的 event、delegate、lambda 可以简化或者消除多少种 GoF 的模式,再想想 Golang 的隐式接口。&/li&&li&C++ 是游戏开发领域最主要的语言,可以 OOP 但并不那么 OO,比如缺少语言层面纯粹的 interface,也缺少 GC、反射等特性。照抄 Java 的设计模式未免有些东施尿频,而且难以实现 C++ 所推崇的零代价抽象。(template 笑而不语)&/li&&li&局部使用 OOP 设计模式来实现模块,并暴露简单接口,是可以起到提升代码质量和逼格的效果。然而在架构层面滥用,往往只是把逻辑中的复杂度转移到架构复杂度上。&/li&&li&滥用设计模式导致的复杂架构,并不对可读性和可维护性有帮助。比如原本 c style 只要一个文件顺序读下来就能了解清楚的模块,滥用设计模式的 OOP 实现,阅读代码时有可能需要在十几个文件中来回跳转,还需要人脑去正确保证阅读代码的上下文...&/li&&li&过多的抽象导致过多的中间层次,却只是把耦合一层一层传递。直到最后结合反射 + IoC框架 + 数据驱动,才算有了靠谱的解决方案。然而一提到反射,C++表示我的蛋蛋有点疼。&/li&&/ul&&p&那么,有没有办法简化和沉淀出游戏开发领域较通用的模式?&/p&&h2&未脱离 OO 思想的 Entity Component 模式 案例:Unity3D&/h2&&p&Unity3D 是个使用了 Entity Component 模式的成功的商业引擎。&/p&&p&相信使用过 Unity3D 的童鞋,都知道 Unity3D 的 Entity Component 模式是怎么回事。(在Unity3D 中,Entity 叫 GameObject)。&/p&&p&其优点:&/p&&ul&&li&&b&组件复用。&/b&体现了 ECS 的基本思想之一,Entity 由 Component 组成,而不是具体逻辑对象。设计得好的 Component 是可以高度复用的。&/li&&li&&b&数据驱动。&/b&场景创建、游戏实体创建,主要源于数据而不是硬编码。以此为基础,引擎实现了以编辑器为中心的开发模式。&/li&&li&&b&编辑器为中心。&/b&用户可在编辑器中可视化地编辑和配置 Entity 和 Component 的关系,修改属性和配置数据。在有成熟 Component 集合的情况下,新的关卡和玩法的开发,都可以完全不需要改动代码,由策划通过编辑器实现。&/li&&/ul&&p&看起来,Unity3D 已经在很大程度上解决了游戏设计领域通用模式的问题。然而,其 Entity Component 模式仍然存在一些问题:Component 仍然延续了一些 OOP 的思路。比如:&/p&&ul&&li&&b&Component 是数据和行为的封装。&/b&虽然此概念容易导致的问题可以通过其它方式避免,但以不加思考照着最自然的方式去做,往往会造成 Component 后期的膨胀。比如 Component 需要支持不同的行为就定义了不同的函数和相关变量;Component 之间有互相依赖的话逻辑该写在哪个 Component 中;多个 Component 逻辑上互相依赖之后,就难以实现单个 Component 级别的复用,最后的引用链有可能都涉及了代码库中大部分 Component 等等。&/li&&li&&b&Component 是支持多态的引用语义。&/b&这意味着单个 Component 需要单独在堆上分配,难以实现下文所提到的,对同类型多个 Component 进行数据局部性友好的存储方式。这样的存储方式好处在于,批量处理可以减少 cache miss 和内存换页的情况。&/li&&/ul&&h2&当前主流的 Entity Component System 架构 案例:EntityX&/h2&&p&那么,综合以上所说的各种问题,一个基于 C++ 的现代 Entity Component System,应该是什么样子?&/p&&p&具体案例,可以参考 [EntityX](&a href=&///?ta}

我要回帖

更多关于 3d游戏编程入门经典 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信