Skip to content

Commit

Permalink
instancing for terrain
Browse files Browse the repository at this point in the history
  • Loading branch information
beaumanvienna committed Jun 9, 2024
1 parent 5394ee5 commit bf8a2f9
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 65 deletions.
35 changes: 29 additions & 6 deletions application/lucre/sceneDescriptions/terrain.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
{
"scale":
[
0.141, 0.141, 0.141
0.054, 0.054, 0.054
],
"rotation":
[
3.14159, 1.07215, 3.14159
0, 0, 0
],
"translation":
[
-0.779968, 2.25822, -4
-0.576, 2.33, -0.117
]
}
},
Expand All @@ -30,15 +30,38 @@
{
"scale":
[
0.140998, 0.140998, 0.140998
0.219, 0.392, 0.219
],
"rotation":
[
3.01614, 1.00771, 2.99355
0, 0, 0
],
"translation":
[
-0.494322, 2.28222, -3.408
-4.807, 0.942, -11.044
]
}
}
]
},
{
"filename": "application/lucre/terrainDescriptions/heightmap.json",
"instances":
[
{
"transform":
{
"scale":
[
0.219, 0.392, 0.219
],
"rotation":
[
0, 0.523, 0
],
"translation":
[
-10.523, 0.942, -2.375
]
}
}
Expand Down
6 changes: 6 additions & 0 deletions application/lucre/terrainDescriptions/heightmap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"file format identifier": 1.2,
"description": "height map 2",
"author": "Copyright (c) 2024 Engine Development Team",
"terrainPngPath": "application/lucre/models/assets/terrain/heightmap.png"
}
118 changes: 66 additions & 52 deletions engine/renderer/builder/terrainBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "core.h"
#include "renderer/builder/terrainBuilder.h"
#include "auxiliary/file.h"
#include "scene/scene.h"
#include "stb_image.h"

Expand Down Expand Up @@ -121,7 +122,9 @@ namespace GfxRenderEngine
{
m_Vertices.clear();
m_Indices.clear();
m_Submeshes.clear();
int width, height, bytesPerPixel;
stbi_set_flip_vertically_on_load(false);
uchar* localBuffer = stbi_load(filepath.c_str(), &width, &height, &bytesPerPixel, 0);
if (localBuffer)
{
Expand All @@ -137,67 +140,78 @@ namespace GfxRenderEngine

PopulateTerrainData(terrainData);

// create game object
entt::entity entity;
std::shared_ptr<InstanceBuffer> instanceBuffer;
// create game objects for all instances
{
auto& registry = scene.GetRegistry();
auto& sceneGraph = scene.GetSceneGraph();
auto& dictionary = scene.GetDictionary();

// create game object
entity = registry.create();
TransformComponent transform{};
PbrMaterialTag pbrMaterialTag{};
auto name = EngineCore::GetFilenameWithoutPath(filepath);
name = EngineCore::GetFilenameWithoutExtension(name);
InstanceTag instanceTag;

// create instance buffer
instanceTag.m_Instances.push_back(entity);
const uint numberOfInstances = instanceCount;
const uint indexOfFirstInstance = 0;
instanceBuffer = InstanceBuffer::Create(numberOfInstances);
instanceTag.m_InstanceBuffer = instanceBuffer;
instanceTag.m_InstanceBuffer->SetInstanceData(indexOfFirstInstance, transform.GetMat4Global(),
transform.GetNormalMatrix());
transform.SetInstance(instanceTag.m_InstanceBuffer, indexOfFirstInstance);

// push into ECS
registry.emplace<TransformComponent>(entity, transform);
registry.emplace<PbrMaterialTag>(entity, pbrMaterialTag);
registry.emplace<InstanceTag>(entity, instanceTag);

// add to scene graph
uint newNode = sceneGraph.CreateNode(entity, "terrain", "terrain", dictionary);
sceneGraph.GetRoot().AddChild(newNode);

Submesh submesh{};
submesh.m_FirstIndex = 0;
submesh.m_FirstVertex = 0;
submesh.m_IndexCount = m_Indices.size();
submesh.m_VertexCount = m_Vertices.size();
submesh.m_InstanceCount = 1;

submesh.m_Material.m_PbrMaterial.m_Roughness = 0.1f;
submesh.m_Material.m_PbrMaterial.m_Metallic = 0.9f;
submesh.m_Material.m_PbrMaterial.m_NormalMapIntensity = 1.0f;

{ // create material descriptor
Material::MaterialTextures materialTextures;

auto materialDescriptor = MaterialDescriptor::Create(MaterialDescriptor::MtPbr, materialTextures);
submesh.m_Material.m_MaterialDescriptor = materialDescriptor;
}
{ // create resource descriptor
Resources::ResourceBuffers resourceBuffers;
for (int instanceIndex = 0; instanceIndex < instanceCount; ++instanceIndex)
{
// create game object
entt::entity entity = registry.create();
std::shared_ptr<Model> model;
TransformComponent transform{};
instanceTag.m_Instances.push_back(entity);

// add to scene graph
auto instanceStr = std::to_string(instanceIndex);
auto shortName = name + "::" + instanceStr;
auto longName = filepath + "::" + instanceStr;
uint newNode = sceneGraph.CreateNode(entity, shortName, longName, dictionary);
sceneGraph.GetRoot().AddChild(newNode);

// only for the 1st instance
if (!instanceIndex)
{
// create instance buffer
instanceTag.m_InstanceBuffer = InstanceBuffer::Create(instanceCount);
registry.emplace<InstanceTag>(entity, instanceTag);

Submesh submesh{};
submesh.m_FirstIndex = 0;
submesh.m_FirstVertex = 0;
submesh.m_IndexCount = m_Indices.size();
submesh.m_VertexCount = m_Vertices.size();
submesh.m_InstanceCount = instanceCount;

submesh.m_Material.m_PbrMaterial.m_Roughness = 0.1f;
submesh.m_Material.m_PbrMaterial.m_Metallic = 0.9f;
submesh.m_Material.m_PbrMaterial.m_NormalMapIntensity = 1.0f;

{ // create material descriptor
Material::MaterialTextures materialTextures;

auto materialDescriptor =
MaterialDescriptor::Create(MaterialDescriptor::MtPbr, materialTextures);
submesh.m_Material.m_MaterialDescriptor = materialDescriptor;
}
{ // create resource descriptor
Resources::ResourceBuffers resourceBuffers;

resourceBuffers[Resources::INSTANCE_BUFFER_INDEX] = instanceTag.m_InstanceBuffer->GetBuffer();
auto resourceDescriptor = ResourceDescriptor::Create(resourceBuffers);
submesh.m_Resources.m_ResourceDescriptor = resourceDescriptor;
}
m_Submeshes.push_back(submesh);
model = Engine::m_Engine->LoadModel(*this);

PbrMaterialTag pbrMaterialTag{};
registry.emplace<PbrMaterialTag>(entity, pbrMaterialTag);
}

instanceTag.m_InstanceBuffer->SetInstanceData(instanceIndex, transform.GetMat4Global(),
transform.GetNormalMatrix());
transform.SetInstance(instanceTag.m_InstanceBuffer, instanceIndex);
registry.emplace<TransformComponent>(entity, transform);

resourceBuffers[Resources::INSTANCE_BUFFER_INDEX] = instanceBuffer->GetBuffer();
auto resourceDescriptor = ResourceDescriptor::Create(resourceBuffers);
submesh.m_Resources.m_ResourceDescriptor = resourceDescriptor;
MeshComponent mesh{shortName, model};
registry.emplace<MeshComponent>(entity, mesh);
}
m_Submeshes.push_back(submesh);
auto model = Engine::m_Engine->LoadModel(*this);
MeshComponent mesh{"terrain", model};
registry.emplace<MeshComponent>(entity, mesh);
}

return true;
Expand Down
14 changes: 7 additions & 7 deletions engine/scene/sceneLoaderDeserializeJSON.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,25 +586,25 @@ namespace GfxRenderEngine
bool loadSuccessful = terrainLoaderJSON.Deserialize(filename, instanceCount);

if (!loadSuccessful)
{
Terrain::TerrainDescription terrainDescriptionScene(filename);
terrainDescriptions.push_back(terrainDescriptionScene);
}
else
{
LOG_CORE_CRITICAL("terrain description did not load properly: {0}", filename);
return;
}

Terrain::TerrainDescription terrainDescriptionScene(filename);
terrainDescriptions.push_back(terrainDescriptionScene);

std::vector<Terrain::Instance>& terrainInstances = terrainDescriptions.back().m_Instances;
terrainInstances.resize(instanceCount);

{
auto name = EngineCore::GetFilenameWithoutPath(filename);
name = EngineCore::GetFilenameWithoutExtension(name);
uint instanceIndex = 0;
for (auto instance : instances)
{
std::string fullEntityName = filename + std::string("::" + std::to_string(instanceIndex));
entt::entity entity = m_Scene.m_Dictionary.Retrieve(fullEntityName);
std::string entityName = name + std::string("::" + std::to_string(instanceIndex));
entt::entity entity = m_Scene.m_Dictionary.Retrieve(entityName);
Terrain::Instance& terrainInstance = terrainInstances[instanceIndex];
terrainInstance.m_Entity = entity;
ondemand::object instanceObjects = instance.value();
Expand Down

0 comments on commit bf8a2f9

Please sign in to comment.