forked from cgvr/DeltaVR
Initial Commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
#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);
|
||||
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user