Tried out this fractal terrain stuff but it just looks the same i guess?

This commit is contained in:
iDunnoDev
2022-05-30 12:32:44 +01:00
committed by iDunnoDev
parent 51afdeecbd
commit fa57ec29aa
9 changed files with 134 additions and 6 deletions

View File

@ -0,0 +1,98 @@
#include "FractalTerrainNode.h"
FractalTerrainNode::FractalTerrainNode(wstring name, wstring seed, float chunkSize, int widthX, int widthZ, float waterHeight, int cellSizeX, int cellSizeZ) : PerlinTerrainNode(name, seed, chunkSize, widthX, widthZ, waterHeight, cellSizeX, cellSizeZ)
{
if (!_initError)
{
float p = 1.0f;
for (int k = 1023; k > 2; k = (k + 1) / 2)
{
GenerateDiamonds(k, p);
GenerateSquares(k, p);
p *= 0.5f;
}
}
}
void FractalTerrainNode::GenerateSquares(const int k, const int p)
{
int stride = k - 1;
uniform_real_distribution<float> distro(0.0f, 1.0f);
for (int z = k / 2; z < _gridRows; z += stride)
{
for (int x = 0; x < _gridCols; x += stride)
{
DoSquare(z, x, k, p * distro(_generator));
}
}
for (int z = 0; z < _gridRows; z += stride)
{
for (int x = k / 2; x < _gridCols; x += stride)
{
DoSquare(z, x, k, p * distro(_generator));
}
}
}
void FractalTerrainNode::GenerateDiamonds(const int k, const int p)
{
int stride = k - 1;
uniform_real_distribution<float> distro(0.0f, 1.0f);
for (int z = k * 0.5f; z < _gridRows; z += stride)
{
for (int x = k * 0.5f; x < _gridCols; x += stride)
{
DoDiamond(z, x, k, p * distro(_generator));
}
}
}
void FractalTerrainNode::DoSquare(const int row, const int col, const int k, const float offset)
{
int step = k * 0.5f;
vector<float> featurePoints;
vector<vector<int>> points = { {row, col - step}, {row, col + step}, {row - step, col}, {row + step, col} };
for (vector<int> point : points)
{
if (point[0] >= 0 && point[0] < (int)_gridRows && point[1] >= 0 && point[1] < (int)_gridCols)
{
int pointIndex = ((point[0] * _gridCols) + point[1]);
featurePoints.push_back(_heightValues[pointIndex]);
}
}
float newHeight = (accumulate(featurePoints.begin(), featurePoints.end(), 0.0f) / featurePoints.size()) + offset;
int currentIndex = ((row * _gridCols) + col);
_heightValues[currentIndex] = newHeight;
}
void FractalTerrainNode::DoDiamond(const int row, const int col, const int k, const float offset)
{
int step = k * 0.5f;
float newHeight = 0.0f;
vector<vector<int>> points = { {row - step, col - step}, {row + step, col - step}, {row - step, col + step}, {row + step, col - step} };
for (vector<int> point : points)
{
if (point[0] >= 0 && point[0] < (int)_gridRows && point[1] >= 0 && point[1] < (int)_gridCols)
{
int pointIndex = ((point[0] * _gridCols) + point[1]);
newHeight += _heightValues[pointIndex];
}
}
newHeight *= 0.25f;
newHeight += offset;
int currentIndex = ((row * _gridCols) + col);
_heightValues[currentIndex] = newHeight;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include <numeric>
#include "PerlinTerrainNode.h"
class FractalTerrainNode : public PerlinTerrainNode
{
public:
FractalTerrainNode(wstring name, wstring seed, float chunkSize, int widthX = 1023, int widthZ = 1023, float waterHeight = 300.0f, int cellSizeX = 10, int cellSizeZ = 10);
private:
void GenerateSquares(const int k, const int p);
void GenerateDiamonds(const int k, const int p);
void DoSquare(const int row, const int col, const int k, const float offset);
void DoDiamond(const int row, const int col, const int k, const float offset);
};

View File

@ -28,7 +28,8 @@ void Graphics2::CreateSceneGraph()
sceneGraph->Add(skyDome);
//shared_ptr<HeightMapTerrainNode> terrainNode = make_shared<HeightMapTerrainNode>(L"MainTerrain", L"Textures\\Example_HeightMap.raw", L"RandomWords");
shared_ptr<PerlinTerrainNode> terrainNode = make_shared<PerlinTerrainNode>(L"MainTerrain", L"LovelyCat", 10.0f);
//shared_ptr<PerlinTerrainNode> terrainNode = make_shared<PerlinTerrainNode>(L"MainTerrain", L"LovelyCat", 10.0f);
shared_ptr<FractalTerrainNode> terrainNode = make_shared<FractalTerrainNode>(L"MainTerrain", L"LovelyCat", 10.0f);
terrainNode->SetAmbientLight(DirectXFramework::GetDXFramework()->GetGlobalLighting()->GetAmbientLight());
terrainNode->SetDirectionalLight(DirectXFramework::GetDXFramework()->GetGlobalLighting()->GetDirectionalLightDirection(), DirectXFramework::GetDXFramework()->GetGlobalLighting()->GetDirectionalLightColor());
terrainNode->SetWaterColor(XMFLOAT4(SharedMethods::RGBValueToIntensity(0x84), SharedMethods::RGBValueToIntensity(0xC1), SharedMethods::RGBValueToIntensity(0xF9), 1.0f));

View File

@ -9,6 +9,7 @@
#include "ControlledSplitMeshNode.h"
#include "HeightMapTerrainNode.h"
#include "PerlinTerrainNode.h"
#include "FractalTerrainNode.h"
#include "SkyNode.h"
#include <ctime>
#include <set>

View File

@ -152,6 +152,7 @@
<ClInclude Include="Core.h" />
<ClInclude Include="DDSTextureLoader.h" />
<ClInclude Include="DirectXCore.h" />
<ClInclude Include="FractalTerrainNode.h" />
<ClInclude Include="Framework.h" />
<ClInclude Include="DirectXFramework.h" />
<ClInclude Include="GamePadController.h" />
@ -197,6 +198,7 @@
<ClCompile Include="ControlledMeshNode.cpp" />
<ClCompile Include="ControlledSplitMeshNode.cpp" />
<ClCompile Include="DDSTextureLoader.cpp" />
<ClCompile Include="FractalTerrainNode.cpp" />
<ClCompile Include="Framework.cpp" />
<ClCompile Include="DirectXFramework.cpp" />
<ClCompile Include="GamePadController.cpp" />

View File

@ -117,6 +117,9 @@
<ClInclude Include="GlobalLighting.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FractalTerrainNode.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Graphics2.rc">
@ -225,6 +228,9 @@
<ClCompile Include="GlobalLighting.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FractalTerrainNode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="shader.hlsl">

View File

@ -14,8 +14,8 @@ PerlinTerrainNode::PerlinTerrainNode(wstring name, wstring seed, float chunkSize
void PerlinTerrainNode::GeneratePerlinValues()
{
std::seed_seq seedGenerator(_seedString.begin(), _seedString.end());
std::mt19937 generator;
generator.seed(seedGenerator);
_generator.seed(seedGenerator);
std::uniform_int_distribution<> dist(0, 511);
char bufferChar;
int newPosition;
@ -25,7 +25,7 @@ void PerlinTerrainNode::GeneratePerlinValues()
for (int i = 0; i < 512; i++)
{
newPosition = dist(generator);
newPosition = dist(_generator);
bufferChar = _p[i];
_p[i] = _p[newPosition];
_p[newPosition] = bufferChar;

View File

@ -11,7 +11,7 @@ class PerlinTerrainNode : public TerrainNode
public:
PerlinTerrainNode(wstring name, wstring seed, float chunkSize, int widthX = 1023, int widthZ = 1023, float waterHeight = 300.0f, int cellSizeX = 10, int cellSizeZ = 10);
private:
protected:
// the static perlin permutation array, we could calculate a random one but apparently you can run into sequencing issues and this just seems like the best solution
vector<unsigned char> _staticP = { 151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
@ -45,6 +45,8 @@ private:
float _chunkSize;
std::mt19937 _generator;
float Fade(float t);
float Grad(int hash, float x, float y);

View File

@ -672,7 +672,7 @@ float TerrainNode::GetHeightAtPoint(float x, float z, bool waterCollide)
int cellX = (int)((x - _terrainStartX) / _cellSizeX);
int cellZ = (int)((_terrainStartZ - z) / _cellSizeZ);
int currentIndex = (cellZ * _gridCols * 4) + (cellX * 4);
int currentIndex = ((cellZ * _gridCols) + cellX) * 4;
float dx = x - _terrainVerts[currentIndex].Position.x;
float dz = z - _terrainVerts[currentIndex].Position.z;