Aetheria/Assets/Plugins/GPUTrail/Shaders/GPUTrailIndirect.compute
Reinier Vens bb297bf84c Lightning
Created Lightning Gun effect (Uses LineRenderer, very slow)
Created GPU Lightning renderer (very fast, still needs integration)
2021-02-04 04:37:47 +00:00

139 lines
4.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
}