Compare commits
	
		
			4 Commits
		
	
	
		
			main
			...
			blue-noise
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2883c69346 | |||
| 3a0ccfdbe8 | |||
| 089458476f | |||
| 67d227deed | 
@ -53,6 +53,6 @@ void main()
 | 
			
		||||
    float kSigma = 7.0;
 | 
			
		||||
    float threshold = 0.3;
 | 
			
		||||
 | 
			
		||||
    FragColor = denoise(ourTexture, TexCoord, sigma, kSigma, threshold);
 | 
			
		||||
    //FragColor = texture(ourTexture, TexCoord);
 | 
			
		||||
    //FragColor = denoise(ourTexture, TexCoord, sigma, kSigma, threshold);
 | 
			
		||||
    FragColor = texture(ourTexture, TexCoord);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -108,6 +108,8 @@ void main()
 | 
			
		||||
 | 
			
		||||
    pixel.xyz = mix(pixel.xyz, vec3(1.0), depth);
 | 
			
		||||
 | 
			
		||||
    pixel.xyz = texture(_noise, uv*.5-.5).xyz;
 | 
			
		||||
 | 
			
		||||
    // output to a specific pixel in the image
 | 
			
		||||
    imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/gfx.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/gfx.c
									
									
									
									
									
								
							@ -1,5 +1,4 @@
 | 
			
		||||
#include "gfx.h"
 | 
			
		||||
#include "random.h"
 | 
			
		||||
 | 
			
		||||
float vertices[] = {
 | 
			
		||||
    // position             color               uvs
 | 
			
		||||
@ -196,7 +195,6 @@ int createTextures(int width, int height, struct Shaders shaders, struct Texture
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// creates a noise texture in active texture 1
 | 
			
		||||
GLuint createNoiseTexture(int width, int height)
 | 
			
		||||
{
 | 
			
		||||
    // same init steps as with a regular texture
 | 
			
		||||
@ -212,14 +210,10 @@ GLuint createNoiseTexture(int width, int height)
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
    }
 | 
			
		||||
    //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);
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
#include <SDL2/SDL_opengl.h>
 | 
			
		||||
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "random.h"
 | 
			
		||||
#include "noise.h"
 | 
			
		||||
 | 
			
		||||
struct Shaders
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										131
									
								
								src/noise.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/noise.c
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								src/noise.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/noise.h
									
									
									
									
									
										Normal file
									
								
							@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user