242 lines
9.7 KiB
C#
242 lines
9.7 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace GPUInstancer
|
|
{
|
|
/// <summary>
|
|
/// Example usage of InitializeWithMatrix4x4Array - UpdateVisibilityBufferWithMatrix4x4Array and DefineAndAddVariationFromArray - UpdateVariationFromArray API methods
|
|
/// </summary>
|
|
public class PrefabsWithoutGameObjects : MonoBehaviour
|
|
{
|
|
// reference to the Prefab Manager
|
|
public GPUInstancerPrefabManager prefabManager;
|
|
// reference to the No Game Object prefab
|
|
public GPUInstancerPrefab prefab;
|
|
// size of array and buffers
|
|
public int bufferSize = 10000;
|
|
|
|
// UI
|
|
public Button addSphere;
|
|
public Button removeSphere;
|
|
public Button clearSphere;
|
|
public Text sphereCountText;
|
|
public Text positionUpdateFrequencyText;
|
|
public Text scaleUpdateFrequencyText;
|
|
public Text colorUpdateFrequencyText;
|
|
public string bufferName = "colorBuffer";
|
|
|
|
// Transform Data Array
|
|
private Matrix4x4[] _matrix4x4Array;
|
|
|
|
private int sphereCount = 0;
|
|
private float positionUpdateFrequency = 1;
|
|
private float scaleUpdateFrequency = 1;
|
|
private float colorUpdateFrequency = 1;
|
|
private Vector4[] variationData;
|
|
|
|
// Use this for initialization
|
|
private void Awake()
|
|
{
|
|
// min buffersize check
|
|
if (bufferSize < 1000)
|
|
bufferSize = 1000;
|
|
// initialize the array with the max size
|
|
_matrix4x4Array = new Matrix4x4[bufferSize];
|
|
// change the data of the array
|
|
AddMatrix4x4ToArray(1000);
|
|
|
|
// initialize the buffers with array
|
|
GPUInstancerAPI.InitializeWithMatrix4x4Array(prefabManager, prefab.prefabPrototype, _matrix4x4Array);
|
|
GPUInstancerAPI.SetInstanceCount(prefabManager, prefab.prefabPrototype, sphereCount);
|
|
|
|
// Color variatons
|
|
variationData = new Vector4[bufferSize];
|
|
for (int i = 0; i < bufferSize; i++)
|
|
variationData[i] = Random.ColorHSV();
|
|
GPUInstancerAPI.DefineAndAddVariationFromArray(prefabManager, prefab.prefabPrototype, bufferName, variationData);
|
|
|
|
// UI
|
|
CheckButtonsAvailablity();
|
|
// Start Update Positions coroutine
|
|
StartCoroutine(UpdatePositions());
|
|
|
|
StartCoroutine(UpdateScale());
|
|
|
|
StartCoroutine(UpdateColors());
|
|
}
|
|
|
|
// Update 100 random sphere positions
|
|
private IEnumerator UpdatePositions()
|
|
{
|
|
while (true)
|
|
{
|
|
if(sphereCount > 100 && positionUpdateFrequency > 0)
|
|
{
|
|
Vector3 newPosition;
|
|
// update 100 positions starting from random index
|
|
int randomIndex = Random.Range(0, sphereCount - 100);
|
|
for (int i = randomIndex; i < randomIndex + 100; i++)
|
|
{
|
|
newPosition = Random.insideUnitSphere * 20;
|
|
_matrix4x4Array[i].SetColumn(3, new Vector4(newPosition.x, newPosition.y, newPosition.z, _matrix4x4Array[i][3, 3]));
|
|
}
|
|
// set updated transform data
|
|
GPUInstancerAPI.UpdateVisibilityBufferWithMatrix4x4Array(prefabManager, prefab.prefabPrototype, _matrix4x4Array, randomIndex, randomIndex, 100);
|
|
}
|
|
yield return new WaitForSeconds(1 - positionUpdateFrequency + 0.01f);
|
|
}
|
|
}
|
|
|
|
// Update 100 random sphere positions
|
|
private IEnumerator UpdateScale()
|
|
{
|
|
while (true)
|
|
{
|
|
if (sphereCount > 100 && scaleUpdateFrequency > 0)
|
|
{
|
|
Matrix4x4 instance;
|
|
Vector3 position;
|
|
Quaternion rotation;
|
|
Vector3 newScale;
|
|
// update 100 positions starting from random index
|
|
int randomIndex = Random.Range(0, sphereCount - 100);
|
|
for (int i = randomIndex; i < randomIndex + 100; i++)
|
|
{
|
|
instance = _matrix4x4Array[i];
|
|
position = instance.GetColumn(3);
|
|
rotation = Quaternion.LookRotation(instance.GetColumn(2), instance.GetColumn(1));
|
|
newScale = Vector3.one * Random.Range(0.5f, 1.5f);
|
|
_matrix4x4Array[i] = Matrix4x4.TRS(position, rotation, newScale);
|
|
}
|
|
// set updated transform data
|
|
GPUInstancerAPI.UpdateVisibilityBufferWithMatrix4x4Array(prefabManager, prefab.prefabPrototype, _matrix4x4Array, randomIndex, randomIndex, 100);
|
|
}
|
|
yield return new WaitForSeconds(1 - scaleUpdateFrequency + 0.01f);
|
|
}
|
|
}
|
|
|
|
// Update 100 random sphere positions
|
|
private IEnumerator UpdateColors()
|
|
{
|
|
while (true)
|
|
{
|
|
if (sphereCount > 100 && colorUpdateFrequency > 0)
|
|
{
|
|
// update 100 positions starting from random index
|
|
int randomIndex = Random.Range(0, sphereCount - 100);
|
|
for (int i = randomIndex; i < randomIndex + 100; i++)
|
|
variationData[i] = Random.ColorHSV();
|
|
// set updated transform data
|
|
GPUInstancerAPI.UpdateVariationFromArray(prefabManager, prefab.prefabPrototype, bufferName, variationData, randomIndex, randomIndex, 100);
|
|
}
|
|
yield return new WaitForSeconds(1 - colorUpdateFrequency + 0.01f);
|
|
}
|
|
}
|
|
|
|
// Add new spheres
|
|
private void AddMatrix4x4ToArray(int instanceCount)
|
|
{
|
|
int start = sphereCount;
|
|
sphereCount += instanceCount;
|
|
for (int i = start; i < sphereCount; i++)
|
|
{
|
|
_matrix4x4Array[i] = Matrix4x4.TRS(Random.insideUnitSphere * 20, Quaternion.identity, Vector3.one * Random.Range(0.5f, 1.5f));
|
|
}
|
|
}
|
|
|
|
// remove spheres
|
|
private void RemoveMatrix4x4FromArray(int instanceCount)
|
|
{
|
|
int end = sphereCount;
|
|
sphereCount -= instanceCount;
|
|
for (int i = sphereCount; i < end; i++)
|
|
{
|
|
_matrix4x4Array[i] = Matrix4x4.zero;
|
|
}
|
|
}
|
|
|
|
// UI
|
|
private void CheckButtonsAvailablity()
|
|
{
|
|
if (sphereCount + 1000 > bufferSize)
|
|
addSphere.interactable = false;
|
|
else
|
|
addSphere.interactable = true;
|
|
|
|
if (sphereCount - 1000 < 0)
|
|
removeSphere.interactable = false;
|
|
else
|
|
removeSphere.interactable = true;
|
|
|
|
if (sphereCount <= 0)
|
|
clearSphere.interactable = false;
|
|
else
|
|
clearSphere.interactable = true;
|
|
|
|
sphereCountText.text = "Sphere Count: " + sphereCount;
|
|
}
|
|
|
|
public void SetPositionUpdateFrequency(float updateInterval)
|
|
{
|
|
this.positionUpdateFrequency = updateInterval;
|
|
if(positionUpdateFrequency <= 0)
|
|
positionUpdateFrequencyText.text = "Updating positions cancelled";
|
|
else
|
|
positionUpdateFrequencyText.text = "Updating positions every " + (1 - positionUpdateFrequency + 0.01f).ToString("0.00") + " seconds";
|
|
}
|
|
|
|
public void SetScaleUpdateFrequency(float updateInterval)
|
|
{
|
|
this.scaleUpdateFrequency = updateInterval;
|
|
if (scaleUpdateFrequency <= 0)
|
|
scaleUpdateFrequencyText.text = "Updating scales cancelled";
|
|
else
|
|
scaleUpdateFrequencyText.text = "Updating scales every " + (1 - scaleUpdateFrequency + 0.01f).ToString("0.00") + " seconds";
|
|
}
|
|
|
|
public void SetColorUpdateFrequency(float updateInterval)
|
|
{
|
|
this.colorUpdateFrequency = updateInterval;
|
|
if (colorUpdateFrequency <= 0)
|
|
colorUpdateFrequencyText.text = "Updating colors cancelled";
|
|
else
|
|
colorUpdateFrequencyText.text = "Updating colors every " + (1 - colorUpdateFrequency + 0.01f).ToString("0.00") + " seconds";
|
|
}
|
|
|
|
public void AddSpheres()
|
|
{
|
|
int previousSphereCount = sphereCount;
|
|
AddMatrix4x4ToArray(1000);
|
|
// UI
|
|
CheckButtonsAvailablity();
|
|
// set updated transform data
|
|
GPUInstancerAPI.UpdateVisibilityBufferWithMatrix4x4Array(prefabManager, prefab.prefabPrototype, _matrix4x4Array,
|
|
previousSphereCount, previousSphereCount, 1000);
|
|
GPUInstancerAPI.SetInstanceCount(prefabManager, prefab.prefabPrototype, sphereCount);
|
|
}
|
|
|
|
public void RemoveSpheres()
|
|
{
|
|
RemoveMatrix4x4FromArray(1000);
|
|
// UI
|
|
CheckButtonsAvailablity();
|
|
// set updated transform data
|
|
GPUInstancerAPI.UpdateVisibilityBufferWithMatrix4x4Array(prefabManager, prefab.prefabPrototype, _matrix4x4Array,
|
|
sphereCount, sphereCount, 1000);
|
|
GPUInstancerAPI.SetInstanceCount(prefabManager, prefab.prefabPrototype, sphereCount);
|
|
}
|
|
|
|
public void ClearSpheres()
|
|
{
|
|
sphereCount = 0;
|
|
// UI
|
|
CheckButtonsAvailablity();
|
|
// clear array
|
|
_matrix4x4Array = new Matrix4x4[bufferSize];
|
|
// set updated transform data
|
|
GPUInstancerAPI.UpdateVisibilityBufferWithMatrix4x4Array(prefabManager, prefab.prefabPrototype, _matrix4x4Array);
|
|
GPUInstancerAPI.SetInstanceCount(prefabManager, prefab.prefabPrototype, sphereCount);
|
|
}
|
|
}
|
|
} |