forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			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);
 | 
						|
    
 | 
						|
    }
 | 
						|
*/ |