/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/Engine/Foundation/SimdMath/Implementation/SimdNoise.cpp
134 строки
5 KB
Jan Krassnigg
Added attraction particle behavior (#1877)
25 мар 2026, 09:33
Не верифицирован
25 мар 2026, 09:33
0e386c0
Код
Авторство
О чём код?
#include <Foundation/FoundationPCH.h> #include <Foundation/Math/Random.h> #include <Foundation/SimdMath/SimdNoise.h> ezSimdPerlinNoise::ezSimdPerlinNoise() { for (ezUInt32 i = 0; i < EZ_ARRAY_SIZE(m_Permutations); ++i) { m_Permutations[i] = static_cast<ezUInt8>(i); } } ezSimdPerlinNoise::ezSimdPerlinNoise(ezUInt32 uiSeed) : ezSimdPerlinNoise() { ezRandom rnd; rnd.Initialize(uiSeed); Initialize(rnd); } void ezSimdPerlinNoise::Initialize(ezRandom& ref_rng) { for (ezUInt32 i = EZ_ARRAY_SIZE(m_Permutations) - 1; i > 0; --i) { ezUInt32 uiRandomIndex = ref_rng.UIntInRange(EZ_ARRAY_SIZE(m_Permutations)); ezMath::Swap(m_Permutations[i], m_Permutations[uiRandomIndex]); } } ezSimdVec4f ezSimdPerlinNoise::NoiseZeroToOne(const ezSimdVec4f& vX, const ezSimdVec4f& vY, const ezSimdVec4f& vZ, ezUInt32 uiNumOctaves /*= 1*/) { ezSimdVec4f result = ezSimdVec4f::MakeZero(); ezSimdFloat amplitude = 1.0f; ezUInt32 uiOffset = 0; uiNumOctaves = ezMath::Max(uiNumOctaves, 1u); for (ezUInt32 i = 0; i < uiNumOctaves; ++i) { ezSimdFloat scale = static_cast<float>(EZ_BIT(i)); ezSimdVec4f offset = Permute(ezSimdVec4i(uiOffset) + ezSimdVec4i(0, 1, 2, 3)).ToFloat(); ezSimdVec4f x = vX * scale + offset.Get<ezSwizzle::XXXX>(); ezSimdVec4f y = vY * scale + offset.Get<ezSwizzle::YYYY>(); ezSimdVec4f z = vZ * scale + offset.Get<ezSwizzle::ZZZZ>(); result += Noise(x, y, z) * amplitude; amplitude *= 0.5f; uiOffset += 23; } return result * 0.5f + ezSimdVec4f(0.5f); } namespace { EZ_FORCE_INLINE ezSimdVec4f Fade(const ezSimdVec4f& t) { return t.CompMul(t).CompMul(t).CompMul(t.CompMul(t * 6.0f - ezSimdVec4f(15.0f)) + ezSimdVec4f(10.0f)); } EZ_FORCE_INLINE ezSimdVec4f Grad(ezSimdVec4i vHash, const ezSimdVec4f& x, const ezSimdVec4f& y, const ezSimdVec4f& z) { // convert low 4 bits of hash code into 12 gradient directions. const ezSimdVec4i h = vHash & ezSimdVec4i(15); const ezSimdVec4f u = ezSimdVec4f::Select(h < ezSimdVec4i(8), x, y); const ezSimdVec4f v = ezSimdVec4f::Select(h < ezSimdVec4i(4), y, ezSimdVec4f::Select(h == ezSimdVec4i(12) || h == ezSimdVec4i(14), x, z)); return ezSimdVec4f::Select((h & ezSimdVec4i(1)) == ezSimdVec4i::MakeZero(), u, -u) + ezSimdVec4f::Select((h & ezSimdVec4i(2)) == ezSimdVec4i::MakeZero(), v, -v); } EZ_ALWAYS_INLINE ezSimdVec4f Lerp(const ezSimdVec4f& t, const ezSimdVec4f& a, const ezSimdVec4f& b) { return ezSimdVec4f::Lerp(a, b, t); } } // namespace // reference: https://mrl.nyu.edu/~perlin/noise/ ezSimdVec4f ezSimdPerlinNoise::Noise(const ezSimdVec4f& inX, const ezSimdVec4f& inY, const ezSimdVec4f& inZ) { ezSimdVec4f x = inX; ezSimdVec4f y = inY; ezSimdVec4f z = inZ; // find unit cube that contains point. const ezSimdVec4f xFloored = x.Floor(); const ezSimdVec4f yFloored = y.Floor(); const ezSimdVec4f zFloored = z.Floor(); const ezSimdVec4i maxIndex = ezSimdVec4i(255); const ezSimdVec4i X = ezSimdVec4i::Truncate(xFloored) & maxIndex; const ezSimdVec4i Y = ezSimdVec4i::Truncate(yFloored) & maxIndex; const ezSimdVec4i Z = ezSimdVec4i::Truncate(zFloored) & maxIndex; // find relative x,y,z of point in cube. x -= xFloored; y -= yFloored; z -= zFloored; // compute fade curves for each of x,y,z. const ezSimdVec4f u = Fade(x); const ezSimdVec4f v = Fade(y); const ezSimdVec4f w = Fade(z); // hash coordinates of the 8 cube corners const ezSimdVec4i i1 = ezSimdVec4i(1); const ezSimdVec4i A = Permute(X) + Y; const ezSimdVec4i AA = Permute(A) + Z; const ezSimdVec4i AB = Permute(A + i1) + Z; const ezSimdVec4i B = Permute(X + i1) + Y; const ezSimdVec4i BA = Permute(B) + Z; const ezSimdVec4i BB = Permute(B + i1) + Z; const ezSimdVec4f f1 = ezSimdVec4f(1.0f); // and add blended results from 8 corners of cube. const ezSimdVec4f c000 = Grad(Permute(AA), x, y, z); const ezSimdVec4f c100 = Grad(Permute(BA), x - f1, y, z); const ezSimdVec4f c010 = Grad(Permute(AB), x, y - f1, z); const ezSimdVec4f c110 = Grad(Permute(BB), x - f1, y - f1, z); const ezSimdVec4f c001 = Grad(Permute(AA + i1), x, y, z - f1); const ezSimdVec4f c101 = Grad(Permute(BA + i1), x - f1, y, z - f1); const ezSimdVec4f c011 = Grad(Permute(AB + i1), x, y - f1, z - f1); const ezSimdVec4f c111 = Grad(Permute(BB + i1), x - f1, y - f1, z - f1); const ezSimdVec4f c000_c100 = Lerp(u, c000, c100); const ezSimdVec4f c010_c110 = Lerp(u, c010, c110); const ezSimdVec4f c001_c101 = Lerp(u, c001, c101); const ezSimdVec4f c011_c111 = Lerp(u, c011, c111); return Lerp(w, Lerp(v, c000_c100, c010_c110), Lerp(v, c001_c101, c011_c111)); }