{"id":10006533,"date":"2022-09-19T15:14:47","date_gmt":"2022-09-19T07:14:47","guid":{"rendered":"https:\/\/ityet.com\/?p=10006533"},"modified":"2022-09-19T15:14:47","modified_gmt":"2022-09-19T07:14:47","slug":"%e6%89%8b%e6%8a%8a%e6%89%8b%e6%95%99%e4%bd%a0%ef%bc%9a%e8%bd%bb%e6%9d%be%e6%89%93%e9%80%a0%e6%b2%89%e6%b5%b8%e6%84%9f%e5%8d%81%e8%b6%b3%e7%9a%84%e5%8a%a8%e6%80%81%e6%bc%ab%e5%8f%8d%e5%b0%84%e5%85%a8","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10006533","title":{"rendered":"\u624b\u628a\u624b\u6559\u4f60\uff1a\u8f7b\u677e\u6253\u9020\u6c89\u6d78\u611f\u5341\u8db3\u7684\u52a8\u6001\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167"},"content":{"rendered":"<p>\u4e00\u4e2a\u6c89\u6d78\u611f\u5341\u8db3\u7684\u6e38\u620f\uff0c\u5176\u573a\u666f\u4e2d\u7684\u5168\u5c40\u5149\u7167\u6548\u679c\u4e00\u5b9a\u529f\u4e0d\u53ef\u6ca1\u3002<\/p>\n<p>\u52a8\u6001<a href=\"https:\/\/link.segmentfault.com\/?enc=1qVFaUNU7CMLiJLo5yptLg%3D%3D.opzlBGgxhtNjFHfQx1pnZALQR8JxCnTxerVpcTxXNxcKZQ3gKy5og9MDSwnwv6o5mHQ1QMSkX74ASgFhjU%2FdPE%2FFkoI99iYL4YTLtqN4IPRSK1ToYrrZDLmBzOlzvzKJkKI6u082bg9OIoXlEPtKNQY4zpOgtxCbzv%2Fn3FPdJwA%3D\" rel=\"nofollow\">\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167<\/a>\uff08DDGI\uff09\u5e26\u6765\u7684\u5149\u5f71\u53d8\u5316\uff0c\u662f\u7ec6\u817b\u5ef6\u5c55\u7684\u89c6\u89c9\u8bed\u8a00\uff0c\u8ba9\u573a\u666f\u4e2d\u6bcf\u79cd\u989c\u8272\u90fd\u6709\u4e86\u201c\u4e94\u5f69\u6591\u6593\u201d\u7684\u8be0\u91ca\uff0c\u573a\u666f\u5e03\u5c40\u5149\u5f71\uff0c\u7269\u4f53\u5173\u7cfb\u7acb\u663e\uff0c\u73af\u5883\u6e29\u5ea6\u964d\u4e34\uff0c\u62d3\u5c55\u4e86\u753b\u9762\u4fe1\u606f\u4f20\u8fbe\u7684\u5c42\u6b21\uff0c\u70b9\u775b\u4e4b\u7b14\u3002<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042508267\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p><strong>\u76f4\u63a5\u5149\u6e32\u67d3 VS \u52a8\u6001\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167<\/strong><\/p>\n<p>\u7ec6\u817b\u7684\u5149\u7167\u89c6\u89c9\u8bed\u8a00\u5e26\u6765\u7684\u6280\u672f\u6311\u6218\u4e0d\u5c0f\u3002\u4e0d\u540c\u6750\u8d28\u8868\u9762\u4e0e\u5149\u7167\u4ea7\u751f\u7684\u5448\u73b0\u6548\u679c\u5343\u5dee\u4e07\u522b\uff0c\u6f2b\u53cd\u5c04\uff08Diffuse\uff09\u5c06\u5149\u7167\u4fe1\u606f\u5747\u5300\u6563\u5c04\uff0c\u5149\u7ebf\u7684\u5f3a\u5f31\u3001\u5149\u7167\u52a8\u52bf\u3001\u7269\u4f53\u8868\u9762\u6750\u8d28\u7684\u53d8\u6362\u7b49\uff0c\u9762\u5bf9\u8fd9\u4e9b\u6d6e\u52a8\u7684\u53d8\u91cf\uff0c\u5e73\u53f0\u6027\u80fd\u548c\u7b97\u529b\u5907\u53d7\u8003\u9a8c\u3002<\/p>\n<p>\u9488\u5bf9\u5168\u5c40\u5149\u7167\u9700\u514b\u670d\u7684\u590d\u6742\u201c\u75c7\u72b6\u201d\uff0cHMS Core<a href=\"https:\/\/link.segmentfault.com\/?enc=gzoDc1%2B%2FobwX2Nxjs5ka7A%3D%3D.qxEB%2BF0Qymp2Ifi6FLxZ%2BQgMmTsxW1yXdoYwu3Q18BN9f5C4CQ3q8AlxPMhiUvAk%2BudyhZsMzqfOrEo%2BqpwOtaXB2r0ETIvTiCa9HSM1Qzs%3D\" rel=\"nofollow\">\u56fe\u5f62\u5f15\u64ce\u670d\u52a1<\/a>\u63d0\u4f9b\u4e86\u4e00\u5957\u5b9e\u65f6\u52a8\u6001\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167\uff08DDGI\uff09\u6280\u672f\uff0c\u9762\u5411\u79fb\u52a8\u7aef\uff0c\u53ef\u6269\u5c55\u5230\u5168\u5e73\u53f0\uff0c\u65e0\u9700\u9884\u70d8\u57f9\u3002\u57fa\u4e8e\u5149\u7167\u63a2\u9488\uff08Light Probe\uff09\u7ba1\u7ebf\uff0c\u5728Probe\u66f4\u65b0\u548c\u7740\u8272\u65f6\u63d0\u51fa\u6539\u8fdb\u7b97\u6cd5\uff0c\u964d\u4f4e\u539f\u6709\u7ba1\u7ebf\u7684\u8ba1\u7b97\u8d1f\u8f7d\u3002\u5b9e\u73b0\u591a\u6b21\u53cd\u5c04\u4fe1\u606f\u7684\u5168\u5c40\u5149\u7167\uff0c\u63d0\u5347\u4e86\u6e32\u67d3\u771f\u5b9e\u611f\uff0c\u6ee1\u8db3\u79fb\u52a8\u7ec8\u7aef\u8bbe\u5907\u5b9e\u65f6\u6027\u3001\u4e92\u52a8\u6027\u8981\u6c42\u3002<\/p>\n<p>\u5e76\u4e14\uff0c\u5b9e\u73b0\u4e00\u4e2a\u6c89\u6d78\u611f\u6ee1\u6ee1\u7684\u52a8\u6001<a href=\"https:\/\/link.segmentfault.com\/?enc=12nBeo78vApD1k8xuac9%2Bw%3D%3D.Fb7ubPPae%2Bok3g2RudU0h92N6PY3262gDnl3D%2FlM5NQX7SU8WtQ7yBJMlgLAFmZZSEBw7jbX1lHynCt4CW6O0zdx%2F5vmHyq2MLuwj2u2tXbL4Npu9vuZgLKzf9gjXd3oMz%2F8%2FCR%2B3IySiGqf8zwhgYHAPg%2FfLdyBWE6o48ZmLD8%3D\" rel=\"nofollow\">\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167<\/a>\uff0c\u51e0\u6b65\u5c31\u80fd\u8f7b\u677e\u641e\u5b9a\uff01<\/p>\n<h3>Demo\u793a\u4f8b<\/h3>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042508268\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<h3>\u5f00\u53d1\u6307\u5357<\/h3>\n<h4>\u6b65\u9aa4\u8bf4\u660e<\/h4>\n<p>1.\u521d\u59cb\u5316\u9636\u6bb5\uff1a\u8bbe\u7f6eVulkan\u8fd0\u884c\u73af\u5883\uff0c\u521d\u59cb\u5316DDGIAPI\u7c7b\u3002<\/p>\n<p>2.\u51c6\u5907\u9636\u6bb5\uff1a<\/p>\n<p>\u521b\u5efa\u7528\u4e8e\u4fdd\u5b58DDGI\u6e32\u67d3\u7ed3\u679c\u7684\u4e24\u5f20Texture\uff0c\u5e76\u5c06Texture\u7684\u4fe1\u606f\u4f20\u9012\u7ed9DDGI\u3002<\/p>\n<p>\u51c6\u5907DDGI\u63d2\u4ef6\u9700\u8981\u7684Mesh\u3001Material\u3001Light\u3001Camera\u3001\u5206\u8fa8\u7387\u7b49\u4fe1\u606f\uff0c\u5e76\u5c06\u5176\u4f20\u9012\u7ed9DDGI\u3002<\/p>\n<p>\u8bbe\u7f6eDDGI\u53c2\u6570\u3002<\/p>\n<p>3.\u6e32\u67d3\u9636\u6bb5<\/p>\n<p>\u5982\u679c\u573a\u666f\u7684Mesh\u53d8\u6362\u77e9\u9635\u3001Light\u3001Camera\u4fe1\u606f\u6709\u53d8\u5316\uff0c\u5219\u540c\u6b65\u66f4\u65b0\u5230DDGI\u4fa7\u3002<\/p>\n<p>\u8c03\u7528Render()\u51fd\u6570\uff0cDDGI\u7684\u6e32\u67d3\u7ed3\u679c\u4fdd\u5b58\u5728\u51c6\u5907\u9636\u6bb5\u521b\u5efa\u7684Texture\u4e2d\u3002<\/p>\n<p>\u5c06DDGI\u7684\u7ed3\u679c\u878d\u5165\u5230\u7740\u8272\u8ba1\u7b97\u4e2d\u3002<\/p>\n<h4>\u7f8e\u672f\u9650\u5236<\/h4>\n<p>1.\u5bf9\u4e8e\u60f3\u8981\u4f7f\u80fdDDGI\u6548\u679c\u7684\u573a\u666f\uff0cDDGI\u7684origin\u53c2\u6570\u5e94\u8be5\u8bbe\u7f6e\u4e3a\u573a\u666f\u7684\u4e2d\u5fc3\uff0c\u5e76\u8bbe\u7f6e\u76f8\u5e94\u6b65\u957f\u548cProbe\u6570\u91cf\u4f7f\u5f97DDGI Volume\u80fd\u8986\u76d6\u6574\u4e2a\u573a\u666f\u3002<\/p>\n<p>2.\u4e3a\u4e86\u8ba9DDGI\u83b7\u5f97\u5408\u9002\u7684\u906e\u6321\u6548\u679c\uff0c\u8bf7\u907f\u514d\u7528\u6ca1\u6709\u539a\u5ea6\u7684\u5899\uff1b\u5982\u679c\u5899\u7684\u539a\u5ea6\u76f8\u5bf9\u4e8eProbe\u7684\u5bc6\u5ea6\u663e\u5f97\u592a\u8584\u4e86\uff0c\u4f1a\u51fa\u73b0\u6f0f\u5149\uff08light leaking\uff09\u73b0\u8c61\u3002\u540c\u65f6\uff0c\u6784\u6210\u5899\u7684\u5e73\u9762\u6700\u597d\u662f\u5355\u9762\uff08single-sided\uff09\u7684\uff0c\u4e5f\u5373\u5899\u662f\u7531\u4e24\u4e2a\u5355\u9762\u5e73\u9762\u7ec4\u6210\u3002<\/p>\n<p>3.\u7531\u4e8e\u662f\u79fb\u52a8\u7aef\u7684DDGI\u65b9\u6848\uff0c\u56e0\u6b64\u4ece\u6027\u80fd\u548c\u529f\u8017\u89d2\u5ea6\u51fa\u53d1\uff0c\u6709\u4ee5\u4e0b\u5efa\u8bae\uff1a\u2460\u63a7\u5236\u4f20\u5230SDK\u4fa7\u7684\u51e0\u4f55\u6570\u91cf\uff08\u5efa\u8bae5\u4e07\u9876\u70b9\u4ee5\u5185\uff09\uff0c\u6bd4\u5982\u53ea\u5c06\u573a\u666f\u4e2d\u7684\u4f1a\u4ea7\u751f\u95f4\u63a5\u5149\u7684\u4e3b\u4f53\u7ed3\u6784\u4f20\u5230SDK\uff1b\u2461\u5c3d\u91cf\u4f7f\u7528\u5408\u9002\u7684Probe\u5bc6\u5ea6\u548c\u6570\u91cf\uff0c\u5c3d\u91cf\u4e0d\u8981\u8d85\u8fc710<em>10<\/em>10\u3002\u4ee5\u4e0a\u5efa\u8bae\u4ee5\u6700\u7ec8\u7684\u5448\u73b0\u7ed3\u679c\u4e3a\u4e3b\u3002<\/p>\n<h3>\u5f00\u53d1\u6b65\u9aa4<\/h3>\n<p>1\u3001\u4e0b\u8f7d\u63d2\u4ef6\u7684SDK\u5305\uff0c\u89e3\u538b\u540e\u83b7\u53d6DDGI SDK\u76f8\u5173\u6587\u4ef6\uff0c\u5176\u4e2d\u5305\u62ec1\u4e2a\u5934\u6587\u4ef6\u548c2\u4e2aso\u6587\u4ef6\u3002Android\u5e73\u53f0\u4f7f\u7528\u7684so\u5e93\u6587\u4ef6\u4e0b\u8f7d\u5730\u5740\u8bf7\u53c2\u89c1\uff1a<a href=\"https:\/\/link.segmentfault.com\/?enc=N7%2BcJyFxovZDgi%2FUIeOjZw%3D%3D.7SVFBRT7es1XpgKyS8N2voLCIYjnxfm43DYDBfjq%2BOXPs5xY6eOVS7Vw79PcVnAU0a6XuWn1Go%2Be2qIZ4vqQOOLI9W34DhAyHGOaqn9%2FE45kPiVYfdiDAmPnnkGcDGw8o6qfZ9bA4tz0LkxcNXbNgpLDxVz0uozGe20uXnjzlNKOSByIF0rPC7kOiDyhT2Ks\" rel=\"nofollow\">\u52a8\u6001\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167\u63d2\u4ef6<\/a>\u3002<\/p>\n<p>2\u3001\u8be5\u63d2\u4ef6\u652f\u6301Android\u5e73\u53f0\uff0c\u4f7f\u7528CMake\u8fdb\u884c\u6784\u5efa\u3002\u4ee5\u4e0b\u662fCMakeLists.txt\u90e8\u5206\u7247\u6bb5\u4ec5\u4f9b\u53c2\u8003\uff1a<\/p>\n<pre><code>cmake_minimum_required(VERSION 3.4.1 FATAL_ERROR)\nset(NAME DDGIExample)\nproject(${NAME})\n\nset(PROJ_ROOT ${CMAKE_CURRENT_SOURCE_DIR})\nset(CMAKE_CXX_FLAGS &quot;${CMAKE_CXX_FLAGS} -std=c++14 -O2 -DNDEBUG -DVK_USE_PLATFORM_ANDROID_KHR&quot;)\nfile(GLOB EXAMPLE_SRC &quot;${PROJ_ROOT}\/src\/*.cpp&quot;) # \u5f15\u5165\u5f00\u53d1\u8005\u4e3b\u7a0b\u5e8f\u4ee3\u7801\u3002\ninclude_directories(${PROJ_ROOT}\/include) # \u5f15\u5165\u5934\u6587\u4ef6\uff0c\u53ef\u4ee5\u5c06DDGIAPI.h\u5934\u6587\u4ef6\u653e\u5728\u6b64\u76ee\u5f55\u3002\n\n# \u5bfc\u5165librtcore.so\u548clibddgi.so\nADD_LIBRARY(rtcore SHARED IMPORTED)\nSET_TARGET_PROPERTIES(rtcore\n                PROPERTIES IMPORTED_LOCATION\n                ${CMAKE_SOURCE_DIR}\/src\/main\/libs\/librtcore.so)\n\nADD_LIBRARY(ddgi SHARED IMPORTED)\nSET_TARGET_PROPERTIES(ddgi\n                PROPERTIES IMPORTED_LOCATION\n                ${CMAKE_SOURCE_DIR}\/src\/main\/libs\/libddgi.so)\n\nadd_library(native-lib SHARED ${EXAMPLE_SRC})\ntarget_link_libraries(\n    native-lib\n    ...\n    ddgi # \u94fe\u63a5ddgi\u5e93\u3002\n    rtcore\n    android\n    log\n    z\n    ...\n)<\/code><\/pre>\n<p>3\u3001\u8bbe\u7f6eVulkan\u73af\u5883\uff0c\u521d\u59cb\u5316DDGIAPI\u7c7b\u3002<\/p>\n<pre><code>\/\/ \u8bbe\u7f6eDDGI SDK\u9700\u8981\u7684Vulkan\u73af\u5883\u4fe1\u606f\u3002\n\/\/ \u5305\u62eclogicalDevice, queue, queueFamilyIndex\u4fe1\u606f\u3002\nvoid DDGIExample::SetupDDGIDeviceInfo()\n{\n    m_ddgiDeviceInfo.physicalDevice = physicalDevice;\n    m_ddgiDeviceInfo.logicalDevice = device;\n    m_ddgiDeviceInfo.queue = queue;\n    m_ddgiDeviceInfo.queueFamilyIndex = vulkanDevice-&gt;queueFamilyIndices.graphics;    \n}\n\nvoid DDGIExample::PrepareDDGI()\n{\n    \/\/ \u8bbe\u7f6eVulkan\u73af\u5883\u4fe1\u606f\u3002\n    SetupDDGIDeviceInfo();\n    \/\/ \u8c03\u7528DDGI\u7684\u521d\u59cb\u5316\u51fd\u6570\u3002\n    m_ddgiRender-&gt;InitDDGI(m_ddgiDeviceInfo);\n    ...\n}\n\nvoid DDGIExample::Prepare()\n{\n    ...\n    \/\/ \u521b\u5efaDDGIAPI\u5bf9\u8c61\u3002\n    std::unique_ptr&lt;DDGIAPI&gt; m_ddgiRender = make_unique&lt;DDGIAPI&gt;();\n    ...\n    PrepareDDGI();\n    ...\n}<\/code><\/pre>\n<p>4\u3001\u521b\u5efa\u4e24\u5f20Texture\uff0c\u7528\u4e8e\u4fdd\u5b58\u76f8\u673a\u89c6\u89d2\u7684\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167\u548c\u6cd5\u7ebf\u6df1\u5ea6\u56fe\u3002\u4e3a\u63d0\u9ad8\u6e32\u67d3\u6027\u80fd\uff0cTexture\u652f\u6301\u964d\u5206\u8fa8\u7387\u7684\u8bbe\u7f6e\u3002\u5206\u8fa8\u7387\u8d8a\u5c0f\uff0c\u6e32\u67d3\u6027\u80fd\u8868\u73b0\u8d8a\u597d\uff0c\u4f46\u6e32\u67d3\u7ed3\u679c\u7684\u8d70\u6837\uff0c\u4f8b\u5982\u8fb9\u7f18\u7684\u952f\u9f7f\u7b49\u95ee\u9898\u53ef\u80fd\u4f1a\u66f4\u52a0\u4e25\u91cd\u3002<\/p>\n<pre><code>\/\/ \u521b\u5efa\u7528\u4e8e\u4fdd\u5b58\u6e32\u67d3\u7ed3\u679c\u7684Texture\u3002\nvoid DDGIExample::CreateDDGITexture()\n{\n    VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;\n    int ddgiTexWidth = width \/ m_shadingPara.ddgiDownSizeScale; \/\/ \u7eb9\u7406\u5bbd\u5ea6\u3002\n    int ddgiTexHeight = height \/ m_shadingPara.ddgiDownSizeScale; \/\/ \u7eb9\u7406\u9ad8\u5ea6\u3002\n    glm::ivec2 size(ddgiTexWidth, ddgiTexHeight);\n    \/\/ \u521b\u5efa\u4fdd\u5b58irradiance\u7ed3\u679c\u7684Texture\u3002\n    m_irradianceTex.CreateAttachment(vulkanDevice,\n                                     ddgiTexWidth,\n                                     ddgiTexHeight,\n                                     VK_FORMAT_R16G16B16A16_SFLOAT,\n                                     usage,\n                                     VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,\n                                     m_defaultSampler);\n    \/\/ \u521b\u5efa\u4fdd\u5b58normal\u548cdepth\u7ed3\u679c\u7684Texture\u3002\n    m_normalDepthTex.CreateAttachment(vulkanDevice,\n                                      ddgiTexWidth,\n                                      ddgiTexHeight,\n                                      VK_FORMAT_R16G16B16A16_SFLOAT,\n                                      usage,\n                                      VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,\n                                      m_defaultSampler);\n}\n\/\/ \u8bbe\u7f6eDDGIVulkanImage\u4fe1\u606f\u3002\nvoid DDGIExample::PrepareDDGIOutputTex(const vks::Texture&amp; tex, DDGIVulkanImage *texture) const\n{\n    texture-&gt;image = tex.image;\n    texture-&gt;format = tex.format;\n    texture-&gt;type = VK_IMAGE_TYPE_2D;\n    texture-&gt;extent.width = tex.width;\n    texture-&gt;extent.height = tex.height;\n    texture-&gt;extent.depth = 1;\n    texture-&gt;usage = tex.usage;\n    texture-&gt;layout = tex.imageLayout;\n    texture-&gt;layers = 1;\n    texture-&gt;mipCount = 1;\n    texture-&gt;samples = VK_SAMPLE_COUNT_1_BIT;\n    texture-&gt;tiling = VK_IMAGE_TILING_OPTIMAL;\n}\n\nvoid DDGIExample::PrepareDDGI()\n{\n    ...\n    \/\/ \u8bbe\u7f6eTexture\u5206\u8fa8\u7387\u3002\n    m_ddgiRender-&gt;SetResolution(width \/ m_downScale, height \/ m_downScale);\n    \/\/ \u8bbe\u7f6e\u7528\u4e8e\u4fdd\u5b58\u6e32\u67d3\u7ed3\u679c\u7684DDGIVulkanImage\u4fe1\u606f\u3002\n    PrepareDDGIOutputTex(m_irradianceTex, &amp;m_ddgiIrradianceTex);\n    PrepareDDGIOutputTex(m_normalDepthTex, &amp;m_ddgiNormalDepthTex);\n    m_ddgiRender-&gt;SetAdditionalTexHandler(m_ddgiIrradianceTex, AttachmentTextureType::DDGI_IRRADIANCE);\n    m_ddgiRender-&gt;SetAdditionalTexHandler(m_ddgiNormalDepthTex, AttachmentTextureType::DDGI_NORMAL_DEPTH);\n    ...\n}\n\nvoid DDGIExample::Prepare()\n{\n    ...\n    CreateDDGITexture();\n    ...\n    PrepareDDGI();\n    ...\n}<\/code><\/pre>\n<p>5\u3001\u51c6\u5907DDGI\u6e32\u67d3\u6240\u9700\u7684\u7f51\u683c\u3001\u6750\u8d28\u3001\u5149\u6e90\u3001\u76f8\u673a\u6570\u636e\u3002<\/p>\n<pre><code>\/\/ mesh\u7ed3\u6784\u4f53\uff0c\u652f\u6301submesh\u3002\nstruct DDGIMesh {\n    std::string meshName;\n    std::vector&lt;DDGIVertex&gt; meshVertex;\n    std::vector&lt;uint32_t&gt; meshIndice;\n    std::vector&lt;DDGIMaterial&gt; materials;\n    std::vector&lt;uint32_t&gt; subMeshStartIndexes;\n    ...\n};\n\n\/\/ \u65b9\u5411\u5149\u7ed3\u6784\u4f53\uff0c\u5f53\u524d\u4ec5\u652f\u63011\u4e2a\u65b9\u5411\u5149\u3002\nstruct DDGIDirectionalLight {\n    CoordSystem coordSystem = CoordSystem::RIGHT_HANDED;\n    int lightId;\n    DDGI::Mat4f localToWorld;\n    DDGI::Vec4f color;\n    DDGI::Vec4f dirAndIntensity;\n};\n\n\/\/ \u4e3b\u76f8\u673a\u7ed3\u6784\u4f53\u3002\nstruct DDGICamera {\n    DDGI::Vec4f pos;\n    DDGI::Vec4f rotation;\n    DDGI::Mat4f viewMat;\n    DDGI::Mat4f perspectiveMat;\n};\n\n\/\/ \u8bbe\u7f6eDDGI\u7684\u5149\u6e90\u4fe1\u606f\u3002\nvoid DDGIExample::SetupDDGILights()\n{\n    m_ddgiDirLight.color = VecInterface(m_dirLight.color);\n    m_ddgiDirLight.dirAndIntensity = VecInterface(m_dirLight.dirAndPower);\n    m_ddgiDirLight.localToWorld = MatInterface(inverse(m_dirLight.worldToLocal));\n    m_ddgiDirLight.lightId = 0;\n}\n\n\/\/ \u8bbe\u7f6eDDGI\u7684\u76f8\u673a\u4fe1\u606f\u3002\nvoid DDGIExample::SetupDDGICamera()\n{\n    m_ddgiCamera.pos = VecInterface(m_camera.viewPos);\n    m_ddgiCamera.rotation = VecInterface(m_camera.rotation, 1.0);\n    m_ddgiCamera.viewMat = MatInterface(m_camera.matrices.view);\n    glm::mat4 yFlip = glm::mat4(1.0f);\n    yFlip[1][1] = -1;\n    m_ddgiCamera.perspectiveMat = MatInterface(m_camera.matrices.perspective * yFlip);\n}\n\n\/\/ \u51c6\u5907DDGI\u9700\u8981\u7684\u7f51\u683c\u4fe1\u606f\u3002\n\/\/ \u4ee5gltf\u683c\u5f0f\u7684\u6e32\u67d3\u573a\u666f\u4e3a\u4f8b\u3002\nvoid DDGIExample::PrepareDDGIMeshes()\n{\n    for (constauto&amp; node : m_models.scene.linearNodes) {\n        DDGIMesh tmpMesh;\n        tmpMesh.meshName = node-&gt;name;\n        if (node-&gt;mesh) {\n            tmpMesh.meshName = node-&gt;mesh-&gt;name; \/\/ \u7f51\u683c\u7684\u540d\u79f0\u3002\n            tmpMesh.localToWorld = MatInterface(node-&gt;getMatrix()); \/\/ \u7f51\u683c\u7684\u53d8\u6362\u77e9\u9635\u3002\n            \/\/ \u7f51\u683c\u7684\u9aa8\u9abc\u8499\u76ae\u77e9\u9635\u3002\n            if (node-&gt;skin) {\n                tmpMesh.hasAnimation = true;\n                for (auto&amp; matrix : node-&gt;skin-&gt;inverseBindMatrices) {\n                    tmpMesh.boneTransforms.emplace_back(MatInterface(matrix));\n                }\n            }\n            \/\/ \u7f51\u683c\u7684\u6750\u8d28\u8282\u70b9\u3001\u9876\u70b9\u4fe1\u606f\u3002\n            for (vkglTF::Primitive *primitive : node-&gt;mesh-&gt;primitives) {\n                ...\n            }\n        }\n        m_ddgiMeshes.emplace(std::make_pair(node-&gt;index, tmpMesh));\n    }\n}\n\nvoid DDGIExample::PrepareDDGI()\n{\n    ...\n    \/\/ \u8f6c\u6362\u6210DDGI\u9700\u8981\u7684\u6570\u636e\u683c\u5f0f\u3002\n    SetupDDGILights();\n    SetupDDGICamera();\n    PrepareDDGIMeshes();\n    ...\n    \/\/ \u5411DDGI\u4f20\u9012\u6570\u636e\u3002\n    m_ddgiRender-&gt;SetMeshs(m_ddgiMeshes);\n    m_ddgiRender-&gt;UpdateDirectionalLight(m_ddgiDirLight);\n    m_ddgiRender-&gt;UpdateCamera(m_ddgiCamera);\n    ...\n}<\/code><\/pre>\n<p>6\u3001\u8bbe\u7f6eDDGI\u63a2\u9488\u7684\u4f4d\u7f6e\u3001\u6570\u91cf\u7b49\u53c2\u6570\u3002<\/p>\n<pre><code>\/\/ \u8bbe\u7f6eDDGI\u7b97\u6cd5\u53c2\u6570\u3002\nvoid DDGIExample::SetupDDGIParameters()\n{\n    m_ddgiSettings.origin = VecInterface(3.5f, 1.5f, 4.25f, 0.f);\n    m_ddgiSettings.probeStep = VecInterface(1.3f, 0.55f, 1.5f, 0.f);\n    ...\n}\nvoid DDGIExample::PrepareDDGI()\n{\n    ...\n    SetupDDGIParameters();\n    ...\n    \/\/ \u5411DDGI\u4f20\u9012\u6570\u636e\u3002\n    m_ddgiRender-&gt;UpdateDDGIProbes(m_ddgiSettings);\n    ...\n}<\/code><\/pre>\n<p>7\u3001\u8c03\u7528DDGI\u7684Prepare()\u51fd\u6570\u89e3\u6790\u524d\u9762\u4f20\u9012\u7684\u6570\u636e\u3002<\/p>\n<pre><code>void DDGIExample::PrepareDDGI()\n{\n    ...\n    m_ddgiRender-&gt;Prepare();\n}<\/code><\/pre>\n<p>8\u3001\u8c03\u7528DDGI\u7684Render()\uff0c\u5c06\u573a\u666f\u7684\u95f4\u63a5\u5149\u4fe1\u606f\u66f4\u65b0\u7f13\u5b58\u5230\u6b65\u9aa44\u4e2d\u8bbe\u7f6e\u7684\u4e24\u5f20DDGI Texture\u4e2d\u3002<\/p>\n<p><strong>*\u8bf4\u660e<\/strong><\/p>\n<p>\u5f53\u524d\u7248\u672c\u4e2d\uff0c\u6e32\u67d3\u7ed3\u679c\u4e3a\u76f8\u673a\u89c6\u89d2\u7684\u6f2b\u53cd\u5c04\u95f4\u63a5\u5149\u7ed3\u679c\u56fe\u548c\u6cd5\u7ebf\u6df1\u5ea6\u56fe\uff0c\u5f00\u53d1\u8005\u4f7f\u7528\u53cc\u8fb9\u6ee4\u6ce2\u7b97\u6cd5\u7ed3\u5408\u6cd5\u7ebf\u6df1\u5ea6\u56fe\u5c06\u6f2b\u53cd\u5c04\u95f4\u63a5\u5149\u7ed3\u679c\u8fdb\u884c\u4e0a\u91c7\u6837\u64cd\u4f5c\uff0c\u8ba1\u7b97\u5f97\u5230\u5c4f\u5e55\u5c3a\u5bf8\u7684\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167\u7ed3\u679c\u3002<\/p>\n<p>\u5982\u679c\u4e0d\u8c03\u7528Render()\u51fd\u6570\uff0c\u90a3\u4e48\u6e32\u67d3\u7ed3\u679c\u4e3a\u5386\u53f2\u5e27\u7684\u7ed3\u679c\u3002<\/p>\n<pre><code>#define RENDER_EVERY_NUM_FRAME 2\nvoid DDGIExample::Draw()\n{\n    ...\n    \/\/ \u6bcf\u4e24\u5e27\u8c03\u7528\u4e00\u6b21DDGIRender()\u3002\n    if (m_ddgiON &amp;&amp; m_frameCnt % RENDER_EVERY_NUM_FRAME == 0) {\n        m_ddgiRender-&gt;UpdateDirectionalLight(m_ddgiDirLight); \/\/ \u66f4\u65b0\u5149\u6e90\u4fe1\u606f\u3002\n        m_ddgiRender-&gt;UpdateCamera(m_ddgiCamera); \/\/ \u66f4\u65b0\u76f8\u673a\u4fe1\u606f\u3002\n        m_ddgiRender-&gt;DDGIRender(); \/\/ DDGI\u6e32\u67d3(\u6267\u884c)\u4e00\u6b21\uff0c\u6e32\u67d3\u7ed3\u679c\u4fdd\u5b58\u5728\u6b65\u9aa44\u521b\u5efa\u7684Texture\u4e2d\u3002\n    }\n    ...\n}\n\nvoid DDGIExample::Render()\n{\n    if (!prepared) {\n        return;\n    }\n    SetupDDGICamera();\n    if (!paused || m_camera.updated) {\n        UpdateUniformBuffers();\n    }\n    Draw();\n    m_frameCnt++;\n}<\/code><\/pre>\n<p>9\u3001\u53e0\u52a0DDGI\u95f4\u63a5\u5149\u7ed3\u679c\uff0c\u4f7f\u7528\u6d41\u7a0b\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2wvk\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<pre><code>\/\/ \u6700\u7ec8\u7740\u8272shader\u3002\n\n\/\/ \u901a\u8fc7\u4e0a\u91c7\u6837\u8ba1\u7b97\u5c4f\u5e55\u7a7a\u95f4\u5750\u6807\u5bf9\u5e94\u7684DDGI\u503c\u3002\nvec3 Bilateral(ivec2 uv, vec3 normal)\n{\n    ...\n}\n\nvoid main()\n{\n    ...\n    vec3 result = vec3(0.0);\n    result += DirectLighting();\n    result += IndirectLighting();\n    vec3 DDGIIrradiances = vec3(0.0);\n    ivec2 texUV = ivec2(gl_FragCoord.xy);\n    texUV.y = shadingPara.ddgiTexHeight - texUV.y;\n    if (shadingPara.ddgiDownSizeScale == 1) { \/\/ \u672a\u964d\u4f4e\u5206\u8fa8\u7387\u3002\n        DDGIIrradiances = texelFetch(irradianceTex, texUV, 0).xyz;\n    } else { \/\/ \u964d\u4f4e\u5206\u8fa8\u7387\u3002\n        ivec2 inDirectUV = ivec2(vec2(texUV) \/ vec2(shadingPara.ddgiDownSizeScale));\n        DDGIIrradiances = Bilateral(inDirectUV, N);\n    }\n    result += DDGILighting();\n    ...\n    Image = vec4(result_t, 1.0);\n}<\/code><\/pre>\n<p><strong>\u4e86\u89e3\u66f4\u591a\u8be6\u60c5&gt;&gt;<\/strong><\/p>\n<p>\u8bbf\u95ee<a href=\"https:\/\/link.segmentfault.com\/?enc=nt8yDJvXNr2FTVau%2Fbl2iA%3D%3D.y65I0P%2B0uTz316HOayNm%2B%2FRG%2FEocSoT%2BCbwLjID5teI%2Fde16mDfKQE3whViyYdxk26%2FHEtWUjoIbdNs%2BvA0s%2Bw%3D%3D\" rel=\"nofollow\">\u534e\u4e3a\u5f00\u53d1\u8005\u8054\u76df\u5b98\u7f51<\/a>  <br \/>\u83b7\u53d6<a href=\"https:\/\/link.segmentfault.com\/?enc=CCJlzNDbO7%2FGDmU%2FNR71VA%3D%3D.Z4aGKqhsbZyoh1XQijG0HxT0qzs0diu1EXtL65TTm9O7pEAKAFiS38Z5YzXQG69jwtNBLUyOqMwlUuE1NMdwhtO7JPZ7Oi%2FzgbwkBgyru9c%3D\" rel=\"nofollow\">\u5f00\u53d1\u6307\u5bfc\u6587\u6863<\/a>  <br \/>\u534e\u4e3a\u79fb\u52a8\u670d\u52a1\u5f00\u6e90\u4ed3\u5e93\u5730\u5740\uff1a<a href=\"https:\/\/link.segmentfault.com\/?enc=6SOzuUKIeikOEKDHiaj0HQ%3D%3D.NiAty80unpGaYMa%2FfD4q%2FfG6z%2BczY0yulmr4KzEhbpg%3D\" rel=\"nofollow\">GitHub<\/a>\u3001<a href=\"https:\/\/link.segmentfault.com\/?enc=5AybmU6%2Fvppyq2Mro4BUVg%3D%3D.ccJ7HbIt89qp5APbIP%2FL1oJnzVc3PnpJSgV4UHOsMpc%3D\" rel=\"nofollow\">Gitee<\/a><\/p>\n<p><strong>\u5173\u6ce8\u6211\u4eec\uff0c\u7b2c\u4e00\u65f6\u95f4\u4e86\u89e3 HMS Core \u6700\u65b0\u6280\u672f\u8d44\u8baf~<\/strong><\/p>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000042508358\">https:\/\/segmentfault.com\/a\/1190000042508358<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4e00\u4e2a\u6c89\u6d78\u611f\u5341\u8db3\u7684\u6e38\u620f\uff0c\u5176\u573a\u666f\u4e2d\u7684\u5168\u5c40\u5149\u7167\u6548\u679c\u4e00\u5b9a\u529f\u4e0d\u53ef\u6ca1\u3002 \u52a8\u6001\u6f2b\u53cd\u5c04\u5168\u5c40\u5149\u7167\uff08DDGI\uff09\u5e26\u6765\u7684\u5149\u5f71\u53d8\u5316\uff0c\u662f\u7ec6 [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-10006533","post","type-post","status-publish","format-standard","hentry"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10006533"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006533\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10006533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10006533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10006533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}