You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
364 lines
11 KiB
Plaintext
364 lines
11 KiB
Plaintext
2 weeks ago
|
/******************************************************************************/
|
||
|
/*
|
||
|
Project - MudBun
|
||
|
Publisher - Long Bunny Labs
|
||
|
http://LongBunnyLabs.com
|
||
|
Author - Ming-Lun "Allen" Chou
|
||
|
http://AllenChou.net
|
||
|
*/
|
||
|
/******************************************************************************/
|
||
|
|
||
|
#pragma kernel generate_flat_marching_cubes_mesh
|
||
|
#pragma kernel generate_smooth_marching_cubes_mesh
|
||
|
#pragma kernel generate_marching_splats
|
||
|
#pragma kernel generate_flat_marching_cubes_mesh_2d
|
||
|
#pragma kernel generate_smooth_marching_cubes_mesh_2d
|
||
|
#pragma kernel generate_marching_splats_2d
|
||
|
#pragma kernel update_marching_cubes_auto_smooth_indirect_dispatch_args
|
||
|
#pragma kernel marching_cubes_update_auto_smooth
|
||
|
#pragma kernel marching_cubes_compute_auto_smooth
|
||
|
|
||
|
// yes I know I'm using a lot of registers
|
||
|
#pragma warning (disable : 4714)
|
||
|
|
||
|
#include "../../Shader/ComputeCommon.cginc"
|
||
|
|
||
|
#include "../../Shader/AutoSmoothFuncs.cginc"
|
||
|
#include "../../Shader/BrushFuncs.cginc"
|
||
|
#include "../../Shader/GenPointDefs.cginc"
|
||
|
#include "../../Shader/IndirectArgsDefs.cginc"
|
||
|
#include "../../Shader/MarchingCubesFuncs.cginc"
|
||
|
#include "../../Shader/Math/MathConst.cginc"
|
||
|
#include "../../Shader/MeshingModeDefs.cginc"
|
||
|
#include "../../Shader/NormalFuncs.cginc"
|
||
|
#include "../../Shader/RenderModeDefs.cginc"
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void generate_flat_marching_cubes_mesh(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
#if defined(MUDBUN_DISABLE_MARCHING_CUBES_FLAT_MESH)
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
uint iNode = uint(id.x);
|
||
|
if (iNode >= uint(aNumNodesAllocated[currentNodeDepth + 1]))
|
||
|
return;
|
||
|
|
||
|
for (int i = 1; i <= currentNodeDepth; ++i)
|
||
|
iNode += aNumNodesAllocated[i];
|
||
|
if (iNode >= nodePoolSize)
|
||
|
return;
|
||
|
|
||
|
int iBrushMask = get_brush_mask_index(iNode);
|
||
|
SdfBrushMaterial cubeMat;
|
||
|
MARCHING_CUBES(nodePool[iNode].center, currentNodeSize, sdf_masked_brushes, iBrushMask, false, cubeMat,
|
||
|
// tStmtPre
|
||
|
int iVertBase = 0;
|
||
|
InterlockedAdd(indirectDrawArgs[0], 3, iVertBase);
|
||
|
,
|
||
|
// vStmt
|
||
|
int iGenPoint = iVertBase + iVert;
|
||
|
aGenPoint[iVertBase + iVert].posNorm = float4(aVertPos[iVert], pack_normal(aVertNorm[iVert] * (invertNormals ? -1.0f : 1.0f)));
|
||
|
aGenPoint[iVertBase + iVert].material = pack_material(cubeMat);
|
||
|
aGenPoint[iVertBase + iVert].vertId = auto_smooth_vert_data_id(aEdgeCenter[iVert]);
|
||
|
aGenPoint[iVertBase + iVert].iBrushMask = iBrushMask;
|
||
|
aGenPoint[iVertBase + iVert].sdfValue = surfaceShift;
|
||
|
,
|
||
|
// tStmtPost
|
||
|
{ }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void generate_smooth_marching_cubes_mesh(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
#if defined(MUDBUN_DISABLE_MARCHING_CUBES_SMOOTH_MESH) || defined(MUDBUN_FAST_ITERATION)
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
uint iNode = uint(id.x);
|
||
|
if (iNode >= uint(aNumNodesAllocated[currentNodeDepth + 1]))
|
||
|
return;
|
||
|
|
||
|
for (int i = 1; i <= currentNodeDepth; ++i)
|
||
|
iNode += aNumNodesAllocated[i];
|
||
|
if (iNode >= nodePoolSize)
|
||
|
return;
|
||
|
|
||
|
int iBrushMask = get_brush_mask_index(iNode);
|
||
|
SdfBrushMaterial cubeMat;
|
||
|
MARCHING_CUBES(nodePool[iNode].center, currentNodeSize, sdf_masked_brushes, iBrushMask, true, cubeMat,
|
||
|
// tStmtPre
|
||
|
int iVertBase = 0;
|
||
|
InterlockedAdd(indirectDrawArgs[0], 3, iVertBase);
|
||
|
,
|
||
|
// vStmt
|
||
|
int iGenPoint = iVertBase + iVert;
|
||
|
aGenPoint[iGenPoint].posNorm = float4(aVertPos[iVert], pack_normal(aVertNorm[iVert] * (invertNormals ? -1.0f : 1.0f)));
|
||
|
aGenPoint[iGenPoint].material = pack_material(aVertMat[iVert]);
|
||
|
aGenPoint[iGenPoint].vertId = auto_smooth_vert_data_id(aEdgeCenter[iVert]);
|
||
|
aGenPoint[iGenPoint].iBrushMask = iBrushMask;
|
||
|
aGenPoint[iGenPoint].sdfValue = surfaceShift;
|
||
|
,
|
||
|
// tStmtPost
|
||
|
{ }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void generate_marching_splats(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
#if defined(MUDBUN_DISABLE_MARCHING_CUBES_SPLATS) || defined(MUDBUN_FAST_ITERATION)
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
uint iNode = uint(id.x);
|
||
|
if (iNode >= uint(aNumNodesAllocated[currentNodeDepth + 1]))
|
||
|
return;
|
||
|
|
||
|
for (int i = 1; i <= currentNodeDepth; ++i)
|
||
|
iNode += aNumNodesAllocated[i];
|
||
|
if (iNode >= nodePoolSize)
|
||
|
return;
|
||
|
|
||
|
int numTris = 0;
|
||
|
float3 avgPos = 0.0f;
|
||
|
float3 avgNorm = 0.0f;
|
||
|
float avgWeight = 0.0f;
|
||
|
int iBrushMask = get_brush_mask_index(iNode);
|
||
|
SdfBrushMaterial cubeMat;
|
||
|
MARCHING_CUBES(nodePool[iNode].center, currentNodeSize, sdf_masked_brushes, iBrushMask, false, cubeMat,
|
||
|
// tStmtPre
|
||
|
{ }
|
||
|
,
|
||
|
// vStmt
|
||
|
{ }
|
||
|
,
|
||
|
// tStmtPost
|
||
|
float3 c = cross(aVertPos[1] - aVertPos[0], aVertPos[2] - aVertPos[0]);
|
||
|
float w = length(c);
|
||
|
avgPos += w * (aVertPos[0] + aVertPos[1] + aVertPos[2]);
|
||
|
if (w > kEpsilon)
|
||
|
avgNorm += w * normalize(c);
|
||
|
avgWeight += w;
|
||
|
++numTris;
|
||
|
);
|
||
|
|
||
|
if (numTris > 0)
|
||
|
{
|
||
|
avgPos /= avgWeight * 3.0f;
|
||
|
avgNorm = normalize(avgNorm);
|
||
|
|
||
|
int iVertBase;
|
||
|
int iGenPoint = 0;
|
||
|
switch (renderMode)
|
||
|
{
|
||
|
case kRenderModeCircleSplats:
|
||
|
InterlockedAdd(indirectDrawArgs[0], 3, iVertBase);
|
||
|
iGenPoint = uint(iVertBase) / 3;
|
||
|
break;
|
||
|
case kRenderModeQuadSplats:
|
||
|
InterlockedAdd(indirectDrawArgs[0], 6, iVertBase);
|
||
|
iGenPoint = uint(iVertBase) / 6;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
float scaleMult = pow(saturate(avgWeight / (0.2f * voxelSize * voxelSize)), 0.1f);
|
||
|
cubeMat.metallicSmoothnessSizeTightness.z *= scaleMult;
|
||
|
|
||
|
aGenPoint[iGenPoint].posNorm = float4(avgPos, pack_normal(avgNorm * (invertNormals ? -1.0f : 1.0f)));
|
||
|
aGenPoint[iGenPoint].material = pack_material(cubeMat);
|
||
|
aGenPoint[iGenPoint].iBrushMask = iBrushMask;
|
||
|
aGenPoint[iGenPoint].sdfValue = surfaceShift;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void generate_flat_marching_cubes_mesh_2d(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
#if defined(MUDBUN_DISABLE_MARCHING_CUBES_FLAT_MESH) || defined(MUDBUN_FAST_ITERATION)
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
uint iNode = uint(id.x);
|
||
|
if (iNode >= uint(aNumNodesAllocated[currentNodeDepth + 1]))
|
||
|
return;
|
||
|
|
||
|
for (int i = 1; i <= currentNodeDepth; ++i)
|
||
|
iNode += aNumNodesAllocated[i];
|
||
|
if (iNode >= nodePoolSize)
|
||
|
return;
|
||
|
|
||
|
int iBrushMask = get_brush_mask_index(iNode);
|
||
|
SdfBrushMaterial cubeMat;
|
||
|
MARCHING_CUBES_2D(nodePool[iNode].center, currentNodeSize, sdf_masked_brushes, iBrushMask, false, cubeMat,
|
||
|
// tStmtPre
|
||
|
int iVertBase = 0;
|
||
|
InterlockedAdd(indirectDrawArgs[0], 3, iVertBase);
|
||
|
,
|
||
|
// vStmt
|
||
|
int iGenPoint = iVertBase + iVert;
|
||
|
aGenPoint[iGenPoint].posNorm = float4(aVertPos[iVert], pack_normal(aVertNorm[iVert]));
|
||
|
aGenPoint[iGenPoint].material = pack_material(cubeMat);
|
||
|
aGenPoint[iGenPoint].iBrushMask = iBrushMask;
|
||
|
aGenPoint[iGenPoint].sdfValue = aVertSdfValue[iVert] + surfaceShift;
|
||
|
aGenPoint[iGenPoint].norm2d = pack_normal(aVertNorm2d[iVert]);
|
||
|
,
|
||
|
// tStmtPost
|
||
|
{ }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void generate_smooth_marching_cubes_mesh_2d(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
#if defined(MUDBUN_DISABLE_MARCHING_CUBES_SMOOTH_MESH) || defined(MUDBUN_FAST_ITERATION)
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
uint iNode = uint(id.x);
|
||
|
if (iNode >= uint(aNumNodesAllocated[currentNodeDepth + 1]))
|
||
|
return;
|
||
|
|
||
|
for (int i = 1; i <= currentNodeDepth; ++i)
|
||
|
iNode += aNumNodesAllocated[i];
|
||
|
if (iNode >= nodePoolSize)
|
||
|
return;
|
||
|
|
||
|
int iBrushMask = get_brush_mask_index(iNode);
|
||
|
SdfBrushMaterial cubeMat;
|
||
|
MARCHING_CUBES_2D(nodePool[iNode].center, currentNodeSize, sdf_masked_brushes, iBrushMask, true, cubeMat,
|
||
|
// tStmtPre
|
||
|
int iVertBase = 0;
|
||
|
InterlockedAdd(indirectDrawArgs[0], 3, iVertBase);
|
||
|
,
|
||
|
// vStmt
|
||
|
int iGenPoint = iVertBase + iVert;
|
||
|
aGenPoint[iGenPoint].posNorm = float4(aVertPos[iVert], pack_normal(aVertNorm[iVert]));
|
||
|
aGenPoint[iGenPoint].material = pack_material(aVertMat[iVert]);
|
||
|
aGenPoint[iGenPoint].iBrushMask = iBrushMask;
|
||
|
aGenPoint[iGenPoint].sdfValue = aVertSdfValue[iVert] + surfaceShift;
|
||
|
aGenPoint[iGenPoint].norm2d = pack_normal(aVertNorm2d[iVert]);
|
||
|
,
|
||
|
// tStmtPost
|
||
|
{ }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void generate_marching_splats_2d(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
#if defined(MUDBUN_DISABLE_MARCHING_CUBES_SPLATS) || defined(MUDBUN_FAST_ITERATION)
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
uint iNode = uint(id.x);
|
||
|
if (iNode >= uint(aNumNodesAllocated[currentNodeDepth + 1]))
|
||
|
return;
|
||
|
|
||
|
for (int i = 1; i <= currentNodeDepth; ++i)
|
||
|
iNode += aNumNodesAllocated[i];
|
||
|
if (iNode >= nodePoolSize)
|
||
|
return;
|
||
|
|
||
|
int numTris = 0;
|
||
|
float3 avgPos = 0.0f;
|
||
|
float avgSdfValue = 0.0f;
|
||
|
float avgWeight = 0.0f;
|
||
|
int iBrushMask = get_brush_mask_index(iNode);
|
||
|
SdfBrushMaterial cubeMat;
|
||
|
MARCHING_CUBES_2D(nodePool[iNode].center, currentNodeSize, sdf_masked_brushes, iBrushMask, false, cubeMat,
|
||
|
// tStmtPre
|
||
|
{ }
|
||
|
,
|
||
|
// vStmt
|
||
|
{ }
|
||
|
,
|
||
|
// tStmtPost
|
||
|
float3 c = cross(aVertPos[1] - aVertPos[0], aVertPos[2] - aVertPos[0]);
|
||
|
float w = length(c);
|
||
|
avgPos += w * (aVertPos[0] + aVertPos[1] + aVertPos[2]);
|
||
|
avgSdfValue += w * (aVertSdfValue[0] + aVertSdfValue[1] + aVertSdfValue[2]);
|
||
|
avgWeight += w;
|
||
|
++numTris;
|
||
|
);
|
||
|
|
||
|
if (numTris > 0)
|
||
|
{
|
||
|
float normFactor = 1.0f / (avgWeight * 3.0f);
|
||
|
avgPos *= normFactor;
|
||
|
avgSdfValue *= normFactor;
|
||
|
|
||
|
int iVertBase;
|
||
|
int iGenPoint = 0;
|
||
|
switch (renderMode)
|
||
|
{
|
||
|
case kRenderModeCircleSplats:
|
||
|
InterlockedAdd(indirectDrawArgs[0], 3, iVertBase);
|
||
|
iGenPoint = uint(iVertBase) / 3;
|
||
|
break;
|
||
|
case kRenderModeQuadSplats:
|
||
|
InterlockedAdd(indirectDrawArgs[0], 6, iVertBase);
|
||
|
iGenPoint = uint(iVertBase) / 6;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
float scaleMult = pow(saturate(avgWeight / (0.2f * voxelSize * voxelSize)), 0.1f);
|
||
|
cubeMat.metallicSmoothnessSizeTightness.z *= scaleMult;
|
||
|
|
||
|
aGenPoint[iGenPoint].posNorm = float4(avgPos, pack_normal(float3(0.0f, 0.0f, -1.0f) * (invertNormals ? -1.0f : 1.0f)));
|
||
|
aGenPoint[iGenPoint].material = pack_material(cubeMat);
|
||
|
aGenPoint[iGenPoint].iBrushMask = iBrushMask;
|
||
|
aGenPoint[iGenPoint].sdfValue = avgSdfValue + surfaceShift;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[numthreads(1, 1, 1)]
|
||
|
void update_marching_cubes_auto_smooth_indirect_dispatch_args(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
indirectDispatchArgs[0] = max(1, uint(indirectDrawArgs[0] + kThreadGroupSize - 1) / kThreadGroupSize);
|
||
|
}
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void marching_cubes_update_auto_smooth(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
if (id.x >= indirectDrawArgs[0])
|
||
|
return;
|
||
|
|
||
|
uint iGenPoint = uint(id.x);
|
||
|
uint iTriBase = iGenPoint - (iGenPoint % 3);
|
||
|
|
||
|
float3 pos0 = aGenPoint[iTriBase ].posNorm.xyz;
|
||
|
float3 pos1 = aGenPoint[iTriBase + 1].posNorm.xyz;
|
||
|
float3 pos2 = aGenPoint[iTriBase + 2].posNorm.xyz;
|
||
|
|
||
|
float3 v01 = pos1 - pos0;
|
||
|
float3 v12 = pos2 - pos1;
|
||
|
float3 c = cross(v01, v12);
|
||
|
float area = length(c);
|
||
|
|
||
|
update_auto_smooth_vert_data(aGenPoint[iGenPoint].vertId, aGenPoint[iGenPoint].posNorm.w, area);
|
||
|
}
|
||
|
|
||
|
[numthreads(kThreadGroupSize, 1, 1)]
|
||
|
void marching_cubes_compute_auto_smooth(int3 id : SV_DispatchThreadID)
|
||
|
{
|
||
|
if (id.x >= indirectDrawArgs[0])
|
||
|
return;
|
||
|
|
||
|
uint iGenPoint = uint(id.x);
|
||
|
float3 pos = aGenPoint[iGenPoint].posNorm.xyz;
|
||
|
int iBrushMask = aGenPoint[iGenPoint].iBrushMask;
|
||
|
|
||
|
SdfBrushMaterial mat;
|
||
|
sdf_masked_brushes(pos, iBrushMask, mat);
|
||
|
|
||
|
float3 autoSmoothNormal = compute_auto_smooth_normal(aGenPoint[iGenPoint].vertId, unpack_normal(aGenPoint[iGenPoint].posNorm.w));
|
||
|
|
||
|
aGenPoint[iGenPoint].posNorm.w = pack_normal(autoSmoothNormal);
|
||
|
aGenPoint[iGenPoint].material = pack_material(mat);
|
||
|
//aGenPoint[iGenPoint].material.color = pack_rgba(float4(n, 1.0f));
|
||
|
}
|
||
|
|