extract noise to file
This commit is contained in:
parent
3a0ccfdbe8
commit
2883c69346
202
src/gfx.c
202
src/gfx.c
|
@ -1,5 +1,4 @@
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
#include "random.h"
|
|
||||||
|
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
// position color uvs
|
// position color uvs
|
||||||
|
@ -196,184 +195,33 @@ int createTextures(int width, int height, struct Shaders shaders, struct Texture
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates a noise texture in active texture 1
|
|
||||||
GLuint createWhiteNoiseTexture(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);
|
|
||||||
|
|
||||||
float* data = (float*)malloc(length*sizeof(float));
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
data[i] = randomFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void generateBlueNoisePoints(vec2* points, int m, int n)
|
|
||||||
{
|
|
||||||
float start = now();
|
|
||||||
float elapsed;
|
|
||||||
int candidatesTested = 0;
|
|
||||||
|
|
||||||
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];
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
candidatesTested += i;
|
|
||||||
|
|
||||||
float killAfter = 10.0;
|
|
||||||
elapsed = now() - start;
|
|
||||||
if (elapsed > killAfter)
|
|
||||||
{
|
|
||||||
printf("noise generation took too long, exiting\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
elapsed = now() - start;
|
|
||||||
printf("generated %d blue noise (m=%d) points from %d candidates in %fs\n",
|
|
||||||
n,
|
|
||||||
m,
|
|
||||||
candidatesTested,
|
|
||||||
elapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
// blue noise gen parameters
|
|
||||||
int m = 10; // roughly controls the evenness...?
|
|
||||||
int n = 100; // number of points to generate
|
|
||||||
|
|
||||||
// for each channel
|
|
||||||
for (int channel = 0; channel < channels; channel++)
|
|
||||||
{
|
|
||||||
// generate a bunch of points
|
|
||||||
vec2 points[n];
|
|
||||||
generateBlueNoisePoints(points, m, n);
|
|
||||||
|
|
||||||
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};
|
|
||||||
|
|
||||||
float value = 0.0f;
|
|
||||||
int componentIdx = i * channels + channel;
|
|
||||||
for (int j = 0; j < n; j++)
|
|
||||||
{
|
|
||||||
float d = glm_vec2_distance(points[j], pixel);
|
|
||||||
//value += 1.0f / (d*d);
|
|
||||||
|
|
||||||
float r = 0.01;
|
|
||||||
if (d < r)
|
|
||||||
{
|
|
||||||
data[componentIdx] = 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//data[componentIdx] = value / (float)n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
GLuint createNoiseTexture(int width, int height)
|
||||||
{
|
{
|
||||||
//return createWhiteNoiseTexture(width, height);
|
// same init steps as with a regular texture
|
||||||
return createBlueNoiseTexture(width, height);
|
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;
|
||||||
|
float* data = (float*)malloc(length*sizeof(float));
|
||||||
|
|
||||||
|
//writeWhiteNoiseToTexture(data, width, height);
|
||||||
|
writeBlueNoiseToTexture(data, width, height);
|
||||||
|
|
||||||
|
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 createWriteOnlyTexture(int width, int height)
|
GLuint createWriteOnlyTexture(int width, int height)
|
||||||
|
|
|
@ -6,11 +6,8 @@
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_opengl.h>
|
#include <SDL2/SDL_opengl.h>
|
||||||
|
|
||||||
#include <cglm/vec2.h>
|
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "random.h"
|
#include "noise.h"
|
||||||
#include "clock.h"
|
|
||||||
|
|
||||||
struct Shaders
|
struct Shaders
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
#include "noise.h"
|
||||||
|
|
||||||
|
void writeWhiteNoiseToTexture(float* data, int width, int height)
|
||||||
|
{
|
||||||
|
int channels = 4; // rgba
|
||||||
|
int length = width*height*channels;
|
||||||
|
|
||||||
|
printf("generating %d random floats\n", length);
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = randomFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateBlueNoisePoints(vec2* points, int m, int n)
|
||||||
|
{
|
||||||
|
float start = now();
|
||||||
|
float elapsed;
|
||||||
|
int candidatesTested = 0;
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
candidatesTested += i;
|
||||||
|
|
||||||
|
float killAfter = 10.0;
|
||||||
|
elapsed = now() - start;
|
||||||
|
if (elapsed > killAfter)
|
||||||
|
{
|
||||||
|
printf("noise generation took too long (%fs), exiting\n", elapsed);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsed = now() - start;
|
||||||
|
printf("generated %d blue noise (m=%d) points from %d candidates in %fs\n",
|
||||||
|
n,
|
||||||
|
m,
|
||||||
|
candidatesTested,
|
||||||
|
elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeBlueNoiseToTexture(float* data, int width, int height)
|
||||||
|
{
|
||||||
|
printf("generating blue noise\n");
|
||||||
|
int channels = 4;
|
||||||
|
|
||||||
|
// blue noise gen parameters
|
||||||
|
int m = 10; // roughly controls the evenness...?
|
||||||
|
int n = 100; // number of points to generate
|
||||||
|
|
||||||
|
// for each channel
|
||||||
|
for (int channel = 0; channel < channels; channel++)
|
||||||
|
{
|
||||||
|
// generate a bunch of points
|
||||||
|
vec2 points[n];
|
||||||
|
generateBlueNoisePoints(points, m, n);
|
||||||
|
|
||||||
|
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};
|
||||||
|
|
||||||
|
//float value = 0.0f;
|
||||||
|
int componentIdx = i * channels + channel;
|
||||||
|
for (int j = 0; j < n; j++)
|
||||||
|
{
|
||||||
|
float d = glm_vec2_distance(points[j], pixel);
|
||||||
|
//value += 1.0f / (d*d);
|
||||||
|
|
||||||
|
float r = 0.01;
|
||||||
|
if (d < r)
|
||||||
|
{
|
||||||
|
data[componentIdx] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//data[componentIdx] = value / (float)n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GL/glew.h"
|
||||||
|
#include <cglm/vec2.h>
|
||||||
|
|
||||||
|
#include "io.h"
|
||||||
|
#include "random.h"
|
||||||
|
#include "clock.h"
|
||||||
|
|
||||||
|
void writeWhiteNoiseToTexture(float* data, int width, int height);
|
||||||
|
|
||||||
|
void generateBlueNoisePoints(vec2* points, int m, int n);
|
||||||
|
void writeBlueNoiseToTexture(float* data, int width, int height);
|
Loading…
Reference in New Issue