-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathProceduralTextureUnsafe.cs
More file actions
89 lines (81 loc) · 2.32 KB
/
ProceduralTextureUnsafe.cs
File metadata and controls
89 lines (81 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using UnityEngine;
using System;
using System.Runtime.InteropServices;
public class ProceduralTextureUnsafe : MonoBehaviour
{
public GameObject Quad;
public int Width = 128;
public int Height = 128;
[Range(1, 16)] public int Quality = 12;
private Texture2D _Texture;
private int _Size;
private IntPtr _Data;
private unsafe int* _Pixels;
unsafe void Init()
{
_Size = Width * Height * sizeof(int);
_Data = Marshal.AllocHGlobal(_Size);
_Texture = new Texture2D(Width, Height, TextureFormat.RGBA32, false);
_Pixels = (int*)_Data.ToPointer();
Quad.GetComponent<Renderer>().material.mainTexture = _Texture;
}
float SandWaves(float x, float y, float h, float time, int octaves, float amplitude, float scale)
{
float radius = 8.0f;
float frequency = 0.03f;
float speed = -0.05f;
for (int i = 0; i < octaves; i++)
{
float s = Mathf.Sin(time * 0.021f) * 0.1f + 0.41f * Mathf.Sin(i * 0.71f + time * 0.02f);
float angle = 1.8f + s * amplitude;
float dx = Mathf.Cos(angle);
float dy = Mathf.Sin(angle);
float t = -1.0f * ((x - scale) * dx + (y - scale) * dy);
float sineWave = Mathf.Sin(time * speed + t * frequency) * radius;
float cosineWave = Mathf.Cos(time * speed + t * frequency) * radius;
x -= cosineWave * dx * 2.0f;
y -= cosineWave * dy * 2.0f;
h -= sineWave;
radius *= 0.72f;
frequency *= 1.27f;
speed *= 1.21f;
}
h = h + 22.0f;
h *= 0.018f;
return h;
}
unsafe void Generate()
{
float scale = 512.0f;
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
int index = y * Width + x;
float uvX = x / (float)Width * scale;
float uvY = y / (float)Height * scale;
float h = SandWaves(uvX, uvY, 0.0f, Time.time * 20.0f, Quality, 1.0f, scale);
byte r = (byte)Mathf.Min((0.3f + h * 1.2f) * 255, 255);
byte g = (byte)Mathf.Min((0.2f + h * 0.9f) * 255, 255);
byte b = (byte)Mathf.Min((0.1f + h * 0.6f) * 255, 255);
byte a = 255;
_Pixels[index] = (a << 24) | (b << 16) | (g << 8) | r;
}
}
_Texture.LoadRawTextureData(_Data, _Size);
_Texture.Apply();
}
void Start()
{
Init();
}
void Update()
{
Generate();
}
void OnDestroy()
{
if (_Data != IntPtr.Zero) Marshal.FreeHGlobal(_Data);
if (_Texture != null) Destroy(_Texture);
}
}