You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
6.3 KiB
237 lines
6.3 KiB
Shader "Hidden/VoxelizeShader"
|
|
{
|
|
|
|
SubShader
|
|
{
|
|
|
|
HLSLINCLUDE
|
|
#include "Packages/com.unity.visualeffectgraph/Shaders/SDFBaker/SdfUtils.hlsl"
|
|
#define AABB_EPS 1e-5
|
|
|
|
// Vertex input attributes
|
|
struct Attributes
|
|
{
|
|
uint vertexId : SV_VertexID;
|
|
};
|
|
|
|
// Fragment varyings
|
|
struct Varyings
|
|
{
|
|
float4 position : SV_POSITION;
|
|
uint triangleID : TEXCOORD0;
|
|
};
|
|
StructuredBuffer<float4> vertices;
|
|
StructuredBuffer<int> coordFlip;
|
|
|
|
RWStructuredBuffer<float4> voxels : register(u1);
|
|
RWStructuredBuffer<float4> aabb : register(u4);
|
|
RWStructuredBuffer<uint> counter : register(u2);
|
|
RWStructuredBuffer<uint> triangleIDs : register(u3);
|
|
|
|
int currentAxis;
|
|
|
|
int dimX, dimY, dimZ;
|
|
|
|
uint id3(int i, int j, int k)
|
|
{
|
|
return (uint)(i + dimX * j + dimX * dimY * k);
|
|
}
|
|
uint id3(int3 coord)
|
|
{
|
|
return id3(coord.x, coord.y, coord.z);
|
|
}
|
|
|
|
|
|
float2 GetCustomScreenParams()
|
|
{
|
|
float2 myScreenParams;
|
|
if (currentAxis == 1)
|
|
{
|
|
myScreenParams = float2(dimZ, dimX);
|
|
}
|
|
else if (currentAxis == 2)
|
|
{
|
|
myScreenParams = float2(dimY, dimZ);
|
|
}
|
|
else
|
|
{
|
|
myScreenParams = float2(dimX, dimY);
|
|
}
|
|
return myScreenParams;
|
|
}
|
|
void ScreenToUV(inout float4 pos, float2 myScreenParams)
|
|
{
|
|
#if UNITY_REVERSED_Z
|
|
pos.z = 1.0f - pos.z;
|
|
#endif
|
|
pos.xy = pos.xy / myScreenParams;
|
|
#if UNITY_UV_STARTS_AT_TOP
|
|
pos.y = 1 - pos.y;
|
|
#endif
|
|
}
|
|
void CullWithAABB(float4 pos, int triangleID)
|
|
{
|
|
float2 ndc_pos = pos.xy * 2.0f - 1.0f;
|
|
if (ndc_pos.x < aabb[triangleID].x - AABB_EPS ||
|
|
ndc_pos.y < aabb[triangleID].y - AABB_EPS ||
|
|
ndc_pos.x > aabb[triangleID].z + AABB_EPS ||
|
|
ndc_pos.y > aabb[triangleID].w + AABB_EPS)
|
|
{
|
|
discard;
|
|
}
|
|
}
|
|
|
|
void ComputeCoordAndDepthStep(float2 myScreenParams, float4 pos, out int3 coord, out int3 depthStep, out bool stepMinus, out bool stepPlus)
|
|
{
|
|
stepPlus = true;
|
|
stepMinus = true; //TODO : Now we're conservative about how we share triangle data across neighbouring cells, to fix visible artefacts
|
|
if (currentAxis == 1)
|
|
{
|
|
coord = (pos.xyz * float3(myScreenParams, dimY));
|
|
coord.xyz = coord.yzx;
|
|
depthStep = int3(0, 1, 0);
|
|
if (coord.y == 0)
|
|
{
|
|
stepMinus = false;
|
|
}
|
|
if (coord.y == dimY - 1)
|
|
{
|
|
stepPlus = false;
|
|
}
|
|
}
|
|
else if (currentAxis == 2)
|
|
{
|
|
coord = (pos.xyz * float3(myScreenParams, dimX));
|
|
coord.xyz = coord.zxy;
|
|
depthStep = int3(1, 0, 0);
|
|
if (coord.x == 0)
|
|
{
|
|
stepMinus = false;
|
|
}
|
|
if (coord.x == dimX - 1)
|
|
{
|
|
stepPlus = false;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
coord = (pos.xyz * float3(myScreenParams, dimZ));
|
|
depthStep = int3(0, 0, 1);
|
|
if (coord.z == 0)
|
|
{
|
|
stepMinus = false;
|
|
}
|
|
if (coord.z == dimZ - 1)
|
|
{
|
|
stepPlus = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GetCellCoordinatesData(Varyings input, out int3 coord, out int3 depthStep, out bool stepMinus, out bool stepPlus)
|
|
{
|
|
float4 pos = input.position;
|
|
|
|
float2 myScreenParams = GetCustomScreenParams();
|
|
ScreenToUV(pos, myScreenParams);
|
|
|
|
CullWithAABB(pos, input.triangleID);
|
|
|
|
ComputeCoordAndDepthStep(myScreenParams, pos, coord, depthStep, stepMinus, stepPlus);
|
|
}
|
|
|
|
|
|
|
|
Varyings Vertex(Attributes input)
|
|
{
|
|
Varyings o = (Varyings)(0);
|
|
float4 pos = vertices[input.vertexId];
|
|
o.triangleID = input.vertexId / 3;
|
|
if (coordFlip[o.triangleID] != currentAxis)
|
|
{
|
|
o.position = float4(-1,-1,-1,-1);
|
|
return o;
|
|
}
|
|
o.position = pos;
|
|
return o;
|
|
}
|
|
|
|
ENDHLSL
|
|
// Shader code
|
|
Pass{
|
|
|
|
Cull Off
|
|
ZTest Always
|
|
|
|
HLSLPROGRAM
|
|
|
|
#pragma target 5.0
|
|
#pragma vertex Vertex
|
|
#pragma fragment Fragment
|
|
|
|
float4 Fragment(Varyings input) : SV_Target{
|
|
|
|
int3 depthStep, coord;
|
|
bool stepMinus, stepPlus;
|
|
|
|
GetCellCoordinatesData(input, coord, depthStep, stepMinus, stepPlus);
|
|
|
|
float3 voxelUV = ((float3(coord)+float3(0.5f, 0.5f, 0.5f)) / Max3(dimX, dimY, dimZ));
|
|
voxels[id3(coord)] = float4(voxelUV, 1.0f);
|
|
InterlockedAdd(counter[id3(coord)], 1u);
|
|
if (stepPlus)
|
|
{
|
|
voxels[id3(coord + depthStep)] = float4(voxelUV, 1.0f);
|
|
InterlockedAdd(counter[id3(coord + depthStep)], 1u);
|
|
}
|
|
if (stepMinus)
|
|
{
|
|
voxels[id3(coord - depthStep)] = float4(voxelUV, 1.0f);
|
|
InterlockedAdd(counter[id3(coord - depthStep)], 1u);
|
|
}
|
|
|
|
return float4(voxelUV,1);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass
|
|
{
|
|
|
|
Cull Off
|
|
ZTest Always
|
|
|
|
HLSLPROGRAM
|
|
|
|
#pragma target 5.0
|
|
#pragma vertex Vertex
|
|
#pragma fragment Fragment
|
|
float4
|
|
Fragment(Varyings input) : SV_Target
|
|
{
|
|
int3 depthStep, coord;
|
|
bool stepMinus, stepPlus;
|
|
|
|
GetCellCoordinatesData(input, coord, depthStep, stepMinus, stepPlus);
|
|
|
|
uint indexTri = 0u;
|
|
|
|
InterlockedAdd(counter[id3(coord)], 1, indexTri);
|
|
triangleIDs[indexTri] = input.triangleID;
|
|
if (stepPlus)
|
|
{
|
|
InterlockedAdd(counter[id3(coord + depthStep)], 1, indexTri);
|
|
triangleIDs[indexTri] = input.triangleID;
|
|
}
|
|
if (stepMinus)
|
|
{
|
|
InterlockedAdd(counter[id3(coord - depthStep)], 1, indexTri);
|
|
triangleIDs[indexTri] = input.triangleID;
|
|
}
|
|
return input.position;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|