generate blue noise points
This commit is contained in:
parent
67d227deed
commit
089458476f
126
src/gfx.c
126
src/gfx.c
|
@ -197,7 +197,7 @@ int createTextures(int width, int height, struct Shaders shaders, struct Texture
|
|||
}
|
||||
|
||||
// creates a noise texture in active texture 1
|
||||
GLuint createNoiseTexture(int width, int height)
|
||||
GLuint createWhiteNoiseTexture(int width, int height)
|
||||
{
|
||||
// same init steps as with a regular texture
|
||||
GLuint texture;
|
||||
|
@ -230,6 +230,130 @@ GLuint createNoiseTexture(int width, int height)
|
|||
return texture;
|
||||
}
|
||||
|
||||
void generateBlueNoisePoints(vec2* points, int m, int n)
|
||||
{
|
||||
vec2 firstSample = {randomFloat(), randomFloat()};
|
||||
struct Candidate
|
||||
{
|
||||
vec2 pos;
|
||||
// distance to closest point already in pattern
|
||||
float distance;
|
||||
};
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
// generate a bunch of candidates
|
||||
int count = m * i;
|
||||
struct Candidate candidates[count];
|
||||
//int closest = -1;
|
||||
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
struct Candidate* c = &candidates[j];
|
||||
|
||||
c->pos[0] = randomFloat();
|
||||
c->pos[1] = randomFloat();
|
||||
// the largest distance we should expect is sqrt(2),
|
||||
// so pick a maximum larger than that
|
||||
c->distance = 1.5;
|
||||
|
||||
// get the distance of the closest point already in the pattern
|
||||
for (int k = 0; k < i; k++)
|
||||
{
|
||||
float distance = glm_vec2_distance(c->pos, points[k]);
|
||||
if (distance < c->distance)
|
||||
{
|
||||
c->distance = distance;
|
||||
//closest = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// of our candidates, now determine which of them has the furthest
|
||||
// closest-distance
|
||||
int furthest = -1;
|
||||
float furthestDistance = 0.0;
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
if (candidates[j].distance > furthestDistance)
|
||||
{
|
||||
furthest = j;
|
||||
furthestDistance = candidates[j].distance;
|
||||
}
|
||||
}
|
||||
|
||||
glm_vec2_copy(candidates[furthest].pos, points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
GLuint createBlueNoiseTexture(int width, int height)
|
||||
{
|
||||
// same init steps as with a regular texture
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_REPEAT);
|
||||
|
||||
int channels = 4; // rgba
|
||||
int length = width*height*channels;
|
||||
//printf("generating %d random floats\n", length);
|
||||
printf("generating blue noise\n");
|
||||
|
||||
float* data = (float*)malloc(length*sizeof(float));
|
||||
|
||||
// generate a bunch of points
|
||||
int m = 100;
|
||||
int n = 100;
|
||||
vec2 points[n];
|
||||
generateBlueNoisePoints(points, m, n);
|
||||
|
||||
// use those points to generate a texture
|
||||
|
||||
//for (int i = 0; i < length; i++)
|
||||
//{
|
||||
// data[i] = randomFloat();
|
||||
//}
|
||||
|
||||
for (int i = 0; i < width*height; i++)
|
||||
{
|
||||
int pixelIdx = i;
|
||||
int x = pixelIdx % width;
|
||||
int y = pixelIdx / width;
|
||||
float u = x / (float)width;
|
||||
float v = y / (float)height;
|
||||
vec2 pixel = {u,v};
|
||||
|
||||
for (int j = 0; j < n; j++)
|
||||
{
|
||||
float d = glm_vec2_distance(points[j], pixel);
|
||||
float r = 0.01;
|
||||
if (d < r)
|
||||
{
|
||||
data[i * channels + 2] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data);
|
||||
glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
free(data);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
GLuint createNoiseTexture(int width, int height)
|
||||
{
|
||||
//return createWhiteNoiseTexture(width, height);
|
||||
return createBlueNoiseTexture(width, height);
|
||||
}
|
||||
|
||||
GLuint createWriteOnlyTexture(int width, int height)
|
||||
{
|
||||
GLuint texture;
|
||||
|
|
Loading…
Reference in New Issue