Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

free garden

Chap9. Using Noise in Shaders(1) 본문

카테고리 없음

Chap9. Using Noise in Shaders(1)

KUflower 2020. 2. 11. 01:43

Creating a noise texture using GLM

 

#include <glm/gtc/noise.hpp>

GLubyte *data = new GLubyte[width * height * 4];

float xFactor = 1.0f / (width - 1);
float yFactor = 1.0f / (height - 1);

for (int row = 0; row < height; ++row) {
    float y = yFactor * row;
    for (int col = 0; col < width; ++col) {
    	float x = xFactor * col;
        float sum = 0.0f;
        float freq = a;
        float scale = b;
        
        // Compute the sum for each octave
        for (int oct = 0; oct < 4; ++oct) {
        	glm::vec2 p(x * freq, y * freq);
			float val = glm::perlin(p) / scale;
            sum += val;
            float result = (sum + 1.0f) / 2.0f;
            
            // Store in texture buffer
            data[((row * width + col) * 4) + oct] = (GLubyte)(result * 255.0f);
            freq *= 2.0f; 	// Double the frequency
            scale *= b;		// Nex power of b            
        }        
    }
}
GLuint texID;
glGenTextures(1, &texID);

glBindTexture(GL_TEXTURE_2D, texID);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);

delete [] data;

 

unsigned byte 를 사용하는 것 보다 floating-point texture 를 사용하는 것이 resolution에 대한 noise data를 더 얻을 수 있다.

 

 

Creating a seamless noise texture

 

왼쪽 이미지는 경계가 뚜렷하다.

 

가장 안쪽의 반복문에서 glm::perlin 대신 periodic perlin noise 를 호출하면 된다.

float val = 0.0f;
if (periodic) {
	val = glm::perlin(p, glm::vec2(freq)) / scale;
} else {
	val = glm::perlin(p) / scale;
}

 

Creating a cloud-like effect

 

하늘과 구름을 닮은 텍스처를 만들기 위해 하늘의 색깔과 구름의 색을 블랜딩하면 된다.

 

#define PI 3.14159265

layout (binding = 0) uniform sampler2D NoiseTex;

uniform vec4 SkyColor = vec4(0.3, 0.3, 0.9, 1.0);
uniform vec4 CloudColor = vec4(1.0, 1.0, 1.0, 1.0);

in vec2 TexCoord;

layout (location = 0) out vec4 FragColor;

void main()
{
	vec4 noise = texture(NoiseTex, TexCoord);
    float t = (cos(noise.g * PI) + 1.0) / 2.0;
    vec4 color = mix(SkyColor, CloudColor, t);
    FragColor = vec4(color.rgb, 1.0);
}

 

혹시 구름을 줄이고 하늘을 더 보이고 싶다면 이렇게 하면 된다.

float t = (cos(noise.g * PI) + 1.0) / 2.0;
t = clamp(t - 0.25, 0.0, 1.0);
Comments