Here is the context. I have been trying to learn Flax Engine by taking Unity tutorials and replicating them in Flax. The current tutorial I am learning uses Unity’s Job System and Burst Compiler to generate a procedure texture with Perlin noise
While I believe Flax’s Job System is different conceptually, I do believe this task is doable but requires some tweaking. However my attempt failed to be performant so I am here to see if there was something I could change to get this to work.
Currently Flax crashed when I try to update per frame with my texture function so I use the stats version to run the same calculations without _tex.SetPixels(colors);
Any ideas or even ways to improve the code in general would be helpful
``using System;
using System.Collections.Generic;
using FlaxEngine;
using FlaxEngine.Utilities;
namespace Game
{
///
/// Perlin Noise Script.
///
///
public class Perlin_DOT : Script
{
[Header("Inscribed")]
public int textureSize = 1080;
public float test = 0.5f;
[Header("Inscribed / Dynamic")]
public float noiseScale = 10;
public Vector2 noiseOffset = Vector2.Zero;
public Vector2 offsetVel = Vector2.UnitX;
MaterialBase _mat;
Texture _tex;
private SpriteRender currentActor;
private Float2 perNoise = new Float2();
public PerlinVars perlinVars = new PerlinVars();
private Color32[] colors;
/// <inheritdoc/>
public override void OnStart()
{
currentActor = Actor.As<SpriteRender>();
_mat = Actor.As<SpriteRender>().Material;
InitTex();
_tex.GetPixels(out colors, 0, 0);
UpdateText();
currentActor.Image = _tex;
//SpriteRender
// Here you can add code that needs to be called when script is created, just before the first game update
}
public void Execute(int ndx)
{
float noiseMult = noiseScale / textureSize;
float minusHalf = -(textureSize * test);
int h = ndx % textureSize;
int v = ndx / textureSize;
Float2 loc;
loc.X = (( h) * noiseMult) + noiseOffset.X;
loc.Y = (( v) * noiseMult) + noiseOffset.Y;
float u = Noise.PerlinNoise(loc);
byte b = (byte)(255 * u );
colors[ndx] = new Color32(b, b, b, 255);
}
private void UpdateText()
{
JobSystem.Execute(Execute, colors.Length);
// Debug.Log($"Length: {jobData.pixels.Length}");
_tex.SetPixels(colors);
}
private void UpdateTextStats()
{
//Precalulate some math
JobSystem.Execute(Execute, colors.Length);
//_tex.SetPixels(jobData.pixels);
}
public float PerlinOctaves(PerlinVars pVars, Float2 xy)
{
float u = 0, lacu = 1, pers = 1, noiseAmt;
for ( int octave = 0; octave < pVars.numOctaves; octave++)
{
if ( octave != 0 )
{
lacu *= pVars.lacunarity;
pers *= pVars.persistence;
}
xy.X *= lacu;
xy.Y *= lacu;
noiseAmt = (Noise.PerlinNoise(xy) - 0.5f) * pers;
u += noiseAmt;
}
return u + 0.5f;
}
private unsafe void InitTex()
{
// Create new texture asset
var texture = Content.CreateVirtualAsset<Texture>();
_tex = texture;
var initData = new TextureBase.InitData();
initData.Width = textureSize;
initData.Height = textureSize;
initData.ArraySize = 1;
initData.Format = PixelFormat.R8G8B8A8_UNorm;
var data = new byte[initData.Width * initData.Height * PixelFormatExtensions.SizeInBytes(initData.Format)];
fixed (byte* dataPtr = data)
{
// Generate pixels data (linear gradient)
var colorsPtr = (Color32*)dataPtr;
for (int y = 0; y < initData.Height; y++)
{
float t1 = (float)y / initData.Height;
var c1 = Color32.Lerp(Color.Red, Color.Blue, t1);
var c2 = Color32.Lerp(Color.Yellow, Color.Green, t1);
for (int x = 0; x < initData.Width; x++)
{
float t2 = (float)x / initData.Width;
colorsPtr[y * initData.Width + x] = Color32.Lerp(c1, c2, t2);
}
}
}
initData.Mips = new[]
{
// Initialize mip maps data container description
new TextureBase.InitData.MipData
{
Data = data,
RowPitch = data.Length / initData.Height,
SlicePitch = data.Length
},
};
texture.Init(ref initData);
}
/// <inheritdoc/>
public override void OnEnable()
{
// Here you can add code that needs to be called when script is enabled (eg. register for events)
}
/// <inheritdoc/>
public override void OnDisable()
{
// Here you can add code that needs to be called when script is disabled (eg. unregister from events)
}
/// <inheritdoc/>
public override void OnUpdate()
{
// Here you can add code that needs to be called every frame
//noiseOffset += offsetVel * Time.DeltaTime;
UpdateTextStats();
}
public override void OnDestroy()
{
// Ensure to cleanup resources
FlaxEngine.Object.Destroy(ref _tex);
}
}
}