Skip to content

Commit

Permalink
[New] StreamLines GPU
Browse files Browse the repository at this point in the history
  • Loading branch information
Nico04 committed Mar 2, 2019
1 parent 71b6247 commit ca04317
Show file tree
Hide file tree
Showing 15 changed files with 2,031 additions and 20,843 deletions.
19 changes: 14 additions & 5 deletions Assets/Scenes/Main.unity
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!4 &1235011586
Transform:
m_ObjectHideFlags: 0
Expand All @@ -1622,7 +1622,7 @@ VFXRenderer:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1235011585}
m_Enabled: 0
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
Expand Down Expand Up @@ -1680,6 +1680,9 @@ VisualEffect:
m_Array: []
m_Uint:
m_Array:
- m_Value: 8
m_Name: SegmentCount
m_Overridden: 0
- m_Value: 3
m_Name: TextureWidth
m_Overridden: 0
Expand All @@ -1693,6 +1696,12 @@ VisualEffect:
m_Array: []
m_NamedObject:
m_Array:
- m_Value: {fileID: 0}
m_Name: Alphas
m_Overridden: 0
- m_Value: {fileID: 0}
m_Name: Colors
m_Overridden: 0
- m_Value: {fileID: 2800000, guid: f1194d9b3428f524aac4396f56a868c9, type: 3}
m_Name: Trajectories
m_Overridden: 0
Expand Down Expand Up @@ -2125,9 +2134,9 @@ MonoBehaviour:
- Tracers Visibility <i>(default : <color=#ffffffff>c</color>)</i>\r\n - Tracers
GPU Visibility <i>(default : <color=#ffffffff>Alt + c</color>)</i>\r\n - Streamlines
Visibility <i>(default : <color=#ffffffff>v</color>)</i>\r\n - Streamlines GPU
Visibility <i>(default : <color=#ffffffff>Alt + v</color>)</i>\r <color=#ffffffff>[SOON]</color>\n
- Grid Maps Visibility <i>(default : <color=#ffffffff>b</color>)</i>\r\n - Pause/Resume
<i>(default : <color=#ffffffff>Escape</color>)</i></color>\n\n<color=#858585><size=14>(Mapping
Visibility <i>(default : <color=#ffffffff>Alt + v</color>)</i>\r\n - Grid Maps
Visibility <i>(default : <color=#ffffffff>b</color>)</i>\r\n - Pause/Resume <i>(default
: <color=#ffffffff>Escape</color>)</i></color>\n\n<color=#858585><size=14>(Mapping
can be changed at startup in the input section)</size></color>"
--- !u!222 &1573287552
CanvasRenderer:
Expand Down
4 changes: 0 additions & 4 deletions Assets/Scripts/Builders/Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ public void CancelBuild() {
}

public Builder() {
//Disable automatic behaviour for StreamlinesGpuBuilder so it doesn't appears is the App, because it is not ready for production
if (this is StreamlinesGpuBuilder)
return;

Builders.Add(this);
_buildersIsSorted = false;
}
Expand Down
85 changes: 66 additions & 19 deletions Assets/Scripts/Builders/StreamlinesGpuBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,85 @@ protected override void Start() {
_visualEffect = GetComponent<VisualEffect>();
}

private const float SampleValue = 1;
private Texture2D _texture; //We need to keep a ref to the texture because SetTexture only make a binding.
private const int SampleValue = 4;
private Texture2D _positionsTexture; //We need to keep a ref to the texture because SetTexture only make a binding.
private Texture2D _colorsTexture; //We need to keep a ref to the texture because SetTexture only make a binding.
private Texture2D _alphasTexture; //We need to keep a ref to the texture because SetTexture only make a binding.
protected override async Task Build(CancellationToken cancellationToken) {
//Get trajectories
var trajectories = await TrajectoriesManager.Instance.GetInjectionGridTrajectories(cancellationToken).ConfigureAwait(true);

//Get texture size
//Create textures
//Unity max texture width or height is 16k : cannot use a mono-line texture.
int size = (int)Math.Ceiling(Math.Sqrt(trajectories.Sum(t => Math.Ceiling(t.Points.Length / SampleValue))));
_texture = new Texture2D(size, size, TextureFormat.RGBAFloat, false) {
int size = (int)Math.Ceiling(Math.Sqrt(trajectories.Sum(t => Math.Ceiling((float)t.Points.Length / SampleValue))));
_positionsTexture = new Texture2D(size, size, TextureFormat.RGBAFloat, false) {
filterMode = FilterMode.Point,
wrapMode = TextureWrapMode.Clamp //Important for vfx index access
};
};

var textureData = _texture.GetRawTextureData<Vector4>();

_colorsTexture = new Texture2D(size, size, TextureFormat.RGB24, false) {
filterMode = FilterMode.Point,
wrapMode = TextureWrapMode.Clamp //Important for vfx index access
};

_alphasTexture = new Texture2D(size, size, TextureFormat.RFloat, false) {
filterMode = FilterMode.Point,
wrapMode = TextureWrapMode.Clamp //Important for vfx index access
};

//Get textures data
var positionsTextureData = _positionsTexture.GetRawTextureData<Vector4>();
var colorsTextureData = _colorsTexture.GetPixels32();
var alphasTextureData = _alphasTexture.GetRawTextureData<float>();

//Set pixels data
int currentPixelIndex = 0;
foreach (var trajectory in trajectories) {
for (var p = 0; p < trajectory.Points.Length; p += (int)SampleValue) {
textureData[currentPixelIndex++] = trajectory.Points[p];
await Task.Run(() => {
foreach (var trajectory in trajectories) {
cancellationToken.ThrowIfCancellationRequested();
int pNext;

for (var p = 0; p < trajectory.Points.Length; p = pNext) {
pNext = p + SampleValue;

//Position
positionsTextureData[currentPixelIndex] = trajectory.Points[p];

//Color (distance-proportional
//If next point exist on this trajectory
if (pNext < trajectory.Points.Length) {
//Compute the average distance
int i = p;
float sumDist = 0f;
while (i < pNext) {
sumDist += trajectory.Distances[i];
i++;
}

float distAverage = sumDist / (pNext - p);
colorsTextureData[currentPixelIndex] = Color.HSVToRGB(distAverage.Remap(0, 3 * TrajectoriesManager.Instance.TrajectoriesAverageDistance, 0.66f, 1f, true), 1f, 1f); //color scale commonly use (3 * average) as maximum

//Set alpha to visible (default value is 0f = invisible)
alphasTextureData[currentPixelIndex] = 1f;
}

currentPixelIndex++;
}
}
}
}, cancellationToken).ConfigureAwait(true);

_texture.Apply();

//Apply texture modif
_positionsTexture.Apply();
_colorsTexture.SetPixels32(colorsTextureData);
_colorsTexture.Apply();
_alphasTexture.Apply();

//Apply value to VFX
_visualEffect.Reinit(); //Reset vfx otherwise all particules are mixed up between trajectories (colors are mixed)
_visualEffect.SetUInt("TextureWidth", Convert.ToUInt32(_texture.width));
_visualEffect.SetFloat("DistanceMax", TrajectoriesManager.Instance.TrajectoriesDistanceMax);
_visualEffect.SetFloat("DistanceColorMax", 3 * TrajectoriesManager.Instance.TrajectoriesAverageDistance); //color scale commonly use (3 * average) as maximum
_visualEffect.SetTexture("Trajectories", _texture);

//Debug.Log($"BuildStreamLines|size={size}|");
_visualEffect.SetUInt("SegmentCount", Convert.ToUInt32(currentPixelIndex - 1));
_visualEffect.SetTexture("Trajectories", _positionsTexture);
_visualEffect.SetTexture("Colors", _colorsTexture);
_visualEffect.SetTexture("Alphas", _alphasTexture);
}
}
87 changes: 27 additions & 60 deletions Assets/Scripts/Builders/TracerInjectionGridGpuBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,43 +48,41 @@ protected override async Task Build(CancellationToken cancellationToken) {
var positionsTextureData = _positionsTexture.GetRawTextureData<Vector4>();
var colorsTextureData = _colorsTexture.GetPixels32();

//Apply value to VFX
_visualEffect.Reinit(); //Reset vfx otherwise all particules are mixed up between trajectories (colors are mixed)
_visualEffect.SetUInt("TracersCount", Convert.ToUInt32(tracersCount));
_visualEffect.SetUInt("PositionsCount", Convert.ToUInt32(positionsCount));
_visualEffect.SetUInt("AnimationSpeed", Convert.ToUInt32(AnimationSpeed));

int tracersSum = 0;

/** Loop on points indices then on trajectories */
var longEnoughTraj = trajectories;
int longEnoughTrajCount = 0;
int maxPointsInOneTraj = trajectories.Max(tr => tr.Points.Length) / tracerSpacing * tracerSpacing;

for (int p = 0; p < maxPointsInOneTraj; p++) {
if (p % tracerSpacing == 0) {
tracersSum += longEnoughTrajCount;
longEnoughTraj = longEnoughTraj.Where(t => p < (int)(t.Points.Length / tracerSpacing) * tracerSpacing).ToArray();
longEnoughTrajCount = longEnoughTraj.Length;
await Task.Run(() => {
var longEnoughTraj = trajectories;
int longEnoughTrajCount = 0;
int maxPointsInOneTraj = trajectories.Max(tr => tr.Points.Length) / tracerSpacing * tracerSpacing;
int tracersSum = 0;
for (int p = 0; p < maxPointsInOneTraj; p++) {
if (p % tracerSpacing == 0) {
tracersSum += longEnoughTrajCount;
longEnoughTraj = longEnoughTraj.Where(t => p < (int) (t.Points.Length / tracerSpacing) * tracerSpacing).ToArray();
longEnoughTrajCount = longEnoughTraj.Length;
}

// Loop on trajectories containing at least p indices
for (int t = 0; t < longEnoughTrajCount; t++) {
var traj = longEnoughTraj[t];
var point = traj.Points[p];

int pixelIndex = t + tracersSum + (p % tracerSpacing) * tracersCount;
positionsTextureData[pixelIndex] = point;
colorsTextureData[pixelIndex] = traj.Color;
}
}
}, cancellationToken).ConfigureAwait(true);

// Loop on trajectories containing at least p indices
for (int t = 0; t < longEnoughTrajCount; t++) {
var traj = longEnoughTraj[t];
var point = traj.Points[p];

int pixelIndex = t + tracersSum + (p % tracerSpacing) * tracersCount;
positionsTextureData[pixelIndex] = point;
colorsTextureData[pixelIndex] = traj.Color;
}
}

//Apply textures modif
_positionsTexture.Apply();
_colorsTexture.SetPixels32(colorsTextureData);
_colorsTexture.Apply();

//Apply value to VFX
//_visualEffect.Reinit();
_visualEffect.Reinit(); //Reset vfx otherwise all particules are mixed up between trajectories (colors are mixed)
_visualEffect.SetUInt("TracersCount", Convert.ToUInt32(tracersCount));
_visualEffect.SetUInt("PositionsCount", Convert.ToUInt32(positionsCount));
_visualEffect.SetUInt("AnimationSpeed", Convert.ToUInt32(AnimationSpeed));
_visualEffect.SetTexture("Positions", _positionsTexture);
_visualEffect.SetTexture("Colors", _colorsTexture);

Expand Down Expand Up @@ -123,37 +121,6 @@ await Task.Run(() =>
}*/
}

/** Old Method
private Texture2D _texture; //We need to keep a ref to the texture because SetTexture only make a binding.
protected override async Task Build(CancellationToken cancellationToken) {
var trajectories = TrajectoriesManager.Instance.Trajectories;
_texture = new Texture2D(trajectories.Max(t => t.Points.Length), trajectories.Length, TextureFormat.RGBAFloat, false);
var textureData = _texture.GetRawTextureData<Vector4>();
for (int y = 0; y < _texture.height; y++) {
var trajectory = trajectories[y];
for (int x = 0; x < trajectory.Points.Length; x++) {
Vector4 pixel = trajectory.Points[x];
pixel.w = trajectory.Points.Length; //Store length of the trajectory in the alpha channel to be used in the vfx
textureData[y * _texture.width + x] = pixel;
}
}
_texture.Apply();
//Apply value to VFX
_visualEffect.Reinit(); //Reset vfx otherwise all particules are mixed up between trajectories (colors are mixed)
_visualEffect.SetUInt("TextureWidth", Convert.ToUInt32(_texture.width));
_visualEffect.SetUInt("TrajectoriesCount", Convert.ToUInt32(trajectories.Length));
_visualEffect.SetTexture("Trajectories", _texture);
}*/

//Scale an input value that goes between 0 and max, to be in range 0 to 1.
private float ScaleToRange01(float value, float max) => value / max;
private static float PositionToColor(float position) => position * 1f / 20;

public int GetTotalParticlesCount() => _visualEffect != null ? _visualEffect.aliveParticleCount : 0;

public void Pause(bool pause) {
Expand Down
7 changes: 7 additions & 0 deletions Assets/Scripts/Helpers/MethodExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public static string ToStringLong(this Vector3 vec) {
return $"({output[0]},{output[1]},{output[2]})";
}*/

public static float Remap(this float value, float currentRangeMin, float currentRangeMax, float newRangeMin, float newRangeMax, bool clamp) {
var newValue = (value - currentRangeMin) / (currentRangeMax - currentRangeMin) * (newRangeMax - newRangeMin) + newRangeMin;
return clamp ? Mathf.Clamp(newValue, newRangeMin, newRangeMax) : newValue;
}

public static Vector3 SetCoordinate(this Vector3 vector, float? x = null, float? y = null, float? z = null) {
if (x != null)
vector.x = x.GetValueOrDefault();
Expand All @@ -68,6 +73,8 @@ public static Vector3 SetCoordinate(this Vector3 vector, float? x = null, float?
return vector;
}

public static Vector4 ToVector4(this Vector3 vector3, float w) => new Vector4(vector3.x, vector3.y, vector3.z, w);

private static readonly System.Diagnostics.Stopwatch StopWatch = new System.Diagnostics.Stopwatch();
public static void LogWithElapsedTime(string message) {
string timeElapsed = Mathf.RoundToInt((float)StopWatch.Elapsed.TotalMilliseconds) + "ms";
Expand Down
4 changes: 2 additions & 2 deletions Assets/Scripts/TrajectoriesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public class Trajectory {
public Vector3 StartPoint => Points[0];

private float[] _distances;
public float[] Distances => _distances ?? (_distances = BuildDistances()); //OPTI remove if streamLine only use Vfx method that doesn't need this.
public float[] Distances => _distances ?? (_distances = BuildDistances());

public enum Types { InjectionGrid, Manual }
public Types Type;
Expand Down Expand Up @@ -271,7 +271,7 @@ public Trajectory(Vector3[] points, Types type, Color? color = null) {
private float[] BuildDistances() {
var distances = new float[Points.Length - 1];
for (int i = 0; i < distances.Length; i++)
distances[i] = Vector3.Distance(Points[i + 1], Points[i]);
distances[i] = Vector3.Distance(Points[i], Points[i + 1]);

return distances;
}
Expand Down
8 changes: 4 additions & 4 deletions Assets/Scripts/UI/VisibilityControler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ private void UpdateBuildersStatus() {
text += "\n" + ColorizeUiText(builder.Name, builder.IsVisible ? Color.white : Color.gray);

//Second part
if (builder.IsBuilding)
text += $" <Building...>";

//Third part
if (builder.Type == Builder.Types.Gpu)
text += " [GPU]";

//Third part
if (builder.IsBuilding)
text += " <Building...>";
}

BuildersStatusText.text = text;
Expand Down
Loading

0 comments on commit ca04317

Please sign in to comment.