код проверки
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public int seed = 0;
public float scale = 10;
int w = 500;
int h = 500;
Texture2D text;
Color[] pixels;
Noise noise;
void Start()
{
text = new Texture2D(w, h);
noise = new Noise(seed);
pixels = new Color[w * h];
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++) {
float nx = (float)x / w * scale;
float ny = (float)y / h * scale;
float nz = 0;
float nw = 0;
float value = noise.GetNoise(nx, ny, nz, nw);
pixels[x + y * w] = new Color(value, value, value);
}
text.SetPixels(pixels);
text.Apply();
}
void Update()
{
}
void OnGUI()
{
GUI.DrawTexture(new Rect(30, 10, w, h), text);
}
}
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public int seed = 0;
public float scale = 10;
int w = 500;
int h = 500;
Texture2D text;
Color[] pixels;
Noise noise;
void Start()
{
text = new Texture2D(w, h);
noise = new Noise(seed);
pixels = new Color[w * h];
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++) {
float nx = (float)x / w * scale;
float ny = (float)y / h * scale;
float nz = 0;
float nw = 0;
float value = noise.GetNoise(nx, ny, nz, nw);
pixels[x + y * w] = new Color(value, value, value);
}
text.SetPixels(pixels);
text.Apply();
}
void Update()
{
}
void OnGUI()
{
GUI.DrawTexture(new Rect(30, 10, w, h), text);
}
}
код генератора шума
Синтаксис:
Используется csharp
using UnityEngine;
public class Noise
{
Vector4[] randomVectors;
byte[] randomTable;
public Noise(int seed)
{
var random = new System.Random(seed);
randomTable = new byte[1024];
random.NextBytes(randomTable);
randomVectors = new Vector4[81];
float v = 0;
while (v < randomVectors.Length) {
int x = Mathf.FloorToInt(v / 27);
int y = Mathf.FloorToInt((v - x * 27) / 9);
int z = Mathf.FloorToInt((v - x * 27 - y * 9) / 3);
int w = (int)v - x * 27 - y * 9 - z * 3;
randomVectors[(int)v] = new Vector4(x - 1, y - 1, z - 1, w - 1);
v++;
}
}
//Получаем случайный вектор для X, Y, Z и W
Vector2 GetRandomVector(int x, int y, int z, int w)
{
int v = (int)(((x * 183) ^ (y * 297) ^ (z * 174) ^ (w * 193) + 480) & 1023);
v = randomTable[v] & 80;
return randomVectors[v];
}
//Сглаживание кривой
float Curve(float t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
//Функция шума
public float GetNoise(float fx, float fy, float fz, float fw)
{
int pointX = Mathf.FloorToInt(fx);
int pointY = Mathf.FloorToInt(fy);
int pointZ = Mathf.FloorToInt(fz);
int pointW = Mathf.FloorToInt(fw);
float pointInsideX = fx - pointX;
float pointInsideY = fy - pointY;
float pointInsideZ = fz - pointZ;
float pointInsideW = fw - pointW;
float[] points = new float[16];
int[] offsetX = new int[]{ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
int[] offsetY = new int[]{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 };
int[] offsetZ = new int[]{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
int[] offsetW = new int[]{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 };
for (int p = 0; p < points.Length; p++) {
Vector4 gradient = GetRandomVector(pointX + offsetX[p],
pointY + offsetY[p],
pointZ + offsetZ[p],
pointW + offsetW[p]);
Vector4 distance = new Vector4(pointInsideX - offsetX[p],
pointInsideY - offsetY[p],
pointInsideZ - offsetZ[p],
pointInsideW - offsetW[p]);
points[p] = Vector4.Dot(gradient, distance);
}
pointInsideX = Curve(pointInsideX);
pointInsideY = Curve(pointInsideY);
pointInsideZ = Curve(pointInsideZ);
pointInsideW = Curve(pointInsideW);
float x1 = Mathf.Lerp(points[0], points[1], pointInsideX);
float x2 = Mathf.Lerp(points[2], points[3], pointInsideX);
float x3 = Mathf.Lerp(points[4], points[5], pointInsideX);
float x4 = Mathf.Lerp(points[6], points[7], pointInsideX);
float x5 = Mathf.Lerp(points[8], points[9], pointInsideX);
float x6 = Mathf.Lerp(points[10], points[11], pointInsideX);
float x7 = Mathf.Lerp(points[12], points[13], pointInsideX);
float x8 = Mathf.Lerp(points[14], points[15], pointInsideX);
float y1 = Mathf.Lerp(x1, x2, pointInsideY);
float y2 = Mathf.Lerp(x3, x4, pointInsideY);
float y3 = Mathf.Lerp(x5, x6, pointInsideY);
float y4 = Mathf.Lerp(x7, x8, pointInsideY);
float z1 = Mathf.Lerp(y1, y2, pointInsideZ);
float z2 = Mathf.Lerp(y3, y4, pointInsideZ);
float w1 = Mathf.Lerp(z1, z2, pointInsideW);
return (w1 + 1) / 2;
}
}
public class Noise
{
Vector4[] randomVectors;
byte[] randomTable;
public Noise(int seed)
{
var random = new System.Random(seed);
randomTable = new byte[1024];
random.NextBytes(randomTable);
randomVectors = new Vector4[81];
float v = 0;
while (v < randomVectors.Length) {
int x = Mathf.FloorToInt(v / 27);
int y = Mathf.FloorToInt((v - x * 27) / 9);
int z = Mathf.FloorToInt((v - x * 27 - y * 9) / 3);
int w = (int)v - x * 27 - y * 9 - z * 3;
randomVectors[(int)v] = new Vector4(x - 1, y - 1, z - 1, w - 1);
v++;
}
}
//Получаем случайный вектор для X, Y, Z и W
Vector2 GetRandomVector(int x, int y, int z, int w)
{
int v = (int)(((x * 183) ^ (y * 297) ^ (z * 174) ^ (w * 193) + 480) & 1023);
v = randomTable[v] & 80;
return randomVectors[v];
}
//Сглаживание кривой
float Curve(float t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
//Функция шума
public float GetNoise(float fx, float fy, float fz, float fw)
{
int pointX = Mathf.FloorToInt(fx);
int pointY = Mathf.FloorToInt(fy);
int pointZ = Mathf.FloorToInt(fz);
int pointW = Mathf.FloorToInt(fw);
float pointInsideX = fx - pointX;
float pointInsideY = fy - pointY;
float pointInsideZ = fz - pointZ;
float pointInsideW = fw - pointW;
float[] points = new float[16];
int[] offsetX = new int[]{ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
int[] offsetY = new int[]{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 };
int[] offsetZ = new int[]{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 };
int[] offsetW = new int[]{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 };
for (int p = 0; p < points.Length; p++) {
Vector4 gradient = GetRandomVector(pointX + offsetX[p],
pointY + offsetY[p],
pointZ + offsetZ[p],
pointW + offsetW[p]);
Vector4 distance = new Vector4(pointInsideX - offsetX[p],
pointInsideY - offsetY[p],
pointInsideZ - offsetZ[p],
pointInsideW - offsetW[p]);
points[p] = Vector4.Dot(gradient, distance);
}
pointInsideX = Curve(pointInsideX);
pointInsideY = Curve(pointInsideY);
pointInsideZ = Curve(pointInsideZ);
pointInsideW = Curve(pointInsideW);
float x1 = Mathf.Lerp(points[0], points[1], pointInsideX);
float x2 = Mathf.Lerp(points[2], points[3], pointInsideX);
float x3 = Mathf.Lerp(points[4], points[5], pointInsideX);
float x4 = Mathf.Lerp(points[6], points[7], pointInsideX);
float x5 = Mathf.Lerp(points[8], points[9], pointInsideX);
float x6 = Mathf.Lerp(points[10], points[11], pointInsideX);
float x7 = Mathf.Lerp(points[12], points[13], pointInsideX);
float x8 = Mathf.Lerp(points[14], points[15], pointInsideX);
float y1 = Mathf.Lerp(x1, x2, pointInsideY);
float y2 = Mathf.Lerp(x3, x4, pointInsideY);
float y3 = Mathf.Lerp(x5, x6, pointInsideY);
float y4 = Mathf.Lerp(x7, x8, pointInsideY);
float z1 = Mathf.Lerp(y1, y2, pointInsideZ);
float z2 = Mathf.Lerp(y3, y4, pointInsideZ);
float w1 = Mathf.Lerp(z1, z2, pointInsideW);
return (w1 + 1) / 2;
}
}