如图,生成Voronoi图形,代码如下。
// web* src = https://gist.github.com/andrew-raphael-lukasik/cc9d61edbbb44ecb4956c6cb69363a8e using UnityEngine; using Unity.Mathematics; using Unity.Jobs; using Unity.Collections; using Unity.Profiling;[ExecuteInEditMode] public class VoronoiTextureBurstJobComponent : MonoBehaviour {[SerializeField][Min(1)] uint _seed = 769;[SerializeField][Range(2,512)] int _width = 300, _height = 300;[SerializeField][Range(1,64)] int _numRandomPoints = 3;Texture2D _texture;NativeList<ushort2> _points;uint lastSeedUsed = 0;void OnValidate (){bool inputChanged = false;if( !_points.IsCreated ){_points = new NativeList<ushort2>( Allocator.Persistent );inputChanged = true;}if( _points.Length!=_numRandomPoints ){_points.Length = _numRandomPoints;inputChanged = true;}if( _texture==null || _texture.width!=_width || _texture.height!=_height ){if( _texture==null ) DestroyItWillYou( _texture );_texture = new Texture2D( _width , _height , TextureFormat.RGBA32 , mipCount:0 , linear:true );inputChanged = true;}if( inputChanged || _seed!=lastSeedUsed ){lastSeedUsed = _seed;var watch = System.Diagnostics.Stopwatch.StartNew();var dep = new FillRandomPointsJob{TextureWidth = _width ,TextureHeight = _height ,Seed = _seed ,Points = _points ,}.Schedule();NativeArray<RGBA32> textureData = _texture.GetRawTextureData<RGBA32>();new GenerateVoronoiDiagramJob{Points = _points ,TextureWidth = _width ,TextureHeight = _height ,TextureOutput = textureData ,}.Schedule( textureData.Length , _width , dep ).Complete();_texture.Apply();Debug.Log( $"jobs took {watch.ElapsedMilliseconds} [ms] to complete");}}void OnEnable ()=> OnValidate();void OnDisable (){if( _texture!=null ) DestroyItWillYou(_texture);if( _points.IsCreated ) _points.Dispose();}void OnGUI ()=> GUI.DrawTexture( new Rect(0,0,_width,_height) , _texture );void DestroyItWillYou ( Object obj ){if( Application.isPlaying ) Destroy( obj );else DestroyImmediate( obj );}[Unity.Burst.BurstCompile]struct FillRandomPointsJob : IJob{public int TextureWidth, TextureHeight;public uint Seed;[WriteOnly] public NativeArray<ushort2> Points;void IJob.Execute (){var rnd = new Unity.Mathematics.Random( Seed );int len = Points.Length;for( int i=0 ; i<len ; i++ )Points[i] = new ushort2{ x=(ushort)rnd.NextInt(TextureWidth) , y=(ushort)rnd.NextInt(TextureHeight) };}}[Unity.Burst.BurstCompile]struct GenerateVoronoiDiagramJob : IJobParallelFor{[ReadOnly] public NativeArray<ushort2> Points;public int TextureWidth, TextureHeight;[WriteOnly] public NativeArray<RGBA32> TextureOutput;void IJobParallelFor.Execute ( int jobIndex ){float2 pixelPos = new int2{ x=jobIndex%TextureWidth , y=jobIndex/TextureWidth };float pointDist = float.MaxValue;int pointIndex = -1;for( int i=Points.Length-1 ; i!=-1 ; i-- ){float2 pointPos = new float2{ x=Points[i].x , y=Points[i].y };float dist = math.lengthsq( pointPos - pixelPos );// dist sq// float2 vec = math.abs( pointPos - pixelPos );// float dist = vec.x + vec.y;// manhattan distanceif( dist<pointDist ){pointDist = dist;pointIndex = i;}if( dist<math.max(math.min(TextureWidth*0.01f,TextureHeight*0.01f),1) ){TextureOutput[jobIndex] = new RGBA32{ r=0 , g=0 , b=0 , a=255 };return;}}RGBA32 colorFromCoord;{ushort2 pointCoord = Points[pointIndex];float2 f = new float2{ x=pointCoord.x , y=pointCoord.y } / ( new float2{ x=TextureWidth , y=TextureHeight } - new float2{ x=1 , y=1 } );byte r = (byte)( 255*f.x );byte g = (byte)( 255*f.y );byte b = (byte)( (r+g)%255 );colorFromCoord = new RGBA32{ r=r , g=g , b=b , a=255 };}TextureOutput[jobIndex] = colorFromCoord;}}struct ushort2 { public ushort x, y; }struct RGBA32 { public byte r, g, b, a; }}