free garden
Chap9. Using Noise in Shaders(1) 본문
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