Project_WL/Assets/ResWork/Map/ProceduralGrass/Shaders/GrassRenderPrimitivesArgs.c...

92 lines
2.9 KiB
Plaintext

#pragma kernel Main
struct IndirectDrawIndexedArgs {
uint indexCountPerInstance;
uint instanceCount;
uint startIndex;
uint baseVertexIndex;
uint startInstance;
};
RWStructuredBuffer<int> _InstanceTriangles;
RWStructuredBuffer<IndirectDrawIndexedArgs> _IndirectDrawIndexedArgs;
uint grassOriginPointCount;
uint grassBladesPerPoint;
uint grassSegments;
[numthreads(1,1,1)]
void Main (uint id : SV_DispatchThreadID)
{
/* Grass Triangle index generation: (all index are x + grassBladesPerPoint * Index Per Blade)
6 . LastSegment { n*2, n*2+2, n*2 + 1}
/ \
/ \
4 .-----. 5
| /|
| / | N Segment { n*2, n*2 + 3, n*2 + 1 } + { n*2, n*2 + 2, n*2 + 3 }
| / |
| / |
2 .-----. 3
| /|
| / |
| / | Zero Segment: { 0, 3, 1 } + { 0, 2, 3 } (if more than one segment)
| / |
0 .-----. 1
*/
uint indexPerBlade = ((grassSegments-1) * 3 * 2 + 3);
uint indexPerInstance = grassBladesPerPoint * indexPerBlade;
if (id >= indexPerInstance) // No more index to process
{
return;
}
uint bladeIndex = id / indexPerBlade;
uint IndexInsideBlade = id % indexPerBlade;
uint segmentIndex = IndexInsideBlade / 6;
uint IndexInsideSegment = IndexInsideBlade % 6;
uint uniqueIndexPerBlade = grassSegments * 2 + 1 ;
if (segmentIndex == grassSegments-1){ // Last Segment
if (IndexInsideSegment == 0){
_InstanceTriangles[id] = segmentIndex * 2;
}
if (IndexInsideSegment == 1){
_InstanceTriangles[id] = segmentIndex*2 + 2;
}
if (IndexInsideSegment == 2){
_InstanceTriangles[id] = segmentIndex*2 + 1;
}
}
else{
// First triangle
if (IndexInsideSegment == 0){
_InstanceTriangles[id] = segmentIndex * 2;
}
if (IndexInsideSegment == 1){
_InstanceTriangles[id] = segmentIndex*2 + 3;
}
if (IndexInsideSegment == 2){
_InstanceTriangles[id] = segmentIndex*2 + 1;
}
// Second triangle
if (IndexInsideSegment == 3){
_InstanceTriangles[id] = segmentIndex * 2;
}
if (IndexInsideSegment == 4){
_InstanceTriangles[id] = segmentIndex*2 + 2;
}
if (IndexInsideSegment == 5){
_InstanceTriangles[id] = segmentIndex*2 + 3;
}
}
_InstanceTriangles[id] += uniqueIndexPerBlade * bladeIndex;
if (id == 0) {
_IndirectDrawIndexedArgs[0].indexCountPerInstance = indexPerInstance;
_IndirectDrawIndexedArgs[0].instanceCount = grassOriginPointCount;
_IndirectDrawIndexedArgs[0].startIndex = 0; // not used
_IndirectDrawIndexedArgs[0].baseVertexIndex = 0; // not used
_IndirectDrawIndexedArgs[0].startInstance = 0; // not used
}
}