Skip to content

Commit

Permalink
[RaZ] Updated RaZ (commit d70a312)
Browse files Browse the repository at this point in the history
- Color textures are properly handled
  - The static terrain's is created as sRGB
  - The dynamic's color map compute shader applies a gamma correction at the end, as it can't use an sRGB texture

- The slope map is saved as an HDR image
  - As it is necessarily a floating-point texture and that the pixel value clamping has been removed, it is now required

- RaZ's include path is marked as a system one to ignore warnings from it

- Replaced manual image pixel writing by Image::setPixel()

- Added Tracy zones for terrain features

- Added a link on hydraulic erosion in the readme

- In the artifacts' names, the job ID has been replaced by the commit's SHA

- Bumped Actions workflows to v4
  - They now use Node.js 20 instead of 16; see https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/
  • Loading branch information
Razakhel committed Jun 30, 2024
1 parent 65c0b34 commit 2cba3cf
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 24 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/Linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- Release

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Pulling RaZ
run: git submodule update --init --recursive
Expand Down Expand Up @@ -62,16 +62,16 @@ jobs:
# Additional dependencies are libc & libm (located in /usr/lib*), as well as libgcc_s & libstdc++ (which would require another package)
- name: Packaging build
run: |
mkdir Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.run_id }}/ &&
cp -t Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.run_id }}/ \
mkdir Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.sha }}/ &&
cp -t Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.sha }}/ \
${{ runner.workspace }}/build-${{ matrix.compiler.c }}/Midgard \
/usr/lib/*/libGL.so \
/usr/lib/*/libopenal.so
tar -cvf Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.run_id }}.tar \
Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.run_id }}/
tar -cvf Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.sha }}.tar \
Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.sha }}/
- name: Upload build
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.run_id }}
path: Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.run_id }}.tar
name: Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.sha }}
path: Midgard-linux-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.sha }}.tar
6 changes: 3 additions & 3 deletions .github/workflows/Windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- Release

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Pulling RaZ
run: git submodule update --init --recursive
Expand Down Expand Up @@ -53,8 +53,8 @@ jobs:
rm C:/Midgard/lib -r
- name: Upload build
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Midgard-windows-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.run_id }}
name: Midgard-windows-${{ matrix.compiler.c }}-${{ matrix.build_type }}-${{ github.sha }}
path: |
C:/Midgard
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ if (NOT MIDGARD_BUILD_RAZ)
endif ()

target_link_directories(Midgard PRIVATE "${RAZ_LIB_DIR}")
target_include_directories(Midgard PUBLIC "${RAZ_ROOT}/include")
target_include_directories(Midgard SYSTEM PUBLIC "${RAZ_ROOT}/include")
target_compile_definitions(Midgard PRIVATE RAZ_USE_WINDOW) # Raz::Window is needed

# Additional linking flags
Expand Down Expand Up @@ -434,6 +434,9 @@ else ()
# Use RaZ's compiler flags' script
include("${RAZ_ROOT}/cmake/CompilerFlags.cmake")
add_compiler_flags(Midgard PRIVATE)

# Needed to use Tracy's GPU profiling
target_link_libraries(Midgard PRIVATE GLEW)
else ()
message(FATAL_ERROR "Failed to find RaZ; the submodule must be downloaded")
endif ()
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ More progress screenshots are available on the wiki's [milestones page](https://

# Resources

- Wei et al. (2007) - [Fast Hydraulic Erosion Simulation and Visualization on GPU](https://inria.hal.science/inria-00402079/document)
- Paris et al. (2020) - [Modeling Rocky Scenery using Implicit Blocks](https://hal.archives-ouvertes.fr/hal-02926218/file/2020-rocks-author.pdf) ([code](https://github.com/aparis69/Rock-fracturing))
- Paris et al. (2019) - [Desertscape Simulation](https://hal.archives-ouvertes.fr/hal-02273039/document) ([code](https://github.com/aparis69/Desertscapes-Simulation))
- Peytavie et al. (2019) - [Procedural Riverscapes](https://hal.archives-ouvertes.fr/hal-02281637/document)
Expand Down
2 changes: 1 addition & 1 deletion extern/RaZ
Submodule RaZ updated 655 files
2 changes: 1 addition & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ int main() {
#if !defined(USE_OPENGL_ES)
Raz::ImageFormat::save("colorMap.png", colorMap);
Raz::ImageFormat::save("normalMap.png", normalMap);
Raz::ImageFormat::save("slopeMap.png", slopeMap);
Raz::ImageFormat::save("slopeMap.hdr", slopeMap);
#endif

/////////////////////
Expand Down
5 changes: 5 additions & 0 deletions shaders/terrain_color.comp
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@ void main() {
: (height < 0.66 ? mix(groundColor, rockColor, (height - 0.5) * 6.0)
: mix(rockColor, snowColor, (height - 0.66) * 3.0))));

// Applying gamma correction
// This shouldn't be needed here, as ideally the texture should be read later as sRGB; but as it's not possible to use imageRead/Store() on an sRGB texture,
// and to avoid duplicating them to use distinct ones for write & read operations, this correction is applied
color = pow(color, vec3(2.2));

imageStore(uniColorMap, pixelCoords, vec4(color, 1.0));
}
21 changes: 21 additions & 0 deletions src/Midgard/DynamicTerrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include <RaZ/Render/Renderer.hpp>
#include <RaZ/Utils/Logger.hpp>

#include <tracy/Tracy.hpp>
#include <GL/glew.h> // Needed by TracyOpenGL.hpp
#include <tracy/TracyOpenGL.hpp>

namespace {

constexpr int heightmapSize = 1024;
Expand Down Expand Up @@ -40,6 +44,8 @@ inline void checkParameters(float& minTessLevel) {
} // namespace

DynamicTerrain::DynamicTerrain(Raz::Entity& entity) : Terrain(entity) {
ZoneScopedN("DynamicTerrain::DynamicTerrain");

Raz::RenderShaderProgram& terrainProgram = m_entity.getComponent<Raz::MeshRenderer>().getMaterials().front().getProgram();
terrainProgram.setTessellationControlShader(Raz::TessellationControlShader::loadFromSource(tessCtrlSource));
terrainProgram.setTessellationEvaluationShader(Raz::TessellationEvaluationShader::loadFromSource(tessEvalSource));
Expand Down Expand Up @@ -79,6 +85,8 @@ DynamicTerrain::DynamicTerrain(Raz::Entity& entity) : Terrain(entity) {

DynamicTerrain::DynamicTerrain(Raz::Entity& entity, unsigned int width, unsigned int depth,
float heightFactor, float flatness, float minTessLevel) : DynamicTerrain(entity) {
ZoneScopedN("DynamicTerrain::DynamicTerrain");

Raz::RenderShaderProgram& terrainProgram = entity.getComponent<Raz::MeshRenderer>().getMaterials().front().getProgram();
terrainProgram.setAttribute(Raz::Vec2u(width, depth), "uniTerrainSize");
terrainProgram.sendAttributes();
Expand All @@ -87,6 +95,8 @@ DynamicTerrain::DynamicTerrain(Raz::Entity& entity, unsigned int width, unsigned
}

void DynamicTerrain::setParameters(float minTessLevel, float heightFactor, float flatness) {
ZoneScopedN("DynamicTerrain::setParameters");

Terrain::setParameters(heightFactor, flatness);

::checkParameters(minTessLevel);
Expand All @@ -104,6 +114,8 @@ void DynamicTerrain::setParameters(float minTessLevel, float heightFactor, float
}

void DynamicTerrain::generate(unsigned int width, unsigned int depth, float heightFactor, float flatness, float minTessLevel) {
ZoneScopedN("DynamicTerrain::generate");

auto& mesh = m_entity.getComponent<Raz::Mesh>();
mesh.getSubmeshes().resize(1);

Expand Down Expand Up @@ -161,6 +173,9 @@ void DynamicTerrain::generate(unsigned int width, unsigned int depth, float heig
}

const Raz::Texture2D& DynamicTerrain::computeNoiseMap(float factor) {
ZoneScopedN("DynamicTerrain::computeNoiseMap");
TracyGpuZone("DynamicTerrain::computeNoiseMap")

m_noiseProgram.setAttribute(factor, "uniNoiseFactor");
m_noiseProgram.sendAttributes();
m_noiseProgram.execute(heightmapSize, heightmapSize);
Expand All @@ -169,12 +184,18 @@ const Raz::Texture2D& DynamicTerrain::computeNoiseMap(float factor) {
}

const Raz::Texture2D& DynamicTerrain::computeColorMap() {
ZoneScopedN("DynamicTerrain::computeColorMap");
TracyGpuZone("DynamicTerrain::computeColorMap")

m_colorProgram.execute(heightmapSize, heightmapSize);

return *m_colorMap;
}

const Raz::Texture2D& DynamicTerrain::computeSlopeMap() {
ZoneScopedN("DynamicTerrain::computeSlopeMap");
TracyGpuZone("DynamicTerrain::computeSlopeMap")

m_slopeProgram.execute(heightmapSize, heightmapSize);

return *m_slopeMap;
Expand Down
40 changes: 30 additions & 10 deletions src/Midgard/StaticTerrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <RaZ/Render/MeshRenderer.hpp>
#include <RaZ/Utils/Threading.hpp>

#include <tracy/Tracy.hpp>

namespace {

constexpr Raz::Vec3b waterColor(0, 0, 255);
Expand All @@ -18,10 +20,14 @@ constexpr Raz::Vec3b snowColor(255, 255, 255);
} // namespace

StaticTerrain::StaticTerrain(Raz::Entity& entity, unsigned int width, unsigned int depth, float heightFactor, float flatness) : StaticTerrain(entity) {
ZoneScopedN("StaticTerrain::StaticTerrain");

StaticTerrain::generate(width, depth, heightFactor, flatness);
}

void StaticTerrain::setParameters(float heightFactor, float flatness) {
ZoneScopedN("StaticTerrain::setParameters");

checkParameters(heightFactor, flatness);

remapVertices(heightFactor, flatness);
Expand All @@ -32,6 +38,8 @@ void StaticTerrain::setParameters(float heightFactor, float flatness) {
}

void StaticTerrain::generate(unsigned int width, unsigned int depth, float heightFactor, float flatness) {
ZoneScopedN("StaticTerrain::generate");

m_width = width;
m_depth = depth;
Terrain::setParameters(heightFactor, flatness);
Expand All @@ -45,6 +53,8 @@ void StaticTerrain::generate(unsigned int width, unsigned int depth, float heigh
vertices.resize(m_width * m_depth);

Raz::Threading::parallelize(0, vertices.size(), [this, &vertices] (const Raz::Threading::IndexRange& range) noexcept {
ZoneScopedN("StaticTerrain::generate");

for (std::size_t i = range.beginIndex; i < range.endIndex; ++i) {
const auto xCoord = static_cast<float>(i % m_width);
const auto yCoord = static_cast<float>(i / m_width);
Expand Down Expand Up @@ -121,12 +131,16 @@ void StaticTerrain::generate(unsigned int width, unsigned int depth, float heigh
}

const Raz::Image& StaticTerrain::computeColorMap() {
ZoneScopedN("StaticTerrain::computeColorMap");

m_colorMap = Raz::Image(m_width, m_depth, Raz::ImageColorspace::RGB);
auto* imgData = static_cast<uint8_t*>(m_colorMap.getDataPtr());

const std::vector<Raz::Vertex>& vertices = m_entity.getComponent<Raz::Mesh>().getSubmeshes().front().getVertices();

Raz::Threading::parallelize(0, vertices.size(), [this, &vertices, imgData] (const Raz::Threading::IndexRange& range) noexcept {
ZoneScopedN("StaticTerrain::computeColorMap");

for (std::size_t i = range.beginIndex; i < range.endIndex; ++i) {
const float noiseValue = std::pow(vertices[i].position.y() / m_heightFactor, m_invFlatness);
const Raz::Vec3b pixelValue = (noiseValue < 0.33f ? Raz::MathUtils::lerp(waterColor, grassColor, noiseValue * 3.f)
Expand All @@ -141,19 +155,23 @@ const Raz::Image& StaticTerrain::computeColorMap() {
}
});

m_entity.getComponent<Raz::MeshRenderer>().getMaterials().front().getProgram().setTexture(Raz::Texture2D::create(m_colorMap),
m_entity.getComponent<Raz::MeshRenderer>().getMaterials().front().getProgram().setTexture(Raz::Texture2D::create(m_colorMap, true, true),
Raz::MaterialTexture::BaseColor);

return m_colorMap;
}

const Raz::Image& StaticTerrain::computeNormalMap() {
ZoneScopedN("StaticTerrain::computeNormalMap");

m_normalMap = Raz::Image(m_width, m_depth, Raz::ImageColorspace::RGB);
auto* imgData = static_cast<uint8_t*>(m_normalMap.getDataPtr());

const std::vector<Raz::Vertex>& vertices = m_entity.getComponent<Raz::Mesh>().getSubmeshes().front().getVertices();

Raz::Threading::parallelize(0, vertices.size(), [&vertices, imgData] (const Raz::Threading::IndexRange& range) noexcept {
ZoneScopedN("StaticTerrain::computeNormalMap");

for (std::size_t i = range.beginIndex; i < range.endIndex; ++i) {
const Raz::Vec3f& normal = vertices[i].normal;

Expand All @@ -168,34 +186,32 @@ const Raz::Image& StaticTerrain::computeNormalMap() {
}

const Raz::Image& StaticTerrain::computeSlopeMap() {
m_slopeMap = Raz::Image(m_width, m_depth, Raz::ImageColorspace::RGB, Raz::ImageDataType::FLOAT);
auto* imgData = static_cast<float*>(m_slopeMap.getDataPtr());
ZoneScopedN("StaticTerrain::computeSlopeMap");

m_slopeMap = Raz::Image(m_width, m_depth, Raz::ImageColorspace::RGB, Raz::ImageDataType::FLOAT);

const std::vector<Raz::Vertex>& vertices = m_entity.getComponent<Raz::Mesh>().getSubmeshes().front().getVertices();

for (unsigned int j = 1; j < m_depth - 1; ++j) {
const unsigned int depthStride = j * m_width * 3;

for (unsigned int i = 1; i < m_width - 1; ++i) {
const float topHeight = vertices[(j - 1) * m_width + i].position.y();
const float leftHeight = vertices[j * m_width + i - 1].position.y();
const float rightHeight = vertices[j * m_width + i + 1].position.y();
const float botHeight = vertices[(j + 1) * m_width + i].position.y();

Raz::Vec2f slopeVec(leftHeight - rightHeight, topHeight - botHeight);
const Raz::Vec2f slopeVec(leftHeight - rightHeight, topHeight - botHeight);
const float slopeStrength = slopeVec.computeLength() * 0.5f;
slopeVec = slopeVec.normalize();

imgData[depthStride + i * 3 ] = slopeVec.x();
imgData[depthStride + i * 3 + 1] = slopeVec.y();
imgData[depthStride + i * 3 + 2] = slopeStrength;
m_slopeMap.setPixel(i, j, Raz::Vec3f(slopeVec.normalize(), slopeStrength));
}
}

return m_slopeMap;
}

void StaticTerrain::computeNormals() {
ZoneScopedN("StaticTerrain::computeNormals");

std::vector<Raz::Vertex>& vertices = m_entity.getComponent<Raz::Mesh>().getSubmeshes().front().getVertices();

for (unsigned int j = 1; j < m_depth - 1; ++j) {
Expand Down Expand Up @@ -253,10 +269,14 @@ void StaticTerrain::computeNormals() {
}

void StaticTerrain::remapVertices(float newHeightFactor, float newFlatness) {
ZoneScopedN("StaticTerrain::remapVertices");

auto& mesh = m_entity.getComponent<Raz::Mesh>();

std::vector<Raz::Vertex>& vertices = mesh.getSubmeshes().front().getVertices();
Raz::Threading::parallelize(vertices, [this, newHeightFactor, newFlatness] (const auto& range) noexcept {
ZoneScopedN("StaticTerrain::remapVertices");

for (Raz::Vertex& vertex : range) {
const float baseHeight = std::pow(vertex.position.y() / m_heightFactor, m_invFlatness);
vertex.position.y() = std::pow(baseHeight, newFlatness) * newHeightFactor;
Expand Down

0 comments on commit 2cba3cf

Please sign in to comment.