139 lines
4.1 KiB
Text
139 lines
4.1 KiB
Text
|
|
#pragma kernel AddNode
|
|||
|
|
#pragma kernel CreateWidth
|
|||
|
|
|
|||
|
|
#define NUM_THREAD_X 32
|
|||
|
|
|
|||
|
|
#include "GPUTrailVariablesCS.compute"
|
|||
|
|
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
// AddNode
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
StructuredBuffer<InputData> _InputBuffer;
|
|||
|
|
RWStructuredBuffer<Trail> _TrailBufferW;
|
|||
|
|
RWStructuredBuffer<Node> _NodeBufferW;
|
|||
|
|
|
|||
|
|
[numthreads(NUM_THREAD_X,1,1)]
|
|||
|
|
void AddNode (uint3 id : SV_DispatchThreadID)
|
|||
|
|
{
|
|||
|
|
uint trailIdx = id.x;
|
|||
|
|
if ( trailIdx < _TrailNum )
|
|||
|
|
{
|
|||
|
|
Trail trail = _TrailBufferW[trailIdx];
|
|||
|
|
uint totalInputNum = trail.totalInputNum;
|
|||
|
|
bool isFirst = (totalInputNum==0);
|
|||
|
|
|
|||
|
|
InputData inputData = _InputBuffer[trailIdx];
|
|||
|
|
if ( isFirst || (_MinNodeDistance <= distance(inputData.pos, _NodeBufferW[calcNodeIdx(trailIdx, totalInputNum-1)].pos)))
|
|||
|
|
{
|
|||
|
|
Node node;
|
|||
|
|
node.pos = inputData.pos;
|
|||
|
|
node.time = _Time;
|
|||
|
|
node.color = inputData.color;
|
|||
|
|
uint nodeIdx = calcNodeIdx(trailIdx, totalInputNum);
|
|||
|
|
_NodeBufferW[nodeIdx] = node;
|
|||
|
|
|
|||
|
|
trail.startTime = isFirst ? _Time : trail.startTime;
|
|||
|
|
trail.totalInputNum++;
|
|||
|
|
|
|||
|
|
_TrailBufferW[trailIdx] = trail;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
// CreateWidth
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
StructuredBuffer<Trail> _TrailBuffer;
|
|||
|
|
StructuredBuffer<Node> _NodeBuffer;
|
|||
|
|
RWStructuredBuffer<Vertex> _VertexBuffer;
|
|||
|
|
|
|||
|
|
|
|||
|
|
uint calcPrevIdxInTrail(uint idx)
|
|||
|
|
{
|
|||
|
|
return (idx + _NodeNumPerTrail-1) % _NodeNumPerTrail;
|
|||
|
|
}
|
|||
|
|
uint calcNextIdxInTrail(uint idx)
|
|||
|
|
{
|
|||
|
|
return (idx + 1) % _NodeNumPerTrail;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint calcNodeIdxFromInTrail(uint trailIdx, uint idxInTrail)
|
|||
|
|
{
|
|||
|
|
return trailIdx * _NodeNumPerTrail + idxInTrail;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Node getNode(uint trailIdx, uint idxInTrail, uint totalInputNum)
|
|||
|
|
{
|
|||
|
|
idxInTrail = min(idxInTrail, totalInputNum-1); // 未使用ノードのIdxが指定されたら最新のノードを返す
|
|||
|
|
return _NodeBuffer[calcNodeIdxFromInTrail(trailIdx, idxInTrail)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
float3 calcNodeDir(uint trailIdx, uint nodeIdxInTrail, uint totalInputNum)
|
|||
|
|
{
|
|||
|
|
float3 dirPrev = float3(0,0,0);
|
|||
|
|
float3 dirNext = float3(0,0,0);
|
|||
|
|
|
|||
|
|
float3 pos = getNode(trailIdx, nodeIdxInTrail, totalInputNum).pos;
|
|||
|
|
|
|||
|
|
uint prevIdxInTrail = calcPrevIdxInTrail(nodeIdxInTrail);
|
|||
|
|
uint inputIdxInTrail = calcPrevIdxInTrail(totalInputNum);
|
|||
|
|
|
|||
|
|
bool prevEnable = (prevIdxInTrail != inputIdxInTrail) && (prevIdxInTrail < totalInputNum);
|
|||
|
|
if ( prevEnable )
|
|||
|
|
{
|
|||
|
|
dirPrev = normalize(pos - getNode(trailIdx, prevIdxInTrail, totalInputNum).pos);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool nextEnable = nodeIdxInTrail!= inputIdxInTrail;
|
|||
|
|
if ( nextEnable )
|
|||
|
|
{
|
|||
|
|
uint nextIdxInTrail = calcNextIdxInTrail(nodeIdxInTrail);
|
|||
|
|
dirNext = normalize(getNode(trailIdx, nextIdxInTrail, totalInputNum).pos - pos);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return normalize(dirPrev + dirNext);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[numthreads(NUM_THREAD_X,1,1)]
|
|||
|
|
void CreateWidth (uint3 id : SV_DispatchThreadID)
|
|||
|
|
{
|
|||
|
|
uint nodeIdx = id.x;
|
|||
|
|
uint trailIdx = nodeIdx / _NodeNumPerTrail;
|
|||
|
|
if ( trailIdx < _TrailNum )
|
|||
|
|
{
|
|||
|
|
Trail trail = _TrailBuffer[trailIdx];
|
|||
|
|
uint totalInputNum = trail.totalInputNum;
|
|||
|
|
uint nodeIdxInTrail = nodeIdx % _NodeNumPerTrail;
|
|||
|
|
|
|||
|
|
Vertex v0 = GetDefaultVertex();
|
|||
|
|
Vertex v1 = GetDefaultVertex();
|
|||
|
|
{
|
|||
|
|
Node node = getNode(trailIdx, nodeIdxInTrail, totalInputNum);
|
|||
|
|
|
|||
|
|
float life = min(_Life, _Time - trail.startTime);
|
|||
|
|
float rate = life <= 0 ? 1 : max(0, 1 - ((_Time - node.time) / life));
|
|||
|
|
|
|||
|
|
float3 pos = node.pos;
|
|||
|
|
float3 dir = calcNodeDir(trailIdx, nodeIdxInTrail, totalInputNum);
|
|||
|
|
|
|||
|
|
float3 toCameraDir = calcToCameraDir(pos);
|
|||
|
|
float3 right = normalize(cross(dir, toCameraDir)) * lerp(_EndWidth, _StartWidth, rate) * 0.5f;
|
|||
|
|
|
|||
|
|
v0.pos = pos - right;
|
|||
|
|
v0.uv = float2(rate, 0);
|
|||
|
|
v0.color = node.color;
|
|||
|
|
|
|||
|
|
v1.pos = pos + right;
|
|||
|
|
v1.uv = float2(rate, 1);
|
|||
|
|
v1.color = node.color;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint startIdxInTrail = (totalInputNum <= _NodeNumPerTrail) ? 0 : calcNextIdxInTrail(totalInputNum-1);
|
|||
|
|
uint nodeIdxFromStartInTrail = ((nodeIdxInTrail + _NodeNumPerTrail) - startIdxInTrail) % _NodeNumPerTrail;
|
|||
|
|
uint drawIdx = calcNodeIdxFromInTrail(trailIdx, nodeIdxFromStartInTrail);
|
|||
|
|
|
|||
|
|
uint vIdx = drawIdx * 2;
|
|||
|
|
_VertexBuffer[vIdx] = v0;
|
|||
|
|
_VertexBuffer[vIdx+1] = v1;
|
|||
|
|
}
|
|||
|
|
}
|