{"id":364006,"date":"2024-05-21T02:08:06","date_gmt":"2024-05-21T02:08:06","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=364006"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=364006","title":{"rendered":"<span>Navmesh, lightmaps \u0438 lightprobes: \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Playcanvas<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u044b\u0431\u043e\u0440 Playcanvas<\/h2>\n<p>\u0414\u043b\u044f \u043c\u0435\u043d\u044f \u0432\u0435\u0434\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b\u043e \u043e\u0442\u0434\u044b\u0445\u043e\u043c \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043e\u0442\u0432\u043b\u0435\u0447\u044c\u0441\u044f \u043e\u0442 \u0440\u0430\u0431\u043e\u0442\u044b. \u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043c\u043e\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0433\u0435\u0439\u043c\u0434\u0435\u0432\u0430 \u0438\u043b\u0438 \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u043d\u0435\u043c\u0443. \u041c\u043e\u0436\u043d\u043e \u043d\u0435 \u0441\u043f\u0435\u0448\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u044b, \u043f\u0440\u0438\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u0441\u0451, \u0432 \u0447\u0451\u043c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0441\u044f, \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u043e. \u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f 3d-\u0438\u0433\u0440\u044b \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0412\u043e\u0442 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0437\u043d\u0430\u044e \u043f\u043e\u0447\u0435\u043c\u0443. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0443\u043c\u0435\u044e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438 (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 3d), \u0438 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0435 \u0438\u0433\u0440\u044b \u043a\u0430\u0436\u0443\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438: \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e, \u043d\u0430 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432 1 \u043a\u043b\u0438\u043a, \u043f\u0440\u0438 \u0434\u043e\u043b\u0436\u043d\u043e\u0439 \u0441\u043d\u043e\u0440\u043e\u0432\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0442\u043e\u0440\u043c\u043e\u0448\u0438\u0442\u044c \u043d\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435. \u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u044d\u0442\u043e \u0435\u0449\u0451 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u043e\u0433\u0434\u0430 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0435 \u0438\u0433\u0440\u044b \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u043b\u0438 \u0440\u0430\u0441\u0446\u0432\u0435\u0442. \u0422\u0430\u043a \u0432\u043e\u0442 \u0432\u0441\u0451 \u0438 \u043d\u0435 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0435\u0442.<\/p>\n<p>\u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0432\u0441\u0435\u0445 \u0431\u0435\u0434\u043d\u044b\u0445 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u044e\u0442 &#8212; \u043a\u0430\u043a\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0432\u044b\u0431\u0440\u0430\u0442\u044c? \u0418 \u0442\u0443\u0442 \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Unity. \u0421\u043b\u0438\u0448\u043a\u043e\u043c \u0443\u0436 \u043e\u043d \u0445\u043e\u0440\u043e\u0448. \u042d\u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u043d\u044b\u043c \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u0442 \u043d\u0435\u0433\u043e \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0448\u044c\u0441\u044f. \u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0438\u0433\u0440\u043e\u0432\u044b\u043c \u0434\u0432\u0438\u0436\u043a\u043e\u043c \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043d\u0438\u0445, \u0440\u0435\u0448\u0438\u043b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 Playcanvas. \u041e\u0431\u044a\u0451\u043c \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u043a\u0430 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 (\u0447\u0442\u043e-\u0442\u043e \u043e\u043a\u043e\u043b\u043e 1-\u0433\u043e \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0430 \u0432 \u043c\u0438\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435), \u0435\u0441\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0433\u0440\u0430\u0444\u0438\u043a\u0438, \u043d\u043e \u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438\u0433\u0440. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0435\u0441\u0442\u044c \u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b, BabylonJS \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439, \u0438\u043b\u0438 Cocos.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445. \u0412 Playcanvas \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u0435. \u041d\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u043e\u0433\u043e, \u0447\u0435\u0433\u043e \u0432 \u043d\u0451\u043c \u043d\u0435\u0442, \u043d\u043e \u0447\u0442\u043e \u0432 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e \u043d\u0430\u0434\u043e \u0447\u0430\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0412 \u044d\u0442\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u0434\u0432\u0435 \u0442\u0430\u043a\u0438\u0445 \u0442\u0435\u043c\u044b. \u041f\u0435\u0440\u0432\u0430\u044f \u0442\u0435\u043c\u0430 &#8212; \u044d\u0442\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 navmesh-\u0435\u0439. \u0412\u0442\u043e\u0440\u0430\u044f \u0442\u0435\u043c\u0430 &#8212; \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 lightmap-\u043e\u0432 \u0438 lightprob-\u043e\u0432. \u042d\u0442\u043e \u0435\u0441\u0442\u044c \u0432 Unity, \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0442 \u0432 Playcanvas. \u041d\u0430\u0434\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c. \u041e\u0431\u0441\u0443\u0434\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438 \u043f\u043e \u043e\u0431\u0435\u0438\u043c \u0442\u0435\u043c\u0430\u043c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u043e, \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 Playcanvas. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0438 \u0440\u0435\u0446\u0435\u043f\u0442\u044b \u0438 \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434\u043e\u0439\u0434\u0443\u0442 \u0438 \u043f\u043e\u0434 \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a. Playcanvas \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0432\u0443\u0445 \u0432\u0438\u0434\u0430: \u043a\u0430\u043a \u0444\u0440\u044d\u0439\u043c\u0432\u043e\u0440\u043a, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f web-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (WebPack \u0442\u0430\u043c, TypeScript \u0438 \u043f\u0440\u043e\u0447\u0435\u0435), \u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0446\u0435\u043d\u044b \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435. \u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u044d\u0442\u043e\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u0432\u043e\u0442 \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0434\u0430\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 <a href=\"https:\/\/playcanvas.com\/project\/1169594\/overview\/small-dungeon\" rel=\"noopener noreferrer nofollow\">\u0434\u0435\u043c\u043e-\u043f\u0440\u043e\u0435\u043a\u0442<\/a>. \u042d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0438\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u0441\u0451 \u0442\u043e, \u043e \u0447\u0451\u043c \u043f\u043e\u0439\u0434\u0451\u0442 \u0440\u0435\u0447\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/57a\/ebd\/5d1\/57aebd5d140a8d851a86485f1b5f57a9.png\" width=\"1432\" height=\"776\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/57a\/ebd\/5d1\/57aebd5d140a8d851a86485f1b5f57a9.png\"\/><\/figure>\n<h2>Navmesh<\/h2>\n<p>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0435\u0442\u043a\u0430 (\u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043d\u0433\u043b\u0438\u0446\u0438\u0437\u043c navmesh) &#8212; \u044d\u0442\u043e \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043e\u0442\u044b\u0441\u043a\u0430\u043d\u0438\u044e \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0435\u0433\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u0432 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u0441\u0446\u0435\u043d\u0435. \u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438: \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c navmesh, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432 <a href=\"https:\/\/github.com\/recastnavigation\/recastnavigation\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u0422\u0430\u043a\u043e\u0435 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0443\u043c\u0435\u0435\u0442 \u0437\u0430\u043f\u0435\u043a\u0430\u0442\u044c navmesh, \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u043d\u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f. \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u044f \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430 Python \u0438 AssemblyScript. \u0412\u043e\u0442  <a href=\"https:\/\/github.com\/Tugcga\/Path-Finder\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0430\u043c navmesh \u043c\u044b \u0443\u043c\u0435\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438 \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0435\u0440\u0448\u0438\u043d \u0432 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438 \u043d\u0430\u0431\u043e\u0440\u044b \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0432\u0435\u0440\u0448\u0438\u043d, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u044b.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u043a\u0430\u043a \u043d\u0430\u0439\u0442\u0438 \u043f\u0443\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u043d\u0430 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u0445 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e navmesh-\u0430. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440. \u0421\u0446\u0435\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fdd\/a94\/492\/fdda944920af87fc2236b83f5272a1eb.png\" width=\"1225\" height=\"825\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fdd\/a94\/492\/fdda944920af87fc2236b83f5272a1eb.png\"\/><\/figure>\n<p>\u0417\u0430\u043f\u0435\u0447\u0451\u043d\u043d\u044b\u0439 navmesh \u0442\u0430\u043a<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/17a\/b10\/480\/17ab1048015ce502813c10a06722ebf5.png\" width=\"1205\" height=\"788\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/17a\/b10\/480\/17ab1048015ce502813c10a06722ebf5.png\"\/><\/figure>\n<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434, \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u0432 <a href=\"https:\/\/github.com\/donmccurdy\/three-pathfinding\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u0421\u0443\u0442\u044c \u0442\u0430\u043a\u043e\u0432\u0430. \u041d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u044b navmesh-\u0430 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 BVH (Bounding Volume Hierarchy) \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0433\u0440\u0430\u0444. \u0412\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438 \u044d\u0442\u043e\u0433\u043e \u0433\u0440\u0430\u0444\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0446\u0435\u043d\u0442\u0440\u044b \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432, \u0438 \u0434\u0432\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0440\u0435\u0431\u0440\u043e\u043c, \u0435\u0441\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u043c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u044b \u0438\u043c\u0435\u044e\u0442 \u043e\u0431\u0449\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443. \u041f\u043e\u043f\u0443\u0442\u043d\u043e \u0435\u0449\u0451 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u044f\u043a\u0430\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u043e\u0439 \u043f\u043e\u043b\u0438\u0433\u043e\u043d \u043f\u043e \u043a\u0430\u043a\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441 \u043a\u0430\u043a\u0438\u043c \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u043c \u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442.<\/p>\n<p>\u041a\u0440\u0430\u0442\u043a\u043e \u043e\u043f\u0438\u0448\u0435\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438. \u0411\u0435\u0440\u0451\u043c \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5e5\/a46\/7f1\/5e5a467f1c42479ac26e1390fa8b54fa.png\" width=\"927\" height=\"488\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5e5\/a46\/7f1\/5e5a467f1c42479ac26e1390fa8b54fa.png\"\/><\/figure>\n<p>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u0430\u043a\u0438\u0445 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u0445 \u043e\u043d\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f. \u042d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e BVH-\u0430. \u041f\u043e\u0442\u043e\u043c \u0431\u0435\u0440\u0451\u043c \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0438\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0433\u0440\u0430\u0444\u0430, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043f\u0443\u0442\u044c \u0432 \u0433\u0440\u0430\u0444\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e A*.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3fd\/513\/4ee\/3fd5134ee7d46630838f881b5b631fed.png\" width=\"927\" height=\"488\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3fd\/513\/4ee\/3fd5134ee7d46630838f881b5b631fed.png\"\/><\/figure>\n<p>\u041d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0437\u0430\u0434\u0430\u0451\u0442 \u043a\u043e\u0440\u0438\u0434\u043e\u0440 \u0438\u0437 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 \u0432 navmesh-\u0435<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3f7\/e43\/705\/3f7e437058295cc816416eccdb5f1b25.png\" width=\"927\" height=\"488\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3f7\/e43\/705\/3f7e437058295cc816416eccdb5f1b25.png\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043f\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c \u0440\u0451\u0431\u0435\u0440 \u0441\u043c\u0435\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0440\u0438\u0434\u043e\u0440\u0430<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/45a\/9b6\/b59\/45a9b6b59328761b652c60ac49157172.png\" width=\"927\" height=\"488\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/45a\/9b6\/b59\/45a9b6b59328761b652c60ac49157172.png\"\/><\/figure>\n<p>\u041d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u044d\u0442\u0430\u043f\u0435 \u044d\u0442\u043e\u0442 \u043f\u0443\u0442\u044c \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a53\/be6\/23e\/a53be623e908fe354127be24eeae3326.png\" width=\"927\" height=\"488\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a53\/be6\/23e\/a53be623e908fe354127be24eeae3326.png\"\/><\/figure>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0445\u043e\u0440\u043e\u0448\u043e \u0442\u0435\u043c, \u0447\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c. \u0410 \u043f\u043b\u043e\u0445 \u043e\u043d \u0442\u0435\u043c, \u0447\u0442\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0432\u044b\u0434\u0430\u0451\u0442 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c. \u0412\u043e\u0442 \u043a\u0430\u043a \u043d\u0430 \u044d\u0442\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cb8\/a92\/dda\/cb8a92dda64b1ddab32c155de61b9f8d.png\" width=\"340\" height=\"336\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb8\/a92\/dda\/cb8a92dda64b1ddab32c155de61b9f8d.png\"\/><\/figure>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u043e\u043d\u044f\u0442\u043d\u0430. \u041a\u043e\u0433\u0434\u0430 \u0432 \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0435 \u043d\u0430\u0448\u043b\u0438 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0446\u0435\u043d\u0442\u0440\u0430\u043c\u0438 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432, \u043e\u043d \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0438\u0434\u043e\u0440, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043a\u043e\u0440\u0438\u0434\u043e\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0435 \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439. \u041d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c, \u0435\u0441\u043b\u0438 \u0441\u0430\u043c navmesh \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e, \u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u0430\u0451\u0442 \u043f\u0440\u0430\u0432\u0434\u043e\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442. \u0413\u043e\u0434\u0438\u0442\u0441\u044f.<\/p>\n<h3>\u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c navmesh \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 Playcanvas<\/h3>\n<p>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0438\u043c\u0435\u0435\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a\u0443\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c9f\/912\/240\/c9f91224033390eb6d4cd8c9a9670279.png\" width=\"1493\" height=\"839\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c9f\/912\/240\/c9f91224033390eb6d4cd8c9a9670279.png\"\/><\/figure>\n<p>\u0417\u0430\u043f\u0435\u0447\u0451\u043d\u043d\u044b\u0439 navmesh \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b70\/bed\/9fd\/b70bed9fdca49b7d64b9c0efcb11f00d.png\" width=\"1477\" height=\"825\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b70\/bed\/9fd\/b70bed9fdca49b7d64b9c0efcb11f00d.png\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0447\u0430\u0435\u043c \u043f\u043e <a href=\"https:\/\/github.com\/Tugcga\/Path-Finder\/releases\/tag\/as.2.4\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0435<\/a> \u0444\u0430\u0439\u043b\u044b <code>navmesh.wasm<\/code> \u0438 <code>navmesh.js<\/code>. \u042d\u0442\u043e wasm-\u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u0432\u044b\u0448\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 AssemblyScript, \u0438 JavaScript-\u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u0434\u043b\u044f \u043d\u0435\u0433\u043e. \u0417\u0430\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u0430 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 Playcanvas-\u0430. \u0412\u043e\u043e\u0431\u0449\u0435 \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0430\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c wasm-\u043c\u043e\u0434\u0443\u043b\u0438, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u043e \u0434\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 Emscripten-\u043e\u043c. \u0410 \u0443 \u043d\u0430\u0441 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0438\u0437 AssemblyScript. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0432 <code>Script Loading Order<\/code> \u043d\u0430\u0448 \u0444\u0430\u0439\u043b <code>navmesh.js<\/code> \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0432\u044b\u0448\u0435<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2cf\/e02\/59f\/2cfe0259f4d1bb63fc1c454064fe6ab8.png\" width=\"1920\" height=\"924\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2cf\/e02\/59f\/2cfe0259f4d1bb63fc1c454064fe6ab8.png\"\/><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <code>navmeshController.js<\/code> \u0438 \u0432\u0435\u0448\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0441\u0446\u0435\u043d\u0435. \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0434\u0432\u0430 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430<\/p>\n<pre><code class=\"javascript\">var NavmeshController = pc.createScript(\"navmeshController\"); NavmeshController.attributes.add(\"wasm_asset\", {type: \"asset\"}); NavmeshController.attributes.add(\"navmesh_asset\", {type: \"asset\", assetType: \"binary\"});<\/code><\/pre>\n<p>\u0410\u0442\u0440\u0438\u0431\u0443\u0442 <code>wasm_asset<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 wasm-\u043c\u043e\u0434\u0443\u043b\u044c. \u0410\u0442\u0440\u0438\u0431\u0443\u0442 <code>navmesh_asset<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0444\u0430\u0439\u043b \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f navmesh-\u0430. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u044f\u043c\u043e \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0440\u0438 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u0430: \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u0440\u0448\u0438\u043d, \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0432\u0435\u0440\u0448\u0438\u043d \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 (\u0438\u0445 \u0447\u0438\u0441\u043b\u043e \u0441\u0442\u043e\u0440\u043e\u043d). \u041c\u043e\u0436\u043d\u043e \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 (\u0434\u0430 \u0434\u0430\u0436\u0435 \u0432 json). \u041e\u0441\u043e\u0431\u043e\u0439 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u043d\u0435\u0442.<\/p>\n<p>\u041d\u0430\u0434\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0451\u0440\u0442\u043a\u0443 <code>navmesh.js<\/code>. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0438\u0437 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c JavaScript-\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0443\u0441\u043e\u043a \u0441 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430\u043c\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435<\/p>\n<pre><code class=\"javascript\">...   return adaptedExports; } \/*export const {   memory,   create_graph,   create_navmesh,   graph_search,   graph_to_bytes,   graph_from_bytes,   navmesh_get_groups_count,   navmesh_search_path,   navmesh_search_path_batch,   navmesh_sample,   navmesh_raycast,   navmesh_intersect_boundary,   navmesh_set_bvh_delta,   navmesh_get_bvh_delta,   navmesh_to_bytes,   navmesh_from_bytes,   create_rtree,   rtree_insert_polygon,   rtree_insert_point,   rtree_insert_edge,   rtree_search,   rtree_insert_edges,   rtree_find_intersection,   rtree_to_bytes,   rtree_from_bytes } = await (async url => instantiate(   await (async () => {     try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }     catch { return globalThis.WebAssembly.compile(await (await import(\"node:fs\/promises\")).readFile(url)); }   })(), {   } ))(new URL(\"navmesh.wasm\", import.meta.url));*\/<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0438\u0448\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0435 <code>navmeshController<\/code>. \u041e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435<\/p>\n<pre><code class=\"javascript\">NavmeshController.prototype.initialize = function() {     this.exports = null;     this.navmesh = null; };<\/code><\/pre>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0430\u043a\u043e\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>navmesh_asset<\/code> \u0438 \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0438\u0445 \u0432 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a<\/p>\n<pre><code class=\"javascript\">const view = new DataView(this.navmesh_asset.resource); const count = view.byteLength \/ 4; let stage = 0; let vertices = []; let polygons = []; let sizes = []; for (let i = 0; i &lt; count; i++) { let v_float = view.getFloat32(4*i); let v_int = view.getInt32(4*i);  if (v_float == Infinity) { stage += 1; } else { if (stage == 0) { vertices.push(v_float); } else if (stage == 1) { polygons.push(v_int); } else if (stage == 2) { sizes.push(v_int); } } }<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0438 \u043d\u0443\u0436\u043d\u044b\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u0430: <code>vertices<\/code>, <code>polygons<\/code> \u0438 <code>sizes<\/code>. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0435\u043c wasm-\u043c\u043e\u0434\u0443\u043b\u044c<\/p>\n<pre><code class=\"javascript\">fetch(this.wasm_asset.getFileUrl()) .then((response) => globalThis.WebAssembly.compileStreaming(response)) .then((module) => instantiate(module)) .then((inst) => this.init_navmesh(inst, vertices, polygons, sizes));<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <code>instantiate(module)<\/code> \u043a\u0430\u043a \u0440\u0430\u0437 \u0438\u0437 \u043e\u0431\u0451\u0440\u0442\u043a\u0438 <code>navmesh.js<\/code>. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0434\u043e \u0435\u0449\u0451 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>init_navmesh<\/code><\/p>\n<pre><code class=\"javascript\">NavmeshController.prototype.init_navmesh = function(exports, vertices, polygons, sizes) {     this.exports = exports;     this.navmesh = this.exports.create_navmesh(vertices, polygons, sizes); };<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0451, <code>this.exports<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 wasm-\u043c\u043e\u0434\u0443\u043b\u044f, \u0430 <code>this.navmesh<\/code> &#8212; \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 navmesh. \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0430\u0439\u0434\u0451\u0442 \u0441\u0432\u043e\u0439 \u043f\u0443\u0442\u044c. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e<\/p>\n<pre><code class=\"javascript\">this.exports.navmesh_search_path(this.navmesh, start[0], start[1], start[2], end[0], end[1], end[2]);<\/code><\/pre>\n<h3>\u0415\u0449\u0451 \u043f\u0430\u0440\u0443 \u0441\u043b\u043e\u0432 \u043f\u0440\u043e \u043c\u043e\u0434\u0443\u043b\u044c navmesh.wasm<\/h3>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u043e\u0436\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438. \u041f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 navmesh-\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u0435\u0433\u043e \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 BVH. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0442\u043e\u0447\u043a\u0443 \u043d\u0430 navmesh-\u0435, \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0443\u044e \u043a \u0434\u0430\u043d\u043d\u043e\u0439. \u041f\u043e\u043b\u0435\u0437\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043a\u0443\u0434\u0430-\u0442\u043e \u043a\u043b\u0438\u043a\u0430\u0435\u043c \u0438 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u0430 \u043f\u043e\u043f\u0430\u043b\u0438 \u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0443 \u0438\u043b\u0438 \u043c\u0438\u043c\u043e \u043a\u043b\u0438\u043a\u043d\u0443\u043b\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>this.exports.navmesh_sample(this.navmesh, x, y, z)<\/code>. \u041e\u043d\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0432\u0435\u043d <code>1<\/code>, \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0435\u0440\u0432\u044b\u0435 \u0442\u0440\u0438 &#8212; \u044d\u0442\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u0442\u043e\u0447\u043a\u0438. \u0415\u0441\u043b\u0438 <code>0<\/code>, \u0442\u043e \u043a\u043b\u0438\u043a\u043d\u0443\u043b\u0438 \u043c\u0438\u043c\u043e.<\/p>\n<p>\u0415\u0449\u0451 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>this.exports.navmesh_raycast(this.navmesh, origin_x, origin_y, origin_z, dir_x, dir_y, sir_z)<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0441 navmesh-\u0435\u043c.<\/p>\n<p>\u0415\u0449\u0451 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f RTree \u0434\u043b\u044f \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0445 \u0440\u0451\u0431\u0435\u0440. \u0415\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043e\u0442\u0440\u0435\u0437\u043e\u043a \u0441 \u0433\u0440\u0430\u043d\u0438\u0446\u0435\u0439 navmesh-\u0430. \u041d\u0443 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0442\u0430\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e, \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/github.com\/Tugcga\/Path-Finder\/tree\/main\/assemblyscript\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c.<\/a><\/p>\n<h2>Lightmap-\u044b<\/h2>\n<p>\u0422\u0443\u0442 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u043e \u0447\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b Playcanvas \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043b\u043e\u0442 \u0434\u043b\u044f lightmap-\u043e\u0432. \u0412\u0441\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u044d\u0442\u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u0432 3d-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435. \u041f\u043e\u0442\u043e\u043c \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 Playcanvs \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u043c.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u043e \u0432\u043e\u0442 \u043d\u0430 \u0442\u0430\u043a\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7d6\/df7\/67f\/7d6df767fdcf6f419986e97228133d4d.png\" width=\"512\" height=\"512\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7d6\/df7\/67f\/7d6df767fdcf6f419986e97228133d4d.png\"\/><\/figure>\n<p>\u042d\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0430 \u0432 Cycles. \u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0432\u0435\u0442\u0430, \u043e\u0434\u0438\u043d \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f \u0438 \u0448\u0430\u0440\u0438\u043a, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u0433\u0440\u0430\u0442\u044c \u0440\u043e\u043b\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0435\u043a\u0430\u0442\u044c \u0432 lightmap-\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043f\u0440\u044f\u043c\u043e\u0435 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435, \u0430 \u043f\u0440\u044f\u043c\u043e\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0435\u043d\u044f\u043c\u0438 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>\u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0435\u043a\u0430\u043d\u0438\u044f. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0432 \u043b\u044e\u0431\u043e\u043c 3d-\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435, \u0445\u043e\u0442\u044c \u0434\u0430\u0436\u0435 \u0438 \u0432 \u0442\u043e\u043c \u0436\u0435 Blender-\u0435<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/43e\/837\/7a4\/43e8377a4d8aa9cc8897f4b28f97796c.png\" width=\"512\" height=\"512\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/43e\/837\/7a4\/43e8377a4d8aa9cc8897f4b28f97796c.png\"\/><\/figure>\n<p>\u0422\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043d\u044e\u0430\u043d\u0441. \u0421\u0430\u043c\u0430 lightmap-\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0434\u0438\u0444\u0444\u0443\u0437\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u043d\u0430 \u0431\u0435\u043b\u0443\u044e \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c. \u0412 Blender-\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>Color<\/code> \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0437\u0430\u043f\u0435\u043a\u0430\u043d\u0438\u044f \u0434\u0438\u0444\u0444\u0443\u0437\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5ed\/325\/d00\/5ed325d00b8ae5b2e5305a129179bbd9.png\" width=\"293\" height=\"250\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5ed\/325\/d00\/5ed325d00b8ae5b2e5305a129179bbd9.png\"\/><\/figure>\n<p>\u0421\u0432\u044f\u0437\u0430\u043d\u043e \u044d\u0442\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u0448\u044d\u0439\u0434\u0435\u0440\u0435 \u0432 Playcanvas \u0446\u0432\u0435\u0442 lightmap-\u044b \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0434\u0438\u0444\u0444\u0443\u0437\u043d\u044b\u0439 \u0446\u0432\u0435\u0442. \u041d\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u0442\u043e\u0433\u0435 \u043a\u0430\u043a \u043d\u0430\u0434\u043e.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 Playcanvas. \u0422\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e lightmap-\u0443 \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u0441\u043b\u043e\u0442<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ca6\/efa\/638\/ca6efa6384cdebd6db4f6b8c2eec0b61.png\" width=\"1616\" height=\"313\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ca6\/efa\/638\/ca6efa6384cdebd6db4f6b8c2eec0b61.png\"\/><\/figure>\n<p>\u0421\u043a\u0440\u0438\u043d \u0438\u0437 \u043e\u043a\u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/92e\/1a2\/474\/92e1a2474a76edf73276f7937c2a8a25.png\" width=\"1920\" height=\"924\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/92e\/1a2\/474\/92e1a2474a76edf73276f7937c2a8a25.png\"\/><\/figure>\n<p>\u0412\u0438\u0434 \u0438\u0437 \u043a\u0430\u043c\u0435\u0440\u044b<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/951\/eed\/22f\/951eed22ff3151a7580eda5fcda87fc6.png\" width=\"512\" height=\"513\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/951\/eed\/22f\/951eed22ff3151a7580eda5fcda87fc6.png\"\/><\/figure>\n<p>\u041f\u043e\u0445\u043e\u0436\u0435?.. \u041f\u043e\u0445\u043e\u0436\u0435!<\/p>\n<h3>Lightmap-\u044b \u0434\u043b\u044f \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f<\/h3>\n<p>\u041d\u0430\u0448 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/116\/d50\/503\/116d505037f3b9433643a2f1925269e1.png\" width=\"1668\" height=\"838\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/116\/d50\/503\/116d505037f3b9433643a2f1925269e1.png\"\/><\/figure>\n<p>\u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0435\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0430<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/82b\/195\/d53\/82b195d53f7f29ac95fb9b6e7a452789.png\" width=\"1024\" height=\"576\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/82b\/195\/d53\/82b195d53f7f29ac95fb9b6e7a452789.png\"\/><\/figure>\n<p>\u041d\u0435 \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432 \u0443\u0440\u043e\u0432\u043d\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0441\u0432\u0435\u0442\u0430 (\u044d\u0442\u043e \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0435 \u043e\u0440\u0430\u043d\u0436\u0435\u0432\u044b\u0435 \u043a\u0440\u0443\u0436\u043e\u0447\u043a\u0438 \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435 \u0432\u044b\u0448\u0435), \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0437\u0430\u043c\u0435\u0442\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0442\u044b\u0440\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f78\/124\/bea\/f78124beae90684c4deffac2f5c29c32.png\" width=\"1521\" height=\"835\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f78\/124\/bea\/f78124beae90684c4deffac2f5c29c32.png\"\/><\/figure>\n<p>\u0412 lightmap-\u044b \u0437\u0430\u043f\u0435\u0447\u0435\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043f\u0440\u044f\u043c\u043e\u0435 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435, \u043d\u043e \u0438 \u043f\u0440\u044f\u043c\u043e\u0435 \u043e\u0442 \u0432\u0441\u0435\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0441\u0432\u0435\u0442\u0430, \u043a\u0440\u043e\u043c\u0435 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445. \u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0435 lightmap-\u044b<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/667\/515\/cd7\/667515cd74079f42e2fd41c437dcc267.png\" width=\"1024\" height=\"512\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/667\/515\/cd7\/667515cd74079f42e2fd41c437dcc267.png\"\/><\/figure>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0446\u0435\u043d\u0430 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u0441 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0430\u043c\u0438<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b14\/4d5\/0ae\/b144d50ae56bd579c369177393ee3dff.png\" width=\"1298\" height=\"615\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b14\/4d5\/0ae\/b144d50ae56bd579c369177393ee3dff.png\"\/><\/figure>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0435\u0441\u043b\u0438 \u0438 \u043d\u0435 \u043e\u0434\u0438\u043d \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0441 \u043f\u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u043c, \u0442\u043e \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043f\u043e\u0445\u043e\u0436\u0435. \u0425\u043e\u0442\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043a\u043e\u0441\u044f\u043a\u0438 \u0435\u0441\u0442\u044c.<\/p>\n<p>\u0412\u043e\u0442 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u044f\u043c\u043e \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0434\u043d\u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e lightmap \u0434\u043b\u044f \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u044f \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u0415\u0441\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c, \u0442\u043e \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u043d\u043e\u0439. \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0441\u0432\u0435\u0442\u0430 \u0432\u0435\u0434\u044c \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u043e\u0447\u0442\u0438 \u0447\u0442\u043e \u0438 \u043d\u0435\u0442<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/017\/78b\/c89\/01778bc899a7fdb77d292abb8ef1c221.png\" width=\"1440\" height=\"780\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/017\/78b\/c89\/01778bc899a7fdb77d292abb8ef1c221.png\"\/><\/figure>\n<p>\u0418 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043c\u044b \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0442\u0435\u0445\u043d\u0438\u043a\u0435 &#8212; lightprob-\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u0430\u043f\u0435\u0447\u0451\u043d\u043d\u043e\u0435 \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435 \u043a \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c.<\/p>\n<h2>Lightprob-\u044b<\/h2>\n<p>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 lightprob-\u044b? \u042d\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0431 \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u0432 \u043e\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430. \u0414\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438. \u0421\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 &#8212; \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u0441\u0444\u0435\u0440\u0430, \u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0437\u0430\u043f\u0435\u0447\u0435\u043d\u0430 \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u044c \u044d\u0442\u043e\u0439 \u0441\u0444\u0435\u0440\u044b. \u041c\u0438\u043d\u0443\u0441 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0430 &#8212; \u044d\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043f\u043e\u0434\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u043c \u0447\u0438\u0441\u043b\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b.<\/p>\n<p>\u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435. \u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0437\u0430\u043f\u0435\u0447\u0451\u043d\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b (R, G \u0438 B) \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0446\u0435\u043d\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0434\u0438\u0441\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u0441\u0444\u0435\u0440\u0435. \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0443 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c &#8212; \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0430 R-, G- \u0438\u043b\u0438 B-\u043a\u0430\u043d\u0430\u043b\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u043f\u0438\u043a\u0441\u0435\u043b\u0435. \u0418\u0434\u0435\u044f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0438\u0441\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0433\u043b\u0430\u0434\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0447\u0438\u0441\u043b\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u041c\u0435\u0442\u043e\u0434 \u0442\u0430\u043a\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u043a\u0430\u043c\u0438. \u042d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u0440\u0430\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0440\u044f\u0434 \u0422\u0435\u0439\u043b\u043e\u0440\u0430, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u043f\u0440\u044f\u043c\u043e\u0439, \u0430 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u0441\u0444\u0435\u0440\u0435. \u0422\u0430\u043a \u043a\u0430\u043a \u043a\u0430\u0440\u0442\u0430 \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0440\u0435\u0437\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432, \u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043a\u0430\u0436\u0434\u0443\u044e \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u044c \u043f\u0435\u0440\u0432\u044b\u043c\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u043c\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u043a\u0438 \u043f\u043e\u0440\u044f\u0434\u043a\u043e\u0432 1, 2 \u0438 3. \u041e\u043d\u0438 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0431\u0449\u0435\u0439 \u0441\u0443\u043c\u043c\u0435 \u0434\u0435\u0432\u044f\u0442\u044c\u044e \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430\u043c\u0438, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0434\u043d\u0430 lightrob-\u0430 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f 30 \u0447\u0438\u0441\u043b\u0430\u043c\u0438: 3 \u0447\u0438\u0441\u043b\u0430 &#8212; \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, 9 \u0447\u0438\u0441\u0435\u043b &#8212; \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u043a\u0430\u0440\u0442\u044b \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u042d\u0442\u043e, \u0437\u043d\u0430\u0447\u0438\u0442, \u043e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u0442\u0430\u043b\u0438. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/google\/spherical-harmonics\" rel=\"noopener noreferrer nofollow\">\u0432\u043e\u0442 \u044d\u0442\u043e\u043c<\/a> \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0443, \u0441\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0443\u044e\u0441\u044f \u0437\u0430 \u0432\u0441\u0435\u043c\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u043c\u0438, \u043e\u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u0441\u0451 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u043e (\u0441 \u0444\u043e\u0440\u043c\u0443\u043b\u0430\u043c\u0438, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u043b\u0430\u043c\u0438 \u0438 \u043f\u0440\u043e\u0447\u0435\u0439 \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e\u0439 \u0437\u0430\u0443\u043c\u044c\u044e). \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e Ravi Ramamoorthi and Pat Hanrahan, An Efficient Representation for Irradiance Environment Maps \/\/ SIGGRAPH, 2001, 497-500. \u041e\u043d\u0430 \u043b\u0435\u0433\u043a\u043e \u0433\u0443\u0433\u043b\u0438\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u043e\u0442: <a href=\"https:\/\/cseweb.ucsd.edu\/~ravir\/papers\/envmap\/\" rel=\"noopener noreferrer nofollow\">https:\/\/cseweb.ucsd.edu\/~ravir\/papers\/envmap\/<\/a><\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0431\u043e\u0440 \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0448\u0430\u0440\u0438\u043a\u043e\u0432 \u043f\u043e navmesh-\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1bd\/b75\/0bc\/1bdb750bc1fef54640c68bd5c6585ff7.png\" width=\"1500\" height=\"831\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1bd\/b75\/0bc\/1bdb750bc1fef54640c68bd5c6585ff7.png\"\/><\/figure>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u044d\u0442\u0438\u0445 \u0442\u043e\u0447\u043a\u0430\u0445, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043d\u0430\u0448 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u0432\u0443\u043c\u0435\u0440\u043d\u044b\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u0432\u044b\u0441\u043e\u0442\u0435 \u043d\u0430\u043c \u0442\u043e\u0436\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043d\u0438\u043a\u0430\u043a \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0435\u043a\u0430\u0435\u043c \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 lightmap-\u0443. \u041c\u043e\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u043e\u0441\u043e\u0431\u043e \u0437\u0430 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043d\u0435 \u0441\u043b\u0435\u0434\u0438\u0442\u044c, \u043f\u043e\u0434\u043e\u0439\u0434\u0451\u0442 \u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0441\u044d\u043c\u043f\u043b\u043e\u0432 \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0435<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/80b\/12d\/1fe\/80b12d1fedc8eea099a077ee4606affa.png\" width=\"512\" height=\"512\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/80b\/12d\/1fe\/80b12d1fedc8eea099a077ee4606affa.png\"\/><\/figure>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u0443\u0441\u043a\u0430 (\u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u0447\u043a\u0430 \u043d\u0430 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0435) \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u044b \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u0435\u0433\u043e \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u043a. \u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u0434 \u043d\u0430 c++<\/p>\n<details class=\"spoiler\">\n<summary>\u0444\u0443\u043d\u043a\u0446\u0438\u044f image_to_sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">float x_to_phi(int x, int width) {     return 2.0 * M_PI * (x + 0.5) \/ width; }  float y_to_theta(int y, int height) {     return M_PI * (y + 0.5) \/ height; }  size_t get_index(int l, int m) {     return l * (l + 1) + m; }  void to_vector(float phi, float theta, float&amp; x, float&amp; y, float&amp; z) {     float r = sin(theta);     x = r * cos(phi);     y = r * sin(phi);     z = cos(theta); }  float clamp(float val, float min, float max) {     if (val &lt; min) { val = min; }     if (val > max) { val = max; }     return val; }  void to_spherical(float x, float y, float z, float&amp; phi, float&amp; theta) {     theta = acos(clamp(z, -1.0, 1.0));     phi = atan2(y, x); }  float hardcoded_sh_00(float x, float y, float z) {     return 0.282095; }  float hardcoded_sh_1n1(float x, float y, float z) {     return -0.488603 * y; }  float hardcoded_sh_10(float x, float, float z) {     return 0.488603 * z; }  float hardcoded_sh_1p1(float x, float y, float z) {     return -0.488603 * x; }  float hardcoded_sh_2n2(float x, float y, float z) {     return 1.092548 * x * y; }  float hardcoded_sh_2n1(float x, float y, float z) {     return -1.092548 * y * z; }  float hardcoded_sh_20(float x, float y, float z) {     return 0.315392 * (-x * x - y * y + 2.0 * z * z); }  float hardcoded_sh_2p1(float x, float y, float z) {     return -1.092548 * x * z; }  float hardcoded_sh_2p2(float x, float y, float z) {     return 0.546274 * (x * x - y * y); }  float eval_sh(int l, int m, float x, float y, float z) {     switch (l) {     case 0:         return hardcoded_sh_00(x, y, z);     case 1:         switch (m) {         case -1:             return hardcoded_sh_1n1(x, y, z);         case 0:             return hardcoded_sh_10(x, y, z);         case 1:             return hardcoded_sh_1p1(x, y, z);         }     case 2:         switch (m) {         case -2:             return hardcoded_sh_2n2(x, y, z);         case -1:             return hardcoded_sh_2n1(x, y, z);         case 0:             return hardcoded_sh_20(x, y, z);         case 1:             return hardcoded_sh_2p1(x, y, z);         case 2:             return hardcoded_sh_2p2(x, y, z);         }     }     return 0.0; }  float eval_sh(int l, int m, float phi, float theta) {     float x, y, z;     to_vector(phi, theta, x, y, z);     return eval_sh(l, m, x, y, z); }  float linear_to_srgb(float v) { if (v &lt;= 0.0f) { return 0.0; } if (v >= 1.0f) { return v; } if (v &lt;= 0.0031308f) { return  12.92f * v; }  return (1.055f * pow(v, 1.0f \/ 2.4f)) - 0.055f; }  std::vector&lt;float> image_to_sh(const std::vector&lt;float>&amp; image_pixels, size_t width, size_t height, size_t channels, bool apply_srgb) {     std::vector&lt;float> to_return(3 * 9);      float pixel_area = (2.0 * M_PI \/ width) * (M_PI \/ height);      for (size_t y = 0; y &lt; height; y++) {         float theta = y_to_theta(y, height);         float weight = pixel_area * sin(theta);          for (size_t x = 0; x &lt; width; x++) {             float phi = x_to_phi(x, width);              float r = image_pixels[channels * (y * width + x)];             float g = image_pixels[channels * (y * width + x) + 1];             float b = image_pixels[channels * (y * width + x) + 2];             if (apply_srgb) {                 r = linear_to_srgb(r);                 g = linear_to_srgb(g);                 b = linear_to_srgb(b);             }              for (int l = 0; l &lt;= 2; l++) {                 for (int m = -l; m &lt;= l; m++) {                     size_t i = get_index(l, m);                     float sh = eval_sh(l, m, phi, theta);                      \/\/ update the i-th coefficient                     to_return[3 * i] += sh * weight * r;                     to_return[3 * i + 1] += sh * weight * g;                     to_return[3 * i + 2] += sh * weight * b;                 }             }         }     }      return to_return; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0443\u0442 \u043d\u0443\u0436\u043d\u0430 &#8212; \u044d\u0442\u043e <code>image_to_sh<\/code>. \u041e\u043d\u0430 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u0435\u0451 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0438 <code>true\/false<\/code> \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043d\u0430\u0434\u043e \u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 sRGB \u0438\u043b\u0438 \u043d\u0435\u0442. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 27 \u0447\u0438\u0441\u0435\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u043a \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043f\u043e \u0438\u0445 \u043f\u043e\u0440\u044f\u0434\u043a\u0430\u043c: \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0440\u0438 \u0447\u0438\u0441\u043b\u0430 (\u0434\u043b\u044f R, G \u0438 B \u043a\u0430\u043d\u0430\u043b\u043e\u0432), \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442, \u043f\u043e\u0442\u043e\u043c \u0435\u0449\u0451 \u0442\u0440\u0438 \u0447\u0438\u0441\u043b\u0430 \u0434\u043b\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b. \u0412\u043e\u0442 \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 <code>256x128<\/code><\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/709\/4d1\/f49\/7094d1f49dbf07f705202a5da5a9adad.png\" width=\"256\" height=\"128\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/709\/4d1\/f49\/7094d1f49dbf07f705202a5da5a9adad.png\"\/><\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u043e\u0432, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u043a\u0438<\/p>\n<pre><code>[1.7648712396621704, 1.6993560791015625, 1.7052123546600342,   -0.5724795460700989, -0.4202347695827484, -0.1682588905096054,   0.4165051579475403, 0.4504852890968323, 0.5280810594558716,   -0.37911805510520935, -0.32987675070762634, -0.2012496143579483,  0.10270054638385773, 0.11499594151973724, 0.09571883082389832,   -0.07035323977470398, -0.048954349011182785, -0.01829037256538868,   -0.1626722514629364, -0.13568037748336792, -0.09725187718868256,   -0.04176412150263786, -0.023417677730321884, 0.0016406839713454247,   -0.007291402202099562, -0.00979363452643156, 0.003937914036214352]<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u043e\u0432, \u043a\u0430\u043a \u043f\u043e \u043d\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u044c, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443. \u0412\u043e\u0442 \u043a\u043e\u0434<\/p>\n<pre><code class=\"cpp\">float eval_sh_sum(const std::vector&lt;float>&amp; sh_coefficients, int channel, float x, float y, float z) {     float sum = 0.0f;     for (int l = 0; l &lt;= 2; l++) {         for (int m = -l; m &lt;= l; m++) {             sum += eval_sh(l, m, x, y, z) * sh_coefficients[get_index(l, m) * 3 + channel];         }     }     return sum; }  std::vector&lt;float> sh_to_image(const std::vector&lt;float>&amp; sh_coefficients, int width, int height) {     std::vector&lt;float> to_return(width * height * 3);  \/\/ return 3-channel image      for (size_t y = 0; y &lt; height; y++) {         float theta = y_to_theta(y, height);         for (size_t x = 0; x &lt; width; x++) {             float phi = x_to_phi(x, width);             float dir_x, dir_y, dir_z;             to_vector(phi, theta, dir_x, dir_y, dir_z);              to_return[3 * (width * y + x)] = eval_sh_sum(sh_coefficients, 0, dir_x, dir_y, dir_z);             to_return[3 * (width * y + x) + 1] = eval_sh_sum(sh_coefficients, 1, dir_x, dir_y, dir_z);             to_return[3 * (width * y + x) + 2] = eval_sh_sum(sh_coefficients, 2, dir_x, dir_y, dir_z);         }     }      return to_return; }<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043d\u0443\u0436\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>sh_to_image<\/code>. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u043e\u0432 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0449\u0435\u0439\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430\u043c, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a32\/4d3\/fa7\/a324d3fa7cf12066b78a79e9b300b4bf.png\" width=\"256\" height=\"128\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a32\/4d3\/fa7\/a324d3fa7cf12066b78a79e9b300b4bf.png\"\/><\/figure>\n<p>\u042d\u0444\u0444\u0435\u043a\u0442\u043d\u043e?.. \u041d\u0435 \u0442\u043e \u0441\u043b\u043e\u0432\u043e!<\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 lightprob-\u044b \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u043e\u0432 \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0432\u0441\u0451 \u0432 \u0444\u0430\u0439\u043b, \u0445\u043e\u0442\u044f \u0431\u044b \u0434\u0430\u0436\u0435 \u0432 *.json. \u0417\u0430\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 Playcanvas, \u0438 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 \u0432\u0441\u0442\u0430\u0451\u0442 \u0434\u0440\u0443\u0433\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c?<\/p>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0435\u0447\u0451\u043d\u043d\u044b\u0445 lightprob-\u043e\u0432 \u0432 Playcanvas<\/h3>\n<p>\u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0451\u0442\u0443 \u043d\u0430\u0434\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0448\u044d\u0439\u0434\u0435\u0440 \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u043b \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0441 lightprob-\u0430\u043c\u0438. \u0425\u043e\u0440\u043e\u0448\u043e, \u0447\u0442\u043e \u0432 Playcanvas \u0435\u0441\u0442\u044c \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c (\u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c) \u0448\u044d\u0439\u0434\u0435\u0440 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430. \u041d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u0430 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f chunk patching. \u041e\u043d\u0430 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u043d\u043e \u0435\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0439 \u043d\u0430 \u0444\u043e\u0440\u0443\u043c\u0435, \u043a\u043e\u0435-\u0447\u0435\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043c\u043e\u0436\u043d\u043e.<\/p>\n<p>\u0428\u044d\u0439\u0434\u0435\u0440 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 &#8212; \u044d\u0442\u043e \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 uber shader. \u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0437 \u043a\u043e\u0434\u0430 \u0448\u044d\u0439\u0434\u0435\u0440\u0430 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043a\u0443\u0441\u043a\u0438, \u0438 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0440\u043e\u0432\u043d\u043e \u0442\u043e\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u0435\u043d. \u0421\u0430\u043c \u0448\u044d\u0439\u0434\u0435\u0440 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0447\u0430\u043d\u043a\u043e\u0432, \u043a\u0430\u043a \u0434\u043b\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u043e\u0433\u043e. \u041d\u0430\u0434\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0447\u0430\u043d\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u043d\u0430\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0448\u044d\u0439\u0434\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044f \u0414\u0435\u043b\u043e\u043d\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u043f\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 lightprob-\u043e\u0432. \u0414\u0430\u043b\u0435\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 update \u0432 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0442\u0440\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u043e\u0432, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u043a\u0438. \u0418\u0445 \u0442\u0440\u0438, \u043d\u0435 \u043f\u043e\u0442\u043e\u043c \u0447\u0442\u043e \u0442\u0440\u0438 \u043a\u0430\u043d\u0430\u043b\u0430, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0435 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438, \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0430\u0434\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431 \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u0435\u0433\u043e \u0432\u0435\u0440\u0448\u0438\u043d. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0431\u0430\u0440\u0438\u0446\u0435\u043d\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0435 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438. \u042d\u0442\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441\u043c\u0435\u0448\u0430\u0442\u044c \u043e\u0441\u0432\u0435\u0449\u0451\u043d\u043d\u043e\u0441\u0442\u044c \u0438\u0437 \u0442\u0440\u0451\u0445 \u0432\u0435\u0440\u0448\u0438\u043d, \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043a \u0446\u0432\u0435\u0442\u0443 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>\u0411\u0443\u0434\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0438 \u0447\u0430\u043d\u043a\u0430:<\/p>\n<ul>\n<li>\n<p><code>startVS<\/code> \u0412 \u043d\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/p>\n<\/li>\n<li>\n<p><code>endVS<\/code> \u0412 \u043d\u0451\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432\u0441\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p><code>emissivePS<\/code> \u0412 \u043d\u0451\u043c \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0439 \u0446\u0432\u0435\u0442<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u0444\u0430\u0439\u043b \u0448\u044d\u0439\u0434\u0435\u0440\u0430 (\u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b) \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <code>startvs_sh_chunk<\/code>. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432 \u043d\u0435\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0447\u0430\u043d\u043a\u0430 <code>startVS<\/code> \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 Playcanvas<\/p>\n<pre><code>void main(void) {     gl_Position = getPosition();<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/p>\n<pre><code>varying vec3 sh_color; uniform vec3 sh0_coefficients[9]; uniform vec3 sh1_coefficients[9]; uniform vec3 sh2_coefficients[9]; uniform vec3 baricenteric_coordinates;  void main(void) {     gl_Position = getPosition();<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u0448\u044d\u0439\u0434\u0435\u0440\u0430 <code>endvs_sh_chunk<\/code>. \u0415\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0443\u0441\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0438\u0448\u0435\u043c<\/p>\n<pre><code>vec3 n = vNormalW;  sh_color =     (sh0_coefficients[0] * baricenteric_coordinates.x + sh1_coefficients[0] * baricenteric_coordinates.y + sh2_coefficients[0] * baricenteric_coordinates.z) * 0.282095 +     (sh0_coefficients[1] * baricenteric_coordinates.x + sh1_coefficients[1] * baricenteric_coordinates.y + sh2_coefficients[1] * baricenteric_coordinates.z) * -0.488603 * n.z +     (sh0_coefficients[2] * baricenteric_coordinates.x + sh1_coefficients[2] * baricenteric_coordinates.y + sh2_coefficients[2] * baricenteric_coordinates.z) * 0.488603 * n.y +     (sh0_coefficients[3] * baricenteric_coordinates.x + sh1_coefficients[3] * baricenteric_coordinates.y + sh2_coefficients[3] * baricenteric_coordinates.z) * -0.488603 * n.x +     (sh0_coefficients[4] * baricenteric_coordinates.x + sh1_coefficients[4] * baricenteric_coordinates.y + sh2_coefficients[4] * baricenteric_coordinates.z) * 1.092548 * n.x * n.z +     (sh0_coefficients[5] * baricenteric_coordinates.x + sh1_coefficients[5] * baricenteric_coordinates.y + sh2_coefficients[5] * baricenteric_coordinates.z) * -1.092548 * n.z * n.y +     (sh0_coefficients[6] * baricenteric_coordinates.x + sh1_coefficients[6] * baricenteric_coordinates.y + sh2_coefficients[6] * baricenteric_coordinates.z) * 0.315392 * (-n.x * n.x - n.z * n.z + 2.0 * n.y * n.y) +     (sh0_coefficients[7] * baricenteric_coordinates.x + sh1_coefficients[7] * baricenteric_coordinates.y + sh2_coefficients[7] * baricenteric_coordinates.z) * -1.092548 * n.x * n.y +     (sh0_coefficients[8] * baricenteric_coordinates.x + sh1_coefficients[8] * baricenteric_coordinates.y + sh2_coefficients[8] * baricenteric_coordinates.z) * 0.546274 * (n.x * n.x - n.z * n.z);<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0444\u0430\u0439\u043b <code>emissive_sh_chunk<\/code>. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435<\/p>\n<pre><code>#ifdef MAPCOLOR uniform vec3 material_emissive; #endif  #ifdef MAPFLOAT uniform float material_emissiveIntensity; #endif  void getEmission() {     dEmission = vec3(1.0);      #ifdef MAPFLOAT     dEmission *= material_emissiveIntensity;     #endif      #ifdef MAPCOLOR     dEmission *= material_emissive;     #endif      #ifdef MAPTEXTURE     dEmission *= $DECODE(texture2DBias($SAMPLER, $UV, textureBias)).$CH;     #endif      #ifdef MAPVERTEX     dEmission *= gammaCorrectInput(saturate(vVertexColor.$VC));     #endif }<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u043a<\/p>\n<pre><code>#ifdef MAPCOLOR uniform vec3 material_emissive; #endif  #ifdef MAPFLOAT uniform float material_emissiveIntensity; #endif  varying vec3 sh_color;  void getEmission() {     dEmission = vec3(1.0);      #ifdef MAPFLOAT     dEmission *= material_emissiveIntensity;     #endif      #ifdef MAPCOLOR     dEmission *= material_emissive;     #endif      #ifdef MAPTEXTURE     dEmission *= $DECODE(texture2DBias($SAMPLER, $UV, textureBias)).$CH;     #endif      #ifdef MAPVERTEX     dEmission *= gammaCorrectInput(saturate(vVertexColor.$VC));     #endif      dEmission += sh_color * dAlbedo; }<\/code><\/pre>\n<p>\u0427\u0430\u043d\u043a\u0438 \u0433\u043e\u0442\u043e\u0432\u044b. \u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0445 \u043d\u0430\u0434\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432 \u0448\u044d\u0439\u0434\u0435\u0440\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <code>probesController.js<\/code> \u0438 \u0432\u0435\u0448\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432<\/p>\n<pre><code class=\"javascript\">var ProbesController = pc.createScript(\"probesController\"); ProbesController.attributes.add(\"probes_data\", {type: 'asset', assetType: 'json'}) ProbesController.attributes.add(\"emissive_chunk\", {type: \"asset\", assetType: \"shader\"}); ProbesController.attributes.add(\"startvs_chunk\", {type: \"asset\", assetType: \"shader\"}); ProbesController.attributes.add(\"endvs_chunk\", {type: \"asset\", assetType: \"shader\"});<\/code><\/pre>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043f\u043e\u043d\u044f\u0442\u043d\u043e. <code>emissive_chunk<\/code>, <code>startvs_chunk<\/code> \u0438 <code>endvs_chunk<\/code> &#8212; \u044d\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0442\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438, \u0430 <code>probes_data<\/code> &#8212; \u044d\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 *.json \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 lightprob-\u043e\u0432. \u041d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044e \u0414\u0435\u043b\u043e\u043d\u0435 \u0438 \u0443\u043b\u043e\u0436\u0438\u0442\u044c \u0435\u0451 \u0432 BVH \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432. \u0418\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0441\u0430\u043c\u0443 \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u044e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0451 \u0432 \u0444\u0430\u0439\u043b *.json. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0443\u0442 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e BVH<\/p>\n<details class=\"spoiler\">\n<summary>\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f BVH<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">class Triangle {     constructor(index, i0, i1, i2, positions) {         this.index = index;         \/\/ point indices         this.i0 = i0;         this.i1 = i1;         this.i2 = i2;          \/\/ point coordinates         this.v0 = positions[i0];         this.v1 = positions[i1];         this.v2 = positions[i2];          this.center = [(this.v0[0] + this.v1[0] + this.v2[0]) \/ 3.0,                         (this.v0[1] + this.v1[2] + this.v2[3]) \/ 3.0];         this.aabb = [Math.min(this.v0[0], this.v1[0], this.v2[0]),                       Math.min(this.v0[1], this.v1[1], this.v2[1]),                      Math.max(this.v0[0], this.v1[0], this.v2[0]),                       Math.max(this.v0[1], this.v1[1], this.v2[1])]                  \/\/ need for baricentric calculations         this.det = (this.v0[0] - this.v2[0]) * (this.v1[1] - this.v2[1]) -                     (this.v1[0] - this.v2[0]) * (this.v0[1] - this.v2[1]);     }      get_center() { return this.center; }      get_aabb() { return this.aabb; }      get_i0() { return this.i0; }     get_i1() { return this.i1; }     get_i2() { return this.i2; }      is_point_inside(x, y) {         const as_x = x - this.v0[0];         const as_y = y - this.v0[1];          const s_ab = ((this.v1[0] - this.v0[0]) * as_y - (this.v1[1] - this.v0[1]) * as_x) > 0;          if (((this.v2[0] - this.v0[0]) * as_y - (this.v2[1] - this.v0[1]) * as_x > 0) == s_ab) {             return false;         }         if (((this.v2[0] - this.v1[0]) * (y - this.v1[1]) - (this.v2[1] - this.v1[1]) * (x - this.v1[0]) > 0) != s_ab) {             return false;         }         return true;     }      \/\/ return 3-valued array [a, b, c] with a + b + c = 1     get_baricentric(x, y) {         const l1 = ((this.v1[1] - this.v2[1]) * (x - this.v2[0]) +                      (this.v2[0] - this.v1[0]) * (y - this.v2[1])) \/ this.det;         const l2 = ((this.v2[1] - this.v0[1]) * (x - this.v2[0]) +                      (this.v0[0] - this.v2[0]) * (y - this.v2[1])) \/ this.det;         return [l1, l2, 1.0 - l1 - l2];     } }  function union_aabbs(a1, a2) {     return [Math.min(a1[0], a2[0]),             Math.min(a1[1], a2[1]),             Math.max(a1[2], a2[2]),             Math.max(a1[3], a2[3])]; }  class BVHNode {     constructor(triangles) {         this.left = null;         this.right = null;         this.object = null;         this.aabb = null;         const objects_count = triangles.length;         if (objects_count == 1) {             this.object = triangles[0];             this.aabb = this.object.get_aabb();         } else {             let median = [0.0, 0.0];             let x_min = Number.MAX_VALUE;             let y_min = Number.MAX_VALUE;             let x_max = Number.MIN_VALUE;             let y_max = Number.MIN_VALUE;              for (let i = 0; i &lt; objects_count; i++) {                 const t = triangles[i];                 const t_center = t.get_center();                 median[0] += t_center[0];                 median[1] += t_center[1];                 if (t_center[0] &lt; x_min) { x_min = t_center[0]; }                 if (t_center[0] > x_max) { x_max = t_center[0]; }                 if (t_center[1] &lt; y_min) { y_min = t_center[1]; }                 if (t_center[1] > y_max) { y_max = t_center[1]; }             }             median[0] = median[0] \/ objects_count;             median[1] = median[1] \/ objects_count;              const split_axis = (x_max - x_min) > (y_max - y_min) ? 0 : 1;             const median_value = median[split_axis];              let left_objects = [];             let right_objects = [];             for (let i = 0; i &lt; objects_count; i++) {                 const t = triangles[i];                 const t_center = t.get_center();                 if (t_center[split_axis] &lt; median_value) {                     left_objects.push(t);                 } else {                     right_objects.push(t);                 }             }             if (left_objects.length == 0) {                 left_objects.push(right_objects.pop());             }else if (right_objects.length == 0) {                 right_objects.push(left_objects.pop());             }              this.left = new BVHNode(left_objects);             this.right = new BVHNode(right_objects);              this.aabb = union_aabbs(this.left.get_aabb(), this.right.get_aabb());         }     }      get_aabb() {         return this.aabb;     }      is_inside_aabb(x, y) {         return this.aabb[0] &lt; x &amp;&amp; this.aabb[1] &lt; y &amp;&amp; this.aabb[2] > x &amp;&amp; this.aabb[3] > y;     }      sample(x, y) {         if (this.is_inside_aabb(x, y)) {             if (this.object != null) {                 if (this.object.is_point_inside(x, y)) {                     return this.object;                 } else {                     return null;                 }             } else {                 const left_sample = this.left.sample(x, y);                 const right_sample = this.right.sample(x, y);                 if (left_sample == null) {                     return right_sample;                 } else {                     if (right_sample == null) {                         return left_sample;                     }                      const left_center = left_sample.get_center();                     const right_center = right_sample.get_center();                      const left_dist = (x - left_center[0]) * (x - left_center[0]) +                                        (y - left_center[1]) * (y - left_center[1]);                     const right_dist = (x - right_center[0]) * (x - right_center[0]) +                                         (y - right_center[1]) * (y - right_center[1]);                                          if (left_dist &lt; right_dist) {                         return left_sample;                     } else {                         return right_sample;                     }                 }             }         } else {             return null;         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 BVH \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"javascript\">ProbesController.prototype.initialize = function() {     const probes_data = this.probes_data.resource;     this.probes = probes_data.probes;     const triangulation = probes_data.triangulation;     const probes_positions = [];     for (let index = 0; index &lt; this.probes.length; index++) {         const probe = this.probes[index];         const coords = probe.coordinates         probes_positions.push([coords[0], coords[2]]);     }     const triangles = [];     const triangles_count = triangulation.length \/ 3;     for (let i = 0; i &lt; triangles_count; i++) {         triangles.push(new Triangle(i,                                     triangulation[3*i],                                     triangulation[3*i + 1],                                     triangulation[3*i + 2],                                     probes_positions));     }      this.bvh = new BVHNode(triangles);     this.entities = new Map(); };<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0442\u0447\u0438\u0442\u044c \u0448\u044d\u0439\u0434\u0435\u0440 \u043b\u044e\u0431\u043e\u0433\u043e \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/p>\n<pre><code class=\"javascript\">ProbesController.prototype.add_entity = function(entity) {     const e_render = entity.render;     const inst_count = e_render.meshInstances.length;     const materials = [];     for (let i = 0; i &lt; inst_count; i++) {         const inst = e_render.meshInstances[i];         const m = inst.material.clone();         m.chunks.APIVersion = pc.CHUNKAPI_1_62;         m.chunks.emissivePS = this.emissive_chunk.resource;         m.chunks.startVS = this.startvs_chunk.resource;         m.chunks.endVS = this.endvs_chunk.resource;          m.update();         materials.push(m);          e_render.meshInstances[i].material = m;     }      const e_pos = entity.getPosition();     const e_triangle = this.bvh.sample(e_pos.x, e_pos.z);          this.entities.set(entity, {position: [e_pos.x, e_pos.y, e_pos.z],                                triangle: e_triangle,                                materials: materials});     if (e_triangle != null) {         const bc = e_triangle.get_baricentric(e_pos.x, e_pos.z);         for (let i = 0; i &lt; materials.length; i++) {             const m = materials[i];             m.setParameter(\"sh0_coefficients[0]\", this.probes[e_triangle.get_i0()].sh);             m.setParameter(\"sh1_coefficients[0]\", this.probes[e_triangle.get_i1()].sh);             m.setParameter(\"sh2_coefficients[0]\", this.probes[e_triangle.get_i2()].sh);             m.setParameter(\"baricenteric_coordinates\", bc);         }     } }<\/code><\/pre>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 &#8212; \u043c\u0435\u0442\u043e\u0434 <code>update<\/code><\/p>\n<pre><code class=\"javascript\">ProbesController.prototype.update = function(dt) {     for (const [entity, e_data] of this.entities) {         const e_pos = entity.getPosition();         const prev_pos = e_data.position;         const delta = (e_pos.x - prev_pos[0]) * (e_pos.x - prev_pos[0]) +                        (e_pos.y - prev_pos[1]) * (e_pos.y - prev_pos[1]) +                        (e_pos.z - prev_pos[2]) * (e_pos.z - prev_pos[2]);         if (delta > 0.001) {             e_data.position[0] = e_pos.x;             e_data.position[1] = e_pos.y;             e_data.position[2] = e_pos.z;              const e_triangle = this.bvh.sample(e_pos.x, e_pos.z);             e_data.triangle = e_triangle;              if (e_triangle != null) {                 const bc = e_triangle.get_baricentric(e_pos.x, e_pos.z);                 const materials = e_data.materials;                 for (let i = 0; i &lt; materials.length; i++) {                     const m = materials[i];                     m.setParameter(\"sh0_coefficients[0]\", this.probes[e_triangle.get_i0()].sh);                     m.setParameter(\"sh1_coefficients[0]\", this.probes[e_triangle.get_i1()].sh);                     m.setParameter(\"sh2_coefficients[0]\", this.probes[e_triangle.get_i2()].sh);                     m.setParameter(\"baricenteric_coordinates\", bc);                 }             }         }     } };<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u0441\u0432\u0435\u0449\u0430\u043b\u0441\u044f lightprob-\u0430\u043c\u0438, \u0442\u043e \u043f\u0440\u0438 \u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u043c\u0435\u0442\u043e\u0434 <code>add_entity<\/code> \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0418 \u0432\u0441\u0451.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ec\/890\/bab\/3ec890baba352fb2c363e1e2db50566b.png\" width=\"800\" height=\"1299\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ec\/890\/bab\/3ec890baba352fb2c363e1e2db50566b.png\"\/><\/figure>\n<p>\u041d\u0443, \u043a\u0430\u043a\u0430\u0432\u0430 \u043a\u0440\u0430\u0441\u043e\u0442\u0430&#8230;<\/p>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0438<\/h2>\n<ul>\n<li>\n<p><a href=\"https:\/\/playcanvas.com\" rel=\"noopener noreferrer nofollow\">https:\/\/playcanvas.com<\/a> &#8212; \u0441\u0430\u0439\u0442 \u0434\u0432\u0438\u0436\u043a\u0430, <a href=\"https:\/\/github.com\/playcanvas\/engine\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/playcanvas\/engine<\/a> &#8212; \u0435\u0433\u043e \u0433\u0438\u0442\u0445\u0430\u0431<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/playcanvas.com\/project\/1169594\/overview\/small-dungeon\" rel=\"noopener noreferrer nofollow\">https:\/\/playcanvas.com\/project\/1169594\/overview\/small-dungeon<\/a> &#8212; \u0435\u0449\u0451 \u0440\u0430\u0437 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/recastnavigation\/recastnavigation\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/recastnavigation\/recastnavigation<\/a> &#8212; \u043a\u0430\u043d\u043e\u043d\u0438\u0447\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u043f\u0435\u043a\u0430\u043d\u0438\u044f navmesh-\u0435\u0439<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/Tugcga\/Path-Finder\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Tugcga\/Path-Finder<\/a> &#8212; \u0435\u0449\u0451 \u0440\u0430\u0437 \u043c\u043e\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f navmesh-\u0435\u0439 \u043d\u0430 Python \u0438 AssemblyScript<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/donmccurdy\/three-pathfinding\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/donmccurdy\/three-pathfinding<\/a> &#8212; \u043e\u0442\u0441\u044e\u0434\u0430 \u0432\u0437\u044f\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043f\u043e\u0438\u0441\u043a\u0443 \u043f\u0443\u0442\u0435\u0439 \u043d\u0430 navmesh-\u0430\u0445<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/google\/spherical-harmonics\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/google\/spherical-harmonics<\/a> &#8212; \u0433\u0438\u0442\u0445\u0430\u0431 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0433\u0430\u0440\u043c\u043e\u043d\u0438\u043a, \u0442\u0430\u043c \u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u044b<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/783174\/\"> https:\/\/habr.com\/ru\/articles\/783174\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u044b\u0431\u043e\u0440 Playcanvas<\/h2>\n<p>\u0414\u043b\u044f \u043c\u0435\u043d\u044f \u0432\u0435\u0434\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b\u043e \u043e\u0442\u0434\u044b\u0445\u043e\u043c \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043e\u0442\u0432\u043b\u0435\u0447\u044c\u0441\u044f \u043e\u0442 \u0440\u0430\u0431\u043e\u0442\u044b. \u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043c\u043e\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0433\u0435\u0439\u043c\u0434\u0435\u0432\u0430 \u0438\u043b\u0438 \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u043d\u0435\u043c\u0443. \u041c\u043e\u0436\u043d\u043e \u043d\u0435 \u0441\u043f\u0435\u0448\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u044b, \u043f\u0440\u0438\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u0441\u0451, \u0432 \u0447\u0451\u043c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0441\u044f, \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u043e. \u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f 3d-\u0438\u0433\u0440\u044b \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0412\u043e\u0442 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0437\u043d\u0430\u044e \u043f\u043e\u0447\u0435\u043c\u0443. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0443\u043c\u0435\u044e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438 (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 3d), \u0438 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0435 \u0438\u0433\u0440\u044b \u043a\u0430\u0436\u0443\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438: \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e, \u043d\u0430 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432 1 \u043a\u043b\u0438\u043a, \u043f\u0440\u0438 \u0434\u043e\u043b\u0436\u043d\u043e\u0439 \u0441\u043d\u043e\u0440\u043e\u0432\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0442\u043e\u0440\u043c\u043e\u0448\u0438\u0442\u044c \u043d\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435. \u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u044d\u0442\u043e \u0435\u0449\u0451 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u043e\u0433\u0434\u0430 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u0435 \u0438\u0433\u0440\u044b \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u043b\u0438 \u0440\u0430\u0441\u0446\u0432\u0435\u0442. \u0422\u0430\u043a \u0432\u043e\u0442 \u0432\u0441\u0451 \u0438 \u043d\u0435 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0435\u0442.<\/p>\n<p>\u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0432\u0441\u0435\u0445 \u0431\u0435\u0434\u043d\u044b\u0445 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u044e\u0442 &#8212; \u043a\u0430\u043a\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0432\u044b\u0431\u0440\u0430\u0442\u044c? \u0418 \u0442\u0443\u0442 \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Unity. \u0421\u043b\u0438\u0448\u043a\u043e\u043c \u0443\u0436 \u043e\u043d \u0445\u043e\u0440\u043e\u0448. \u042d\u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u043d\u044b\u043c \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u0442 \u043d\u0435\u0433\u043e \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0448\u044c\u0441\u044f. \u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0438\u0433\u0440\u043e\u0432\u044b\u043c \u0434\u0432\u0438\u0436\u043a\u043e\u043c \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043d\u0438\u0445, \u0440\u0435\u0448\u0438\u043b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 Playcanvas. \u041e\u0431\u044a\u0451\u043c \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u043a\u0430 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 (\u0447\u0442\u043e-\u0442\u043e \u043e\u043a\u043e\u043b\u043e 1-\u0433\u043e \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0430 \u0432 \u043c\u0438\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435), \u0435\u0441\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0433\u0440\u0430\u0444\u0438\u043a\u0438, \u043d\u043e \u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438\u0433\u0440. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0435\u0441\u0442\u044c \u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b, BabylonJS \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439, \u0438\u043b\u0438 Cocos.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445. \u0412 Playcanvas \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u0435. \u041d\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u043e\u0433\u043e, \u0447\u0435\u0433\u043e \u0432 \u043d\u0451\u043c \u043d\u0435\u0442, \u043d\u043e \u0447\u0442\u043e \u0432 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e \u043d\u0430\u0434\u043e \u0447\u0430\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0412 \u044d\u0442\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u0434\u0432\u0435 \u0442\u0430\u043a\u0438\u0445 \u0442\u0435\u043c\u044b. \u041f\u0435\u0440\u0432\u0430\u044f \u0442\u0435\u043c\u0430 &#8212; \u044d\u0442\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 navmesh-\u0435\u0439. \u0412\u0442\u043e\u0440\u0430\u044f \u0442\u0435\u043c\u0430 &#8212; \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 lightmap-\u043e\u0432 \u0438 lightprob-\u043e\u0432. \u042d\u0442\u043e \u0435\u0441\u0442\u044c \u0432 Unity, \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0442 \u0432 Playcanvas. \u041d\u0430\u0434\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c. \u041e\u0431\u0441\u0443\u0434\u0438\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438 \u043f\u043e \u043e\u0431\u0435\u0438\u043c \u0442\u0435\u043c\u0430\u043c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u043e, \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 Playcanvas. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0438 \u0440\u0435\u0446\u0435\u043f\u0442\u044b \u0438 \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434\u043e\u0439\u0434\u0443\u0442 \u0438 \u043f\u043e\u0434 \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a. Playcanvas \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0432\u0443\u0445 \u0432\u0438\u0434\u0430: \u043a\u0430\u043a \u0444\u0440\u044d\u0439\u043c\u0432\u043e\u0440\u043a, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f web-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (WebPack \u0442\u0430\u043c, TypeScript \u0438 \u043f\u0440\u043e\u0447\u0435\u0435), \u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0446\u0435\u043d\u044b \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435. \u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u044d\u0442\u043e\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u0432\u043e\u0442 \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0434\u0430\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 <a href=\"https:\/\/playcanvas.com\/project\/1169594\/overview\/small-dungeon\" rel=\"noopener noreferrer nofollow\">\u0434\u0435\u043c\u043e-\u043f\u0440\u043e\u0435\u043a\u0442<\/a>. \u042d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0438\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u0441\u0451 \u0442\u043e, \u043e \u0447\u0451\u043c \u043f\u043e\u0439\u0434\u0451\u0442 \u0440\u0435\u0447\u044c.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h2>Navmesh<\/h2>\n<p>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0435\u0442\u043a\u0430 (\u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043d\u0433\u043b\u0438\u0446\u0438\u0437\u043c navmesh) &#8212; \u044d\u0442\u043e \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043e\u0442\u044b\u0441\u043a\u0430\u043d\u0438\u044e \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0435\u0433\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u0432 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u0441\u0446\u0435\u043d\u0435. \u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438: \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c navmesh, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432 <a href=\"https:\/\/github.com\/recastnavigation\/recastnavigation\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u0422\u0430\u043a\u043e\u0435 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0443\u043c\u0435\u0435\u0442 \u0437\u0430\u043f\u0435\u043a\u0430\u0442\u044c navmesh, \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u043d\u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f. \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u044f \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430 Python \u0438 AssemblyScript. \u0412\u043e\u0442  <a href=\"https:\/\/github.com\/Tugcga\/Path-Finder\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0430\u043c navmesh \u043c\u044b \u0443\u043c\u0435\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438 \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0435\u0440\u0448\u0438\u043d \u0432 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438 \u043d\u0430\u0431\u043e\u0440\u044b \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0432\u0435\u0440\u0448\u0438\u043d, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u044b.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u043a\u0430\u043a \u043d\u0430\u0439\u0442\u0438 \u043f\u0443\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u043d\u0430 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u0445 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e navmesh-\u0430. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440. \u0421\u0446\u0435\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u0430\u043f\u0435\u0447\u0451\u043d\u043d\u044b\u0439 navmesh \u0442\u0430\u043a<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434, \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u0432 <a href=\"https:\/\/github.com\/donmccurdy\/three-pathfinding\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u0421\u0443\u0442\u044c \u0442\u0430\u043a\u043e\u0432\u0430. \u041d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u044b navmesh-\u0430 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 BVH (Bounding Volume Hierarchy) \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0433\u0440\u0430\u0444. \u0412\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438 \u044d\u0442\u043e\u0433\u043e \u0433\u0440\u0430\u0444\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0446\u0435\u043d\u0442\u0440\u044b \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432, \u0438 \u0434\u0432\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0440\u0435\u0431\u0440\u043e\u043c, \u0435\u0441\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u043c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u044b \u0438\u043c\u0435\u044e\u0442 \u043e\u0431\u0449\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443. \u041f\u043e\u043f\u0443\u0442\u043d\u043e \u0435\u0449\u0451 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u044f\u043a\u0430\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u043e\u0439 \u043f\u043e\u043b\u0438\u0433\u043e\u043d \u043f\u043e \u043a\u0430\u043a\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441 \u043a\u0430\u043a\u0438\u043c \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u043c \u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442.<\/p>\n<p>\u041a\u0440\u0430\u0442\u043a\u043e \u043e\u043f\u0438\u0448\u0435\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438. \u0411\u0435\u0440\u0451\u043c \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u043a\u0430\u043a\u0438\u0445 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u0445 \u043e\u043d\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f. \u042d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e BVH-\u0430. \u041f\u043e\u0442\u043e\u043c \u0431\u0435\u0440\u0451\u043c \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0438\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0433\u0440\u0430\u0444\u0430, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043f\u0443\u0442\u044c \u0432 \u0433\u0440\u0430\u0444\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e A*.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0437\u0430\u0434\u0430\u0451\u0442 \u043a\u043e\u0440\u0438\u0434\u043e\u0440 \u0438\u0437 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 \u0432 navmesh-\u0435<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043f\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c \u0440\u0451\u0431\u0435\u0440 \u0441\u043c\u0435\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0440\u0438\u0434\u043e\u0440\u0430<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u044d\u0442\u0430\u043f\u0435 \u044d\u0442\u043e\u0442 \u043f\u0443\u0442\u044c \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0445\u043e\u0440\u043e\u0448\u043e \u0442\u0435\u043c, \u0447\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c. \u0410 \u043f\u043b\u043e\u0445 \u043e\u043d \u0442\u0435\u043c, \u0447\u0442\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0432\u044b\u0434\u0430\u0451\u0442 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c. \u0412\u043e\u0442 \u043a\u0430\u043a \u043d\u0430 \u044d\u0442\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435<\/p>\n<figure class=\"\"><\/figure>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u043e\u043d\u044f\u0442\u043d\u0430. \u041a\u043e\u0433\u0434\u0430 \u0432 \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0435 \u043d\u0430\u0448\u043b\u0438 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0446\u0435\u043d\u0442\u0440\u0430\u043c\u0438 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432, \u043e\u043d \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0438\u0434\u043e\u0440, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043a\u043e\u0440\u0438\u0434\u043e\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0434\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0435 \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439. \u041d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c, \u0435\u0441\u043b\u0438 \u0441\u0430\u043c navmesh \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e, \u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u0430\u0451\u0442 \u043f\u0440\u0430\u0432\u0434\u043e\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442. \u0413\u043e\u0434\u0438\u0442\u0441\u044f.<\/p>\n<h3>\u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c navmesh \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 Playcanvas<\/h3>\n<p>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0438\u043c\u0435\u0435\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a\u0443\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u0430\u043f\u0435\u0447\u0451\u043d\u043d\u044b\u0439 navmesh \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0447\u0430\u0435\u043c \u043f\u043e <a href=\"https:\/\/github.com\/Tugcga\/Path-Finder\/releases\/tag\/as.2.4\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0435<\/a> \u0444\u0430\u0439\u043b\u044b <code>navmesh.wasm<\/code> \u0438 <code>navmesh.js<\/code>. \u042d\u0442\u043e wasm-\u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u0432\u044b\u0448\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 AssemblyScript, \u0438 JavaScript-\u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u0434\u043b\u044f \u043d\u0435\u0433\u043e. \u0417\u0430\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u0430 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 Playcanvas-\u0430. \u0412\u043e\u043e\u0431\u0449\u0435 \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0430\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c wasm-\u043c\u043e\u0434\u0443\u043b\u0438, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u043e \u0434\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 Emscripten-\u043e\u043c. \u0410 \u0443 \u043d\u0430\u0441 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0438\u0437 AssemblyScript. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0432 <code>Script Loading Order<\/code> \u043d\u0430\u0448 \u0444\u0430\u0439\u043b <code>navmesh.js<\/code> \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0432\u044b\u0448\u0435<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <code>navmeshController.js<\/code> \u0438 \u0432\u0435\u0448\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0441\u0446\u0435\u043d\u0435. \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0434\u0432\u0430 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430<\/p>\n<pre><code class=\"javascript\">var NavmeshController = pc.createScript(\"navmeshController\"); NavmeshController.attributes.add(\"wasm_asset\", {type: \"asset\"}); NavmeshController.attributes.add(\"navmesh_asset\", {type: \"asset\", assetType: \"binary\"});<\/code><\/pre>\n<p>\u0410\u0442\u0440\u0438\u0431\u0443\u0442 <code>wasm_asset<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 wasm-\u043c\u043e\u0434\u0443\u043b\u044c. \u0410\u0442\u0440\u0438\u0431\u0443\u0442 <code>navmesh_asset<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0444\u0430\u0439\u043b \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f navmesh-\u0430. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u044f\u043c\u043e \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0440\u0438 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u0430: \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u0440\u0448\u0438\u043d, \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0432\u0435\u0440\u0448\u0438\u043d \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u043e\u0432 (\u0438\u0445 \u0447\u0438\u0441\u043b\u043e \u0441\u0442\u043e\u0440\u043e\u043d). \u041c\u043e\u0436\u043d\u043e \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 (\u0434\u0430 \u0434\u0430\u0436\u0435 \u0432 json). \u041e\u0441\u043e\u0431\u043e\u0439 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u043d\u0435\u0442.<\/p>\n<p>\u041d\u0430\u0434\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0451\u0440\u0442\u043a\u0443 <code>navmesh.js<\/code>. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0438\u0437 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c JavaScript-\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u0443\u0441\u043e\u043a \u0441 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430\u043c\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435<\/p>\n<pre><code class=\"javascript\">...   return adaptedExports; } \/*export const {   memory,   create_graph,   create_navmesh,   graph_search,   graph_to_bytes,   graph_from_bytes,   navmesh_get_groups_count,   navmesh_search_path,   navmesh_search_path_batch,   navmesh_sample,   navmesh_raycast,   navmesh_intersect_boundary,   navmesh_set_bvh_delta,   navmesh_get_bvh_delta,   navmesh_to_bytes,   navmesh_from_bytes,   create_rtree,   rtree_insert_polygon,   rtree_insert_point,   rtree_insert_edge,   rtree_search,   rtree_insert_edges,   rtree_find_intersection,   rtree_to_bytes,   rtree_from_bytes } = await (async url => instantiate(   await (async () => {     try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }     catch { return globalThis.WebAssembly.compile(await (await import(\"node:fs\/promises\")).readFile(url)); }   })(), {   } ))(new URL(\"navmesh.wasm\", import.meta.url));*\/<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0438\u0448\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0435 <code>navmeshController<\/code>. \u041e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435<\/p>\n<pre><code class=\"javascript\">NavmeshController.prototype.initialize = function() {     this.exports = null;     this.navmesh = null; };<\/code><\/pre>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u0430\u043a\u043e\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>navmesh_asset<\/code> \u0438 \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0438\u0445 \u0432 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a<\/p>\n<pre><code class=\"javascript\">const view = new DataView(this.navmesh_asset.resource); const count = view.byteLength \/ 4; let stage = 0; let vertices = []; let polygons = []; let sizes = []; for (let i = 0; i &lt; count; i++) { let v_float = view.getFloat32(4*i); let v_int = view.getInt32(4*i);  if (v_float == Infinity) { stage += 1; } else { if (stage == 0) { vertices.push(v_float); } else if (stage == 1) { polygons.push(v_int); } else if (stage == 2) { sizes.push(v_int); } } }<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0438 \u043d\u0443\u0436\u043d\u044b\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u0430: <code>vertices<\/code>, <code>polygons<\/code> \u0438 <code>sizes<\/code>. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0435\u043c wasm-\u043c\u043e\u0434\u0443\u043b\u044c<\/p>\n<pre><code class=\"javascript\">fetch(this.wasm_asset.getFileUrl()) .then((response) => globalThis.WebAssembly.compileStreaming(response)) .then((module) => instantiate(module)) .then((inst) => this.init_navmesh(inst, vertices, polygons, sizes));<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <code>instantiate(module)<\/code> \u043a\u0430\u043a \u0440\u0430\u0437 \u0438\u0437 \u043e\u0431\u0451\u0440\u0442\u043a\u0438 <code>navmesh.js<\/code>. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0434\u043e \u0435\u0449\u0451 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>init_navmesh<\/code><\/p>\n<pre><code class=\"javascript\">NavmeshController.prototype.init_navmesh = function(exports, vertices, polygons, sizes) {     this.exports = exports;     this.navmesh = this.exports.create_navmesh(vertices, polygons, sizes); };<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0451, <code>this.exports<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 wasm-\u043c\u043e\u0434\u0443\u043b\u044f, \u0430 <code>this.navmesh<\/code> &#8212; \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 navmesh. \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0430\u0439\u0434\u0451\u0442 \u0441\u0432\u043e\u0439 \u043f\u0443\u0442\u044c. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e<\/p>\n<pre><code class=\"javascript\">this.exports.navmesh_search_path(this.navmesh, start[0], start[1], start[2], end[0], end[1], end[2]);<\/code><\/pre>\n<h3>\u0415\u0449\u0451 \u043f\u0430\u0440\u0443 \u0441\u043b\u043e\u0432 \u043f\u0440\u043e \u043c\u043e\u0434\u0443\u043b\u044c navmesh.wasm<\/h3>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u043e\u0436\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438. \u041f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 navmesh-\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u0435\u0433\u043e \u0442\u0440\u0438\u0430\u043d\u0433\u0443\u043b\u044f\u0446\u0438\u0438 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 BVH. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0442\u043e\u0447\u043a\u0443 \u043d\u0430 navmesh-\u0435, \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0443\u044e \u043a \u0434\u0430\u043d\u043d\u043e\u0439. \u041f\u043e\u043b\u0435\u0437\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043a\u0443\u0434\u0430-\u0442\u043e \u043a\u043b\u0438\u043a\u0430\u0435\u043c \u0438 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u0430 \u043f\u043e\u043f\u0430\u043b\u0438 \u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0443 \u0438\u043b\u0438 \u043c\u0438\u043c\u043e \u043a\u043b\u0438\u043a\u043d\u0443\u043b\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>this.exports.navmesh_sample(this.navmesh, x, y, z)<\/code>. \u041e\u043d\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0432\u0435\u043d <code>1<\/code>, \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0435\u0440\u0432\u044b\u0435 \u0442\u0440\u0438 &#8212; \u044d\u0442\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u0442\u043e\u0447\u043a\u0438. \u0415\u0441\u043b\u0438 <code>0<\/code>, \u0442\u043e \u043a\u043b\u0438\u043a\u043d\u0443\u043b\u0438 \u043c\u0438\u043c\u043e.<\/p>\n<p>\u0415\u0449\u0451 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>this.exports.navmesh_raycast(this.navmesh, origin_x, origin_y, origin_z, dir_x, dir_y, sir_z)<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u0447\u043a\u0443 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0430 \u0441 navmesh-\u0435\u043c.<\/p>\n<p>\u0415\u0449\u0451 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f RTree \u0434\u043b\u044f \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0445 \u0440\u0451\u0431\u0435\u0440. \u0415\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043e\u0442\u0440\u0435\u0437\u043e\u043a \u0441 \u0433\u0440\u0430\u043d\u0438\u0446\u0435\u0439 navmesh-\u0430. \u041d\u0443 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0442\u0430\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e, \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/github.com\/Tugcga\/Path-Finder\/tree\/main\/assemblyscript\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c.<\/a><\/p>\n<h2>Lightmap-\u044b<\/h2>\n<p>\u0422\u0443\u0442 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u043e \u0447\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b Playcanvas \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-364006","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/364006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=364006"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/364006\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=364006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=364006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=364006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}