mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 12:46:03 +03:00
135 lines
4.1 KiB
GLSL
135 lines
4.1 KiB
GLSL
#version 460
|
|
|
|
#include "common_shader.glsl"
|
|
|
|
layout (set = 0, binding = 0) uniform UniformFrameData { PerFrameData frameData; };
|
|
layout (set = 0, binding = 1) buffer SSBOLODReadyNodeList { uvec3 data[]; } ssboReadyLodNodeList;
|
|
layout (set = 0, binding = 2) buffer SSBOLODReadyNodeListCount { uint counter; } ssboReadyLodNodeListCounter;
|
|
|
|
layout (set = 0, binding = 3) buffer SSBOPatchCount { uint counter; } ssboPatchCounter;
|
|
|
|
layout (set = 0, binding = 4) buffer SSBOPatchBuffer { TerrainPatch patches[]; } ssboPatchBuffer;
|
|
|
|
layout (set = 0, binding = 5) buffer SSBOIndirectDraws { uint drawCommand[]; };
|
|
layout (set = 0, binding = 6) uniform texture2D lodTexture;
|
|
|
|
#ifdef DRAW_COMMAND_PASS
|
|
|
|
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
|
void main()
|
|
{
|
|
uint patchCount = ssboPatchCounter.counter;
|
|
|
|
drawCommand[0] = 16 * 16 * 3 * 2;
|
|
drawCommand[1] = patchCount;
|
|
drawCommand[2] = 0;
|
|
drawCommand[3] = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef PATCH_CULL_PASS
|
|
|
|
layout (local_size_x = 8, local_size_y = 8) in;
|
|
void main()
|
|
{
|
|
uint wavefrontIndex = gl_WorkGroupID.x;
|
|
if (wavefrontIndex >= ssboReadyLodNodeListCounter.counter)
|
|
{
|
|
return;
|
|
}
|
|
uvec3 lodNode = ssboReadyLodNodeList.data[wavefrontIndex];
|
|
|
|
ivec2 lodTexSize = textureSize(lodTexture, 0).xy;
|
|
|
|
// Generate patch per lane.
|
|
|
|
ivec2 patchInnerPos = ivec2(gl_LocalInvocationID.xy);
|
|
|
|
// Get patch position.
|
|
float tileDim = getTerrainLODSizeFromLOD(lodNode.z);
|
|
float patchDim = tileDim / 8.0;
|
|
|
|
vec2 pos2D = vec2(lodNode.xy) * tileDim;
|
|
|
|
// Patch offset.
|
|
pos2D += vec2(patchInnerPos) * patchDim;
|
|
|
|
// Global offset in 2d.
|
|
pos2D += vec2(frameData.landscape.offsetX, frameData.landscape.offsetY);
|
|
|
|
TerrainPatch patchResult;
|
|
patchResult.position = pos2D;
|
|
patchResult.lod = lodNode.z;
|
|
patchResult.patchCrossLOD = 0;
|
|
|
|
const bool bPatchInEdge = (patchInnerPos.x == 0) || (patchInnerPos.y == 0) || (patchInnerPos.x == 7) || (patchInnerPos.y == 7);
|
|
|
|
// Check cross lod case.
|
|
if(bPatchInEdge)
|
|
{
|
|
const bool bUpCheck = (patchInnerPos.y == 0);
|
|
const bool bDownCheck = (patchInnerPos.y == 7);
|
|
const bool bLeftCheck = (patchInnerPos.x == 0);
|
|
const bool bRightCheck = (patchInnerPos.x == 7);
|
|
|
|
uint level = frameData.landscape.lodCount - lodNode.z - 1;
|
|
|
|
vec2 currentUv = vec2(lodNode.xy) / float(4 * exp2(level));
|
|
|
|
ivec2 currentPos = ivec2(currentUv * lodTexSize + 0.5);
|
|
|
|
int texelSize = int(1.0f / float(4 * exp2(level)) * lodTexSize);
|
|
int currentLod = int(texelFetch(lodTexture, currentPos, 0).x * 255.0f + 0.5f);
|
|
|
|
// NOTE: currentLod - sampleLod > 7 case? I hope it will never happen.
|
|
if(bUpCheck)
|
|
{
|
|
ivec2 samplePos = currentPos + ivec2(0, -1) * texelSize;
|
|
int sampleLod = int(texelFetch(lodTexture, samplePos, 0).x * 255.0f + 0.5f);
|
|
|
|
if(sampleLod < currentLod)
|
|
{
|
|
patchResult.patchCrossLOD |= uint(currentLod - sampleLod) << 0;
|
|
}
|
|
}
|
|
|
|
if(bDownCheck)
|
|
{
|
|
ivec2 samplePos = currentPos + ivec2(0, 1) * texelSize;
|
|
int sampleLod = int(texelFetch(lodTexture, samplePos, 0).x * 255.0f + 0.5f);
|
|
|
|
if(sampleLod < currentLod)
|
|
{
|
|
patchResult.patchCrossLOD |= uint(currentLod - sampleLod) << 8;
|
|
}
|
|
}
|
|
|
|
if(bLeftCheck)
|
|
{
|
|
ivec2 samplePos = currentPos + ivec2(-1, 0) * texelSize;
|
|
int sampleLod = int(texelFetch(lodTexture, samplePos, 0).x * 255.0f + 0.5f);
|
|
|
|
if(sampleLod < currentLod)
|
|
{
|
|
patchResult.patchCrossLOD |= uint(currentLod - sampleLod) << 16;
|
|
}
|
|
}
|
|
|
|
if(bRightCheck)
|
|
{
|
|
ivec2 samplePos = currentPos + ivec2(1, 0) * texelSize;
|
|
int sampleLod = int(texelFetch(lodTexture, samplePos, 0).x * 255.0f + 0.5f);
|
|
|
|
if(sampleLod < currentLod)
|
|
{
|
|
patchResult.patchCrossLOD |= uint(currentLod - sampleLod) << 24;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint indexId = atomicAdd(ssboPatchCounter.counter, 1);
|
|
ssboPatchBuffer.patches[indexId] = patchResult;
|
|
}
|
|
|
|
#endif |