{"id":349439,"date":"2023-06-27T21:00:19","date_gmt":"2023-06-27T21:00:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=349439"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=349439","title":{"rendered":"<span>\u041a\u0430\u043a \u044f \u043d\u043e\u0440\u043c\u0430\u043b\u0438 \u0440\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0432\u0430\u043b<\/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<h3>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430 \u044d\u0442\u043e \u0432\u0437\u044f\u043b\u0441\u044f?<\/h3>\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043e\u0442\u0432\u0435\u0442: \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u044e\u0442\u0443\u0431\u0430.<\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u043e\u0442 <a href=\"https:\/\/www.youtube.com\/@t3ssel8r\" rel=\"noopener noreferrer nofollow\">t3ssel8r<\/a> \u0438 \u043c\u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u0441\u0442\u0438\u043b\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0430 \u043f\u043e\u0440\u044b\u0432\u0435 \u043c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435.<\/p>\n<h3>\u0421 \u0447\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c?<\/h3>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043c\u0435\u043d\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a Godot, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c.<\/p>\n<p>\u0418\u0437 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432:<\/p>\n<ul>\n<li>\n<p>\u0414\u0432\u0438\u0436\u043e\u043a \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442<\/p>\n<\/li>\n<li>\n<p>\u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041a\u0443\u0447\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432-\u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u0434 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043a\u0440\u0443\u043f\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0451 \u0435\u0449\u0451 \u043c\u043e\u043b\u043e\u0434\u0430 \u0442.\u0435. \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u0431\u0430\u0433\u0438<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 UE4\/5 \u0438 Unity<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0431\u044d\u043a\u044d\u043d\u0434\u0430\u0445<\/p>\n<\/li>\n<\/ul>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430<\/h3>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u0447\u0442\u043e \u0438 \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u0430\u0434\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/p>\n<p>\u041e\u0431\u0449\u0430\u044f\u044f \u0438\u0434\u0435\u044f:<\/p>\n<ul>\n<li>\n<p>\u0418\u043c\u0435\u0442\u044c \u0432\u0438\u0434 pixel-art: <\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438 \u0441\u043c\u043e\u0442\u0440\u044f\u0449\u0438\u0435 \u043d\u0430 \u043a\u0430\u043c\u0435\u0440\u0443<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0442\u0435\u043c\u043d\u044f\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u041d\u0438\u0437\u043a\u043e\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0414\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u043e\u0434 HTML5<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043d\u0435 \u0442\u0430\u0438\u0435 \u0443\u0436 \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u043b \u043b\u0438 \u043a\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0434\u043e \u043d\u0430\u0441? \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u043b! \u042d\u0442\u043e-\u0436\u0435 \u043d\u0435 \u044f\u0434\u0435\u0440\u043d\u0430 \u0444\u0438\u0437\u0438\u043a\u0430 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432.<br \/> <a href=\"https:\/\/godotshaders.com\/shader\/3d-pixel-art-outline-highlight-post-processing-shader\/\" rel=\"noopener noreferrer nofollow\">\u0418\u043c\u0435\u043d\u043d\u043e \u0442\u043e \u0447\u0442\u043e \u043c\u043d\u0435 \u043d\u0430\u0434\u043e<\/a> \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043e \u043c\u0435\u043d\u044f!<br \/> \u041d\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u044d\u043a\u044d\u043d\u0434 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Forward+ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0451\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0431\u0443\u0444\u0435\u0440\u0443 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u043c.<br \/> \u0422\u0430\u043a \u0432 \u0447\u0451\u043c \u0436\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430? \u042d\u0442\u043e\u0442 \u0431\u0443\u0444\u0444\u0435\u0440 \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u043e\u0434 HTML5.<br \/> \u041d\u043e \u0431\u0435\u0437 \u043d\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438, \u0441\u043c\u043e\u0442\u0440\u044f\u0449\u0438\u0435 \u043d\u0430 \u043a\u0430\u043c\u0435\u0440\u0443, \u0442\u0430\u043a \u0447\u0442\u043e \u0436\u0435 \u043d\u0430\u043c \u0434\u0435\u043b\u0430\u0442\u044c?<\/p>\n<h3>\u0420\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439<\/h3>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 \u0442\u0435\u0440\u043c\u0438\u043d\u0443 \u044f \u043f\u0440\u0438\u0448\u0451\u043b \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:<br \/> &#171;Godot compatibility renderer normal buffer&#187; &#8212; \u0412\u044b\u0432\u043e\u0434: \u0431\u0443\u0444\u0444\u0435\u0440 \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 compatibility (HTML5);<br \/> &#171;What buffers Godot uses in compatibility renderer&#187; &#8212; \u0412\u044b\u0432\u043e\u0434: \u043f\u043e\u043c\u0438\u043c\u043e \u0431\u0443\u0444\u0444\u0435\u0440\u0430 \u0446\u0432\u0435\u0442\u0430 Godot \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0431\u0443\u0444\u0444\u0435\u0440 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0432\u043e \u0432\u0441\u0435\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438;<br \/> &#171;Godot reconstruct normals from depth&#187; &#8212; \u042f \u043d\u0435 \u043d\u0430\u0448\u0451\u043b \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043f\u0440\u0438\u043f\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0442\u0435\u0445\u043d\u0438\u043a \u0432 Godot, \u043d\u043e \u043c\u044b \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0434\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043f\u0430\u0440\u044b \u0441\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0433\u043b\u0430 \u043c\u043d\u0435 \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441;<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u043b\u0438 \u043e \u0447\u0451\u043c \u044f \u0434\u0430\u043b\u044c\u0448\u0435 \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c, \u043f\u0440\u043e\u0439\u0434\u0451\u043c\u0441\u044f \u043f\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u043d\u0438\u044f\u043c.<\/p>\n<ol>\n<li>\n<p>\u041d\u043e\u0440\u043c\u0430\u043b\u044c &#8212; \u043f\u0435\u0440\u043f\u0435\u043d\u0434\u0438\u043a\u0443\u043b\u044f\u0440 \u043a \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0442\u0440\u0435\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c \u0432\u0438\u0434\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"z = a*x + b*y +c\" alt=\"z = a*x + b*y +c\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6f6\/fbc\/f96\/6f6fbcf9695f04c84e8c3c31063d3326.svg\" width=\"169\" height=\"21\"\/> <\/p>\n<p>\u0418 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u043a \u043b\u044e\u0431\u043e\u0439 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"cross(a,b)\" alt=\"cross(a,b)\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/04d\/436\/65e\/04d43665e0c65427f1afd87ef5298644.svg\" width=\"88\" height=\"22\"\/> \u0438\u043b\u0438 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"cross(x_1 - x_c,x_2 - x_c)\" alt=\"cross(x_1 - x_c,x_2 - x_c)\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c40\/326\/0e1\/c403260e112c834f9b1f95373f3b5a17.svg\" width=\"196\" height=\"22\"\/> , \u0433\u0434\u0435 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"x_1,x_2,x_c\" alt=\"x_1,x_2,x_c\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a7d\/74c\/34b\/a7d74c34b8cfda210964c716c2e88194.svg\" width=\"77\" height=\"15\"\/> &#8212; \u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438. \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0434\u043b\u0438\u043d\u0443 != 1, \u0430 \u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0446\u0435\u043b\u044f\u0445 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u0434\u043b\u0438\u043d\u043e\u0439 1, \u0442\u0430\u043a \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"normalize()\" alt=\"normalize()\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4f6\/96d\/d3b\/4f696dd3bd09545170eb8644ff861c73.svg\" width=\"104\" height=\"22\"\/>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0418\u0442\u0430\u043a, &#171;Normal reconstruction&#187;:<\/p>\n<ul>\n<li>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 &#8212; <a href=\"https:\/\/wickedengine.net\/2019\/09\/22\/improved-normal-reconstruction-from-depth\/\" rel=\"noopener noreferrer nofollow\">Improved normal reconstruction from depth<\/a>. \u041e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f &#8212; \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u0438 \u0438\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0445 \u0435\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0440\u0435\u0434\u043d\u0435\u0435. \u0422\u0430\u043a \u043a\u0430\u043a \u0430\u0432\u0442\u043e\u0440 \u043f\u043e\u0442\u043e\u043c \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u043b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u0440\u044b\u0439 \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0442.\u043a \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0431\u0443\u0444\u0444\u0435\u0440 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439 \u0442\u0430\u043a\u043e\u0433\u043e-\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u0430\u043a \u0431\u0443\u0444\u0444\u0435\u0440 \u0446\u0432\u0435\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 &#8212; <a href=\"https:\/\/atyuwen.github.io\/posts\/normal-reconstruction\/\" rel=\"noopener noreferrer nofollow\">Accurate Normal Reconstruction from Depth Buffer<\/a>. \u041e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u043c \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435\u043c. \u0414\u0430\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0435\u0441\u0442\u044c, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c&#8230;<br \/> <a href=\"https:\/\/gist.github.com\/bgolus\/a07ed65602c009d5e2f753826e8078a0\" rel=\"noopener noreferrer nofollow\">\u042f \u0438\u0441\u043a\u0430\u043b \u043c\u0435\u0434\u044c, \u043d\u043e \u043d\u0430\u0448\u0451\u043b \u0437\u043e\u043b\u043e\u0442\u043e<\/a>. \u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u043e! \u042d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u044f \u0438\u0441\u043a\u0430\u043b! \u041f\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u044d\u0442\u043e \u0432 Godot, \u0438 \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0446\u0435\u043d\u0443 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0448\u0435\u0439\u0434\u0435\u0440\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d65\/bc8\/7b7\/d65bc87b7492a3c29dd810ea8feb7fc9.png\" alt=\"\u041f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0430\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0446\u0435\u043d\u0430\" title=\"\u041f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0430\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0446\u0435\u043d\u0430\" width=\"1920\" height=\"1080\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d65\/bc8\/7b7\/d65bc87b7492a3c29dd810ea8feb7fc9.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0430\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0446\u0435\u043d\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u0440\u0430\u0441\u0442\u044f\u043d\u0435\u043c \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cb2\/117\/ebd\/cb2117ebd0c1ebfa84ea54339a57c8cf.png\" alt=\"\u0422\u0435 \u0441\u0430\u043c\u044b\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438\" title=\"\u0422\u0435 \u0441\u0430\u043c\u044b\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438\" width=\"1920\" height=\"1080\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb2\/117\/ebd\/cb2117ebd0c1ebfa84ea54339a57c8cf.png\"\/><\/p>\n<div><figcaption>\u0422\u0435 \u0441\u0430\u043c\u044b\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u043a\u0430 \u043c\u044b \u0432\u0441\u0451 \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Forward+, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u0430 \u0438\u0441\u0442\u0438\u043d\u043d\u044b\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438<\/p>\n<pre><code>shader_type spatial; render_mode unshaded,depth_draw_never;  uniform sampler2D normals : hint_normal_roughness_texture;  void vertex() { POSITION = vec4(VERTEX.xy,0.0,1.0); }  void fragment() { ALBEDO = texture(normals,SCREEN_UV).rgb; ALPHA = 1.0; }<\/code><\/pre>\n<p>\u0410 \u043f\u0440\u0430\u0432\u0430\u044f &#8212; \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u0440\u0430\u0448\u0435\u043d\u0430 \u0437\u0435\u043b\u0451\u043d\u044b\u043c<\/p>\n<pre><code>shader_type spatial; render_mode unshaded,depth_draw_never;  void vertex() { POSITION = vec4(VERTEX.xy,0.0,1.0); }  void fragment() { ALBEDO = vec3(0.0,1.0,0.0); ALPHA = 0.5; }<\/code><\/pre>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442!<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bd4\/41e\/2cc\/bd441e2cc4e87f87f4d86c5b38bf17bd.webp\" alt=\"2 \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435\" title=\"2 \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435\" width=\"960\" height=\"540\"\/><\/p>\n<div><figcaption>2 \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0440\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439.<\/p>\n<h4>\u041e\u0431\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<p>\u042d\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e  \u0438\u0434\u0451\u0442 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430<\/p>\n<pre><code>shader_type spatial; render_mode unshaded,depth_draw_never;  uniform sampler2D depth_texture : hint_depth_texture,filter_nearest;  void vertex(){ POSITION = vec4(VERTEX.xy,0.0,1.0); }<\/code><\/pre>\n<p>\u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u0442 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0441\u0440\u0430\u0437\u0443 \u0432 NDC (x(-1..=1),y(-1..=1),z(0..=1)) \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442<\/p>\n<pre><code>vec3 viewPosDepth(float depth,vec2 uv,mat4 ipm){ vec3 ndc = vec3(uv*2.0 - 1.0,depth); vec4 view = ipm * vec4(ndc,1.0); view.xyz \/= view.w; return view.xyz; }  vec3 viewPosSampler(sampler2D depth_tex,vec2 uv,mat4 ipm){ float depth = texture(depth_tex,uv).x; return viewPosDepth(depth,uv,ipm); }<\/code><\/pre>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0437 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 (NDC) \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0432\u0438\u0434\u0430 \u0442.\u0435. \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u043c\u0435\u0440\u044b<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21161 Simple 3 tap<\/h4>\n<pre><code>...  vec3 NR_3tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ float depth_c = texture(depth_tex,uv).x; \/\/\u0440\u0430\u043d\u043d\u0438\u0439 \u0432\u044b\u0445\u043e\u0434 \u0435\u0441\u043b\u0438 \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0432\u044b\u0441\u043e\u043a\u0430 if (depth_c == 1.0){ return vec3(0.5); }  vec3 view_c = viewPosDepth(depth_c,uv,ipm); vec3 view_r = viewPosSampler(depth_tex,uv + vec2(1.0,0.0)*el,ipm); vec3 view_u = viewPosSampler(depth_tex,uv + vec2(0.0,1.0)*el,ipm);  vec3 h_der = view_r - view_c; vec3 v_der = view_u - view_c;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  void fragment() { vec2 uv = SCREEN_UV; vec2 el = 1.0\/VIEWPORT_SIZE; mat4 ipm = INV_PROJECTION_MATRIX; vec3 normal = NR_3tap(uv,el,ipm,depth_texture); ALBEDO = normal; }<\/code><\/pre>\n<p>\u041e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f \u0442\u0430\u043a\u043e\u0432\u0430 :<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/aec\/ad8\/1bf\/aecad81bf4c708db489ceb24e9699b56.png\" width=\"256\" height=\"256\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/aec\/ad8\/1bf\/aecad81bf4c708db489ceb24e9699b56.png\"\/><\/figure>\n<p>\u0417\u0435\u043b\u0451\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 &#8212; \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0438\u043a\u0441\u0435\u043b\u044f (SCREEN_UV)<br \/> \u041c\u044b \u0431\u0435\u0440\u0451\u043c \u0435\u0451 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0441\u043f\u0440\u0430\u0432\u0430 \u0438 \u0441\u043d\u0438\u0437\u0443, \u0438\u0437 \u043d\u0438\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0434\u0432\u0438\u0433. \u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u0438\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0441\u0434\u0432\u0438\u0433\u043e\u0432.<br \/> \u0418 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442: \u0441\u043b\u0435\u0432\u0430 &#8212; \u0438\u0441\u0442\u0438\u043d\u043d\u044b\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438, \u0441\u043f\u0440\u0430\u0432\u0430 &#8212; \u0440\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dd2\/a0d\/3c5\/dd2a0d3c59671988db03dc5ce8914135.png\" width=\"1090\" height=\"699\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dd2\/a0d\/3c5\/dd2a0d3c59671988db03dc5ce8914135.png\"\/><\/figure>\n<p>\u041d\u0435 \u043e\u0441\u043e\u0431\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u0430 \u0440\u0430\u0437\u043d\u0438\u0446\u0430. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043d\u0438\u0437\u0438\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435!<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2d6\/6f0\/7d6\/2d66f07d6ccbcfdc00a8b48b8bef7139.webp\" width=\"960\" height=\"540\"\/><\/figure>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043d\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043e\u0442 MeshInstance.<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21162 Simple 4 tap<\/h4>\n<pre><code>...  vec3 NR_4tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ float depth_l = texture(depth_tex,uv - vec2(1.0,0.0)*el).x; \/\/early exit if on the end of view distance if (depth_l == 1.0){ return vec3(0.5); }  vec3 view_l = viewPosDepth(depth_l,uv - vec2(1.0,0.0)*el,ipm); vec3 view_d = viewPosSampler(uv - vec2(0.0,1.0)*el,ipm,depth_tex); vec3 view_r = viewPosSampler(uv + vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_u = viewPosSampler(uv + vec2(0.0,1.0)*el,ipm,depth_tex);  vec3 h_der = view_r - view_l; vec3 v_der = view_u - view_d;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  ...<\/code><\/pre>\n<p>\u0422\u043e\u0442 \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f, \u043a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u0435, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u043f\u0438\u043a\u0441\u0435\u043b\u044c \u0441\u043d\u0438\u0437\u0443 \u0441 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u043c \u0441\u0432\u0435\u0440\u0445\u0443, \u0430 \u043d\u0435 \u0441 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u043c. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0441 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u043c \u0441\u043f\u0440\u0430\u0432\u0430.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0f6\/3e3\/e09\/0f63e3e090d0d2b8964f980970c0c031.png\" width=\"256\" height=\"256\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0f6\/3e3\/e09\/0f63e3e090d0d2b8964f980970c0c031.png\"\/><\/figure>\n<p>\u0418 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f5f\/00e\/3cf\/f5f00e3cf0fcbe301db94f5dd3da83a7.webp\" width=\"960\" height=\"540\"\/><\/figure>\n<p>\u0415\u0449\u0451 \u0445\u0443\u0436\u0435, \u043d\u043e \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e \u0442.\u043a. \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0431\u043e\u043b\u0435\u0435 &#171;\u0433\u0440\u0443\u0431\u043e\u0435&#187; \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044f \u043f\u0438\u043a\u0441\u0435\u043b\u044c, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c.<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21163 Improved 5 tap<\/h4>\n<pre><code>...  vec3 NR_5tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ float depth_c = texture(depth_tex,uv).x; \/\/early exit if on the end of view distance if (depth_c == 1.0){ return vec3(0.5); }  vec3 view_c = viewPosDepth(depth_c,uv,ipm); vec3 view_l = viewPosSampler(uv - vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_d = viewPosSampler(uv - vec2(0.0,1.0)*el,ipm,depth_tex); vec3 view_r = viewPosSampler(uv + vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_u = viewPosSampler(uv + vec2(0.0,1.0)*el,ipm,depth_tex);  vec3 l = view_c - view_l; vec3 r = view_r - view_c; vec3 d = view_c - view_d; vec3 u = view_u - view_c;  vec3 h_der = abs(l.z) &lt; abs(r.z) ? l : r; vec3 v_der = abs(d.z) &lt; abs(u.z) ? d : u;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  ...<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u043e\u0431\u0449\u0435\u0435 \u0434\u043b\u044f \u043e\u0441\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435(\u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 cross()).<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b05\/d3f\/de5\/b05d3fde547199c8990199716c8c749c.png\" width=\"256\" height=\"256\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b05\/d3f\/de5\/b05d3fde547199c8990199716c8c749c.png\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u043e \u0440\u0430\u0437\u043d\u0438\u0446\u0435 \u0433\u043b\u0443\u0431\u0438\u043d \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 &#171;\u0431\u043b\u0438\u0436\u0435&#187; \u0438 \u0438\u0437 &#171;\u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445&#187; \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7fb\/97b\/6cf\/7fb97b6cf74d2638fbfdca142513275a.webp\" alt=\"\u041f\u043e\u0447\u0442\u0438 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e!\" title=\"\u041f\u043e\u0447\u0442\u0438 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e!\" width=\"960\" height=\"540\"\/><\/p>\n<div><figcaption>\u041f\u043e\u0447\u0442\u0438 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e!<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0438\u0441\u043a\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0451 \u0435\u0449\u0451 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0443\u044e\u0442, \u043d\u043e \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0437\u0430\u043c\u0435\u0442\u043d\u043e\u0441\u0442\u044c \u043a\u0440\u0430\u0439\u043d\u0435 \u043c\u0430\u043b\u044b.<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21164 Accurate 9 tap<\/h4>\n<pre><code>...  vec3 NR_9tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ vec3 view_c = viewPosSampler(uv,ipm,depth_tex); vec3 view_l = viewPosSampler(uv - vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_r = viewPosSampler(uv + vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_d = viewPosSampler(uv - vec2(0.0,1.0)*el,ipm,depth_tex); vec3 view_u = viewPosSampler(uv + vec2(0.0,1.0)*el,ipm,depth_tex);  vec3 l = view_c - view_l; vec3 r = view_r - view_c; vec3 d = view_c - view_d; vec3 u = view_u - view_c;   \/\/deside from which direction to sample \/\/center depth float depth_c = texture(depth_tex,uv).x; \/\/early exit if on the end of view distance if (depth_c == 1.0){ return vec3(0.5); } \/\/horizontal depths vec4 H = vec4( texture(depth_tex,uv - vec2(1.0,0.0)*el).x, texture(depth_tex,uv - vec2(2.0,0.0)*el).x, texture(depth_tex,uv + vec2(1.0,0.0)*el).x, texture(depth_tex,uv + vec2(2.0,0.0)*el).x ); \/\/vertical depths vec4 V = vec4( texture(depth_tex,uv - vec2(0.0,1.0)*el).x, texture(depth_tex,uv - vec2(0.0,2.0)*el).x, texture(depth_tex,uv + vec2(0.0,1.0)*el).x, texture(depth_tex,uv + vec2(0.0,2.0)*el).x ); \/\/find diff of true center and extrapolated one vec2 he = abs((2.0*H.xz - H.yw) - depth_c); vec2 ve = abs((2.0*V.xz - V.yw) - depth_c);  vec3 h_der = he.x &lt; he.y ? l : r; vec3 v_der = ve.x &lt; ve.y ? d : u;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  ...<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 <a href=\"https:\/\/atyuwen.github.io\/posts\/normal-reconstruction\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439<\/a> \u0441\u0442\u0430\u0442\u044c\u0435. \u0415\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443, \u043e\u0434\u043d\u0430\u043a\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u0430\u043a\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0431\u0440\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u043a\u0441\u0442\u0440\u0430\u043f\u043e\u043b\u044f\u0446\u0438\u0438 \u0446\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/579\/daf\/a04\/579dafa0488f04aee17c05ba65e9b2f4.png\" alt=\"\" title=\"\" width=\"726\" height=\"341\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/579\/daf\/a04\/579dafa0488f04aee17c05ba65e9b2f4.png\"\/><\/figure>\n<ol>\n<li>\n<p>\u041f\u0440\u043e\u0434\u043b\u0438\u0442\u044c <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"ab\" alt=\"ab\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3d7\/b67\/e35\/3d7b67e35d83a93ab3ec03938388f9fc.svg\" width=\"19\" height=\"17\"\/> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"c_1\" alt=\"c_1\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1d4\/ac2\/98d\/1d4ac298d662da89a4be99560d164ac7.svg\" width=\"17\" height=\"14\"\/><\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0434\u043b\u0438\u0442\u044c <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"ed\" alt=\"ed\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dcc\/02f\/a12\/dcc02fa1272ba2b5947427e631aff439.svg\" width=\"19\" height=\"17\"\/> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"c_2\" alt=\"c_2\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/534\/410\/0f8\/5344100f83f2eaa502059718c010305c.svg\" width=\"17\" height=\"14\"\/><\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"|c_1 - c| &lt; |c_2 - c|\" alt=\"|c_1 - c| &lt; |c_2 - c|\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1ac\/1b2\/4be\/1ac1b24bef7f5c44a5e4796a822351f9.svg\" width=\"148\" height=\"22\"\/>, \u0442\u043e <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"c\" alt=\"c\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/db3\/ef4\/eed\/db3ef4eed488fb70bea31f9831a2dc68.svg\" width=\"9\" height=\"12\"\/> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"ab\" alt=\"ab\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/60b\/abe\/81c\/60babe81c89f6d503d2aef802f71ccfd.svg\" width=\"19\" height=\"17\"\/>, \u0438\u043d\u0430\u0447\u0435 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"c\" alt=\"c\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0e5\/aaa\/a4b\/0e5aaaa4b042899ecd6ef3b324a24d0a.svg\" width=\"9\" height=\"12\"\/> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"de\" alt=\"de\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ef0\/e90\/f25\/ef0e90f2557bde46060ebd9f592a711b.svg\" width=\"19\" height=\"17\"\/><\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fcd\/80b\/1ea\/fcd80b1ead539ca0d64a358b1b3de5a2.webp\" alt=\"\" title=\"\" width=\"960\" height=\"540\"\/><\/figure>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0447\u0442\u0438 \u0438\u0434\u0435\u0430\u043b\u0435\u043d, \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c, \u0433\u0434\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 2 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439, \u043e\u0434\u043d\u0430\u043a\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c, \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0432 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0438\u0437 NDC \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0438\u0434\u0430<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21165 \u0423\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u044b\u0439 \u043c\u043d\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u21164<\/h4>\n<pre><code>...  vec3 NR_9tap_plus(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ \/\/center depth float depth_c = texture(depth_tex,uv).x; \/\/early exit if on the end of view distance if (depth_c == 1.0){ return vec3(0.5); } \/\/horizontal depths vec4 H = vec4( texture(depth_tex,uv - vec2(1.0,0.0)*el).x, texture(depth_tex,uv - vec2(2.0,0.0)*el).x, texture(depth_tex,uv + vec2(1.0,0.0)*el).x, texture(depth_tex,uv + vec2(2.0,0.0)*el).x ); \/\/vertical depths vec4 V = vec4( texture(depth_tex,uv - vec2(0.0,1.0)*el).x, texture(depth_tex,uv - vec2(0.0,2.0)*el).x, texture(depth_tex,uv + vec2(0.0,1.0)*el).x, texture(depth_tex,uv + vec2(0.0,2.0)*el).x ); \/\/find diff of true center and extrapolated one vec2 he = abs((2.0*H.xz - H.yw) - depth_c); vec2 ve = abs((2.0*V.xz - V.yw) - depth_c); \/\/from which direction to sample float h_sign = he.x &lt; he.y ? -1.0 : 1.0; float v_sign = ve.x &lt; ve.y ? -1.0 : 1.0;  vec3 view_h = viewPosDepth(H[1 + int(h_sign)],uv + vec2(h_sign,0.0)*el,ipm); vec3 view_v = viewPosDepth(V[1 + int(v_sign)],uv + vec2(0.0,v_sign)*el,ipm);  vec3 view_c = viewPosDepth(depth_c,uv,ipm);  vec3 h_der = h_sign*(view_h - view_c); vec3 v_der = v_sign*(view_v - view_c);  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  ... <\/code><\/pre>\n<p>\u0425\u043e\u0442\u044f \u0432\u043d\u0435\u0441\u0451\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u043c\u0438, \u043e\u043d\u0438 \u0443\u0431\u0438\u0440\u0430\u044e\u0442 5 \u043b\u0438\u0448\u043d\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u0431\u0443\u0444\u0444\u0435\u0440 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0438 2 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0438\u0437 NDC \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0438\u0434\u0430. \u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043e\u0442 \u043c\u0435\u0442\u043e\u0434\u0430 \u21164 \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u0434\u0440\u0430 \u043d\u0430 10% \u043d\u0430 \u043c\u043e\u0435\u0439 \u0432\u0441\u0442\u0440\u0435\u043d\u043e\u0439 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u044d\u0442\u043e \u0443\u0441\u043f\u0435\u0445\u043e\u043c. <\/p>\n<h3>\u0421\u0431\u043e\u0440\u043a\u0430 \u043f\u043e\u0434 HTML5<\/h3>\n<p>\u0412 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Compatibility Godot \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 NDC \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u0442 \u0442\u0430\u043a\u043e\u0432\u044b\u0445 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 Forward+, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u0440\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 NDC:<\/p>\n<pre><code>void vertex(){ POSITION = vec4(VERTEX.xy,-1.0,1.0); }  vec3 viewPosDepth(float depth,vec2 uv,mat4 ipm){ vec3 ndc = vec3(uv,depth)*2.0 - 1.0; vec4 view = ipm * vec4(ndc,1.0); view.xyz \/= view.w; return view.xyz; } <\/code><\/pre>\n<p>\u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 \u0433\u043b\u0443\u0431\u0438\u043d\u044b:<\/p>\n<ul>\n<li>\n<p>\u0412 Forward+ z: 0..=1<\/p>\n<\/li>\n<li>\n<p>\u0412 Compatibility z: -1..=1<\/p>\n<\/li>\n<\/ul>\n<h3>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u043e\u0437\u043d\u0438 \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c, \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043c\u0438\u043d\u0438 \u043f\u0440\u043e\u0435\u043a\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"https:\/\/snail-with-tea.itch.io\/pixelart-look-with-normal-reconstruct\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439 \u0432\u0435\u0431 \u0434\u0435\u043c\u043e<\/a>.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u0430\u043c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0430\u0441\u044c \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f(\u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u0430\u043d\u043d\u043e\u0435 \u0447\u0442\u0438\u0432\u043e \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c?), \u0435\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/DimonNeAdekvat\/Normal-Reconstruction-Godot\" rel=\"noopener noreferrer nofollow\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a>.<\/p>\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\/744336\/\"> https:\/\/habr.com\/ru\/articles\/744336\/<\/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<h3>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430 \u044d\u0442\u043e \u0432\u0437\u044f\u043b\u0441\u044f?<\/h3>\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043e\u0442\u0432\u0435\u0442: \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u044e\u0442\u0443\u0431\u0430.<\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u043e\u0442 <a href=\"https:\/\/www.youtube.com\/@t3ssel8r\" rel=\"noopener noreferrer nofollow\">t3ssel8r<\/a> \u0438 \u043c\u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u0441\u0442\u0438\u043b\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0430 \u043f\u043e\u0440\u044b\u0432\u0435 \u043c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435.<\/p>\n<h3>\u0421 \u0447\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c?<\/h3>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043c\u0435\u043d\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a Godot, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c.<\/p>\n<p>\u0418\u0437 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432:<\/p>\n<ul>\n<li>\n<p>\u0414\u0432\u0438\u0436\u043e\u043a \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442<\/p>\n<\/li>\n<li>\n<p>\u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041a\u0443\u0447\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432-\u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u0434 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043a\u0440\u0443\u043f\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0451 \u0435\u0449\u0451 \u043c\u043e\u043b\u043e\u0434\u0430 \u0442.\u0435. \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u0431\u0430\u0433\u0438<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 UE4\/5 \u0438 Unity<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0431\u044d\u043a\u044d\u043d\u0434\u0430\u0445<\/p>\n<\/li>\n<\/ul>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430<\/h3>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u0447\u0442\u043e \u0438 \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u0430\u0434\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/p>\n<p>\u041e\u0431\u0449\u0430\u044f\u044f \u0438\u0434\u0435\u044f:<\/p>\n<ul>\n<li>\n<p>\u0418\u043c\u0435\u0442\u044c \u0432\u0438\u0434 pixel-art: <\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438 \u0441\u043c\u043e\u0442\u0440\u044f\u0449\u0438\u0435 \u043d\u0430 \u043a\u0430\u043c\u0435\u0440\u0443<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0442\u0435\u043c\u043d\u044f\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u041d\u0438\u0437\u043a\u043e\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0414\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u043e\u0434 HTML5<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043d\u0435 \u0442\u0430\u0438\u0435 \u0443\u0436 \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u043b \u043b\u0438 \u043a\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0434\u043e \u043d\u0430\u0441? \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u043b! \u042d\u0442\u043e-\u0436\u0435 \u043d\u0435 \u044f\u0434\u0435\u0440\u043d\u0430 \u0444\u0438\u0437\u0438\u043a\u0430 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432.<br \/> <a href=\"https:\/\/godotshaders.com\/shader\/3d-pixel-art-outline-highlight-post-processing-shader\/\" rel=\"noopener noreferrer nofollow\">\u0418\u043c\u0435\u043d\u043d\u043e \u0442\u043e \u0447\u0442\u043e \u043c\u043d\u0435 \u043d\u0430\u0434\u043e<\/a> \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043e \u043c\u0435\u043d\u044f!<br \/> \u041d\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u044d\u043a\u044d\u043d\u0434 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Forward+ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0451\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0431\u0443\u0444\u0435\u0440\u0443 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u043c.<br \/> \u0422\u0430\u043a \u0432 \u0447\u0451\u043c \u0436\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430? \u042d\u0442\u043e\u0442 \u0431\u0443\u0444\u0444\u0435\u0440 \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u043e\u0434 HTML5.<br \/> \u041d\u043e \u0431\u0435\u0437 \u043d\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438, \u0441\u043c\u043e\u0442\u0440\u044f\u0449\u0438\u0435 \u043d\u0430 \u043a\u0430\u043c\u0435\u0440\u0443, \u0442\u0430\u043a \u0447\u0442\u043e \u0436\u0435 \u043d\u0430\u043c \u0434\u0435\u043b\u0430\u0442\u044c?<\/p>\n<h3>\u0420\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439<\/h3>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 \u0442\u0435\u0440\u043c\u0438\u043d\u0443 \u044f \u043f\u0440\u0438\u0448\u0451\u043b \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:<br \/> &#171;Godot compatibility renderer normal buffer&#187; &#8212; \u0412\u044b\u0432\u043e\u0434: \u0431\u0443\u0444\u0444\u0435\u0440 \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 compatibility (HTML5);<br \/> &#171;What buffers Godot uses in compatibility renderer&#187; &#8212; \u0412\u044b\u0432\u043e\u0434: \u043f\u043e\u043c\u0438\u043c\u043e \u0431\u0443\u0444\u0444\u0435\u0440\u0430 \u0446\u0432\u0435\u0442\u0430 Godot \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0431\u0443\u0444\u0444\u0435\u0440 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u0432\u043e \u0432\u0441\u0435\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438;<br \/> &#171;Godot reconstruct normals from depth&#187; &#8212; \u042f \u043d\u0435 \u043d\u0430\u0448\u0451\u043b \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043f\u0440\u0438\u043f\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0442\u0435\u0445\u043d\u0438\u043a \u0432 Godot, \u043d\u043e \u043c\u044b \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0434\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043f\u0430\u0440\u044b \u0441\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0433\u043b\u0430 \u043c\u043d\u0435 \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441;<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u043b\u0438 \u043e \u0447\u0451\u043c \u044f \u0434\u0430\u043b\u044c\u0448\u0435 \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c, \u043f\u0440\u043e\u0439\u0434\u0451\u043c\u0441\u044f \u043f\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u043d\u0438\u044f\u043c.<\/p>\n<ol>\n<li>\n<p>\u041d\u043e\u0440\u043c\u0430\u043b\u044c &#8212; \u043f\u0435\u0440\u043f\u0435\u043d\u0434\u0438\u043a\u0443\u043b\u044f\u0440 \u043a \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0442\u0440\u0435\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c \u0432\u0438\u0434\u0430  <\/p>\n<p>\u0418 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u043a \u043b\u044e\u0431\u043e\u0439 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438  \u0438\u043b\u0438  , \u0433\u0434\u0435  &#8212; \u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438. \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0434\u043b\u0438\u043d\u0443 != 1, \u0430 \u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0446\u0435\u043b\u044f\u0445 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u0434\u043b\u0438\u043d\u043e\u0439 1, \u0442\u0430\u043a \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e .<\/p>\n<\/li>\n<\/ol>\n<p>\u0418\u0442\u0430\u043a, &#171;Normal reconstruction&#187;:<\/p>\n<ul>\n<li>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 &#8212; <a href=\"https:\/\/wickedengine.net\/2019\/09\/22\/improved-normal-reconstruction-from-depth\/\" rel=\"noopener noreferrer nofollow\">Improved normal reconstruction from depth<\/a>. \u041e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f &#8212; \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u0438 \u0438\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0445 \u0435\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0440\u0435\u0434\u043d\u0435\u0435. \u0422\u0430\u043a \u043a\u0430\u043a \u0430\u0432\u0442\u043e\u0440 \u043f\u043e\u0442\u043e\u043c \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u043b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u0440\u044b\u0439 \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0442.\u043a \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0431\u0443\u0444\u0444\u0435\u0440 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439 \u0442\u0430\u043a\u043e\u0433\u043e-\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u0430\u043a \u0431\u0443\u0444\u0444\u0435\u0440 \u0446\u0432\u0435\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 &#8212; <a href=\"https:\/\/atyuwen.github.io\/posts\/normal-reconstruction\/\" rel=\"noopener noreferrer nofollow\">Accurate Normal Reconstruction from Depth Buffer<\/a>. \u041e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u043c \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435\u043c. \u0414\u0430\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0435\u0441\u0442\u044c, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c&#8230;<br \/> <a href=\"https:\/\/gist.github.com\/bgolus\/a07ed65602c009d5e2f753826e8078a0\" rel=\"noopener noreferrer nofollow\">\u042f \u0438\u0441\u043a\u0430\u043b \u043c\u0435\u0434\u044c, \u043d\u043e \u043d\u0430\u0448\u0451\u043b \u0437\u043e\u043b\u043e\u0442\u043e<\/a>. \u0412\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u043e! \u042d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u044f \u0438\u0441\u043a\u0430\u043b! \u041f\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u044d\u0442\u043e \u0432 Godot, \u0438 \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0446\u0435\u043d\u0443 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0448\u0435\u0439\u0434\u0435\u0440\u044b:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0430\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0446\u0435\u043d\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u0440\u0430\u0441\u0442\u044f\u043d\u0435\u043c \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0422\u0435 \u0441\u0430\u043c\u044b\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u043a\u0430 \u043c\u044b \u0432\u0441\u0451 \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 Forward+, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u0430 \u0438\u0441\u0442\u0438\u043d\u043d\u044b\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438<\/p>\n<pre><code>shader_type spatial; render_mode unshaded,depth_draw_never;  uniform sampler2D normals : hint_normal_roughness_texture;  void vertex() { POSITION = vec4(VERTEX.xy,0.0,1.0); }  void fragment() { ALBEDO = texture(normals,SCREEN_UV).rgb; ALPHA = 1.0; }<\/code><\/pre>\n<p>\u0410 \u043f\u0440\u0430\u0432\u0430\u044f &#8212; \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u0440\u0430\u0448\u0435\u043d\u0430 \u0437\u0435\u043b\u0451\u043d\u044b\u043c<\/p>\n<pre><code>shader_type spatial; render_mode unshaded,depth_draw_never;  void vertex() { POSITION = vec4(VERTEX.xy,0.0,1.0); }  void fragment() { ALBEDO = vec3(0.0,1.0,0.0); ALPHA = 0.5; }<\/code><\/pre>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442!<\/p>\n<figure class=\"full-width\">\n<div><figcaption>2 \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0440\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439.<\/p>\n<h4>\u041e\u0431\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<p>\u042d\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e  \u0438\u0434\u0451\u0442 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430<\/p>\n<pre><code>shader_type spatial; render_mode unshaded,depth_draw_never;  uniform sampler2D depth_texture : hint_depth_texture,filter_nearest;  void vertex(){ POSITION = vec4(VERTEX.xy,0.0,1.0); }<\/code><\/pre>\n<p>\u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u0442 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0441\u0440\u0430\u0437\u0443 \u0432 NDC (x(-1..=1),y(-1..=1),z(0..=1)) \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442<\/p>\n<pre><code>vec3 viewPosDepth(float depth,vec2 uv,mat4 ipm){ vec3 ndc = vec3(uv*2.0 - 1.0,depth); vec4 view = ipm * vec4(ndc,1.0); view.xyz \/= view.w; return view.xyz; }  vec3 viewPosSampler(sampler2D depth_tex,vec2 uv,mat4 ipm){ float depth = texture(depth_tex,uv).x; return viewPosDepth(depth,uv,ipm); }<\/code><\/pre>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0437 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 (NDC) \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0432\u0438\u0434\u0430 \u0442.\u0435. \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u043c\u0435\u0440\u044b<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21161 Simple 3 tap<\/h4>\n<pre><code>...  vec3 NR_3tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ float depth_c = texture(depth_tex,uv).x; \/\/\u0440\u0430\u043d\u043d\u0438\u0439 \u0432\u044b\u0445\u043e\u0434 \u0435\u0441\u043b\u0438 \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0432\u044b\u0441\u043e\u043a\u0430 if (depth_c == 1.0){ return vec3(0.5); }  vec3 view_c = viewPosDepth(depth_c,uv,ipm); vec3 view_r = viewPosSampler(depth_tex,uv + vec2(1.0,0.0)*el,ipm); vec3 view_u = viewPosSampler(depth_tex,uv + vec2(0.0,1.0)*el,ipm);  vec3 h_der = view_r - view_c; vec3 v_der = view_u - view_c;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  void fragment() { vec2 uv = SCREEN_UV; vec2 el = 1.0\/VIEWPORT_SIZE; mat4 ipm = INV_PROJECTION_MATRIX; vec3 normal = NR_3tap(uv,el,ipm,depth_texture); ALBEDO = normal; }<\/code><\/pre>\n<p>\u041e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f \u0442\u0430\u043a\u043e\u0432\u0430 :<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0417\u0435\u043b\u0451\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 &#8212; \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0438\u043a\u0441\u0435\u043b\u044f (SCREEN_UV)<br \/> \u041c\u044b \u0431\u0435\u0440\u0451\u043c \u0435\u0451 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0441\u043f\u0440\u0430\u0432\u0430 \u0438 \u0441\u043d\u0438\u0437\u0443, \u0438\u0437 \u043d\u0438\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0434\u0432\u0438\u0433. \u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c \u0438\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0441\u0434\u0432\u0438\u0433\u043e\u0432.<br \/> \u0418 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442: \u0441\u043b\u0435\u0432\u0430 &#8212; \u0438\u0441\u0442\u0438\u043d\u043d\u044b\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438, \u0441\u043f\u0440\u0430\u0432\u0430 &#8212; \u0440\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u0435 \u043e\u0441\u043e\u0431\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u0430 \u0440\u0430\u0437\u043d\u0438\u0446\u0430. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043d\u0438\u0437\u0438\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435!<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043d\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043e\u0442 MeshInstance.<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21162 Simple 4 tap<\/h4>\n<pre><code>...  vec3 NR_4tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ float depth_l = texture(depth_tex,uv - vec2(1.0,0.0)*el).x; \/\/early exit if on the end of view distance if (depth_l == 1.0){ return vec3(0.5); }  vec3 view_l = viewPosDepth(depth_l,uv - vec2(1.0,0.0)*el,ipm); vec3 view_d = viewPosSampler(uv - vec2(0.0,1.0)*el,ipm,depth_tex); vec3 view_r = viewPosSampler(uv + vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_u = viewPosSampler(uv + vec2(0.0,1.0)*el,ipm,depth_tex);  vec3 h_der = view_r - view_l; vec3 v_der = view_u - view_d;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  ...<\/code><\/pre>\n<p>\u0422\u043e\u0442 \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f, \u043a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u0435, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u043f\u0438\u043a\u0441\u0435\u043b\u044c \u0441\u043d\u0438\u0437\u0443 \u0441 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u043c \u0441\u0432\u0435\u0440\u0445\u0443, \u0430 \u043d\u0435 \u0441 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u043c. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0441 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u043c \u0441\u043f\u0440\u0430\u0432\u0430.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0418 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0415\u0449\u0451 \u0445\u0443\u0436\u0435, \u043d\u043e \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e \u0442.\u043a. \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0431\u043e\u043b\u0435\u0435 &#171;\u0433\u0440\u0443\u0431\u043e\u0435&#187; \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044f \u043f\u0438\u043a\u0441\u0435\u043b\u044c, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c.<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21163 Improved 5 tap<\/h4>\n<pre><code>...  vec3 NR_5tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ float depth_c = texture(depth_tex,uv).x; \/\/early exit if on the end of view distance if (depth_c == 1.0){ return vec3(0.5); }  vec3 view_c = viewPosDepth(depth_c,uv,ipm); vec3 view_l = viewPosSampler(uv - vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_d = viewPosSampler(uv - vec2(0.0,1.0)*el,ipm,depth_tex); vec3 view_r = viewPosSampler(uv + vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_u = viewPosSampler(uv + vec2(0.0,1.0)*el,ipm,depth_tex);  vec3 l = view_c - view_l; vec3 r = view_r - view_c; vec3 d = view_c - view_d; vec3 u = view_u - view_c;  vec3 h_der = abs(l.z) &lt; abs(r.z) ? l : r; vec3 v_der = abs(d.z) &lt; abs(u.z) ? d : u;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  ...<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u043e\u0431\u0449\u0435\u0435 \u0434\u043b\u044f \u043e\u0441\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435(\u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 cross()).<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u043e \u0440\u0430\u0437\u043d\u0438\u0446\u0435 \u0433\u043b\u0443\u0431\u0438\u043d \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 &#171;\u0431\u043b\u0438\u0436\u0435&#187; \u0438 \u0438\u0437 &#171;\u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445&#187; \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u043e\u0447\u0442\u0438 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e!<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0438\u0441\u043a\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0451 \u0435\u0449\u0451 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0443\u044e\u0442, \u043d\u043e \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0437\u0430\u043c\u0435\u0442\u043d\u043e\u0441\u0442\u044c \u043a\u0440\u0430\u0439\u043d\u0435 \u043c\u0430\u043b\u044b.<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21164 Accurate 9 tap<\/h4>\n<pre><code>...  vec3 NR_9tap(vec2 uv,vec2 el,mat4 ipm,sampler2D depth_tex){ vec3 view_c = viewPosSampler(uv,ipm,depth_tex); vec3 view_l = viewPosSampler(uv - vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_r = viewPosSampler(uv + vec2(1.0,0.0)*el,ipm,depth_tex); vec3 view_d = viewPosSampler(uv - vec2(0.0,1.0)*el,ipm,depth_tex); vec3 view_u = viewPosSampler(uv + vec2(0.0,1.0)*el,ipm,depth_tex);  vec3 l = view_c - view_l; vec3 r = view_r - view_c; vec3 d = view_c - view_d; vec3 u = view_u - view_c;   \/\/deside from which direction to sample \/\/center depth float depth_c = texture(depth_tex,uv).x; \/\/early exit if on the end of view distance if (depth_c == 1.0){ return vec3(0.5); } \/\/horizontal depths vec4 H = vec4( texture(depth_tex,uv - vec2(1.0,0.0)*el).x, texture(depth_tex,uv - vec2(2.0,0.0)*el).x, texture(depth_tex,uv + vec2(1.0,0.0)*el).x, texture(depth_tex,uv + vec2(2.0,0.0)*el).x ); \/\/vertical depths vec4 V = vec4( texture(depth_tex,uv - vec2(0.0,1.0)*el).x, texture(depth_tex,uv - vec2(0.0,2.0)*el).x, texture(depth_tex,uv + vec2(0.0,1.0)*el).x, texture(depth_tex,uv + vec2(0.0,2.0)*el).x ); \/\/find diff of true center and extrapolated one vec2 he = abs((2.0*H.xz - H.yw) - depth_c); vec2 ve = abs((2.0*V.xz - V.yw) - depth_c);  vec3 h_der = he.x &lt; he.y ? l : r; vec3 v_der = ve.x &lt; ve.y ? d : u;  vec3 view_n = normalize(cross(v_der,h_der));  return (view_n+1.0)*0.5; }  ...<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 <a href=\"https:\/\/atyuwen.github.io\/posts\/normal-reconstruction\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439<\/a> \u0441\u0442\u0430\u0442\u044c\u0435. \u0415\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443, \u043e\u0434\u043d\u0430\u043a\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u0430\u043a\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0431\u0440\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u043a\u0441\u0442\u0440\u0430\u043f\u043e\u043b\u044f\u0446\u0438\u0438 \u0446\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u044b:<\/p>\n<figure class=\"full-width\"><\/figure>\n<ol>\n<li>\n<p>\u041f\u0440\u043e\u0434\u043b\u0438\u0442\u044c  \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0434\u043b\u0438\u0442\u044c  \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 , \u0442\u043e  \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 , \u0438\u043d\u0430\u0447\u0435  \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 <\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><\/figure>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0447\u0442\u0438 \u0438\u0434\u0435\u0430\u043b\u0435\u043d, \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c, \u0433\u0434\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 2 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439, \u043e\u0434\u043d\u0430\u043a\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c, \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0432 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0438\u0437 NDC \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0438\u0434\u0430<\/p>\n<h4>\u041c\u0435\u0442\u043e\u0434 \u21165 \u0423\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u044b\u0439 \u043c\u043d\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u21164<\/h4>\n<pre><code>...  vec3<\/code><\/pre>\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-349439","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/349439","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=349439"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/349439\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=349439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=349439"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=349439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}