146 lines
4.5 KiB
Plaintext
146 lines
4.5 KiB
Plaintext
#pragma kernel CSCullIndividual
|
|
#pragma kernel CSCullCell
|
|
|
|
struct GrassElement {
|
|
float3 position;
|
|
float rotation;
|
|
float size;
|
|
float colorBlend;//0-1
|
|
};
|
|
|
|
struct grassCell {
|
|
uint grassElementIndexes[512];//map to grass elements
|
|
};
|
|
|
|
//struct grassOcclusionCell {
|
|
// uint grassCellIndex;
|
|
// uint visibleCellIndexes[2048];//Map to occlusion cells
|
|
// };
|
|
|
|
//General
|
|
uint grassCount;
|
|
float2 distanceBounts;//Start, end
|
|
Texture2D<float4> ditherTex;
|
|
int ditherTexSizeX;
|
|
float ditherSize;
|
|
|
|
//Input
|
|
StructuredBuffer<GrassElement> grassBuffer;
|
|
|
|
//Frustrum culling
|
|
float3 cameraPos;
|
|
float4x3 cameraFrustumNormals;
|
|
|
|
//settings
|
|
int doOcclusion;
|
|
|
|
//Cells
|
|
uint grassCellCount;
|
|
uint grassCellSize;
|
|
StructuredBuffer<grassCell> grassCellBuffer;
|
|
|
|
//Occlusion culling
|
|
//StructuredBuffer<grassOcclusionCell> grassOcclusionBuffer;
|
|
|
|
//Output
|
|
AppendStructuredBuffer<uint> outGrassBuffer;
|
|
AppendStructuredBuffer<uint> outCellIndexBuffer;
|
|
|
|
bool Is3DDither (float dist, float2 pos) {
|
|
float distAmount = 1 - (dist-distanceBounts.x)/(distanceBounts.y-distanceBounts.x);//0-1
|
|
float2 relativePos = pos/ditherSize;
|
|
float2 positivePos = float2(relativePos.x*sign(relativePos.x),relativePos.y*sign(relativePos.y));
|
|
float2 repeatingPos = float2(fmod(positivePos.x,ditherTexSizeX),fmod(positivePos.y,ditherTexSizeX));
|
|
float dit = ditherTex[repeatingPos].x;
|
|
return distAmount - dit > 0;
|
|
}
|
|
|
|
[numthreads(16,16,4)]
|
|
void CSCullIndividual (uint index : SV_GroupIndex, uint3 group : SV_GroupID) {//This only does frustrum culling
|
|
//1. get index
|
|
uint realIndex = index + 1024 * group.x;//id.x + id.y group.x + id.z group.x * group.y
|
|
|
|
//2. index valid?
|
|
if(realIndex < grassCount) {
|
|
GrassElement data = grassBuffer[realIndex];
|
|
float3 pos = data.position;
|
|
|
|
float3 posFromCamera = pos - cameraPos;
|
|
float scale = data.size;
|
|
|
|
//3. frustrum culling
|
|
if( (dot(cameraFrustumNormals[0], posFromCamera) > -scale) &&
|
|
(dot(cameraFrustumNormals[1], posFromCamera) > -scale) &&
|
|
(dot(cameraFrustumNormals[2], posFromCamera) > -scale) &&
|
|
(dot(cameraFrustumNormals[3], posFromCamera) > -scale) ){
|
|
//3D dither culling (includes dist culling)
|
|
float dist = length(posFromCamera);
|
|
if(Is3DDither(dist,pos.xz)) {
|
|
outGrassBuffer.Append(realIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[numthreads(8,8,1)]
|
|
void CSCullCell (uint index : SV_GroupIndex, uint3 group : SV_GroupID) {//This does frustrum and occlusion culling on cells
|
|
//1. get index
|
|
uint realIndex = index + 8*8*group.x;
|
|
//2. index valid?
|
|
|
|
if(realIndex < grassCellCount) {
|
|
//outGrassBuffer.Append(realIndex);
|
|
//outCellIndexBuffer.Append(realIndex);
|
|
grassCell cell = grassCellBuffer[realIndex];
|
|
|
|
//for(int i=0;i<512;i++) {
|
|
// int k = cell.grassElementIndexes[i];
|
|
// if(k != 0)outGrassBuffer.Append(k);
|
|
// }
|
|
|
|
//Doing frustrum check with ranodom element from cell
|
|
float3 pos = grassBuffer[cell.grassElementIndexes[0]].position;
|
|
|
|
float3 posFromCamera = pos - cameraPos;
|
|
float scale = grassCellSize;
|
|
|
|
//3. frustrum culling
|
|
if( (dot(cameraFrustumNormals[0], posFromCamera) > -scale) &&
|
|
(dot(cameraFrustumNormals[1], posFromCamera) > -scale) &&
|
|
(dot(cameraFrustumNormals[2], posFromCamera) > -scale) &&
|
|
(dot(cameraFrustumNormals[3], posFromCamera) > -scale) ){
|
|
|
|
if(length(posFromCamera) <= distanceBounts.y) {//Dist check
|
|
if(doOcclusion == 1) {
|
|
//TODO see if this chunk is visible from current chunk
|
|
//TODO if yes then append chunk grass indexes
|
|
}
|
|
else {
|
|
outCellIndexBuffer.Append(realIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//group -> thread
|
|
//SV_GroupThreadID = current threads num.xyz
|
|
//SV_GroupIndex = num.x * num.y * num.z;
|
|
//SV_GroupID = current gorup indices
|
|
|
|
|
|
/* This works for some reason
|
|
[numthreads(8,8,8)]
|
|
void Converter (uint callIndex : SV_GroupIndex, uint3 groupID : SV_GroupID) {
|
|
uint realIndex = groupID.x + groupID.y + groupID.z;
|
|
|
|
uint cellIndex = grassCellIndexBuffer[realIndex];
|
|
|
|
grassCell cell = grassCellBuffer[ cellIndex ];
|
|
|
|
int elementIndex = callIndex;//Correct
|
|
uint objIndex = cell.grassElementIndexes[elementIndex];
|
|
if(objIndex != 0) outGrassBuffer.Append(objIndex);
|
|
|
|
}
|
|
*/ |