Worley Noise не дает правильного вывода

Я пытаюсь создать функцию Worley Noise. Я оглянулся и прочитал оригинальную статью Стивена Уорли и написал свою реализацию. Вывод не представляется правильным, хотя. Я ожидаю увидеть что-то подобное.

введите описание изображения здесь

Но это выводит это.

введите описание изображения здесь

Я не уверен, что я делаю неправильно. Я смотрел онлайн на программы других людей, и я делаю это так же. Вот код

float WorleyNoise::noise( Vector3 input ) {
unsigned int lastRandom;
unsigned int numberFeaturePoints;

Vector3 randomDiff;
Vector3 featurePoint;

int cubeX;
int cubeY;
int cubeZ;

float distanceArray[ 3 ];
for ( int i = 0; i < 3; i++ ) {
distanceArray[ i ] = 6666.0f;
}

int evalX = ( int ) floorf( input.m_x );
int evalY = ( int ) floorf( input.m_y );
int evalZ = ( int ) floorf( input.m_z );

for ( int i = -1; i < 2; ++i ) {
for ( int j = -1; j < 2; ++j ) {
for ( int k = -1; k < 2; ++k ) {
cubeX = evalX + i;
cubeY = evalY + j;
cubeZ = evalZ + k;

lastRandom = lcg_random( hash( ( unsigned int ) ( cubeX + m_seed ), ( unsigned int ) cubeY, ( unsigned int ) cubeZ ) );
numberFeaturePoints = lookup( lastRandom );

for ( unsigned int l = 0; l < numberFeaturePoints; ++l ) {
lastRandom = lcg_random( lastRandom );
randomDiff.m_x = ( float ) lastRandom / 0x100000000;

lastRandom = lcg_random( lastRandom );
randomDiff.m_y = ( float ) lastRandom / 0x100000000;

lastRandom = lcg_random( lastRandom );
randomDiff.m_z = ( float ) lastRandom / 0x100000000;

featurePoint.m_x = randomDiff.m_x + ( float ) cubeX;
featurePoint.m_y = randomDiff.m_y + ( float ) cubeY;
featurePoint.m_z = randomDiff.m_z + ( float ) cubeZ;

insert( distanceArray, euclidian_distance( input, featurePoint ) );
}
}
}
}

return Utility::clampf( combine_function_1( distanceArray ), 0.0f, 1.0f );
}

unsigned int WorleyNoise::hash( unsigned int i, unsigned int j, unsigned int k ) {
return ( unsigned int ) ( ( ( ( ( ( OFFSET_BASIS ^ ( unsigned int ) i ) * FNV_PRIME ) ^ ( unsigned int ) j ) * FNV_PRIME ) ^ ( unsigned int ) k ) * FNV_PRIME );
}

unsigned int WorleyNoise::lcg_random( unsigned int last ) {
return ( unsigned int ) ( ( 1103515245 * last + 12345 ) % 0x100000000 );
}

void WorleyNoise::insert( float arr[] , float value ) {
float temp = 0.0f;

for ( int i = 2; i >= 0; i-- ) {
if ( value > arr[ i ] ) {
break;
}

temp = arr[ i ];
arr[ i ] = value;
if ( i + 1 < 3 ) {
arr[ i + 1 ] = temp;
}
}
}

unsigned int WorleyNoise::lookup( unsigned int value ) {
value = value & 0xffffffff;
if ( value < 393325350 )
return 1;
if ( value < 1022645910 )
return 2;
if ( value < 1861739990 )
return 3;
if ( value < 2700834071 )
return 4;
if ( value < 3372109335 )
return 5;
if ( value < 3819626178 )
return 6;
if ( value < 4075350088 )
return 7;
if ( value < 4203212043 )
return 8;
return 9;
}

float WorleyNoise::euclidian_distance( Vector3 p1, Vector3 p2 ) {
return ( p1.m_x - p2.m_x ) * ( p1.m_x - p2.m_x ) + ( p1.m_y - p2.m_y ) * ( p1.m_y - p2.m_y ) + ( p1.m_z - p2.m_z ) *  ( p1.m_z - p2.m_z );
}

float WorleyNoise::combine_function_1( float arr[] ) {
return arr[ 0 ];
}

Затем я выводить результаты, как и с pngwriter.

void WorleyNoise::to_png( const std::string &file, unsigned int width, unsigned int height ) {
pngwriter png( width, height, 0, file.c_str() );

for ( unsigned int i = 0; i < width; i++ ) {
for ( unsigned int j = 0; j < height; j++ ) {
float value = noise( Vector3( i, j, 0 ) );

png.plot( i, j, ( double ) value, ( double ) value, ( double ) value );
}
}

png.close();
}

Так что здесь не так? Я посмотрел повсюду, особенно на этот урок и не могу понять, почему он не выводит правильно. Любая помощь с благодарностью, спасибо.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]