Skip to content

Instantly share code, notes, and snippets.

@Fewes
Last active May 21, 2022 08:49
Show Gist options
  • Save Fewes/3487ad19d18a91b0d8c24ce8b07273f1 to your computer and use it in GitHub Desktop.
Save Fewes/3487ad19d18a91b0d8c24ce8b07273f1 to your computer and use it in GitHub Desktop.
// Uniform random distribution.
// Great for effects with a limited number of samples, like SSAO.
public static Vector4[] UniformKernel(int n, bool hemisphere)
{
Random.State state = Random.state;
// Set the random seed so repeat calls with n samples always returns the same result
Random.InitState(0);
Vector4[] result = new Vector4[n];
for (int i = 0; i < n; i++)
{
result[i] = new Vector3(Random.value * 2 - 1, hemisphere ? Random.value : Random.value * 2 - 1, Random.value * 2 - 1).normalized;
// Scale vector length with sample index. This is great for SSAO implementations. Scalar length is stored in .w
float d = (i + 0.5f) / n;
result[i].w = 1;
result[i] *= Mathf.Lerp(0.1f, 1.0f, d * d);
}
Random.state = state;
return result;
}
// Fibonacci or "sunflower" distribution.
// Great for getting an even result when baking things, like ambient occlusion.
public static Vector4[] SunflowerKernel(int n, bool hemisphere)
{
Vector4[] result = new Vector4[n];
float phi = Mathf.PI * (3f - Mathf.Sqrt(5f)); // Golden angle in radians
for (int i = 0; i < n; i++)
{
float y = 1 - ((float)i / (n - 1)) * 2; // Y goes from 1 to -1
float radius = Mathf.Sqrt(1 - y * y); // Radius at y
float theta = phi * i; // Golden angle increment
float x = Mathf.Cos(theta) * radius;
float z = Mathf.Sin(theta) * radius;
result[i] = new Vector3(x, hemisphere ? Mathf.Abs(y) : y, z);
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment