Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdint>
- #include <cmath>
- #include "glm/glm/glm.hpp"
- #include <iostream>
- // This is an implementation of 2D perlin noise(3D noise is not that much more complex, but this should be easier to understand).
- // MurmurHash implementation for a 2-dimensional unsigned integer input vector.
- uint32_t hash2D(uint32_t x, uint32_t y, uint32_t seed) {
- const uint32_t m = 0x5bd1e995U;
- uint32_t hash = seed;
- uint32_t k1 = x;
- k1 *= m;
- k1 ^= k1 >> 24;
- k1 *= m;
- hash *= m;
- hash ^= k1;
- uint32_t k2 = y;
- k2 *= m;
- k2 ^= k2 >> 24;
- k2 *= m;
- hash *= m;
- hash ^= k2;
- hash ^= hash >> 13;
- hash *= m;
- hash ^= hash >> 15;
- return hash;
- }
- // Gradient direction based on hash value
- glm::vec2 gradientDirection(uint32_t hash) {
- switch (int(hash) & 3) {
- case 0:
- return glm::vec2(1.0f, 1.0f);
- case 1:
- return glm::vec2(-1.0f, 1.0f);
- case 2:
- return glm::vec2(1.0f, -1.0f);
- case 3:
- return glm::vec2(-1.0f, -1.0f);
- default:
- return glm::vec2(0.0f);
- }
- }
- // Linear interpolation function
- float interpolate(float value1, float value2, float value3, float value4, glm::vec2 t) {
- return glm::mix(glm::mix(value1, value2, t.x), glm::mix(value3, value4, t.x), t.y);
- }
- // Fade function for smooth interpolation
- glm::vec2 fade(glm::vec2 t) {
- return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
- }
- // Perlin noise function
- float perlinNoise(glm::vec2 position, uint32_t seed) {
- glm::vec2 floorPosition = glm::floor(position);
- glm::vec2 fractPosition = position - floorPosition;
- uint32_t x0 = static_cast<uint32_t>(floorPosition.x);
- uint32_t y0 = static_cast<uint32_t>(floorPosition.y);
- uint32_t x1 = x0 + 1;
- uint32_t y1 = y0 + 1;
- float value1 = glm::dot(gradientDirection(hash2D(x0, y0, seed)), fractPosition);
- float value2 = glm::dot(gradientDirection(hash2D(x1, y0, seed)), fractPosition - glm::vec2(1.0f, 0.0f));
- float value3 = glm::dot(gradientDirection(hash2D(x0, y1, seed)), fractPosition - glm::vec2(0.0f, 1.0f));
- float value4 = glm::dot(gradientDirection(hash2D(x1, y1, seed)), fractPosition - glm::vec2(1.0f, 1.0f));
- return interpolate(value1, value2, value3, value4, fade(fractPosition));
- }
- // Noise seed - change to get different wind patterns
- const uint SEED = 0xDEADBABE;
- glm::vec2 GetWindGradient(glm::vec2 pos){
- // Sample the noise at the current position
- float c = perlinNoise(pos,0xDEAD);
- // Sample the noise offset in the x direction
- float x = perlinNoise(pos + glm::vec2(0.001,0.0),SEED);
- // Sample the noise offset in the x direction
- float y = perlinNoise(pos + glm::vec2(0.0,0.001),SEED);
- return glm::vec2 (c - x,c - y)*(1.0f/0.001f);
- }
- //
- // This is the bechmark function
- int main(){
- // I use this to prevent the compiler from optimizing the noise sampling away.
- // It also serves as a small proof that the wind works: it checks that the direction of the wind was up&right 25% of the time.
- unsigned int prevent_opts = 0;
- for(int iy = 0; iy < 10000; iy++){
- for(int ix = 0; ix < 10000; ix++){
- float x = (float)ix;
- float y = (float)iy;
- glm::vec2 gradient = GetWindGradient(glm::vec2(x,y));
- //std::cout<<gradient.x<<","<<gradient.y<<std::endl;
- if (gradient.x > 0 && gradient.y > 0){
- prevent_opts += 1;
- }
- }
- }
- std::cout<<prevent_opts<<std::endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement