{"id":117,"date":"2024-06-23T00:17:50","date_gmt":"2024-06-22T15:17:50","guid":{"rendered":"https:\/\/xn--k10aa.com\/?p=117"},"modified":"2024-10-26T12:44:22","modified_gmt":"2024-10-26T03:44:22","slug":"unity-instanted-grass","status":"publish","type":"post","link":"https:\/\/remoooo.com\/en\/unity-instanted-grass\/","title":{"rendered":"Unity interactive and chopable octree grass sea rendering \u2013 geometry, compute shader (BIRP\/URP)"},"content":{"rendered":"<p>Project (BIRP) on Github:<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/Remyuu\/Unity-Interactive-Grass%E2%80%8Bgithub.com\/Remyuu\/Unity-Interactive-Grass\">https:\/\/github.com\/Remyuu\/Unity-Interactive-Grass<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image.jpeg\" alt=\"\" class=\"wp-image-118 lazyload\"\/><noscript><img decoding=\"async\" width=\"1930\" height=\"1344\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image.jpeg\" alt=\"\" class=\"wp-image-118 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image.jpeg 1930w, https:\/\/remoooo.com\/wp-content\/uploads\/image-300x209.jpeg 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-1024x713.jpeg 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-768x535.jpeg 768w, https:\/\/remoooo.com\/wp-content\/uploads\/image-1536x1070.jpeg 1536w\" sizes=\"(max-width: 1930px) 100vw, 1930px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-4.png\" alt=\"\" class=\"wp-image-123 lazyload\"\/><noscript><img decoding=\"async\" width=\"1428\" height=\"962\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-4.png\" alt=\"\" class=\"wp-image-123 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-4.png 1428w, https:\/\/remoooo.com\/wp-content\/uploads\/image-4-300x202.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-4-1024x690.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-4-768x517.png 768w\" sizes=\"(max-width: 1428px) 100vw, 1428px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-8.png\" alt=\"\" class=\"wp-image-127 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"494\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-8.png\" alt=\"\" class=\"wp-image-127 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-8.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-8-300x103.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-8-1024x351.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-8-768x263.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>First, here is a screenshot of 10,0500 grasses running on Compute Shader on my M1 pro without any optimization. It can run more than 200 frames.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-10.png\" alt=\"\" class=\"wp-image-129 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"1008\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-10.png\" alt=\"\" class=\"wp-image-129 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-10.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-10-300x210.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-10-1024x717.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-10-768x538.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>After adding octree frustum culling, distance fading and other operations, the frame rate is not so stable (I want to die). I guess it is because the CPU has too much pressure to operate each frame and needs to maintain such a large amount of grass information. But as long as enough culling is done, running 700+ frames is no problem (comfort). In addition, the depth of the octree also needs to be optimized according to the actual situation. In the figure below, I set the depth of the octree to 5.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-6.png\" alt=\"\" class=\"wp-image-125 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"1058\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-6.png\" alt=\"\" class=\"wp-image-125 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-6.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-6-300x220.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-6-1024x752.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-6-768x564.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Preface<\/h2>\n\n\n\n<p>This article is getting longer and longer. I mainly use it to review my knowledge. When you read it, you may feel that there are a lot of basic contents. I am a complete novice, and I beg for discussion and correction from you.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image.png\" alt=\"\" class=\"wp-image-119 lazyload\"\/><noscript><img decoding=\"async\" width=\"252\" height=\"252\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image.png\" alt=\"\" class=\"wp-image-119 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image.png 252w, https:\/\/remoooo.com\/wp-content\/uploads\/image-150x150.png 150w\" sizes=\"(max-width: 252px) 100vw, 252px\" \/><\/noscript><\/figure>\n\n\n\n<p>This article mainly has two stages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The GS + TS method achieves the most basic effect of grass rendering<\/li>\n\n\n\n<li>Then I used CS to re-render the sea of grass, adding various optimization methods<\/li>\n<\/ul>\n\n\n\n<p>The rendering method of geometry shader + tessellation shader should be relatively simple, but the performance ceiling is relatively low and the platform compatibility is poor.<\/p>\n\n\n\n<p>The method of combining compute shaders with GPU Instancing should be the mainstream method in the current industry, and it can also run well on mobile terminals.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-2.png\" alt=\"\" class=\"wp-image-121 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"394\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-2.png\" alt=\"\" class=\"wp-image-121 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-2.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-2-300x82.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-2-1024x280.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-2-768x210.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>The CS rendering of the sea of grass in this article mainly refers to the implementation of Colin and Minions Art, which is more like a hybrid of the two (the former has been analyzed by a big guy on Zhihu<a target=\"_blank\" href=\"https:\/\/zhuanlan.zhihu.com\/p\/397620652\" rel=\"noreferrer noopener\">Grass rendering study notes based on GPU Instance<\/a>). Use three sets of ComputeBuffer, one is the buffer containing all the grass, one is the buffer that is appended into the Material, and the other is a visible buffer (obtained in real time based on frustum culling). Implemented the use of a quad-octree (odd-even depth) for space division, plus the frustum culling to get the index of all the grass in the current frustum, pass it to the Compute Shader for further processing (such as Mesh generation, quaternion calculation rotation, LoD, etc.), and then use a variable-length ComputeBuffer (ComputeBufferType.Append) to pass the grass to be rendered to the Material through Instancing for final rendering.<\/p>\n\n\n\n<p>You can also use the Hi-Z solution to eliminate it. I&#039;m digging a hole and working hard to learn.<\/p>\n\n\n\n<p>In addition, I referred to the article by Minions Art and copied a set of editor grass brushing tools (incomplete version), which stores the positions of all grass vertices by maintaining a vertex list.<\/p>\n\n\n\n<p>Furthermore, by maintaining another set of Cut Buffer, if the grass is marked with a -1 value, it will not be processed. If it is marked with a non--1 value of the chopper height, it will be passed to the Material, and through the WorldPos + Split.y plus the lerp operation, the upper half of the grass will be made invisible, and the color of the grass will be modified, and finally some grass clippings will be added to achieve a grass-cutting effect.<\/p>\n\n\n\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\">\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" data-id=\"120\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-1.png\" alt=\"\" class=\"wp-image-120 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"598\" data-id=\"120\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-1.png\" alt=\"\" class=\"wp-image-120 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-1.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-1-300x125.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-1-1024x425.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-1-768x319.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><figcaption class=\"wp-element-caption\">GS&#039;s swan song<\/figcaption><\/figure>\n<\/figure>\n<\/div>\n\n\n\n<p><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/695636520\" target=\"_blank\" rel=\"noreferrer noopener\">Previous article<\/a>I have introduced in detail what a tessellation shader is and various optimization methods. Next, I will integrate tessellation into actual development. In addition, I combined the compute shader I learned in a few days to create a grass field based on the compute shader. You can find more details in the following article.<a href=\"https:\/\/zhuanlan.zhihu.com\/p\/701633578\" target=\"_blank\" rel=\"noreferrer noopener\">This note<\/a>The following is the small effect that this article will achieve, with complete code attached:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Grass Rendering<\/li>\n\n\n\n<li>Grass Rendering \u2013 Geometry Shader (BIRP\/URP)<\/li>\n\n\n\n<li>Define grass width, height, orientation, pour, curvature, gradient, color, band, normal<\/li>\n\n\n\n<li>INTEGER tessellation<\/li>\n\n\n\n<li>URP adds Visibility Map<\/li>\n\n\n\n<li>Grass rendering \u2013 Compute Shader (BIRP\/URP) work on MacOS<\/li>\n\n\n\n<li>Octree frustum culling<\/li>\n\n\n\n<li>Distance fades<\/li>\n\n\n\n<li>Grass Interaction<\/li>\n\n\n\n<li>Interactive Geometry Shaders (BIRP\/URP)<\/li>\n\n\n\n<li>Interactive Compute Shader (BIRP) work on MacOS<\/li>\n\n\n\n<li>Unity custom grass generation tool<\/li>\n\n\n\n<li>Grass cutting system<\/li>\n<\/ul>\n\n\n\n<p>Main references<strong>(plagiarism)<\/strong>article:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Drawing grass with geometry shader (BIRP):<a href=\"https:\/\/roystan.net\/articles\/grass-shader\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/roystan.net\/articles\/grass-shader\/<\/a><\/li>\n\n\n\n<li>Drawing Grass with Geometry Shader (URP)<a href=\"https:\/\/danielilett.com\/2021-08-24-tut5-17-stylised-grass\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/danielilett.com\/2021-08-24-tut5-17-stylised-grass\/<\/a><\/li>\n\n\n\n<li>Compute Shader Tutorial-1:<a href=\"https:\/\/catlikecoding.com\/unity\/tutorials\/basics\/compute-shaders\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/catlikecoding.com\/unity\/tutorials\/basics\/compute-shaders\/<\/a><\/li>\n\n\n\n<li>Compute Shader Tutorial-2:<a href=\"https:\/\/medium.com\/ericzhan-publication\/shader%E7%AD%86%E8%A8%98-%E5%88%9D%E6%8E%A2compute-shader-9efeebd579c1\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/medium.com\/ericzhan-publication\/shader notes-a preliminary exploration of compute-shader-9efeebd579c1<\/a><\/li>\n\n\n\n<li>Compute Shader draws the grass:<a href=\"https:\/\/www.patreon.com\/posts\/53587750\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/53587750<\/a><\/li>\n\n\n\n<li>Grass painting tool integration:<a href=\"https:\/\/www.youtube.com\/watch?v=xKJHL8nQiuM\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.youtube.com\/watch?v=xKJHL8nQiuM<\/a><\/li>\n\n\n\n<li>Interactive Geometry Shader Grass (BIRP):<a href=\"https:\/\/www.patreon.com\/posts\/40090373\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/40090373<\/a><\/li>\n\n\n\n<li>Interactive Geometry Shader Grass (URP):<a href=\"https:\/\/www.patreon.com\/posts\/47447321\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/47447321<\/a><\/li>\n\n\n\n<li>Interactive Compute Shader Grass (BIRP\/URP):<a href=\"https:\/\/www.patreon.com\/posts\/wip-patron-only-83683483\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/wip-patron-only-83683483<\/a><\/li>\n\n\n\n<li>Ned&#039;s reference:<a href=\"https:\/\/www.youtube.com\/watch?v=DeATXF4Szqo\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.youtube.com\/watch?v=DeATXF4Szqo<\/a><\/li>\n\n\n\n<li>URP Grass Compute Shader reference code:<a href=\"https:\/\/github.com\/ColinLeung-NiloCat\/UnityURP-MobileDrawMeshInstancedIndirectExample\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/ColinLeung-NiloCat\/UnityURP-MobileDrawMeshInstancedIndirectExample<\/a><\/li>\n\n\n\n<li>Compute Shader reference code:<a href=\"https:\/\/github.com\/ellioman\/Indirect-Rendering-With-Compute-Shaders\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/ellioman\/Indirect-Rendering-With-Compute-Shaders<\/a><\/li>\n<\/ul>\n\n\n\n<p>There are many ways to render grass, two of which are shown in this article:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Geometry Shader + Tessellation Shader<\/li>\n\n\n\n<li>Compute Shaders + GPU Instancing<\/li>\n<\/ul>\n\n\n\n<p>First of all, the first solution has great limitations. Many mobile devices and Metal do not support GS, and GS will recalculate the Mesh every frame, which is quite expensive.<\/p>\n\n\n\n<p>Secondly, can MacOS no longer run geometry shaders? Not really. If you want to use GS, you must use OpenGL, not Metal. But it should be noted that Apple supports OpenGL up to OpenGL 4.1. In other words, this version does not support Compute Shader. Of course, MacOS in the Intel era can support OpenGL 4.3 and can run CS and GS at the same time. The M series chips do not have this fate. Either use 4.1 or use Metal. On my M1p mbp, even if you choose a virtual machine (Parallels 18+ provides DX11 and Vulkan), the Vulkan running on macOS is translated and is essentially Metal, so there is still no GS. Therefore, there is no native GS after macOS M1.<\/p>\n\n\n\n<p>Furthermore, Metal doesn&#039;t even support Tessellation shaders directly. Apple doesn&#039;t want to support these two things on the chip at all. Why? Because the efficiency is too low. On the M chip, TS is even simulated by CS!<\/p>\n\n\n\n<p>To sum up, geometry shaders are a dead-end technology, especially after the advent of Mesh Shader. Although GS is very popular in Unity, any similar effect can be instanced on CS, and it is more efficient. Although new graphics cards will still support GS, there are still quite a few games on the market that use GS. It&#039;s just that Apple didn&#039;t consider compatibility and directly cut it off.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" data-id=\"122\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-3.png\" alt=\"\" class=\"wp-image-122 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"994\" data-id=\"122\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-3.png\" alt=\"\" class=\"wp-image-122 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-3.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-3-300x207.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-3-1024x707.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-3-768x530.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><figcaption class=\"wp-element-caption\">DX11 for MacOS<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p>This article explains in detail why GS is so slow:<a target=\"_blank\" href=\"http:\/\/www.joshbarczak.com\/blog\/?p=667\" rel=\"noreferrer noopener\">http:\/\/www.joshbarczak.com\/blog\/?p=667<\/a>. Simply put, Intel optimized GS by blocking threads, etc., while other chips do not have this optimization.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>This article is a study note and is likely to contain errors.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">1. Overview of Geometry Shader Rendering Grass (BIRP)<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>This chapter is<a target=\"_blank\" href=\"https:\/\/roystan.net\/articles\/grass-shader\/\" rel=\"noreferrer noopener\">Roystan<\/a>A concise summary of the . If you need the project file or the final code, you can download it from the original article. Or read<a target=\"_blank\" href=\"https:\/\/zhuanlan.zhihu.com\/p\/433385999\" rel=\"noreferrer noopener\">Socrates has no bottom article<\/a>.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">1.1 Overview<\/h3>\n\n\n\n<p>After the Domain Stage, you can choose to use a geometry shader.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-7.png\" alt=\"\" class=\"wp-image-126 lazyload\"\/><noscript><img decoding=\"async\" width=\"1328\" height=\"726\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-7.png\" alt=\"\" class=\"wp-image-126 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-7.png 1328w, https:\/\/remoooo.com\/wp-content\/uploads\/image-7-300x164.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-7-1024x560.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-7-768x420.png 768w\" sizes=\"(max-width: 1328px) 100vw, 1328px\" \/><\/noscript><\/figure>\n\n\n\n<p>A geometry shader takes a whole primitive as input and is able to generate vertices on output. The input to a geometry shader is the vertices of a complete primitive (three vertices for a triangle, two vertices for a line or a single vertex for a point). The geometry shader is called once for each primitive.<\/p>\n\n\n\n<p>from<a target=\"_blank\" href=\"https:\/\/roystan.net\/articles\/grass-shader\/\" rel=\"noreferrer noopener\">Web Download<\/a>Initial engineering.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.2 Drawing a triangle<\/h3>\n\n\n\n<p>Draw a triangle.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * 1rem);line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Add inside the CGINCLUDE block.struct geometryOutput{    float4 pos : SV_POSITION;};...    \/\/\u9876\u70b9\u7740\u8272\u5668return vertex;...[maxvertexcount(3)]void geo(triangle float4 IN[3] : SV_POSITION, inout TriangleStream<geometryOutput&gt; triStream){    geometryOutput o;    o.pos = UnityObjectToClipPos(float4(0.5, 0, 0, 1));    triStream.Append(o);    o.pos = UnityObjectToClipPos(float4(-0.5, 0, 0, 1));    triStream.Append(o);    o.pos = UnityObjectToClipPos(float4(0, 1, 0, 1));    triStream.Append(o);}\u2026\/\/ Add inside the SubShader Pass, just below the #pragma fragment frag line.#pragma geometry geo\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Add inside the CGINCLUDE block.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">struct<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">geometryOutput<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    float4 pos : SV_POSITION;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">};<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">    \/\/Vertex shader<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #4EC9B0\">maxvertexcount<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">void<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">geo<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">triangle<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> IN[3] : SV_POSITION, <\/span><span style=\"color: #4EC9B0\">inout<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">TriangleStream<\/span><span style=\"color: #D4D4D4\">triStream)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4EC9B0\">geometryOutput<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToClipPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">float4<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToClipPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">float4<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToClipPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">float4<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2026<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Add inside the SubShader Pass, just below the #pragma fragment frag line.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">#pragma geometry geo<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-5.png\" alt=\"\" class=\"wp-image-124 lazyload\"\/><noscript><img decoding=\"async\" width=\"752\" height=\"266\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-5.png\" alt=\"\" class=\"wp-image-124 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-5.png 752w, https:\/\/remoooo.com\/wp-content\/uploads\/image-5-300x106.png 300w\" sizes=\"(max-width: 752px) 100vw, 752px\" \/><\/noscript><\/figure>\n\n\n\n<p>We actually draw a triangle for each vertex in the mesh, but the positions we assign to the triangle vertices are constant - they don&#039;t change for each input vertex - placing all the triangles on top of each other.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.3 Vertex Offset<\/h3>\n\n\n\n<p>Therefore, we can just make an offset according to the position of each vertex.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">C#<\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Add to the top of the geometry shader.float3 pos = IN[0];\u2026\/\/ Update each assignment of o.pos.o.pos = UnityObjectToClipPos(pos + float3(0.5, 0, 0));\u2026o.pos = UnityObjectToClipPos(pos + float3(-0.5, 0, 0));\u2026o.pos = UnityObjectToClipPos(pos + float3(0, 1, 0));\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Add to the top of the geometry shader.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4EC9B0\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">IN<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2026<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Update each assignment of o.pos.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToClipPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2026<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToClipPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2026<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToClipPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">1.4 Rotating blades<\/h3>\n\n\n\n<p>However, it should be noted that currently all triangles are emitted in one direction, so normal correction is added. TBN matrix is constructed and multiplied with the current direction. And the code is organized.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float3 vNormal = IN[0].normal;float4 vTangent = IN[0].tangent;float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;float3x3 tangentToLocal = float3x3(    vTangent.x, vBinormal.x, vNormal.x,    vTangent.y, vBinormal.y, vNormal.y,    vTangent.z, vBinormal.z, vNormal.z    );triStream.Append(VertexOutput(pos + mul(tangentToLocal, float3(0.5, 0, 0))));triStream.Append(VertexOutput(pos + mul(tangentToLocal, float3(-0.5, 0, 0))));triStream.Append(VertexOutput(pos + mul(tangentToLocal, float3(0, 0, 1))));\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #4EC9B0\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vNormal<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">IN<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">normal<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4EC9B0\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vTangent<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">IN<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">tangent<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4EC9B0\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vBinormal<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">cross<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">vNormal<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vTangent<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #9CDCFE\">vTangent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4EC9B0\">float3x3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tangentToLocal<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">float3x3<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">vTangent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vBinormal<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vNormal<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">vTangent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vBinormal<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vNormal<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">vTangent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vBinormal<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vNormal<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    );<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tangentToLocal<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">))));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tangentToLocal<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">))));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tangentToLocal<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">))));<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-9.png\" alt=\"\" class=\"wp-image-128 lazyload\"\/><noscript><img decoding=\"async\" width=\"538\" height=\"262\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-9.png\" alt=\"\" class=\"wp-image-128 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-9.png 538w, https:\/\/remoooo.com\/wp-content\/uploads\/image-9-300x146.png 300w\" sizes=\"(max-width: 538px) 100vw, 538px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.5 Coloring<\/h3>\n\n\n\n<p>Then define the upper and lower colors of the grass, and use UV to make a lerp gradient.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"return lerp(_BottomColor, _TopColor, i.uv.y);\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">lerp<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_BottomColor<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_TopColor<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">uv<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#1E1E1E;color:#c7c7c7;font-size:12px;line-height:1;position:relative\">C#<\/span><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-11.png\" alt=\"\" class=\"wp-image-130 lazyload\"\/><noscript><img decoding=\"async\" width=\"738\" height=\"348\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-11.png\" alt=\"\" class=\"wp-image-130 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-11.png 738w, https:\/\/remoooo.com\/wp-content\/uploads\/image-11-300x141.png 300w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.6 Rotation Matrix Principle<\/h3>\n\n\n\n<p>Make a random orientation. Here a rotation matrix is constructed. The principle is also mentioned in GAMES101. There is also a<a href=\"https:\/\/www.bilibili.com\/video\/BV1Eu411r7GC\/?vd_source=3cbbf97be64ba32491141ce34bff7c53\" target=\"_blank\" rel=\"noreferrer noopener\">Video of formula derivation<\/a>, and it is very clear! The simple derivation idea is, assuming that the vector $a$ rotates around the n-axis to $b$, then decompose $a$\u200b into the component parallel to the n-axis (found to be constant) plus the component perpendicular to the n-axis.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-12.png\" alt=\"\" class=\"wp-image-131 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"892\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-12.png\" alt=\"\" class=\"wp-image-131 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-12.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-12-300x186.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-12-1024x634.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-12-768x476.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float3x3 AngleAxis3x3(float angle, float3 axis){    float c, s;    sincos(angle, s, c);    float t = 1 - c;    float x = axis.x;    float y = axis.y;    float z = axis.z;    return float3x3(        t * x * x + c, t * x * y - s * z, t * x * z + s * y,        t * x * y + s * z, t * y * y + c, t * y * z - s * x,        t * x * z - s * y, t * y * z + s * x, t * z * z + c        );}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">float3x3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">AngleAxis3x3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">angle<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">axis<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">sincos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">angle<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">axis<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">axis<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">axis<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">float3x3<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">c<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The rotation matrix $R$ is calculated here using Rodrigues&#039; rotation formula: $$R=I+sin\u2061(\u03b8)\u22c5[k]\u00d7+(1\u2212cos\u2061(\u03b8))\u22c5[k]\u00d72$$<\/p>\n\n\n\n<p>Among them, $\\theta$ is the rotation angle. $k$ is the unit rotation axis. $I$ is the identity matrix. $[k]_{\\times}$ is the antisymmetric matrix corresponding to the axis $k$.<\/p>\n\n\n\n<p>For a unit vector $k=(x,y,z)$ , the antisymmetric matrix $[k]_{\\times}=\\left[\\begin{array}{ccc} 0 &amp; -z &amp; y \\\\ z &amp; 0 &amp; -x \\\\ -y &amp; x &amp; 0 \\end{array}\\right]$ finally obtains the matrix elements:<\/p>\n\n\n\n<p>$$ \\begin{array}{ccc} tx^2 + c &amp; txy \u2013 sz &amp; txz + sy \\\\ txy + sz &amp; ty^2 + c &amp; tyz \u2013 sx \\\\ txz \u2013 sy &amp; tyz + sx &amp; tz^2 + c \\\\ \\end{array} $$<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0, 0, 1));\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">float3x3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">facingRotationMatrix<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">AngleAxis3x3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">rand<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #4FC1FF\">UNITY_TWO_PI<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-15.png\" alt=\"\" class=\"wp-image-134 lazyload\"\/><noscript><img decoding=\"async\" width=\"732\" height=\"328\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-15.png\" alt=\"\" class=\"wp-image-134 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-15.png 732w, https:\/\/remoooo.com\/wp-content\/uploads\/image-15-300x134.png 300w\" sizes=\"(max-width: 732px) 100vw, 732px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.7 Blade tipping<\/h3>\n\n\n\n<p>Get the grass in a random direction, and then pour it in any random direction on the x or y axis.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.5, float3(-1, 0, 0));\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">float3x3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">bendRotationMatrix<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">AngleAxis3x3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">rand<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">zzx<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #9CDCFE\">_BendRotationRandom<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #4FC1FF\">UNITY_PI<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-16.png\" alt=\"\" class=\"wp-image-135 lazyload\"\/><noscript><img decoding=\"async\" width=\"1130\" height=\"562\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-16.png\" alt=\"\" class=\"wp-image-135 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-16.png 1130w, https:\/\/remoooo.com\/wp-content\/uploads\/image-16-300x149.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-16-1024x509.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-16-768x382.png 768w\" sizes=\"(max-width: 1130px) 100vw, 1130px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.8 Leaf size<\/h3>\n\n\n\n<p>Adjust the width and height of the grass. Originally, we set the height and width to be one unit. To make the grass more natural, we add rand to this step to make it look more natural.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"_BladeWidth(&quot;Blade Width&quot;, Float) = 0.05_BladeWidthRandom(&quot;Blade Width Random&quot;, Float) = 0.02_BladeHeight(&quot;Blade Height&quot;, Float) = 0.5_BladeHeightRandom(&quot;Blade Height Random&quot;, Float) = 0.3float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight;float width = (rand(pos.xzy) * 2 - 1) * _BladeWidthRandom + _BladeWidth;triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(width, 0, 0)), float2(0, 0)));triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(-width, 0, 0)), float2(1, 0)));triStream.Append(VertexOutput(pos + mul(transformationMatrix, float3(0, 0, height)), float2(0.5, 1)));\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCDCAA\">_BladeWidth<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Blade Width&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">Float<\/span><span style=\"color: #D4D4D4\">) = <\/span><span style=\"color: #B5CEA8\">0.05<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">_BladeWidthRandom<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Blade Width Random&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">Float<\/span><span style=\"color: #D4D4D4\">) = <\/span><span style=\"color: #B5CEA8\">0.02<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">_BladeHeight<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Blade Height&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">Float<\/span><span style=\"color: #D4D4D4\">) = <\/span><span style=\"color: #B5CEA8\">0.5<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">_BladeHeightRandom<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Blade Height Random&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">Float<\/span><span style=\"color: #D4D4D4\">) = <\/span><span style=\"color: #B5CEA8\">0.3<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">height<\/span><span style=\"color: #D4D4D4\"> = (<\/span><span style=\"color: #DCDCAA\">rand<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">zyx<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #9CDCFE\">_BladeHeightRandom<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">_BladeHeight<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">width<\/span><span style=\"color: #D4D4D4\"> = (<\/span><span style=\"color: #DCDCAA\">rand<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">xzy<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #9CDCFE\">_BladeWidthRandom<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">_BladeWidth<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">transformationMatrix<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">width<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">transformationMatrix<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #9CDCFE\">width<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">transformationMatrix<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">height<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">)));<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-13.png\" alt=\"\" class=\"wp-image-132 lazyload\"\/><noscript><img decoding=\"async\" width=\"790\" height=\"338\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-13.png\" alt=\"\" class=\"wp-image-132 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-13.png 790w, https:\/\/remoooo.com\/wp-content\/uploads\/image-13-300x128.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-13-768x329.png 768w\" sizes=\"(max-width: 790px) 100vw, 790px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.9 Tessellation<\/h3>\n\n\n\n<p>Since the number is too small, the upper surface is subdivided here.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-17.png\" alt=\"\" class=\"wp-image-136 lazyload\"\/><noscript><img decoding=\"async\" width=\"754\" height=\"438\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-17.png\" alt=\"\" class=\"wp-image-136 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-17.png 754w, https:\/\/remoooo.com\/wp-content\/uploads\/image-17-300x174.png 300w\" sizes=\"(max-width: 754px) 100vw, 754px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.10 Perturbations<\/h3>\n\n\n\n<p>To animate the grass, add the normals to the _Time perturbation. Sample the texture, then calculate the wind rotation matrix and apply it to the grass.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;float2 windSample = (tex2Dlod(_WindDistortionMap, float4(uv, 0, 0)).xy * 2 - 1) * _WindStrength;float3 wind = normalize(float3(windSample.x, windSample.y, 0));float3x3 windRotation = AngleAxis3x3(UNITY_PI * windSample, wind);float3x3 transformationMatrix = mul(mul(mul(tangentToLocal, windRotation), facingRotationMatrix), bendRotationMatrix);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">float2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">uv<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">POS<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">xz<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_WindDistortionMap_ST<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">xy<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_WindDistortionMap_ST<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">z<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_WindFrequency<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_Time<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">windSample<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #88C0D0\">tex2Dlod<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">_WindDistortionMap<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float4<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">uv<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">xy<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_WindStrength<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">wind<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">normalize<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">float3<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">windSample<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">windSample<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float3x3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">windRotation<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">AngleAxis3x3<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">UNITY_PI<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">windSample<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">wind<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float3x3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">transformationMatrix<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">mul<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">mul<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">mul<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">tangentToLocal<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">windRotation<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">facingRotationMatrix<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">bendRotationMatrix<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">1.11 Fixed blade rotation issue<\/h3>\n\n\n\n<p>At this time, the wind may rotate along the x and y axes, which is specifically manifested as:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-14.png\" alt=\"\" class=\"wp-image-133 lazyload\"\/><noscript><img decoding=\"async\" width=\"1220\" height=\"808\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-14.png\" alt=\"\" class=\"wp-image-133 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-14.png 1220w, https:\/\/remoooo.com\/wp-content\/uploads\/image-14-300x199.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-14-1024x678.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-14-768x509.png 768w\" sizes=\"(max-width: 1220px) 100vw, 1220px\" \/><\/noscript><\/figure>\n\n\n\n<p>Write a matrix for the two points under your feet that rotates only along z.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float3x3 transformationMatrixFacing = mul(tangentToLocal, facingRotationMatrix);\u2026triStream.Append(VertexOutput(pos + mul(transformationMatrixFacing, float3(width, 0, 0)), float2(0, 0)));triStream.Append(VertexOutput(pos + mul(transformationMatrixFacing, float3(-width, 0, 0)), float2(1, 0)));\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">float3x3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">transformationMatrixFacing<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tangentToLocal<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">facingRotationMatrix<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2026<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">transformationMatrixFacing<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">width<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">VertexOutput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">transformationMatrixFacing<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #9CDCFE\">width<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)), <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)));<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">1.12 Blade curvature<\/h3>\n\n\n\n<p>In order to make the leaves have curvature, we have to add vertices. In addition, since double-sided rendering is currently enabled, the order of vertices does not matter. Here, a manual interpolation for loop is used to construct triangles. A forward is calculated to bend the leaves.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float forward = rand(pos.yyz) * _BladeForward;for (int i = 0; i &lt; BLADE_SEGMENTS; i++){    float t = i \/ (float)BLADE_SEGMENTS;    \/\/ Add below the line declaring float t.    float segmentHeight = height * t;    float segmentWidth = width * (1 - t);    float segmentForward = pow(t, _BladeCurve) * forward;    float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;    triStream.Append(GenerateGrassVertex(pos, segmentWidth, segmentHeight, segmentForward, float2(0, t), transformMatrix));    triStream.Append(GenerateGrassVertex(pos, -segmentWidth, segmentHeight, segmentForward, float2(1, t), transformMatrix));}triStream.Append(GenerateGrassVertex(pos, 0, height, forward, float2(0.5, 1), transformationMatrix));\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">forward<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">rand<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">yyz<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #9CDCFE\">_BladeForward<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">int<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #4FC1FF\">BLADE_SEGMENTS<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> \/ (<\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\">)<\/span><span style=\"color: #4FC1FF\">BLADE_SEGMENTS<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #6A9955\">\/\/ Add below the line declaring float t.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">segmentHeight<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">height<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">segmentWidth<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">width<\/span><span style=\"color: #D4D4D4\"> * (<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">segmentForward<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">pow<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_BladeCurve<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #9CDCFE\">forward<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float3x3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">transformMatrix<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> ? <\/span><span style=\"color: #9CDCFE\">transformationMatrixFacing<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #9CDCFE\">transformationMatrix<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">GenerateGrassVertex<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">segmentWidth<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">segmentHeight<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">segmentForward<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">transformMatrix<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">GenerateGrassVertex<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">, -<\/span><span style=\"color: #9CDCFE\">segmentWidth<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">segmentHeight<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">segmentForward<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">transformMatrix<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">triStream<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">GenerateGrassVertex<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">height<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">forward<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">float2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">transformationMatrix<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter is-resized\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image.gif\" alt=\"\" class=\"wp-image-141 lazyload\" style=\"width:466px;height:auto\"\/><noscript><img decoding=\"async\" width=\"800\" height=\"800\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image.gif\" alt=\"\" class=\"wp-image-141 lazyload\" style=\"width:466px;height:auto\"\/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-18.png\" alt=\"\" class=\"wp-image-137 lazyload\"\/><noscript><img decoding=\"async\" width=\"884\" height=\"438\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-18.png\" alt=\"\" class=\"wp-image-137 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-18.png 884w, https:\/\/remoooo.com\/wp-content\/uploads\/image-18-300x149.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-18-768x381.png 768w\" sizes=\"(max-width: 884px) 100vw, 884px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.13 Creating Shadows<\/h3>\n\n\n\n<p>Create shadows in another Pass and output.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"Pass{    Tags{        &quot;LightMode&quot; = &quot;ShadowCaster&quot;    }    CGPROGRAM    #pragma vertex vert    #pragma geometry geo    #pragma fragment frag    #pragma hull hull    #pragma domain domain    #pragma target 4.6    #pragma multi_compile_shadowcaster    float4 frag(geometryOutput i) : SV_Target{        SHADOW_CASTER_FRAGMENT(i)    }    ENDCG}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">Pass<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Tags<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;LightMode&quot;<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;ShadowCaster&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">CGPROGRAM<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vert<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">geometry<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">geo<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">fragment<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">frag<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hull<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hull<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">domain<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">domain<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">target<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">4.6<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">multi_compile_shadowcaster<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">frag<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">geometryOutput<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">) : <\/span><span style=\"color: #9CDCFE\">SV_Target<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">SHADOW_CASTER_FRAGMENT<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">ENDCG<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-20.png\" alt=\"\" class=\"wp-image-139 lazyload\"\/><noscript><img decoding=\"async\" width=\"688\" height=\"370\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-20.png\" alt=\"\" class=\"wp-image-139 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-20.png 688w, https:\/\/remoooo.com\/wp-content\/uploads\/image-20-300x161.png 300w\" sizes=\"(max-width: 688px) 100vw, 688px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.14 Receiving Shadows<\/h3>\n\n\n\n<p>Use SHADOW_ATTENUATION directly in Frag to determine the shadow.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ geometryOutput struct.unityShadowCoord4 _ShadowCoord : TEXCOORD1;...o._ShadowCoord = ComputeScreenPos(o.pos);...#pragma multi_compile_fwdbase...return SHADOW_ATTENUATION(i);\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ geometryOutput struct.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">unityShadowCoord4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">_ShadowCoord<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #4FC1FF\">TEXCOORD1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">_ShadowCoord<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">ComputeScreenPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">multi_compile_fwdbase<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SHADOW_ATTENUATION<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-24.png\" alt=\"\" class=\"wp-image-144 lazyload\"\/><noscript><img decoding=\"async\" width=\"778\" height=\"412\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-24.png\" alt=\"\" class=\"wp-image-144 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-24.png 778w, https:\/\/remoooo.com\/wp-content\/uploads\/image-24-300x159.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-24-768x407.png 768w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-19.png\" alt=\"\" class=\"wp-image-138 lazyload\"\/><noscript><img decoding=\"async\" width=\"624\" height=\"334\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-19.png\" alt=\"\" class=\"wp-image-138 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-19.png 624w, https:\/\/remoooo.com\/wp-content\/uploads\/image-19-300x161.png 300w\" sizes=\"(max-width: 624px) 100vw, 624px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.15 Removing shadow acne<\/h3>\n\n\n\n<p>Removes surface acne.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"#if UNITY_PASS_SHADOWCASTER    o.pos = UnityApplyLinearShadowBias(o.pos);#endif\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">UNITY_PASS_SHADOWCASTER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityApplyLinearShadowBias<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">endif<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-21.png\" alt=\"\" class=\"wp-image-140 lazyload\"\/><noscript><img decoding=\"async\" width=\"738\" height=\"416\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-21.png\" alt=\"\" class=\"wp-image-140 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-21.png 738w, https:\/\/remoooo.com\/wp-content\/uploads\/image-21-300x169.png 300w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.16 Adding Normals<\/h3>\n\n\n\n<p>Add normal information to vertices generated by the geometry shader.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"struct geometryOutput{    float4 pos : SV_POSITION;    float2 uv : TEXCOORD0;    unityShadowCoord4 _ShadowCoord : TEXCOORD1;    float3 normal : NORMAL;};...o.normal = UnityObjectToWorldNormal(normal);\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">struct<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">geometryOutput<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">POS<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #4FC1FF\">SV_POSITION<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float2<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">uv<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #4FC1FF\">TEXCOORD0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">unityShadowCoord4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">_ShadowCoord<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #4FC1FF\">TEXCOORD1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">normal<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #4FC1FF\">NORMAL<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">};<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">normal<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToWorldNormal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">normal<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter is-resized\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-22.png\" alt=\"\" class=\"wp-image-142 lazyload\" style=\"width:648px;height:auto\"\/><noscript><img decoding=\"async\" width=\"748\" height=\"396\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-22.png\" alt=\"\" class=\"wp-image-142 lazyload\" style=\"width:648px;height:auto\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-22.png 748w, https:\/\/remoooo.com\/wp-content\/uploads\/image-22-300x159.png 300w\" sizes=\"(max-width: 748px) 100vw, 748px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter is-resized\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-26.png\" alt=\"\" class=\"wp-image-146 lazyload\" style=\"width:693px;height:auto\"\/><noscript><img decoding=\"async\" width=\"756\" height=\"384\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-26.png\" alt=\"\" class=\"wp-image-146 lazyload\" style=\"width:693px;height:auto\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-26.png 756w, https:\/\/remoooo.com\/wp-content\/uploads\/image-26-300x152.png 300w\" sizes=\"(max-width: 756px) 100vw, 756px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1.17 Full code\u203c\ufe0f (BIRP)<\/h3>\n\n\n\n<p>The final effect.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-23.png\" alt=\"\" class=\"wp-image-143 lazyload\"\/><noscript><img decoding=\"async\" width=\"1020\" height=\"542\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-23.png\" alt=\"\" class=\"wp-image-143 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-23.png 1020w, https:\/\/remoooo.com\/wp-content\/uploads\/image-23-300x159.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-23-768x408.png 768w\" sizes=\"(max-width: 1020px) 100vw, 1020px\" \/><\/noscript><\/figure>\n\n\n\n<p>Code:<\/p>\n\n\n\n<p><a href=\"https:\/\/pastebin.com\/8u1ytGgU\">https:\/\/pastebin.com\/8u1ytGgU<\/a><\/p>\n\n\n\n<p>Complete: https:\/\/pastebin.com\/U14m1Nu0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Geometry Shader Rendering Grass (URP)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">2.1 References<\/h3>\n\n\n\n<p>I have already written the BIRP version, and now I just need to port it.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>URP code specification reference: https:\/\/www.cyanilux.com\/tutorials\/urp-shader-code\/<\/li>\n\n\n\n<li>BIRP-&gt;URP quick reference table: https:\/\/cuihongzhi1991.github.io\/blog\/2020\/05\/27\/builtinttourp\/<\/li>\n<\/ul>\n\n\n\n<p>You can follow<a target=\"_blank\" href=\"https:\/\/danielilett.com\/2021-08-24-tut5-17-stylised-grass\/\" rel=\"noreferrer noopener\">This article by Daniel<\/a>You can also follow me to modify the code. It should be noted that the space transformation code in the original repo has problems.<a target=\"_blank\" href=\"https:\/\/github.com\/daniel-ilett\/shaders-botw-grass\/pull\/2\" rel=\"noreferrer noopener\">Pull requests<\/a>The solution was found in<\/p>\n\n\n\n<p>Now put the above BIRP tessellation shader together.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Tags changed to URP<\/li>\n\n\n\n<li>The header file is introduced and replaced with the URP version<\/li>\n\n\n\n<li>Variables are surrounded by CBuffer<\/li>\n\n\n\n<li>Shadow casting, receiving code<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2.2 Start to change<\/h3>\n\n\n\n<p>Declare the URP pipeline.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"LOD 100Cull OffPass{    Tags{        &quot;RenderType&quot; = &quot;Opaque&quot;        &quot;Queue&quot; = &quot;Geometry&quot;        &quot;RenderPipeline&quot; = &quot;UniversalPipeline&quot;    }\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #4FC1FF\">LOD<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">100<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Cull<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Off<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Pass<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Tags<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;RenderType&quot;<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;Opaque&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;Queue&quot;<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;Geometry&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;RenderPipeline&quot;<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;UniversalPipeline&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Import the URP library.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"#include &quot;Packages\/com.unity.render-pipelines.universal\/ShaderLibrary\/Core.hlsl&quot;#include &quot;Packages\/com.unity.render-pipelines.universal\/ShaderLibrary\/Lighting.hlsl&quot;#include &quot;Packages\/com.unity.render-pipelines.universal\/ShaderLibrary\/ShaderVariablesFunctions.hlsl&quot;o._ShadowCoord = ComputeScreenPos(o.pos);\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">include<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Packages\/com.unity.render-pipelines.universal\/ShaderLibrary\/Core.hlsl&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">include<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Packages\/com.unity.render-pipelines.universal\/ShaderLibrary\/Lighting.hlsl&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">include<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Packages\/com.unity.render-pipelines.universal\/ShaderLibrary\/ShaderVariablesFunctions.hlsl&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">_ShadowCoord<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">ComputeScreenPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">POS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Change the function.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ o.normal = UnityObjectToWorldNormal(normal);o.normal = TransformObjectToWorldNormal(normal);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ o.normal = UnityObjectToWorldNormal(normal);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">o<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">normal<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">TransformObjectToWorldNormal<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">normal<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>URP receives the shadow. It is best to calculate this in the vertex shader, but for convenience, it is all calculated in the geometry shader.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-29.png\" alt=\"\" class=\"wp-image-149 lazyload\"\/><noscript><img decoding=\"async\" width=\"1184\" height=\"532\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-29.png\" alt=\"\" class=\"wp-image-149 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-29.png 1184w, https:\/\/remoooo.com\/wp-content\/uploads\/image-29-300x135.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-29-1024x460.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-29-768x345.png 768w\" sizes=\"(max-width: 1184px) 100vw, 1184px\" \/><\/noscript><\/figure>\n\n\n\n<p>Then generate the shadows. ShadowCaster Pass.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"Pass{    Name &quot;ShadowCaster&quot;    Tags{ &quot;LightMode&quot; = &quot;ShadowCaster&quot; }    ZWrite On    ZTest LEqual    HLSLPROGRAM        half4 frag(geometryOutput input) : SV_TARGET{            return 1;        }    ENDHLSL}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">Pass<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;ShadowCaster&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Tags<\/span><span style=\"color: #D4D4D4\">{ <\/span><span style=\"color: #CE9178\">&quot;LightMode&quot;<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;ShadowCaster&quot;<\/span><span style=\"color: #D4D4D4\"> }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">ZWrite<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">On<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">ZTest<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">LEqual<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">HLSLPROGRAM<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">half4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">frag<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">geometryOutput<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">) : <\/span><span style=\"color: #4FC1FF\">SV_TARGET<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">ENDHLSL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-30.png\" alt=\"\" class=\"wp-image-150 lazyload\"\/><noscript><img decoding=\"async\" width=\"1184\" height=\"500\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-30.png\" alt=\"\" class=\"wp-image-150 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-30.png 1184w, https:\/\/remoooo.com\/wp-content\/uploads\/image-30-300x127.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-30-1024x432.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-30-768x324.png 768w\" sizes=\"(max-width: 1184px) 100vw, 1184px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">2.3 Full code\u203c\ufe0f\uff08URP\uff09<\/h3>\n\n\n\n<p><a href=\"https:\/\/pastebin.com\/6KveEKMZ\">https:\/\/pastebin.com\/6KveEKMZ<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Optimize tessellation logic (BIRP\/URP)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 Organize the code<\/h3>\n\n\n\n<p>Above we just use a fixed number of subdivision levels, which I cannot accept. If you don&#039;t understand the principle of surface subdivision, you can see<a target=\"_blank\" href=\"https:\/\/zhuanlan.zhihu.com\/p\/695636520\" rel=\"noreferrer noopener\">My Tessellation Articles<\/a>, which details several solutions for optimizing segmentation.<\/p>\n\n\n\n<p>I use the BIRP version of the code that I completed in Section 1 as an example. The current version only has the Uniform subdivision.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-25.png\" alt=\"\" class=\"wp-image-145 lazyload\"\/><noscript><img decoding=\"async\" width=\"536\" height=\"58\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-25.png\" alt=\"\" class=\"wp-image-145 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-25.png 536w, https:\/\/remoooo.com\/wp-content\/uploads\/image-25-300x32.png 300w\" sizes=\"(max-width: 536px) 100vw, 536px\" \/><\/noscript><\/figure>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"_TessellationUniform(&quot;Tessellation Uniform&quot;, Range(1, 64)) = 1\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCDCAA\">_TessellationUniform<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Tessellation Uniform&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">Range<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">64<\/span><span style=\"color: #D4D4D4\">)) = <\/span><span style=\"color: #B5CEA8\">1<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-31.png\" alt=\"\" class=\"wp-image-151 lazyload\"\/><noscript><img decoding=\"async\" width=\"1224\" height=\"490\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-31.png\" alt=\"\" class=\"wp-image-151 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-31.png 1224w, https:\/\/remoooo.com\/wp-content\/uploads\/image-31-300x120.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-31-1024x410.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-31-768x307.png 768w\" sizes=\"(max-width: 1224px) 100vw, 1224px\" \/><\/noscript><\/figure>\n\n\n\n<p>The output structures of each stage are quite confusing, so let&#039;s reorganize them.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-28.png\" alt=\"\" class=\"wp-image-148 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"617\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-28.png\" alt=\"\" class=\"wp-image-148 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-28.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-28-300x129.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-28-1024x439.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-28-768x329.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 Partitioning Mode<\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-27.png\" alt=\"\" class=\"wp-image-147 lazyload\"\/><noscript><img decoding=\"async\" width=\"554\" height=\"246\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-27.png\" alt=\"\" class=\"wp-image-147 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-27.png 554w, https:\/\/remoooo.com\/wp-content\/uploads\/image-27-300x133.png 300w\" sizes=\"(max-width: 554px) 100vw, 554px\" \/><\/noscript><\/figure>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"[KeywordEnum(INTEGER, FRAC_EVEN, FRAC_ODD, POW2)] _PARTITIONING(&quot;Partition algoritm&quot;, Float) = 0#pragma shader_feature_local _PARTITIONING_INTEGER _PARTITIONING_FRAC_EVEN _PARTITIONING_FRAC_ODD _PARTITIONING_POW2#if defined(_PARTITIONING_INTEGER)    [partitioning(&quot;integer&quot;)]#elif defined(_PARTITIONING_FRAC_EVEN)    [partitioning(&quot;fractional_even&quot;)]#elif defined(_PARTITIONING_FRAC_ODD)    [partitioning(&quot;fractional_odd&quot;)]#elif defined(_PARTITIONING_POW2)    [partitioning(&quot;pow2&quot;)]#else     [partitioning(&quot;integer&quot;)]#endif\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #DCDCAA\">KeywordEnum<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">INTEGER<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">FRAC_EVEN<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">FRAC_ODD<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">POW2<\/span><span style=\"color: #D4D4D4\">)] <\/span><span style=\"color: #DCDCAA\">_PARTITIONING<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Partition algorithm&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">Float<\/span><span style=\"color: #D4D4D4\">) = <\/span><span style=\"color: #B5CEA8\">0<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">Pragmas<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">shader_feature_local<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_PARTITIONING_INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_PARTITIONING_FRAC_EVEN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_PARTITIONING_FRAC_ODD<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_PARTITIONING_POW2<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">defined<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_PARTITIONING_INTEGER<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #DCDCAA\">partitioning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;integer&quot;<\/span><span style=\"color: #D4D4D4\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">elif<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">defined<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_PARTITIONING_FRAC_EVEN<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #DCDCAA\">partitioning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;fractional_even&quot;<\/span><span style=\"color: #D4D4D4\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">elif<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">defined<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_PARTITIONING_FRAC_ODD<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #DCDCAA\">partitioning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;fractional_odd&quot;<\/span><span style=\"color: #D4D4D4\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">elif<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">defined<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_PARTITIONING_POW2<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #DCDCAA\">partitioning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;pow2&quot;<\/span><span style=\"color: #D4D4D4\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #C586C0\">else<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #DCDCAA\">partitioning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;integer&quot;<\/span><span style=\"color: #D4D4D4\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">#<\/span><span style=\"color: #9CDCFE\">endif<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">3.2 Subdivided Frustum Culling<\/h3>\n\n\n\n<p>In BIRP, use _ProjectionParams.z to represent the far plane, and in URP use UNITY_RAW_FAR_CLIP_VALUE.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"bool IsOutOfBounds(float3 p, float3 lower, float3 higher) { \/\/\u7ed9\u5b9a\u77e9\u5f62\u5224\u65ad    return p.x < lower.x || p.x &gt; higher.x || p.y < lower.y || p.y &gt; higher.y || p.z < lower.z || p.z &gt; higher.z;}bool IsPointOutOfFrustum(float4 positionCS) { \/\/\u89c6\u9525\u4f53\u5224\u65ad    float3 culling = positionCS.xyz;    float w = positionCS.w;    float3 lowerBounds = float3(-w, -w, -w * _ProjectionParams.z);    float3 higherBounds = float3(w, w, w);    return IsOutOfBounds(culling, lowerBounds, higherBounds);}bool ShouldClipPatch(float4 p0PositionCS, float4 p1PositionCS, float4 p2PositionCS) {    bool allOutside = IsPointOutOfFrustum(p0PositionCS) &amp;&amp;        IsPointOutOfFrustum(p1PositionCS) &amp;&amp;        IsPointOutOfFrustum(p2PositionCS);    return allOutside;}TessellationControlPoint vert(Attributes v){    ...    o.positionCS = UnityObjectToClipPos(v.vertex);    ...}TessellationFactors patchConstantFunction (InputPatch<TessellationControlPoint, 3&gt; patch){    TessellationFactors f;    if(ShouldClipPatch(patch[0].positionCS, patch[1].positionCS, patch[2].positionCS)){        f.edge[0] = f.edge[1] = f.edge[2] = f.inside = 0;    }else{        f.edge[0] = _TessellationFactor;        f.edge[1] = _TessellationFactor;        f.edge[2] = _TessellationFactor;        f.inside = _TessellationFactor;    }    return f;}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">IsOutOfBounds<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">lower<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">higher<\/span><span style=\"color: #D4D4D4\">) { <\/span><span style=\"color: #6A9955\">\/\/Given rectangle judgment<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">lower<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #9CDCFE\">higher<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">x<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">lower<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #9CDCFE\">higher<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">y<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">lower<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #9CDCFE\">higher<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">IsPointOutOfFrustum<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">) { <\/span><span style=\"color: #6A9955\">\/\/View cone judgment<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">culling<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">xyz<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">lowerBounds<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(-<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">, -<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">, -<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">_ProjectionParams<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">z<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">higherBounds<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">float3<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">IsOutOfBounds<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">culling<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">lowerBounds<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">higherBounds<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ShouldClipPatch<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p0PositionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p1PositionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p2PositionCS<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">allOutside<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">IsPointOutOfFrustum<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p0PositionCS<\/span><span style=\"color: #D4D4D4\">) &amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">IsPointOutOfFrustum<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p1PositionCS<\/span><span style=\"color: #D4D4D4\">) &amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">IsPointOutOfFrustum<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p2PositionCS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">allOutside<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">TessellationControlPoint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">vert<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">Attributes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">v<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">o<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">UnityObjectToClipPos<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">v<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">TessellationFactors<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">patchConstantFunction<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">InputPatch<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #9CDCFE\">TessellationControlPoint<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">TessellationFactors<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">ShouldClipPatch<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">)){<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">inside<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><span style=\"color: #C586C0\">else<\/span><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">_TessellationFactor<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">_TessellationFactor<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">_TessellationFactor<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">inside<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_TessellationFactor<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>However, it should be noted that the judgment input here is the CS coordinates of the grass. If the triangular grass completely leaves the screen, but the grass grows high and may still be on the screen, it will cause a screen bug where the grass suddenly disappears. This depends on the needs of the project. If it is a project with an upward viewing angle and the grass is relatively short, this operation can be used.<\/p>\n\n\n\n<p>The viewing angle is not a big problem.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-33.png\" alt=\"\" class=\"wp-image-153 lazyload\"\/><noscript><img decoding=\"async\" width=\"1294\" height=\"596\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-33.png\" alt=\"\" class=\"wp-image-153 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-33.png 1294w, https:\/\/remoooo.com\/wp-content\/uploads\/image-33-300x138.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-33-1024x472.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-33-768x354.png 768w\" sizes=\"(max-width: 1294px) 100vw, 1294px\" \/><\/noscript><\/figure>\n\n\n\n<p>If viewed from Voldemort&#039;s perspective, the grass is incomplete and over-culled.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-34.png\" alt=\"\" class=\"wp-image-154 lazyload\"\/><noscript><img decoding=\"async\" width=\"1102\" height=\"428\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-34.png\" alt=\"\" class=\"wp-image-154 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-34.png 1102w, https:\/\/remoooo.com\/wp-content\/uploads\/image-34-300x117.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-34-1024x398.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-34-768x298.png 768w\" sizes=\"(max-width: 1102px) 100vw, 1102px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">3.3 Fine-grained control of screen distance<\/h3>\n\n\n\n<p>The grass is dense near and sparse far, but based on the screen distance (CS space). This method is affected by the resolution.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float EdgeTessellationFactor(float scale, float4 p0PositionCS, float4 p1PositionCS) {    float factor = distance(p0PositionCS.xyz \/ p0PositionCS.w, p1PositionCS.xyz \/ p1PositionCS.w) \/ scale;    return max(1, factor);}TessellationFactors patchConstantFunction (InputPatch<TessellationControlPoint, 3&gt; patch){    TessellationFactors f;    f.edge[0] = EdgeTessellationFactor(_TessellationFactor,         patch[1].positionCS, patch[2].positionCS);    f.edge[1] = EdgeTessellationFactor(_TessellationFactor,         patch[2].positionCS, patch[0].positionCS);    f.edge[2] = EdgeTessellationFactor(_TessellationFactor,         patch[0].positionCS, patch[1].positionCS);    f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) \/ 3.0;    #if defined(_CUTTESS_TRUE)        if(ShouldClipPatch(patch[0].positionCS, patch[1].positionCS, patch[2].positionCS))            f.edge[0] = f.edge[1] = f.edge[2] = f.inside = 0;    #endif    return f;}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">scale<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p0PositionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float4<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p1PositionCS<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">factor<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">distance<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p0PositionCS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">xyz<\/span><span style=\"color: #D4D4D4\"> \/ <\/span><span style=\"color: #9CDCFE\">p0PositionCS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">p1PositionCS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">xyz<\/span><span style=\"color: #D4D4D4\"> \/ <\/span><span style=\"color: #9CDCFE\">p1PositionCS<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">w<\/span><span style=\"color: #D4D4D4\">) \/ <\/span><span style=\"color: #9CDCFE\">scale<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">max<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">factor<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">TessellationFactors<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">patchConstantFunction<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">InputPatch<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #9CDCFE\">TessellationControlPoint<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">TessellationFactors<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_TessellationFactor<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_TessellationFactor<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_TessellationFactor<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">inside<\/span><span style=\"color: #D4D4D4\"> = (<\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] + <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] + <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">]) \/ <\/span><span style=\"color: #B5CEA8\">3.0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">defined<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_CUTTESS_TRUE<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">ShouldClipPatch<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">positionCS<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">inside<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    #<\/span><span style=\"color: #9CDCFE\">endif<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Tessellation Factor = 0.08<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-32.png\" alt=\"\" class=\"wp-image-152 lazyload\"\/><noscript><img decoding=\"async\" width=\"924\" height=\"416\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-32.png\" alt=\"\" class=\"wp-image-152 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-32.png 924w, https:\/\/remoooo.com\/wp-content\/uploads\/image-32-300x135.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-32-768x346.png 768w\" sizes=\"(max-width: 924px) 100vw, 924px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-35.png\" alt=\"\" class=\"wp-image-155 lazyload\"\/><noscript><img decoding=\"async\" width=\"1014\" height=\"374\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-35.png\" alt=\"\" class=\"wp-image-155 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-35.png 1014w, https:\/\/remoooo.com\/wp-content\/uploads\/image-35-300x111.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-35-768x283.png 768w\" sizes=\"(max-width: 1014px) 100vw, 1014px\" \/><\/noscript><\/figure>\n\n\n\n<p>It is not recommended to select Frac as the segmentation mode, otherwise there will be strong shaking, which is very eye-catching. I don&#039;t like this method very much.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.4 Camera distance classification<\/h3>\n\n\n\n<p>Calculate the ratio of &quot;the distance between two points&quot; to &quot;the distance between the midpoint of the two vertices and the camera position&quot;. The larger the ratio, the larger the space occupied on the screen, and the more subdivision is required.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float EdgeTessellationFactor_WorldBase(float scale, float3 p0PositionWS, float3 p1PositionWS) {    float length = distance(p0PositionWS, p1PositionWS);    float distanceToCamera = distance(_WorldSpaceCameraPos, (p0PositionWS + p1PositionWS) * 0.5);    float factor = length \/ (scale * distanceToCamera * distanceToCamera);    return max(1, factor);}...f.edge[0] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,     patch[1].vertex, patch[2].vertex);f.edge[1] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,     patch[2].vertex, patch[0].vertex);f.edge[2] = EdgeTessellationFactor_WorldBase(_TessellationFactor_WORLD_BASE,     patch[0].vertex, patch[1].vertex);f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) \/ 3.0;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor_WorldBase<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">scale<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p0PositionWS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">float3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">p1PositionWS<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">distance<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p0PositionWS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">p1PositionWS<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">distanceToCamera<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">distance<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_WorldSpaceCameraPos<\/span><span style=\"color: #D4D4D4\">, (<\/span><span style=\"color: #9CDCFE\">p0PositionWS<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">p1PositionWS<\/span><span style=\"color: #D4D4D4\">) * <\/span><span style=\"color: #B5CEA8\">0.5<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">factor<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\"> \/ (<\/span><span style=\"color: #9CDCFE\">scale<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">distanceToCamera<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">distanceToCamera<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">max<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">factor<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor_WorldBase<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_TessellationFactor_WORLD_BASE<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor_WorldBase<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_TessellationFactor_WORLD_BASE<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">EdgeTessellationFactor_WorldBase<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_TessellationFactor_WORLD_BASE<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">patch<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">vertex<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">inside<\/span><span style=\"color: #D4D4D4\"> = (<\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] + <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] + <\/span><span style=\"color: #9CDCFE\">f<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">edge<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">]) \/ <\/span><span style=\"color: #B5CEA8\">3.0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-37.png\" alt=\"\" class=\"wp-image-157 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"617\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-37.png\" alt=\"\" class=\"wp-image-157 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-37.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-37-300x129.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-37-1024x439.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-37-768x329.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-41.png\" alt=\"\" class=\"wp-image-161 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"624\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-41.png\" alt=\"\" class=\"wp-image-161 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-41.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-41-300x130.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-41-1024x444.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-41-768x333.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>There is still room for improvement. Adjust the density of the grass so that the grass at close distance is not too dense, and the grass curve at medium distance is smoother, and introduce a nonlinear factor to control the relationship between distance and tessellation factor.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float EdgeTessellationFactor_WorldBase(float scale, float3 p0PositionWS, float3 p1PositionWS) {    float length = distance(p0PositionWS, p1PositionWS);    float distanceToCamera = distance(_WorldSpaceCameraPos, (p0PositionWS + p1PositionWS) * 0.5);    \/\/ \u4f7f\u7528\u5e73\u65b9\u6839\u51fd\u6570\u8c03\u6574\u8ddd\u79bb\u7684\u5f71\u54cd\uff0c\u4f7f\u4e2d\u8ddd\u79bb\u7684\u9576\u5d4c\u56e0\u5b50\u53d8\u5316\u66f4\u5e73\u6ed1    float adjustedDistance = sqrt(distanceToCamera);    \/\/ \u8c03\u6574 scale \u7684\u5f71\u54cd\uff0c\u53ef\u80fd\u9700\u8981\u6839\u636e\u5b9e\u9645\u6548\u679c\u8fdb\u4e00\u6b65\u5fae\u8c03\u8fd9\u91cc\u7684\u7cfb\u6570    float factor = length \/ (scale * adjustedDistance);    return max(1, factor);}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">EdgeTessellationFactor_WorldBase<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">scale<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">p0PositionWS<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">p1PositionWS<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">length<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">distance<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">p0PositionWS<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">p1PositionWS<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">distanceToCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">distance<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">_WorldSpaceCameraPos<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">p0PositionWS<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">p1PositionWS<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.5<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">    <\/span><span style=\"color: #616E88\">\/\/ Use the square root function to adjust the effect of distance to make the tessellation factor change more smoothly at medium distances<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">adjustedDistance<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">sqrt<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">distanceToCamera<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">    <\/span><span style=\"color: #616E88\">\/\/ Adjust the impact of scale. You may need to further fine-tune the coefficient here based on the actual effect.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">factor<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">length<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">scale<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">adjustedDistance<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">max<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">factor<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>This is more appropriate.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-38.png\" alt=\"\" class=\"wp-image-158 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"624\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-38.png\" alt=\"\" class=\"wp-image-158 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-38.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-38-300x130.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-38-1024x444.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-38-768x333.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">3.5 Visibility Map Controls Grass Subdivision<\/h3>\n\n\n\n<figure class=\"wp-block-image aligncenter is-resized\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-36.png\" alt=\"\" class=\"wp-image-156 lazyload\" style=\"width:439px;height:auto\"\/><noscript><img decoding=\"async\" width=\"554\" height=\"346\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-36.png\" alt=\"\" class=\"wp-image-156 lazyload\" style=\"width:439px;height:auto\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-36.png 554w, https:\/\/remoooo.com\/wp-content\/uploads\/image-36-300x187.png 300w\" sizes=\"(max-width: 554px) 100vw, 554px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-39.png\" alt=\"\" class=\"wp-image-159 lazyload\"\/><noscript><img decoding=\"async\" width=\"1160\" height=\"410\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-39.png\" alt=\"\" class=\"wp-image-159 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-39.png 1160w, https:\/\/remoooo.com\/wp-content\/uploads\/image-39-300x106.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-39-1024x362.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-39-768x271.png 768w\" sizes=\"(max-width: 1160px) 100vw, 1160px\" \/><\/noscript><\/figure>\n\n\n\n<p>The vertex shader reads the texture and passes it to the tessellation shader, which calculates the tessellation logic in PCF.<\/p>\n\n\n\n<p>Take FIXED mode as an example:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"_VisibilityMap(&quot;Visibility Map&quot;, 2D) = &quot;white&quot; {}TEXTURE2D (_VisibilityMap);SAMPLER(sampler_VisibilityMap);struct Attributes{    ...    float2 uv : TEXCOORD0;};struct TessellationControlPoint{    ...    float visibility : TEXCOORD1;};TessellationControlPoint vert(Attributes v){    ...    float visibility = SAMPLE_TEXTURE2D_LOD(_VisibilityMap, sampler_VisibilityMap, v.uv, 0).r;     o.visibility    = visibility;    ...}TessellationFactors patchConstantFunction (InputPatch<TessellationControlPoint, 3&gt; patch){    ...    float averageVisibility = (patch[0].visibility + patch[1].visibility + patch[2].visibility) \/ 3; \/\/ \u8ba1\u7b97\u4e09\u4e2a\u9876\u70b9\u7070\u5ea6\u503c\u7684\u5e73\u5747\u503c    float baseTessellationFactor = _TessellationFactor_FIXED;     float tessellationMultiplier = lerp(0.1, 1.0, averageVisibility); \/\/ \u6839\u636e\u5e73\u5747\u7070\u5ea6\u503c\u8c03\u6574\u56e0\u5b50    #if defined(_DYNAMIC_FIXED)        f.edge[0] = _TessellationFactor_FIXED * tessellationMultiplier;        f.edge[1] = _TessellationFactor_FIXED * tessellationMultiplier;        f.edge[2] = _TessellationFactor_FIXED * tessellationMultiplier;        f.inside  = _TessellationFactor_FIXED * tessellationMultiplier;    ...\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #88C0D0\">_VisibilityMap<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Visibility Map<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> 2<\/span><span style=\"color: #D8DEE9\">D<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">white<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">{}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #88C0D0\">TEXTURE2D<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">_VisibilityMap<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #88C0D0\">SAMPLER<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">sampler_VisibilityMap<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">struct<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Attributes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float2<\/span><span style=\"color: #D8DEE9FF\"> uv <\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">TEXCOORD0<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">struct<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">TessellationControlPoint<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> visibility <\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">TEXCOORD1<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">TessellationControlPoint<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">vert<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">Attributes<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">v<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">visibility<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">SAMPLE_TEXTURE2D_LOD<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">_VisibilityMap<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">sampler_VisibilityMap<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">v<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">uv<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">r<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">o<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">visibility<\/span><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">visibility<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">TessellationFactors<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">patchConstantFunction<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">InputPatch<\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9\">TessellationControlPoint<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">3<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">patch<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">averageVisibility<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">patch<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">visibility<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">patch<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">visibility<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">patch<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">visibility<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">3<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Calculate the average grayscale value of the three vertices<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">baseTessellationFactor<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_TessellationFactor_FIXED<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">tessellationMultiplier<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">lerp<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">0.1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1.0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">averageVisibility<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Adjust the factor based on the average gray value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    #<\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">defined<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">_DYNAMIC_FIXED<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">edge<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_TessellationFactor_FIXED<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">tessellationMultiplier<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">edge<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_TessellationFactor_FIXED<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">tessellationMultiplier<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">edge<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_TessellationFactor_FIXED<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">tessellationMultiplier<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">inside<\/span><span style=\"color: #D8DEE9FF\">  <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_TessellationFactor_FIXED<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">tessellationMultiplier<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">3.6 Complete code\u203c\ufe0f (BIRP)<\/h3>\n\n\n\n<p>Grass Shader:<\/p>\n\n\n\n<p><a href=\"https:\/\/pastebin.com\/TD0AupGz\">https:\/\/pastebin.com\/TD0AupGz<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.7 Full code \u203c \ufe0f (URP)<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-40.png\" alt=\"\" class=\"wp-image-160 lazyload\"\/><noscript><img decoding=\"async\" width=\"1214\" height=\"462\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-40.png\" alt=\"\" class=\"wp-image-160 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-40.png 1214w, https:\/\/remoooo.com\/wp-content\/uploads\/image-40-300x114.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-40-1024x390.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-40-768x292.png 768w\" sizes=\"(max-width: 1214px) 100vw, 1214px\" \/><\/noscript><\/figure>\n\n\n\n<p>There are some differences in URP. For example, to calculate ShadowBias, you need to do the following. I won\u2019t expand on it. Just look at the code yourself.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"#if UNITY_PASS_SHADOWCASTER    \/\/ o.pos = UnityApplyLinearShadowBias(o.pos);    o.shadowCoord = TransformWorldToShadowCoord(ApplyShadowBias(posWS, norWS, 0));#endif\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">UNITY_PASS_SHADOWCASTER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">    <\/span><span style=\"color: #616E88\">\/\/ o.pos = UnityApplyLinearShadowBias(o.pos);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">o<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">shadowCoord<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">TransformWorldToShadowCoord<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">ApplyShadowBias<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">posWS<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">norWS<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #D8DEE9\">endif<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Grass Shader:<\/p>\n\n\n\n<p><a href=\"https:\/\/pastebin.com\/2ZX2aVm9\">https:\/\/pastebin.com\/2ZX2aVm9<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Interactive Grassland<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>URP and BIRP are exactly the same.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">4.1 Implementation steps<\/h3>\n\n\n\n<p>The principle is very simple. The script transmits the character&#039;s world coordinates, and then bends the grass according to the set radius and interaction strength.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">uniform float3 _PositionMoving; \/\/ Object position float _Radius; \/\/ Object interaction radius float _Strength; \/\/ Interaction strength<\/pre>\n\n\n\n<p>In the grass generation loop, calculate the distance between each grass fragment and the object and adjust the grass position according to this distance.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float dis = distance(_PositionMoving, posWS); \/\/ \u8ba1\u7b97\u8ddd\u79bbfloat radiusEffect = 1 - saturate(dis \/ _Radius); \/\/ \u6839\u636e\u8ddd\u79bb\u8ba1\u7b97\u6548\u679c\u8870\u51cffloat3 sphereDisp = pos - _PositionMoving; \/\/ \u8ba1\u7b97\u4f4d\u7f6e\u5deesphereDisp *= radiusEffect * _Strength; \/\/ \u5e94\u7528\u8870\u51cf\u548c\u5f3a\u5ea6sphereDisp = clamp(sphereDisp, -0.8, 0.8); \/\/ \u9650\u5236\u6700\u5927\u4f4d\u79fb\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">dis<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">distance<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">_PositionMoving<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">posWS<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Calculate distance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radiusEffect<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">saturate<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">dis<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_Radius<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Calculate effect attenuation based on distance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">sphereDisp<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">POS<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_PositionMoving<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Calculate the position difference<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">sphereDisp<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radiusEffect<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_Strength<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Apply falloff and intensity<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">sphereDisp<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">clamp<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">sphereDisp<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">0.8<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.8<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Limit the maximum displacement<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The new positions are then calculated within each blade of grass.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ \u5e94\u7528\u4ea4\u4e92\u6548\u679cfloat3 newPos = i == 0 ? pos : pos + (sphereDisp * t);triStream.Append(GenerateGrassVertex(newPos, segmentWidth, segmentHeight, segmentForward, float2(0, t), transformMatrix));triStream.Append(GenerateGrassVertex(newPos, -segmentWidth, segmentHeight, segmentForward, float2(1, t), transformMatrix));\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Apply interactive effects<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">newPos<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">?<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">POS<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">POS<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">sphereDisp<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">triStream<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Append<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">GenerateGrassVertex<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">newPos<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">segmentWidth<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">segmentHeight<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">segmentForward<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float2<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">transformMatrix<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">triStream<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Append<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">GenerateGrassVertex<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">newPos<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9\">segmentWidth<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">segmentHeight<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">segmentForward<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float2<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">transformMatrix<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Don&#039;t forget the outside of the for loop, which is the top vertex.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ \u6700\u540e\u7684\u8349\u7247\u6bb5float3 newPosTop = pos + sphereDisp;triStream.Append(GenerateGrassVertex(newPosTop, 0, height, forward, float2(0.5, 1), transformationMatrix));triStream.RestartStrip();\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Final grass fragment<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">newPosTop<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">POS<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">sphereDisp<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">triStream<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Append<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">GenerateGrassVertex<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">newPosTop<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">height<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">forward<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float2<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">0.5<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">transformationMatrix<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">triStream<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">RestartStrip<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>In URP, using uniform float3 _PositionMoving may cause SRP Batcher to fail.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-43.png\" alt=\"\" class=\"wp-image-163 lazyload\"\/><noscript><img decoding=\"async\" width=\"984\" height=\"482\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-43.png\" alt=\"\" class=\"wp-image-163 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-43.png 984w, https:\/\/remoooo.com\/wp-content\/uploads\/image-43-300x147.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-43-768x376.png 768w\" sizes=\"(max-width: 984px) 100vw, 984px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-46.png\" alt=\"\" class=\"wp-image-166 lazyload\"\/><noscript><img decoding=\"async\" width=\"1130\" height=\"520\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-46.png\" alt=\"\" class=\"wp-image-166 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-46.png 1130w, https:\/\/remoooo.com\/wp-content\/uploads\/image-46-300x138.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-46-1024x471.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-46-768x353.png 768w\" sizes=\"(max-width: 1130px) 100vw, 1130px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">4.2 Script Code<\/h3>\n\n\n\n<p>Bind the object that needs interaction.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"using UnityEngine;public class ShaderInteractor : MonoBehaviour{    \/\/ Update is called once per frame    void Update()    {        Shader.SetGlobalVector(&quot;_PositionMoving&quot;, transform.position);    }}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">using<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">UnityEngine<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">class<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #8FBCBB\">ShaderInteractor<\/span><span style=\"color: #D8DEE9FF\"> : <\/span><span style=\"color: #8FBCBB\">MonoBehaviour<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">    <\/span><span style=\"color: #616E88\">\/\/ Update is called once per frame<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">Update<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">Shader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetGlobalVector<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">_PositionMoving<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">4.3 Full code \u203c \ufe0f (URP)<\/h3>\n\n\n\n<p>Grass shader:<\/p>\n\n\n\n<p><a href=\"https:\/\/pastebin.com\/Zs77EQgy\">https:\/\/pastebin.com\/Zs77EQgy<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Compute Shader Rendering Grass v1.0<\/h2>\n\n\n\n<p>Why v1.0? Because I think it is quite difficult to render the sea of grass with this compute shader. Many of the things that are not available now can be improved slowly in the future. I also wrote some notes about Compute Shader.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/699253914\" target=\"_blank\" rel=\"noreferrer noopener\">Compute Shader Study Notes (I)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/700148560\" target=\"_blank\" rel=\"noreferrer noopener\">Compute Shader Learning Notes (II) Post-processing Effects<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/700370323\" target=\"_blank\" rel=\"noreferrer noopener\">Compute Shader Learning Notes (II) Particle Effects and Cluster Behavior Simulation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/701633578\" target=\"_blank\" rel=\"noreferrer noopener\">Compute Shader Learning Notes (Part 3) Grass Rendering<\/a><\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">5.1 Review\/Organization<\/h3>\n\n\n\n<p>The Compute Shader notes above fully describe how to write a stylized grass sea from scratch in CS. If you forgot, review it here.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-42.png\" alt=\"\" class=\"wp-image-162 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"638\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-42.png\" alt=\"\" class=\"wp-image-162 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-42.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-42-300x133.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-42-1024x454.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-42-768x340.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>There are still many things that the CPU needs to do in the initialization stage. First, define the grass Mesh and Buffer transfer (the width and height of the grass, the position of each grass generation, the random orientation of the grass, and the random color depth of the grass). It also needs to specifically pass the maximum curvature value and grass interaction radius to the Compute Shader.<\/p>\n\n\n\n<p>For each frame, the CPU also passes the time variable, wind direction, wind force\/speed, and wind field scaling factor to the Compute Shader.<\/p>\n\n\n\n<p>Compute Shader uses the information passed by the CPU to calculate how the grass should turn, using quaternions as output.<\/p>\n\n\n\n<p>Finally, the shader instantiates the ID and all calculation results, first calculating the vertex offset, then applying the quaternion rotation, and finally modifying the normal information.<\/p>\n\n\n\n<p>This demo can actually be further optimized, such as putting more calculations in the Compute Shader, such as the process of generating Mesh, the width and height of the grass, random tilting, etc. More real-time parameter adjustment variables can also be optimized. Various optimization culling can also be performed, such as culling the incoming camera position by distance, or culling with the view frustum, etc. This culling process requires the use of some atomic operations. There is also multi-object interaction. The logic of interactive grass deformation can also be optimized, such as the degree of interaction is proportional to the power of the distance of the interactive object, etc. The engine function can also be increased, and the function of brushing grass can be developed, which may require a quadtree storage system, etc.<\/p>\n\n\n\n<p>And in Compute Shader, use vectors instead of scalars when possible.<\/p>\n\n\n\n<p>First, organize the code. Put all variables that do not need to be sent to the Compute Shader every frame into a function for unified initialization. Organize the Inspector panel. (There are many code changes)<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-56.png\" alt=\"\" class=\"wp-image-176 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"871\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-56.png\" alt=\"\" class=\"wp-image-176 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-56.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-56-300x181.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-56-1024x619.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-56-768x465.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>First, basically all calculations are run on the GPU, except that the world coordinates of each grass are calculated in the CPU and passed to the GPU through a Buffer.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-44.png\" alt=\"\" class=\"wp-image-164 lazyload\"\/><noscript><img decoding=\"async\" width=\"1262\" height=\"574\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-44.png\" alt=\"\" class=\"wp-image-164 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-44.png 1262w, https:\/\/remoooo.com\/wp-content\/uploads\/image-44-300x136.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-44-1024x466.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-44-768x349.png 768w\" sizes=\"(max-width: 1262px) 100vw, 1262px\" \/><\/noscript><\/figure>\n\n\n\n<p>The size of the buffer transmission depends entirely on the size of the ground mesh and the set density. In other words, if it is a super large open world, the buffer will become super large. For a 5*5 grass field, with the Density set to 0.5, approximately 312576 grass data will be sent, and the actual data will reach 4*312576*4=5001216 bytes. Based on the CPU-&gt;GPU transmission speed of 8 GB\/s, it takes about 10 milliseconds to transmit.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-47.png\" alt=\"\" class=\"wp-image-167 lazyload\"\/><noscript><img decoding=\"async\" width=\"1330\" height=\"144\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-47.png\" alt=\"\" class=\"wp-image-167 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-47.png 1330w, https:\/\/remoooo.com\/wp-content\/uploads\/image-47-300x32.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-47-1024x111.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-47-768x83.png 768w\" sizes=\"(max-width: 1330px) 100vw, 1330px\" \/><\/noscript><\/figure>\n\n\n\n<p>Fortunately, this buffer does not need to be transmitted every frame, but it is enough to attract our attention. If the current grass size increases to 100*100, the time required will increase several times, which is scary. Moreover, we may not use many of the vertices, which causes a great waste of performance.<\/p>\n\n\n\n<p>I added a function to generate perlin noise in the Compute Shader, as well as the xorshift128 random number generation algorithm.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Perlin \u968f\u673a\u6570\u7b97\u6cd5float hash(float x, float y) {    return frac(abs(sin(sin(123.321 + x) * (y + 321.123)) * 456.654));}float perlin(float x, float y){    float col = 0.0;    for (int i = 0; i < 8; i++) {        float fx = floor(x); float fy = floor(y);        float cx = ceil(x); float cy = ceil(y);        float a = hash(fx, fy); float b = hash(fx, cy);        float c = hash(cx, fy); float d = hash(cx, cy);        col += lerp(lerp(a, b, frac(y)), lerp(c, d, frac(y)), frac(x));        col \/= 2.0; x \/= 2.0; y \/= 2.0;    }    return col;}\/\/ XorShift128 \u968f\u673a\u6570\u7b97\u6cd5 -- Edited \u76f4\u63a5\u8f93\u51fa\u5f52\u4e00\u5316\u6570\u636euint state[4];void xorshift_init(uint s) {    state[0] = s; state[1] = s | 0xffff0000u;    state[2] = s << 16; state[3] = s &gt;&gt; 16;}float xorshift128() {    uint t = state[3]; uint s = state[0];    state[3] = state[2]; state[2] = state[1]; state[1] = s;    t ^= t << 11u; t ^= t &gt;&gt; 8u;    state[0] = t ^ s ^ (s &gt;&gt; 19u);    return (float)state[0] \/ float(0xffffffffu);}[numthreads(THREADGROUPSIZE,1,1)]void BendGrass (uint3 id : SV_DispatchThreadID){    xorshift_init(id.x * 73856093u ^ id.y * 19349663u ^ id.z * 83492791u);    ...}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Perlin random number algorithm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">hash<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">frac<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">abs<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">sin<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">sin<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">123.321<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">321.123<\/span><span style=\"color: #D8DEE9FF\">)) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">456.654<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">perlin<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">col<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0.0<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">for<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">8<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #81A1C1\">++<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">fx<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">floor<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">fy<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">floor<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">xx<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">ceil<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">cy<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">ceil<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">a<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">hash<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">fx<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">fy<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">b<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">hash<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">fx<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">cy<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">c<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">hash<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">xx<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">fy<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">d<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">hash<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">xx<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">cy<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">col<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">lerp<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">lerp<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">a<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">b<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">frac<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">lerp<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">c<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">d<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">frac<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">frac<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">col<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2.0<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2.0<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2.0<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">col<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ XorShift128 random number algorithm -- Edited Directly output normalized data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">uint<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">4<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">xorshift_init<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">uint<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">|<\/span><span style=\"color: #D8DEE9FF\"> 0<\/span><span style=\"color: #D8DEE9\">xffff0000u<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">16<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">3<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">16<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">xorshift128<\/span><span style=\"color: #D8DEE9FF\">() <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">uint<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">3<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">uint<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">3<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">^=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> 11<\/span><span style=\"color: #D8DEE9\">u<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">^=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;&gt;<\/span><span style=\"color: #D8DEE9FF\"> 8<\/span><span style=\"color: #D8DEE9\">u<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">t<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">^<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">^<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">s<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;&gt;<\/span><span style=\"color: #D8DEE9FF\"> 19<\/span><span style=\"color: #D8DEE9\">u<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #D8DEE9\">state<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float<\/span><span style=\"color: #D8DEE9FF\">(0<\/span><span style=\"color: #D8DEE9\">xffffffffu<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #88C0D0\">numthreads<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">THREADGROUPSIZE<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">BendGrass<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">uint3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">id<\/span><span style=\"color: #D8DEE9FF\"> : <\/span><span style=\"color: #D8DEE9\">SV_DispatchThreadID<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">xorshift_init<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">id<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> 73856093<\/span><span style=\"color: #D8DEE9\">u<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">^<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">id<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> 19349663<\/span><span style=\"color: #D8DEE9\">u<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">^<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">id<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">z<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> 83492791<\/span><span style=\"color: #D8DEE9\">u<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>To review, at present, the CPU uses an AABB average grass paving logic to generate all possible grass vertices, which are then passed to the GPU to perform some culling, LoD and other operations in the Compute Shader.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-45.png\" alt=\"\" class=\"wp-image-165 lazyload\"\/><noscript><img decoding=\"async\" width=\"704\" height=\"202\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-45.png\" alt=\"\" class=\"wp-image-165 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-45.png 704w, https:\/\/remoooo.com\/wp-content\/uploads\/image-45-300x86.png 300w\" sizes=\"(max-width: 704px) 100vw, 704px\" \/><\/noscript><\/figure>\n\n\n\n<p>So far I have three Buffers.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-50.png\" alt=\"\" class=\"wp-image-170 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"458\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-50.png\" alt=\"\" class=\"wp-image-170 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-50.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-50-300x95.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-50-1024x326.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-50-768x244.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>m_InputBuffer is the structure on the left of the above picture that sends all the grass to the GPU without any culling.<\/p>\n\n\n\n<p>m_OutputBuffer is a variable length buffer that increases slowly in the Compute Shader. If the grass of the current thread ID is suitable, it will be added to this buffer for instanced rendering later. The structure on the right of the above picture.<\/p>\n\n\n\n<p>m_argsBuffer is a parameterized Buffer, which is different from other Buffers. It is used to pass parameters to Draw, and its specific content is to specify the number of vertices to be rendered in batches, the number of rendering instances, etc. Let&#039;s take a look at it in detail:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-48.png\" alt=\"\" class=\"wp-image-168 lazyload\"\/><noscript><img decoding=\"async\" width=\"846\" height=\"256\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-48.png\" alt=\"\" class=\"wp-image-168 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-48.png 846w, https:\/\/remoooo.com\/wp-content\/uploads\/image-48-300x91.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-48-768x232.png 768w\" sizes=\"(max-width: 846px) 100vw, 846px\" \/><\/noscript><\/figure>\n\n\n\n<p>First parameter, my grass mesh has seven triangles, so there are 21 vertices to render.<\/p>\n\n\n\n<p>The second parameter is temporarily set to 0, indicating that nothing needs to be rendered. This number will be dynamically set according to the length of m_OutputBuffer after the Compute Shader calculation is completed. In other words, the number here will be the same as the number of grasses appended in the Compute Shader.<\/p>\n\n\n\n<p>The third and fourth parameters represent respectively: the index of the first rendered vertex and the index of the first instantiation.<\/p>\n\n\n\n<p>I haven&#039;t used the fifth parameter, so I don&#039;t know what it is used for.<\/p>\n\n\n\n<p>The last step looks like this, passing in the Mesh, material, AABB and parameter Buffer.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-51.png\" alt=\"\" class=\"wp-image-171 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"381\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-51.png\" alt=\"\" class=\"wp-image-171 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-51.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-51-300x79.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-51-1024x271.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-51-768x203.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">5.2 Customizing Unity Tools<\/h3>\n\n\n\n<p>Create a new C# script and save it in the Editor directory of the project (if it doesn&#039;t exist, create one). The script inherits from Editor, and then write [CustomEditor(typeof(XXX))] . It means you work for XXX. I work for GrassControl, and then you can attach what you wrote now to XXX. Of course, you can also have a separate window, which should inherit from EditorWindow.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-49.png\" alt=\"\" class=\"wp-image-169 lazyload\"\/><noscript><img decoding=\"async\" width=\"724\" height=\"154\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-49.png\" alt=\"\" class=\"wp-image-169 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-49.png 724w, https:\/\/remoooo.com\/wp-content\/uploads\/image-49-300x64.png 300w\" sizes=\"(max-width: 724px) 100vw, 724px\" \/><\/noscript><\/figure>\n\n\n\n<p>Write tools in the OnInspectorGUI() function, for example, write a Label.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"GUILayout.Label(&quot;== Remo Grass Generator ==&quot;);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">GUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Label<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">== Remo Grass Generator ==<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-52.png\" alt=\"\" class=\"wp-image-172 lazyload\"\/><noscript><img decoding=\"async\" width=\"630\" height=\"54\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-52.png\" alt=\"\" class=\"wp-image-172 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-52.png 630w, https:\/\/remoooo.com\/wp-content\/uploads\/image-52-300x26.png 300w\" sizes=\"(max-width: 630px) 100vw, 630px\" \/><\/noscript><\/figure>\n\n\n\n<p>To center the Inspector, add a parameter.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"GUILayout.Label(&quot;== Remo Grass Generator ==&quot;, new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter });\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">GUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Label<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">== Remo Grass Generator ==<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">GUIStyle<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">EditorStyles<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">boldLabel<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #ECEFF4\">{<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">alignment<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">TextAnchor<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">MiddleCenter<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">}<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-53.png\" alt=\"\" class=\"wp-image-173 lazyload\"\/><noscript><img decoding=\"async\" width=\"710\" height=\"186\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-53.png\" alt=\"\" class=\"wp-image-173 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-53.png 710w, https:\/\/remoooo.com\/wp-content\/uploads\/image-53-300x79.png 300w\" sizes=\"(max-width: 710px) 100vw, 710px\" \/><\/noscript><\/figure>\n\n\n\n<p>Too crowded? Just add a line of space.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"EditorGUILayout.Space();\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">EditorGUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Space<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-54.png\" alt=\"\" class=\"wp-image-174 lazyload\"\/><noscript><img decoding=\"async\" width=\"662\" height=\"98\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-54.png\" alt=\"\" class=\"wp-image-174 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-54.png 662w, https:\/\/remoooo.com\/wp-content\/uploads\/image-54-300x44.png 300w\" sizes=\"(max-width: 662px) 100vw, 662px\" \/><\/noscript><\/figure>\n\n\n\n<p>If you want to attach tools above XXX, then all the logic should be written above OnInspectorGUI.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"... \/\/ \u5199\u5728\u8fd9\/\/ \u9ed8\u8ba4\u7684 GrassControl \u7684 Inspector \u754c\u9762base.OnInspectorGUI();\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">...<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ Write here<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ The default Inspector interface of GrassControl<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">base<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">OnInspectorGUI<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Create a button and press the code:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"if (GUILayout.Button(&quot;xxx&quot;)){    ...\/\/\u6309\u4e0b\u540e\u7684\u4ee3\u7801\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">GUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Button<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">xxx<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><span style=\"color: #616E88\">\/\/Code after pressing<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Anyway, these are the ones I use now.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.3 Editor selects the object to generate grass<\/h3>\n\n\n\n<p>It is also very simple to get the Object of the script of the current service and display it in the Inspector.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"[SerializeField] private GameObject grassObject;...grassObject = (GameObject)EditorGUILayout.ObjectField(&quot;\u540d\u5b57\u968f\u4fbf\u5199&quot;, grassObject, typeof(GameObject), true);if (grassObject == null){    grassObject = FindObjectOfType<GrassControl&gt;()?.gameObject;}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">SerializeField<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #D8DEE9\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">GameObject<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grassObject<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">grassObject<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">GameObject<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #D8DEE9\">EditorGUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">ObjectField<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Write any name<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grassObject<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">typeof<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">GameObject<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">true<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">grassObject<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">grassObject<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">FindObjectOfType<\/span><span style=\"color: #ECEFF4\">&lt;<\/span><span style=\"color: #D8DEE9FF\">GrassControl<\/span><span style=\"color: #ECEFF4\">&gt;<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #ECEFF4\">?.<\/span><span style=\"color: #D8DEE9\">gameObject<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-57.png\" alt=\"\" class=\"wp-image-177 lazyload\"\/><noscript><img decoding=\"async\" width=\"710\" height=\"186\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-57.png\" alt=\"\" class=\"wp-image-177 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-57.png 710w, https:\/\/remoooo.com\/wp-content\/uploads\/image-57-300x79.png 300w\" sizes=\"(max-width: 710px) 100vw, 710px\" \/><\/noscript><\/figure>\n\n\n\n<p>After obtaining it, you can access the contents of the current script through GameObject.<\/p>\n\n\n\n<p>How to get the object selected in the Editor window? It can be done with one line of code.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"foreach (GameObject obj in Selection.gameObjects)\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #88C0D0\">foreach<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">GameObject<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">obj<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">in<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Selection<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">gameObjects<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Display the selected objects in the Inspector panel. Note that you need to handle the case of multiple selections, otherwise a Warning will be issued.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ \u5b9e\u65f6\u663e\u793a\u5f53\u524dEditor\u9009\u4e2d\u5bf9\u8c61\u5e76\u63a7\u5236\u6309\u94ae\u7684\u53ef\u7528\u6027EditorGUILayout.LabelField(&quot;Selection Info:&quot;, EditorStyles.boldLabel);bool hasSelection = Selection.activeGameObject != null;GUI.enabled = hasSelection;if (hasSelection)    foreach (GameObject obj in Selection.gameObjects)        EditorGUILayout.LabelField(obj.name);else    EditorGUILayout.LabelField(&quot;No active object selected.&quot;);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Display the current Editor selected object in real time and control the availability of the button<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">EditorGUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">LabelField<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Selection Info:<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">EditorStyles<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">boldLabel<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">bool<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">hasSelection<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Selection<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">activeGameObject<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">GUI<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">enabled<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">hasSelection<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">hasSelection<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #88C0D0\">foreach<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">GameObject<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">obj<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">in<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Selection<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">gameObjects<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">EditorGUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">LabelField<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">obj<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">name<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">EditorGUILayout<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">LabelField<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">No active object selected.<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-55.png\" alt=\"\" class=\"wp-image-175 lazyload\"\/><noscript><img decoding=\"async\" width=\"262\" height=\"126\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-55.png\" alt=\"\" class=\"wp-image-175 lazyload\"\/><\/noscript><\/figure>\n\n\n\n<p>Next, get the MeshFilter and Renderer of the selected object. Since Raycast detection is required, get a Collider. If it does not exist, create one.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-58.png\" alt=\"\" class=\"wp-image-178 lazyload\"\/><noscript><img decoding=\"async\" width=\"1242\" height=\"444\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-58.png\" alt=\"\" class=\"wp-image-178 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-58.png 1242w, https:\/\/remoooo.com\/wp-content\/uploads\/image-58-300x107.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-58-1024x366.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-58-768x275.png 768w\" sizes=\"(max-width: 1242px) 100vw, 1242px\" \/><\/noscript><\/figure>\n\n\n\n<p>Then I will not talk about the code of sketching grass here.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.4 Processing AABBs<\/h3>\n\n\n\n<p>After generating a bunch of grass, add each grass to the AABB and finally pass it to Instancing.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-60.png\" alt=\"\" class=\"wp-image-180 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"359\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-60.png\" alt=\"\" class=\"wp-image-180 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-60.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-60-300x75.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-60-1024x255.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-60-768x191.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>I assume that each grass is the size of a unit cube, so it is Vector3.one. If the grass is particularly tall, this should need to be modified.<\/p>\n\n\n\n<p>Stuff each blade of grass into the big AABB and pass the new AABB back to the script&#039;s m_LocalBounds for Instancing.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"Graphics.DrawMeshInstancedIndirect(blade, 0, m_Material, m_LocalBounds, m_argsBuffer);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">Graphics<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">DrawMeshInstancedIndirect<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">blade<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_Material<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_LocalBounds<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_argsBuffer<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">5.5 Surface Shader \u2013 Pitfalls<\/h3>\n\n\n\n<p>There is a small problem here. Since the current Material is a Surface Shader, the Vertex of the Surface Shader has calculated the center of the AABB by default to do the vertex offset, so the world coordinates passed in before cannot be used directly. You also need to pass the center of the AABB in and subtract it. It&#039;s so strange. I wonder if there is any elegant way.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-59.png\" alt=\"\" class=\"wp-image-179 lazyload\"\/><noscript><img decoding=\"async\" width=\"946\" height=\"400\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-59.png\" alt=\"\" class=\"wp-image-179 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-59.png 946w, https:\/\/remoooo.com\/wp-content\/uploads\/image-59-300x127.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-59-768x325.png 768w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">5.6 Simple Camera Distance Culling + Fade<\/h3>\n\n\n\n<p>Currently, all generated grass is passed to the Compute Shader on the CPU, and then all grass is added to the AppendBuffer, which means there is no culling logic.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-63.png\" alt=\"\" class=\"wp-image-183 lazyload\"\/><noscript><img decoding=\"async\" width=\"1378\" height=\"560\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-63.png\" alt=\"\" class=\"wp-image-183 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-63.png 1378w, https:\/\/remoooo.com\/wp-content\/uploads\/image-63-300x122.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-63-1024x416.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-63-768x312.png 768w\" sizes=\"(max-width: 1378px) 100vw, 1378px\" \/><\/noscript><\/figure>\n\n\n\n<p>The simplest culling solution is to cull grass based on the distance between the camera and the grass. In the Inspector panel, open a value to represent the culling distance. Calculate the distance between the camera and the current grass instance. If it is greater than the set value, it will not be added to the AppendBuffer.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-62.png\" alt=\"\" class=\"wp-image-182 lazyload\"\/><noscript><img decoding=\"async\" width=\"1284\" height=\"606\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-62.png\" alt=\"\" class=\"wp-image-182 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-62.png 1284w, https:\/\/remoooo.com\/wp-content\/uploads\/image-62-300x142.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-62-1024x483.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-62-768x362.png 768w\" sizes=\"(max-width: 1284px) 100vw, 1284px\" \/><\/noscript><\/figure>\n\n\n\n<p>First, pass the world coordinates of the camera into C#. Here is the semi-pseudo code:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ \u83b7\u53d6\u6444\u50cf\u673aprivate Camera m_MainCamera;m_MainCamera = Camera.main;if (m_MainCamera != null)    m_ComputeShader.SetVector(ID_camreaPos, m_MainCamera.transform.position);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Get the camera<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Camera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Camera<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">main<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_ComputeShader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetVector<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">ID_camreaPos<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>In CS, calculate the distance between the grass and the camera:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float distanceFromCamera = distance(input.position, _CameraPositionWS);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">distanceFromCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">distance<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">input<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_CameraPositionWS<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-64.png\" alt=\"\" class=\"wp-image-184 lazyload\"\/><noscript><img decoding=\"async\" width=\"682\" height=\"352\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-64.png\" alt=\"\" class=\"wp-image-184 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-64.png 682w, https:\/\/remoooo.com\/wp-content\/uploads\/image-64-300x155.png 300w\" sizes=\"(max-width: 682px) 100vw, 682px\" \/><\/noscript><\/figure>\n\n\n\n<p>The distance function code is as follows:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"float distanceFade = 1 - saturate((distanceFromCamera - _MinFadeDist) \/ (_MaxFadeDist - _MinFadeDist));\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">distanceFade<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">saturate<\/span><span style=\"color: #D8DEE9FF\">((<\/span><span style=\"color: #D8DEE9\">distanceFromCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_MinFadeDist<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">_MaxFadeDist<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_MinFadeDist<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>If the value is less than 0, return directly.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ skip if out of fading range tooif (distanceFade < 0.001f){    return;}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ skip if out of fading range too<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">distanceFade<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> 0<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">001<\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">return;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>In the part between culling and not culling, set the grass width + Fade value to achieve a fading effect.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"result.height = (bladeHeight + bladeHeightOffset * (xorshift128()*2-1)) * distanceFade;result.width = (bladeWeight + bladeWeightOffset * (xorshift128()*2-1)) * distanceFade;...result.fade = xorshift128() * distanceFade;\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">Result<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">height<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">bladeHeight<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">bladeHeightOffset<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #88C0D0\">xorshift128<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">)) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">distanceFade<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">Result<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">width<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">bladeWeight<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">bladeWeightOffset<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #88C0D0\">xorshift128<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">)) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">distanceFade<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">Result<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">fade<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">xorshift128<\/span><span style=\"color: #D8DEE9FF\">() <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">distanceFade<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-61.png\" alt=\"\" class=\"wp-image-181 lazyload\"\/><noscript><img decoding=\"async\" width=\"690\" height=\"130\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-61.png\" alt=\"\" class=\"wp-image-181 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-61.png 690w, https:\/\/remoooo.com\/wp-content\/uploads\/image-61-300x57.png 300w\" sizes=\"(max-width: 690px) 100vw, 690px\" \/><\/noscript><\/figure>\n\n\n\n<p>In the figure below, both are set to be relatively small for the convenience of demonstration.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-67.png\" alt=\"\" class=\"wp-image-187 lazyload\"\/><noscript><img decoding=\"async\" width=\"1142\" height=\"562\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-67.png\" alt=\"\" class=\"wp-image-187 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-67.png 1142w, https:\/\/remoooo.com\/wp-content\/uploads\/image-67-300x148.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-67-1024x504.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-67-768x378.png 768w\" sizes=\"(max-width: 1142px) 100vw, 1142px\" \/><\/noscript><\/figure>\n\n\n\n<p>I think the actual effect is quite good and smooth. If the width and height of the grass are not modified, the effect will be greatly reduced.<\/p>\n\n\n\n<p>Of course, you can also modify the logic: do not completely remove the grass that exceeds the maximum drawing range, but reduce the number of drawings; or selectively draw the grass in the transition area.<\/p>\n\n\n\n<p>Both logics are acceptable, and if it were me I would choose the latter.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.7 Maintaining a set of visible ID buffers<\/h3>\n\n\n\n<p>The so-called frustum culling is to reduce the redundant calculations of GPU through various methods at the CPU stage.<\/p>\n\n\n\n<p>So how do I let the Compute Shader know which grass needs to be rendered and which needs to be culled? My approach is to maintain a set of ID Lists. The length is the number of all grasses. If the current grass needs to be culled, otherwise the index value of the grass that needs to be rendered is recorded.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"List<uint&gt; grassVisibleIDList = new List<uint&gt;();\/\/ buffer that contains the ids of all visible instancesprivate ComputeBuffer m_VisibleIDBuffer;private const int VISIBLE_ID_STRIDE        =  1 * sizeof(uint);m_VisibleIDBuffer = new ComputeBuffer(grassData.Count, VISIBLE_ID_STRIDE,    ComputeBufferType.Structured); \/\/uint only, per visible grassm_ComputeShader.SetBuffer(m_ID_GrassKernel, &quot;_VisibleIDBuffer&quot;, m_VisibleIDBuffer);m_VisibleIDBuffer?.Release();\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">List<\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9\">uint<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grassVisibleIDList<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">List<\/span><span style=\"color: #ECEFF4\">&lt;<\/span><span style=\"color: #D8DEE9FF\">uint<\/span><span style=\"color: #ECEFF4\">&gt;<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ buffer that contains the ids of all visible instances<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">ComputeBuffer<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_VisibleIDBuffer<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> VISIBLE_ID_STRIDE        <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">  <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">sizeof<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">uint<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_VisibleIDBuffer<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">ComputeBuffer<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">grassData<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Count<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">VISIBLE_ID_STRIDE<\/span><span style=\"color: #ECEFF4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">ComputeBufferType<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Structured<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/uint only, per visible grass<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_ComputeShader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetBuffer<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">m_ID_GrassKernel<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">_VisibleIDBuffer<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_VisibleIDBuffer<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_VisibleIDBuffer<\/span><span style=\"color: #ECEFF4\">?.<\/span><span style=\"color: #88C0D0\">Release<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Since some grass has been removed before being passed to the Compute Shader, the number of Dispatches is no longer the number of all grasses, but the number of the current List.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ m_ComputeShader.Dispatch(m_ID_GrassKernel, m_DispatchSize, 1, 1);m_DispatchSize = Mathf.CeilToInt(grassVisibleIDList.Count \/ threadGroupSize);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ m_ComputeShader.Dispatch(m_ID_GrassKernel, m_DispatchSize, 1, 1);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_DispatchSize<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Mathf<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">CeilToInt<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">grassVisibleIDList<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Count<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">threadGroupSize<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Generates a fully visible ID sequence.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"void GrassFastList(int count){    grassVisibleIDList = Enumerable.Range(0, count).ToArray().ToList();}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">GrassFastList<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">count<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">grassVisibleIDList<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Enumerable<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Range<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">count<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">ToArray<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">ToList<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>And each frame should be uploaded to GPU. The preparation is complete, and then use Quad tree to operate this array.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.8 Quad\/Octtree Storing Grass Index<\/h3>\n\n\n\n<p>You can consider dividing an AABB into multiple sub-AABBs and then use a quadtree to store and manage them.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-65.png\" alt=\"\" class=\"wp-image-185 lazyload\"\/><noscript><img decoding=\"async\" width=\"892\" height=\"520\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-65.png\" alt=\"\" class=\"wp-image-185 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-65.png 892w, https:\/\/remoooo.com\/wp-content\/uploads\/image-65-300x175.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-65-768x448.png 768w\" sizes=\"(max-width: 892px) 100vw, 892px\" \/><\/noscript><\/figure>\n\n\n\n<p>Currently, all grass is in one AABB. Next, we build an octree and put all the grass in this AABB into branches. This makes it easy to do frustum culling in the early stages of the CPU.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-68.png\" alt=\"\" class=\"wp-image-188 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"489\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-68.png\" alt=\"\" class=\"wp-image-188 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-68.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-68-300x102.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-68-1024x348.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-68-768x261.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>How to store it? If the current grass has a small vertical drop, then a quadtree is enough. If it is an open world with undulating mountains, then use an octree. However, considering that the grass has a relatively high horizontal density, I use a quadtree + octree structure here. The parity of the depth determines whether the current depth is divided into four nodes or eight nodes. If there is no need for strong height division, it is OK to use an octree, but I feel that the efficiency may be a little lower. Here, it is directly evenly distributed. Later optimization can consider the AABB division method based on variable length dynamic changes.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"if (depth % 2 == 0){    ...    m_children.Add(new CullingTreeNode(topLeftSingle, depth - 1));    m_children.Add(new CullingTreeNode(bottomRightSingle, depth - 1));    m_children.Add(new CullingTreeNode(topRightSingle, depth - 1));    m_children.Add(new CullingTreeNode(bottomLeftSingle, depth - 1));}else{    ...    m_children.Add(new CullingTreeNode(topLeft, depth - 1));    m_children.Add(new CullingTreeNode(bottomRight, depth - 1));    m_children.Add(new CullingTreeNode(topRight, depth - 1));    m_children.Add(new CullingTreeNode(bottomLeft, depth - 1));    m_children.Add(new CullingTreeNode(topLeft2, depth - 1));    m_children.Add(new CullingTreeNode(bottomRight2, depth - 1));    m_children.Add(new CullingTreeNode(topRight2, depth - 1));    m_children.Add(new CullingTreeNode(bottomLeft2, depth - 1));}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">%<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">topLeftSingle<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">bottomRightSingle<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">topRightSingle<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">bottomLeftSingle<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">topLeft<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">bottomRight<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">topRight<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">bottomLeft<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">topLeft2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">bottomRight2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">topRight2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">bottomLeft2<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">depth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-66.png\" alt=\"\" class=\"wp-image-186 lazyload\"\/><noscript><img decoding=\"async\" width=\"1734\" height=\"468\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-66.png\" alt=\"\" class=\"wp-image-186 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-66.png 1734w, https:\/\/remoooo.com\/wp-content\/uploads\/image-66-300x81.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-66-1024x276.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-66-768x207.png 768w, https:\/\/remoooo.com\/wp-content\/uploads\/image-66-1536x415.png 1536w\" sizes=\"(max-width: 1734px) 100vw, 1734px\" \/><\/noscript><\/figure>\n\n\n\n<p>The detection of the view frustum and AABB can be done with GeometryUtility.TestPlanesAABB.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"public void RetrieveLeaves(Plane[] frustum, List<Bounds&gt; list, List<int&gt; visibleIDList){    if (GeometryUtility.TestPlanesAABB(frustum, m_bounds))    {        if (m_children.Count == 0)        {            if (grassIDHeld.Count &gt; 0)            {                list.Add(m_bounds);                visibleIDList.AddRange(grassIDHeld);            }        }        else        {            foreach (CullingTreeNode child in m_children)            {                child.RetrieveLeaves(frustum, list, visibleIDList);            }        }    }}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">RetrieveLeaves<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">Plane<\/span><span style=\"color: #D8DEE9FF\">[] <\/span><span style=\"color: #D8DEE9\">frustum<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">List<\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9\">Bounds<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">list<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">List<\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">visibleIDList<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">GeometryUtility<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">TestPlanesAABB<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">frustum<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_bounds<\/span><span style=\"color: #D8DEE9FF\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Count<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">grassIDHeld<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Count<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #D8DEE9\">list<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Add<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">m_bounds<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #D8DEE9\">visibleIDList<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">AddRange<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">grassIDHeld<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #88C0D0\">foreach<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">CullingTreeNode<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">child<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">in<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_children<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #D8DEE9\">child<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">RetrieveLeaves<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">frustum<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">list<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">visibleIDList<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>This code is the key part, passing in:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The six planes of the camera frustum Plane[]<\/li>\n\n\n\n<li>A list of Bounds objects storing all nodes within the frustum<\/li>\n\n\n\n<li>Stores a list of all grass indices contained in the node within the frustum<\/li>\n<\/ul>\n\n\n\n<p>By calling the method of this quad\/octree, you can get the list of all bounding boxes and grass within the frustum.<\/p>\n\n\n\n<p>Then all the grass indexes can be made into a Buffer and passed to the Compute Shader.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"m_VisibleIDBuffer.SetData(grassVisibleIDList);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">m_VisibleIDBuffer<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetData<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">grassVisibleIDList<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>To get a visual AABB, use the OnDrawGizmos() method.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-69.png\" alt=\"\" class=\"wp-image-189 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"706\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-69.png\" alt=\"\" class=\"wp-image-189 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-69.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-69-300x147.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-69-1024x502.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-69-768x377.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>Pass all the AABBs obtained by culling the view frustum into this function. This way you can see the AABBs intuitively.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-70.png\" alt=\"\" class=\"wp-image-190 lazyload\"\/><noscript><img decoding=\"async\" width=\"916\" height=\"410\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-70.png\" alt=\"\" class=\"wp-image-190 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-70.png 916w, https:\/\/remoooo.com\/wp-content\/uploads\/image-70-300x134.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-70-768x344.png 768w\" sizes=\"(max-width: 916px) 100vw, 916px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-72.png\" alt=\"\" class=\"wp-image-192 lazyload\"\/><noscript><img decoding=\"async\" width=\"1082\" height=\"518\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-72.png\" alt=\"\" class=\"wp-image-192 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-72.png 1082w, https:\/\/remoooo.com\/wp-content\/uploads\/image-72-300x144.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-72-1024x490.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-72-768x368.png 768w\" sizes=\"(max-width: 1082px) 100vw, 1082px\" \/><\/noscript><\/figure>\n\n\n\n<p>Also write everything inside the view frustum to the visible grass.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-74.png\" alt=\"\" class=\"wp-image-194 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"914\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-74.png\" alt=\"\" class=\"wp-image-194 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-74.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-74-300x190.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-74-1024x650.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-74-768x487.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">5.9 Flickering grass problem \u2013 Pitfalls<\/h3>\n\n\n\n<p>Here I hit a small pit. I completed the octree and successfully divided many sub-AABBs as shown above. But when I moved the camera, the grass flickered wildly. I was a little lazy and didn&#039;t want to make GIF videos. Observe the two pictures below. I just moved the view slightly and changed the current Visibility List. The position of the grass jumped a lot, and it looked like the grass flickered continuously.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-75.png\" alt=\"\" class=\"wp-image-195 lazyload\"\/><noscript><img decoding=\"async\" width=\"1380\" height=\"690\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-75.png\" alt=\"\" class=\"wp-image-195 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-75.png 1380w, https:\/\/remoooo.com\/wp-content\/uploads\/image-75-300x150.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-75-1024x512.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-75-768x384.png 768w\" sizes=\"(max-width: 1380px) 100vw, 1380px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-71.png\" alt=\"\" class=\"wp-image-191 lazyload\"\/><noscript><img decoding=\"async\" width=\"1392\" height=\"676\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-71.png\" alt=\"\" class=\"wp-image-191 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-71.png 1392w, https:\/\/remoooo.com\/wp-content\/uploads\/image-71-300x146.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-71-1024x497.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-71-768x373.png 768w\" sizes=\"(max-width: 1392px) 100vw, 1392px\" \/><\/noscript><\/figure>\n\n\n\n<p>I can&#039;t figure it out, there is no problem with Compute Shader culling.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-73.png\" alt=\"\" class=\"wp-image-193 lazyload\"\/><noscript><img decoding=\"async\" width=\"1002\" height=\"550\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-73.png\" alt=\"\" class=\"wp-image-193 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-73.png 1002w, https:\/\/remoooo.com\/wp-content\/uploads\/image-73-300x165.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-73-768x422.png 768w\" sizes=\"(max-width: 1002px) 100vw, 1002px\" \/><\/noscript><\/figure>\n\n\n\n<p>The number of dispatches is also calculated based on the length of the visibility list, so there must be enough threads to compute the shader.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-76.png\" alt=\"\" class=\"wp-image-196 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"247\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-76.png\" alt=\"\" class=\"wp-image-196 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-76.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-76-300x51.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-76-1024x176.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-76-768x132.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>And there is no problem with DrawMeshInstancedIndirect.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-77.png\" alt=\"\" class=\"wp-image-197 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"383\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-77.png\" alt=\"\" class=\"wp-image-197 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-77.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-77-300x80.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-77-1024x272.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-77-768x204.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>What&#039;s the problem?<\/p>\n\n\n\n<p>After a long debugging, I found that the problem lies in the process of taking random numbers by Xorshift of Compute Shader.<\/p>\n\n\n\n<p>Before using _VisibleIDBuffer, one grass corresponds to one thread ID, which is determined from the moment the grass is born. Now that this group of indexes has been added, and the ID of the incoming random value is not changed to a Visible ID, the random numbers will appear very discrete.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-78.png\" alt=\"\" class=\"wp-image-198 lazyload\"\/><noscript><img decoding=\"async\" width=\"1162\" height=\"134\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-78.png\" alt=\"\" class=\"wp-image-198 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-78.png 1162w, https:\/\/remoooo.com\/wp-content\/uploads\/image-78-300x35.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-78-1024x118.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-78-768x89.png 768w\" sizes=\"(max-width: 1162px) 100vw, 1162px\" \/><\/noscript><\/figure>\n\n\n\n<p>That is to say, all previous IDs are replaced with index values taken from _VisibleIDBuffer!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-81.png\" alt=\"\" class=\"wp-image-201 lazyload\"\/><noscript><img decoding=\"async\" width=\"1404\" height=\"198\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-81.png\" alt=\"\" class=\"wp-image-201 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-81.png 1404w, https:\/\/remoooo.com\/wp-content\/uploads\/image-81-300x42.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-81-1024x144.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-81-768x108.png 768w\" sizes=\"(max-width: 1404px) 100vw, 1404px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">5.10 Multi-object Interaction<\/h3>\n\n\n\n<p>Currently there is only one trampler passed in. If it is not passed in, an error will be reported, which is unbearable.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-79.png\" alt=\"\" class=\"wp-image-199 lazyload\"\/><noscript><img decoding=\"async\" width=\"928\" height=\"202\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-79.png\" alt=\"\" class=\"wp-image-199 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-79.png 928w, https:\/\/remoooo.com\/wp-content\/uploads\/image-79-300x65.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-79-768x167.png 768w\" sizes=\"(max-width: 928px) 100vw, 928px\" \/><\/noscript><\/figure>\n\n\n\n<p>There are three parameters about interaction:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pos \u2013 Vector3<\/li>\n\n\n\n<li>trampleStrength \u2013 Float<\/li>\n\n\n\n<li>trampleRadius \u2013 Float<\/li>\n<\/ul>\n\n\n\n<p>Now put trampleRadius into pos (Vector4) (or another one, depending on your needs), and pass the position array into it using SetVectorArray. This way each interactive object can have a dedicated interactive radius. For fat interactive objects, make the radius larger, and for skinny ones, make it smaller. That is, remove the following line:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ SetGrassDataBase\u4e2d\uff0c\u4e0d\u9700\u8981\u6bcf\u5e27\u4e0a\u4f20\/\/ m_ComputeShader.SetFloat(&quot;trampleRadius&quot;, trampleRadius);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ In SetGrassDataBase, no need to upload every frame<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ m_ComputeShader.SetFloat(&quot;trampleRadius&quot;, trampleRadius);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>become:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ SetGrassDataUpdate\u4e2d\uff0c\u6bcf\u5e27\u90fd\u8981\u4e0a\u4f20\/\/ \u8bbe\u7f6e\u591a\u4ea4\u4e92\u7269\u4f53if (trampler.Length &gt; 0){    Vector4[] positions = new Vector4[trampler.Length];    for (int i = 0; i < trampler.Length; i++)    {        positions[i] = new Vector4(trampler[i].transform.position.x, trampler[i].transform.position.y, trampler[i].transform.position.z,            trampleRadius);    }    m_ComputeShader.SetVectorArray(ID_tramplePos, positions);}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ In SetGrassDataUpdate, each frame must be uploaded<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ Set up multiple interactive objects<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">trampler<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Length<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">Vector4<\/span><span style=\"color: #D8DEE9FF\">[] <\/span><span style=\"color: #D8DEE9\">positions<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Vector4<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">trampler<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Length<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">for<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampler<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Length<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #81A1C1\">++<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">positions<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">Vector4<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">trampler<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampler<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampler<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">z<\/span><span style=\"color: #ECEFF4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">trampleRadius<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_ComputeShader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetVectorArray<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">ID_tramplePos<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">positions<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Then you have to pass the number of interactive objects so that the Compute Shader knows how many interactive objects need to be processed. This also needs to be updated every frame. I am used to storing an ID index for objects that are updated every frame, which is more efficient.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ \u521d\u59cb\u5316\u4e2dID_trampleLength = Shader.PropertyToID(&quot;_trampleLength&quot;);\/\/ \u6bcf\u5e27\u4e2dm_ComputeShader.SetFloat(ID_trampleLength, trampler.Length);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Initializing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">ID_trampleLength<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Shader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">PropertyToID<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">_trampleLength<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ In each frame<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_ComputeShader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetFloat<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">ID_trampleLength<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampler<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Length<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>I repackaged it:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-82.png\" alt=\"\" class=\"wp-image-202 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"620\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-82.png\" alt=\"\" class=\"wp-image-202 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-82.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-82-300x129.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-82-1024x441.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-82-768x331.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-80.png\" alt=\"\" class=\"wp-image-200 lazyload\"\/><noscript><img decoding=\"async\" width=\"1114\" height=\"174\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-80.png\" alt=\"\" class=\"wp-image-200 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-80.png 1114w, https:\/\/remoooo.com\/wp-content\/uploads\/image-80-300x47.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-80-1024x160.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-80-768x120.png 768w\" sizes=\"(max-width: 1114px) 100vw, 1114px\" \/><\/noscript><\/figure>\n\n\n\n<p>By modifying the corresponding code, you can adjust the radius of each interactive object on the panel. If you want to enrich this adjustment function, you can consider passing a separate Buffer into it.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-85.png\" alt=\"\" class=\"wp-image-205 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"605\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-85.png\" alt=\"\" class=\"wp-image-205 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-85.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-85-300x126.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-85-1024x430.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-85-768x323.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<p>In the Compute Shader, it is relatively simple to combine multiple rotations.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Tramplerfloat4 qt = float4(0, 0, 0, 1); \/\/ \u56db\u5143\u6570\u91cc\u76841\u5c31\u662f\u8fd9\u6837\u7684\uff0c\u865a\u90e8\u90fd\u662f0for (int trampleIndex = 0; trampleIndex < trampleLength; trampleIndex++){    float trampleRadius = tramplePos[trampleIndex].a;    float3 relativePosition = input.position - tramplePos[trampleIndex].xyz;    float dist = length(relativePosition);    if (dist < trampleRadius) {        \/\/ \u4f7f\u7528\u6b21\u65b9\u589e\u5f3a\u8fd1\u8ddd\u79bb\u7684\u6548\u679c        float eff = pow((trampleRadius - dist) \/ trampleRadius, 2) * trampleStrength;        float3 direction = normalize(relativePosition);        float3 newTargetDirection = float3(direction.x * eff, 1, direction.z * eff);        qt = quatMultiply(MapVector(float3(0, 1, 0), newTargetDirection), qt);    }}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Trampler<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float4<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">qt<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float4<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ 1 in quaternion is like this, the imaginary part is 0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">for<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleIndex<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleIndex<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleLength<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleIndex<\/span><span style=\"color: #81A1C1\">++<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleRadius<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">tramplePos<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">trampleIndex<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">a<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">relativePosition<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">input<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">tramplePos<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">trampleIndex<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">xyz<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">dist<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">length<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">relativePosition<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">dist<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleRadius<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">        <\/span><span style=\"color: #616E88\">\/\/ Use the power to enhance the effect at close range<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">eff<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">pow<\/span><span style=\"color: #D8DEE9FF\">((<\/span><span style=\"color: #D8DEE9\">trampleRadius<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">dist<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleRadius<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #D8DEE9FF\">) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">trampleStrength<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">direction<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">normalize<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">relativePosition<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">newTargetDirection<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">float3<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">direction<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">x<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">eff<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">direction<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">z<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">eff<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">qt<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">quatMultiply<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">MapVector<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #88C0D0\">float3<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">newTargetDirection<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">qt<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-86.png\" alt=\"\" class=\"wp-image-206 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"943\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-86.png\" alt=\"\" class=\"wp-image-206 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-86.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-86-300x196.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-86-1024x671.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-86-768x503.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">5.11 Editor real-time preview<\/h3>\n\n\n\n<p>The camera currently passed to the Compute Shader is the main camera, which is the one in the game window. Now you want to temporarily get the main camera&#039;s lens in the editor (Scene window) and restore it after starting the game. You can use the Scene View GUI to draw events.<\/p>\n\n\n\n<p>Here is an example of remodeling my current code:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"#if UNITY_EDITOR    SceneView view;    void OnDestroy()    {        \/\/ When the window is destroyed, remove the delegate        \/\/ so that it will no longer do any drawing.        SceneView.duringSceneGui -= this.OnScene;    }    void OnScene(SceneView scene)    {        view = scene;        if (!Application.isPlaying)        {            if (view.camera != null)            {                m_MainCamera = view.camera;            }        }        else        {            m_MainCamera = Camera.main;        }    }    private void OnValidate()    {        \/\/ Set up components        if (!Application.isPlaying)        {            if (view != null)            {                m_MainCamera = view.camera;            }        }        else        {            m_MainCamera = Camera.main;        }    }#endif\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">UNITY_EDITOR<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">SceneView<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">OnDestroy<\/span><span style=\"color: #D8DEE9FF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">        <\/span><span style=\"color: #616E88\">\/\/ When the window is destroyed, remove the delegate<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">        <\/span><span style=\"color: #616E88\">\/\/ so that it will no longer do any drawing.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">SceneView<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">duringSceneGui<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">this<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">OnScene<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">OnScene<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">SceneView<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">scene<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">scene<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #81A1C1\">!<\/span><span style=\"color: #D8DEE9\">Application<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">isPlaying<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">camera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">camera<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Camera<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">main<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">OnValidate<\/span><span style=\"color: #D8DEE9FF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">        <\/span><span style=\"color: #616E88\">\/\/ Set up components<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #81A1C1\">!<\/span><span style=\"color: #D8DEE9\">Application<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">isPlaying<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">camera<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Camera<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">main<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #D8DEE9\">endif<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>When initializing the shader, subscribe to the event at the beginning, and then determine whether the current state is game, and then pass a camera. If it is in edit mode, then m_MainCamera is still NULL.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"void InitShader(){#if UNITY_EDITOR    SceneView.duringSceneGui += this.OnScene;    if (!Application.isPlaying)    {        if (view != null &amp;&amp; view.camera != null)        {            m_MainCamera = view.camera;        }    }#endif    if (Application.isPlaying)    {        m_MainCamera = Camera.main;    }    ...\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">InitShader<\/span><span style=\"color: #D8DEE9FF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">UNITY_EDITOR<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">SceneView<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">duringSceneGui<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">this<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">OnScene<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #81A1C1\">!<\/span><span style=\"color: #D8DEE9\">Application<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">isPlaying<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&amp;&amp;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">camera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">camera<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #D8DEE9\">endif<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">Application<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">isPlaying<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Camera<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">main<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">...<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>In the frame-by-frame Update function, if it is detected that m_MainCamera is NULL, it is determined that the current mode is edit mode:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ \u4f20\u5165\u6444\u50cf\u673a\u5750\u6807        if (m_MainCamera != null)            m_ComputeShader.SetVector(ID_camreaPos, m_MainCamera.transform.position);#if UNITY_EDITOR        else if (view != null &amp;&amp; view.camera != null)        {            m_ComputeShader.SetVector(ID_camreaPos, view.camera.transform.position);        }#endif\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ Pass in the camera coordinates<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">m_ComputeShader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetVector<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">ID_camreaPos<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_MainCamera<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">UNITY_EDITOR<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">else<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&amp;&amp;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">camera<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">m_ComputeShader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetVector<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">ID_camreaPos<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">view<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">camera<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">#<\/span><span style=\"color: #D8DEE9\">endif<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-87.png\" alt=\"\" class=\"wp-image-207 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"966\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-87.png\" alt=\"\" class=\"wp-image-207 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-87.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-87-300x201.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-87-1024x687.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-87-768x515.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">6. Cutting Grass<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-84.png\" alt=\"\" class=\"wp-image-204 lazyload\"\/><noscript><img decoding=\"async\" width=\"1006\" height=\"554\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-84.png\" alt=\"\" class=\"wp-image-204 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-84.png 1006w, https:\/\/remoooo.com\/wp-content\/uploads\/image-84-300x165.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-84-768x423.png 768w\" sizes=\"(max-width: 1006px) 100vw, 1006px\" \/><\/noscript><\/figure>\n\n\n\n<p>Maintain a set of Cut Buffers<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ added for cuttingprivate ComputeBuffer m_CutBuffer;float[] cutIDs;\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ added for cutting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">ComputeBuffer<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_CutBuffer<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\">[] <\/span><span style=\"color: #D8DEE9\">cutIDs<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Initializing Buffer<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"private const int CUT_ID_STRIDE            =  1 * sizeof(float);\/\/ added for cuttingm_CutBuffer = new ComputeBuffer(grassData.Count, CUT_ID_STRIDE, ComputeBufferType.Structured);\/\/ added for cuttingm_ComputeShader.SetBuffer(m_ID_GrassKernel, &quot;_CutBuffer&quot;, m_CutBuffer);m_CutBuffer.SetData(cutIDs);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> CUT_ID_STRIDE            <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\">  <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">sizeof<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ added for cutting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_CutBuffer<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">ComputeBuffer<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">grassData<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Count<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">CUT_ID_STRIDE<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">ComputeBufferType<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Structured<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #616E88\">\/\/ added for cutting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_ComputeShader<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetBuffer<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">m_ID_GrassKernel<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">_CutBuffer<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">m_CutBuffer<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_CutBuffer<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetData<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">cutIDs<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Don&#039;t forget to release it when you disable it.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ added for cuttingm_CutBuffer?.Release();\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ added for cutting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">m_CutBuffer<\/span><span style=\"color: #ECEFF4\">?.<\/span><span style=\"color: #88C0D0\">Release<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Define a method to pass in the current position and radius to calculate the position of the grass. Set the corresponding cutID to -1.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ newly added for cuttingpublic void UpdateCutBuffer(Vector3 hitPoint, float radius){    \/\/ can't cut grass if there is no grass in the scene    if (grassData.Count &gt; 0)    {        List<int&gt; grasslist = new List<int&gt;();        \/\/ Get the list of IDS that are near the hitpoint within the radius        cullingTree.ReturnLeafList(hitPoint, grasslist, radius);        Vector3 brushPosition = this.transform.position;        \/\/ Compute the squared radius to avoid square root calculations        float squaredRadius = radius * radius;        for (int i = 0; i < grasslist.Count; i++)        {            int currentIndex = grasslist[i];            Vector3 grassPosition = grassData[currentIndex].position + brushPosition;            \/\/ Calculate the squared distance            float squaredDistance = (hitPoint - grassPosition).sqrMagnitude;            \/\/ Check if the squared distance is within the squared radius            \/\/ Check if there is grass to cut, or of the grass is uncut(-1)            if (squaredDistance <= squaredRadius &amp;&amp; (cutIDs[currentIndex] &gt; hitPoint.y || cutIDs[currentIndex] == -1))            {                \/\/ store cutting point                cutIDs[currentIndex] = hitPoint.y;            }        }    }    m_CutBuffer.SetData(cutIDs);}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #616E88\">\/\/ newly added for cutting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">UpdateCutBuffer<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">Vector3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">hitPoint<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radius<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">    <\/span><span style=\"color: #616E88\">\/\/ can&#039;t cut grass if there is no grass in the scene<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">grassData<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Count<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">List<\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grasslist<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">List<\/span><span style=\"color: #ECEFF4\">&lt;<\/span><span style=\"color: #D8DEE9FF\">int<\/span><span style=\"color: #ECEFF4\">&gt;<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">        <\/span><span style=\"color: #616E88\">\/\/ Get the list of IDS that are near the hitpoint within the radius<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">cullingTree<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">ReturnLeafList<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">hitPoint<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grasslist<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radius<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">Vector3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">brushPosition<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">this<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">        <\/span><span style=\"color: #616E88\">\/\/ Compute the squared radius to avoid square root calculations<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">squaredRadius<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radius<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radius<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">for<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grasslist<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Count<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #81A1C1\">++<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">int<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">currentIndex<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grasslist<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">i<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">Vector3<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grassPosition<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grassData<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">currentIndex<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">brushPosition<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">            <\/span><span style=\"color: #616E88\">\/\/ Calculate the squared distance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">squaredDistance<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">hitPoint<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">grassPosition<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">sqrMagnitude<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">            <\/span><span style=\"color: #616E88\">\/\/ Check if the squared distance is within the squared radius<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">            <\/span><span style=\"color: #616E88\">\/\/ Check if there is grass to cut, or of the grass is uncut(-1)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">squaredDistance<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&lt;=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">squaredRadius<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&amp;&amp;<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">cutIDs<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">currentIndex<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">hitPoint<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">||<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">cutIDs<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">currentIndex<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">                <\/span><span style=\"color: #616E88\">\/\/ store cutting point<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #D8DEE9\">cutIDs<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">currentIndex<\/span><span style=\"color: #D8DEE9FF\">] <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">hitPoint<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">y<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">m_CutBuffer<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">SetData<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">cutIDs<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Then bind a script to the object that needs to be cut:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"using System.Collections;using System.Collections.Generic;using UnityEngine;public class Cutgrass : MonoBehaviour{    [SerializeField]    GrassControl grassComputeScript;    [SerializeField]    float radius = 1f;    public bool updateCuts;    Vector3 cachedPos;    \/\/ Start is called before the first frame update    \/\/ Update is called once per frame    void Update()    {        if (updateCuts &amp;&amp; transform.position != cachedPos)        {            Debug.Log(&quot;Cutting&quot;);            grassComputeScript.UpdateCutBuffer(transform.position, radius);            cachedPos = transform.position;        }    }    private void OnDrawGizmos()    {        Gizmos.color = new Color(1, 0, 0, 0.3f);        Gizmos.DrawWireSphere(transform.position, radius);    }}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">using<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">System<\/span><span style=\"color: #D8DEE9FF\">.Collections<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">using<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">System<\/span><span style=\"color: #D8DEE9FF\">.Collections.Generic<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">using<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">UnityEngine<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">class<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #8FBCBB\">Cutgrass<\/span><span style=\"color: #D8DEE9FF\"> : <\/span><span style=\"color: #8FBCBB\">MonoBehaviour<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    [<\/span><span style=\"color: #D8DEE9\">SerializeField<\/span><span style=\"color: #D8DEE9FF\">]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">GrassControl<\/span><span style=\"color: #D8DEE9FF\"> grassComputeScript<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    [<\/span><span style=\"color: #D8DEE9\">SerializeField<\/span><span style=\"color: #D8DEE9FF\">]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> radius <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> 1<\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">bool<\/span><span style=\"color: #D8DEE9FF\"> updateCuts<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">Vector3<\/span><span style=\"color: #D8DEE9FF\"> cachedPos<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">    <\/span><span style=\"color: #616E88\">\/\/ Start is called before the first frame update<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">    <\/span><span style=\"color: #616E88\">\/\/ Update is called once per frame<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">Update<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">updateCuts<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&amp;&amp;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">cachedPos<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">Debug<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Log<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Cutting<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">grassComputeScript<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">UpdateCutBuffer<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radius<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">cachedPos<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">OnDrawGizmos<\/span><span style=\"color: #ECEFF4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">Gizmos<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">color<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">Color<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> 0<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">3<\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">Gizmos<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">DrawWireSphere<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">transform<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">position<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">radius<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>In the Compute Shader, just modify the grass height. (Very straightforward...) You can change the effect to whatever you want.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewbox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"StructuredBuffer<float&gt; _CutBuffer;\/\/ added for cutting    float cut = _CutBuffer[usableID];    result.height = (bladeHeight + bladeHeightOffset * (xorshift128()*2-1)) * distanceFade;    if(cut != -1){        result.height *= 0.1f;    }\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewbox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">StructuredBuffer<\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_CutBuffer<\/span><span style=\"color: #81A1C1\">;<\/span><span style=\"color: #616E88\">\/\/ added for cutting<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">float<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">cut<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_CutBuffer<\/span><span style=\"color: #D8DEE9FF\">[<\/span><span style=\"color: #D8DEE9\">usableID<\/span><span style=\"color: #D8DEE9FF\">]<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">Result<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">height<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #D8DEE9\">bladeHeight<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">bladeHeightOffset<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> (<\/span><span style=\"color: #88C0D0\">xorshift128<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #B48EAD\">2<\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">)) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">distanceFade<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #D8DEE9\">cut<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">!=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\">)<\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">Result<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">height<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*=<\/span><span style=\"color: #D8DEE9FF\"> 0<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9FF\">1<\/span><span style=\"color: #D8DEE9\">f<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Done!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-83.png\" alt=\"\" class=\"wp-image-203 lazyload\"\/><noscript><img decoding=\"async\" width=\"1440\" height=\"494\" src=\"https:\/\/\u80a5\u80a5.com\/wp-content\/uploads\/image-83.png\" alt=\"\" class=\"wp-image-203 lazyload\" srcset=\"https:\/\/remoooo.com\/wp-content\/uploads\/image-83.png 1440w, https:\/\/remoooo.com\/wp-content\/uploads\/image-83-300x103.png 300w, https:\/\/remoooo.com\/wp-content\/uploads\/image-83-1024x351.png 1024w, https:\/\/remoooo.com\/wp-content\/uploads\/image-83-768x263.png 768w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/noscript><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">References<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/zh-cn\/windows\/uwp\/graphics-concepts\/geometry-shader-stage--gs-\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/learn.microsoft.com\/zh-cn\/windows\/uwp\/graphics-concepts\/geometry-shader-stage&#8211;gs-<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/roystan.net\/articles\/grass-shader\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/roystan.net\/articles\/grass-shader\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/roystan.net\/articles\/grass-shader\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/danielilett.com\/2021-08-24-tut5-17-stylised-grass\/<\/a><\/li>\n\n\n\n<li>https:\/\/catlikecoding.com\/unity\/tutorials\/basics\/compute-shaders\/<\/li>\n\n\n\n<li><a href=\"https:\/\/medium.com\/ericzhan-publication\/shader%E7%AD%86%E8%A8%98-%E5%88%9D%E6%8E%A2compute-shader-9efeebd579c1\" target=\"_blank\" rel=\"noreferrer noopener\">Notes - A preliminary exploration of compute-shader<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.patreon.com\/posts\/53587750\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/53587750<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=xKJHL8nQiuM\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.youtube.com\/watch?v=xKJHL8nQiuM<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.patreon.com\/posts\/40090373\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/40090373<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.patreon.com\/posts\/47447321\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/47447321<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.patreon.com\/posts\/wip-patron-only-83683483\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.patreon.com\/posts\/wip-patron-only-83683483<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=DeATXF4Szqo\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.youtube.com\/watch?v=DeATXF4Szqo<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/catlikecoding.com\/unity\/tutorials\/basics\/compute-shaders\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/catlikecoding.com\/unity\/tutorials\/basics\/compute-shaders\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.unity3d.com\/Manual\/class-ComputeShader.html\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/docs.unity3d.com\/Manual\/class-ComputeShader.html<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/ComputeShader.html\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/docs.unity3d.com\/ScriptReference\/ComputeShader.html<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/D3D11\/nf-d3d11-id3d11devicecontext-dispatch\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/D3D11\/nf-d3d11-id3d11devicecontext-dispatch<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/102104374\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/zhuanlan.zhihu.com\/p\/102104374<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.com\/@sengallery\/unity-compute-shader-%E5%9F%BA%E7%A4%8E%E8%AA%8D%E8%AD%98-5a99df53cea1\" target=\"_blank\" rel=\"noreferrer noopener\">Unity-compute-shader-Basic knowledge<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/kylehalladay.com\/blog\/tutorial\/2014\/06\/27\/Compute-Shaders-Are-Nifty.html\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/kylehalladay.com\/blog\/tutorial\/2014\/06\/27\/Compute-Shaders-Are-Nifty.html<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cuihongzhi1991.github.io\/blog\/2020\/05\/27\/builtinttourp\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/cuihongzhi1991.github.io\/blog\/2020\/05\/27\/builtinttourp\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/jadkhoury.github.io\/files\/MasterThesisFinal.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/jadkhoury.github.io\/files\/MasterThesisFinal.pdf<\/a><\/li>\n<\/ol>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>\u9879\u76ee\uff08BIRP\uff09\u5728Github\uff1a https:\/\/github.com\/Remyuu\/Unity-Intera [&hellip;]<\/p>","protected":false},"author":1,"featured_media":123,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53],"tags":[21,14,37],"class_list":["post-117","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech","tag-gpu-instancing","tag-shader","tag-unity"],"_links":{"self":[{"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/posts\/117","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/comments?post=117"}],"version-history":[{"count":21,"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/posts\/117\/revisions"}],"predecessor-version":[{"id":1880,"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/posts\/117\/revisions\/1880"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/media\/123"}],"wp:attachment":[{"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/media?parent=117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/categories?post=117"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/remoooo.com\/en\/wp-json\/wp\/v2\/tags?post=117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}