Aetheria/Assets/Plugins/GPUTrail/Shaders/GPUTrail.compute

106 lines
2.4 KiB
Text
Raw Normal View History

#pragma kernel CreateWidth
#define NUM_THREAD_X 16
#include "GPUTrailVariablesCS.compute"
int _InputNum;
int _TotalInputIdx;
uint _BufferSize;
float _StartTime;
StructuredBuffer<Node> _InputBuffer;
RWStructuredBuffer<Node> _NodeBuffer;
RWStructuredBuffer<Vertex> _VertexBuffer;
// idx must 0~_BufferSize-1
int GetInputBufIdx(int idx)
{
//今回のInputに含まれるIdx
int inputFirst = (_TotalInputIdx - _InputNum + 1) % _BufferSize;
int idxWithOffset = idx + ((idx < inputFirst) ? _BufferSize : 0);
return ((inputFirst <= idxWithOffset) && (idxWithOffset < (inputFirst + _InputNum)))
? idxWithOffset - inputFirst
: -1;
}
Node GetNode(int idx)
{
int inputBufIdx = GetInputBufIdx(idx);
if ( inputBufIdx >= 0 )
{
return _InputBuffer[inputBufIdx];
}
return _NodeBuffer[min(idx, _TotalInputIdx)]; // unused buffer is map to last input buffer
}
[numthreads(NUM_THREAD_X,1,1)]
void CreateWidth (uint3 id : SV_DispatchThreadID)
{
int idx = id.x;
if ( idx < (int)_BufferSize )
{
int inputIdxLast = _TotalInputIdx % _BufferSize;
int inputBufIdx = GetInputBufIdx(idx);
if ( inputBufIdx >= 0 )
{
_NodeBuffer[idx] = _InputBuffer[inputBufIdx];
}
Vertex v0 = GetDefaultVertex();
Vertex v1 = GetDefaultVertex();
Node node = GetNode(idx);
float3 pos = node.pos;
float3 dirPrev = float3(0,0,0);
float3 dirNext = float3(0,0,0);
if ( idx <= _TotalInputIdx )
{
int prevIdx = (idx-1 +_BufferSize) % _BufferSize;
bool prevEnable = (prevIdx != inputIdxLast);
if ( prevEnable )
{
Node nodePrev = GetNode(prevIdx);
dirPrev = normalize(pos - nodePrev.pos);
}
int nextIdx = (idx+1) % _BufferSize;
bool nextEnable = idx != inputIdxLast;
if ( nextEnable )
{
Node nodeNext = GetNode(nextIdx);
dirNext = normalize(nodeNext.pos - pos);
}
}
float life = min(_Life, _Time - _StartTime);
float rate = life <= 0 ? 1 : max(0, 1 - ((_Time - node.time) / life));
float3 dir = normalize(dirPrev + dirNext);
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;
int drawIdx = inputIdxLast - (int)idx;
drawIdx = (drawIdx + _BufferSize) % _BufferSize;
uint vId = drawIdx * 2;
_VertexBuffer[vId] = v0;
_VertexBuffer[vId+1] = v1;
}
}