GPU Instanced Grass in Unity
For the original post, please go to https://www.yuque.com/qwerasdwww/dfy5xd
Part 4: Optimization Grass with Frustum Culling
Now, the grass will be rendered in the whole plane, but we only need to render it inside the camera.
Since we are working on GPU, we can do the culling in the compute shader.
In the C# script, we declare a new boolean to determine whether to use furstum culling and two Vector3 values for the grass bounding box.
In previous part, we initialize our clumpsBuffer inside InitMaterialParameters().
We need to create another coumput buffer to store the unculled data, and let the previous compute buffer be the buffer that store the instance data after culling.
Now, we are having two compute buffers, so we can take that part out and create a new function called InitDefaultBuffer() to initialize it.
We use a macro "UseFrustumCulling" and disable it when not using frustum culling.
Now we create a function to initialize buffers we need to store the data after culling. The buffer type is AppendBuffer.
We write the grass bounding box data into the compute shader and enable the macro "UseFrustumCulling".
So in the Start() function, if we are not using fustum culling, then we initalize the clumpsBuffer as usual.
If we are using frustum culling, the we use clumpsRawBuffer to store the unculled data, and use clumpsBuffer to store the data after culling.
Now we finish the prepare work in C# script, we shall move on to the compute shader.
First we define the macro at the very beginning.
Now the prepare work is done. Let's start the frustum culling.
We can do the culling in the world space or the clip space
Method 1: In the world space, for each grass instance, determine whether the vertices of grass bounding box is inside the frustum.
Let's first define the function for plane. There are two ways to define a plane. A point and a normal vector or three points.
Now let's get the four vertices of the camera far clipping plane. With camera FOV and aspect of ratio, it is easy to calcualte the position of the four vertices.
Every two adjenct vertices on the far clipping plane and the camera position will form a plane.
We then use point on the far plane and near plane and the camera forward to create the far and near plane.
Now we have the six planes of the frustum, we write them into the compute shader and declare the array inside the compute shader.
Now for every grass instance, we determine whether its bounding box is inside each frustum plane.
Since this appendbuffer is dynamically changed, we need to update the buffer every frame inside the C# script.
No comments:
Post a Comment