Created Lightning Gun effect (Uses LineRenderer, very slow) Created GPU Lightning renderer (very fast, still needs integration)
155 lines
3.9 KiB
C#
155 lines
3.9 KiB
C#
using UnityEngine;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Runtime.InteropServices;
|
||
using UnityEngine.Assertions;
|
||
|
||
public class GPUTrail : GPUTrailBase
|
||
{
|
||
LinkedList<Vector3> _posLog = new LinkedList<Vector3>();
|
||
int _totalInputIdx = -1;
|
||
|
||
ComputeBuffer _inputBuffer;
|
||
|
||
protected float _startTime;
|
||
|
||
protected override int TrailNumMax { get { return 1; } }
|
||
|
||
protected override void Awake()
|
||
{
|
||
base.Awake();
|
||
|
||
_inputBuffer = new ComputeBuffer(InputNumMax, Marshal.SizeOf(typeof(Node)));
|
||
}
|
||
|
||
|
||
void Start()
|
||
{
|
||
_posLog.AddLast(transform.position);
|
||
}
|
||
|
||
protected override void ReleaseBuffer()
|
||
{
|
||
base.ReleaseBuffer();
|
||
if (_inputBuffer != null) _inputBuffer.Release();
|
||
}
|
||
|
||
|
||
void _LerpPos(int inputNum, Vector3 pos)
|
||
{
|
||
var timeStep = Time.deltaTime / inputNum;
|
||
var timePrev = Time.time - Time.deltaTime;
|
||
|
||
var posPrev = _posLog.Last();
|
||
var posStep = (pos - posPrev) / inputNum;
|
||
|
||
for (var i = 1; i < inputNum; ++i)
|
||
{
|
||
_newPoints.Add(new Node()
|
||
{
|
||
pos = posPrev + posStep * i,
|
||
time = timePrev + timeStep * i
|
||
});
|
||
}
|
||
}
|
||
|
||
List<Node> _newPoints = new List<Node>();
|
||
protected override void UpdateVertex()
|
||
{
|
||
var pos = transform.position;
|
||
var posPrev = _posLog.Last();
|
||
|
||
if ((Vector3.Distance(posPrev, pos) > MINNodeDistance))
|
||
{
|
||
var inputNum = Mathf.Clamp(Mathf.FloorToInt(Time.deltaTime * InputPerSec), 1, InputNumMax);
|
||
//inputNum = 1;
|
||
|
||
if (inputNum > 1)
|
||
{
|
||
_LerpPos(inputNum, pos);
|
||
}
|
||
|
||
_newPoints.Add(new Node()
|
||
{
|
||
pos = pos,
|
||
time = Time.time
|
||
});
|
||
|
||
_posLog.AddLast(pos);
|
||
|
||
// _posLogには過去2つの位置を保存しとく
|
||
for (var i = 0; i < _posLog.Count - 2; ++i)
|
||
{
|
||
_posLog.RemoveFirst();
|
||
}
|
||
}
|
||
|
||
_UpdateVertex(_newPoints);
|
||
|
||
_newPoints.Clear();
|
||
}
|
||
|
||
const int NUM_THREAD_X = 16;
|
||
void _UpdateVertex(List<Node> newPoints)
|
||
{
|
||
Assert.IsTrue(newPoints.Count <= InputNumMax);
|
||
|
||
var inputNum = newPoints.Count;
|
||
if (inputNum > 0)
|
||
{
|
||
_inputBuffer.SetData(newPoints.ToArray());
|
||
if (_totalInputIdx < 0) _startTime = Time.time;
|
||
_totalInputIdx += inputNum;
|
||
}
|
||
|
||
if (_totalInputIdx >= 0)
|
||
{
|
||
SetCommonParameterForCs();
|
||
|
||
Cs.SetInt("_InputNum", inputNum);
|
||
Cs.SetInt("_TotalInputIdx", _totalInputIdx);
|
||
Cs.SetInt("_BufferSize", nodeNumPerTrail);
|
||
Cs.SetFloat("_StartTime", _startTime);
|
||
|
||
var kernel = Cs.FindKernel("CreateWidth");
|
||
Cs.SetBuffer(kernel, "_InputBuffer", _inputBuffer);
|
||
Cs.SetBuffer(kernel, "_NodeBuffer", nodeBuffer);
|
||
Cs.SetBuffer(kernel, "_VertexBuffer", vertexBuffer);
|
||
|
||
Cs.Dispatch(kernel, Mathf.CeilToInt((float)nodeBuffer.count / NUM_THREAD_X), 1, 1);
|
||
}
|
||
}
|
||
|
||
|
||
public bool _debugDrawLogPoint;
|
||
public bool _debugDrawVertexBuf;
|
||
|
||
public void OnDrawGizmosSelected()
|
||
{
|
||
if (_debugDrawLogPoint)
|
||
{
|
||
Gizmos.color = Color.magenta;
|
||
_posLog.ToList().ForEach(p =>
|
||
{
|
||
Gizmos.DrawWireSphere(p, MINNodeDistance);
|
||
});
|
||
}
|
||
|
||
if (_debugDrawVertexBuf)
|
||
{
|
||
Gizmos.color = Color.yellow;
|
||
var data = new Vertex[vertexBuffer.count];
|
||
vertexBuffer.GetData(data);
|
||
|
||
var num = vertexBuffer.count / 2;
|
||
for(var i=0; i< num; ++i)
|
||
{
|
||
var v0 = data[2*i];
|
||
var v1 = data[2*i +1];
|
||
|
||
Gizmos.DrawLine(v0.pos, v1.pos);
|
||
}
|
||
}
|
||
}
|
||
}
|