Skip to content

Commit

Permalink
[DynamicTerrain] Added slope map computation
Browse files Browse the repository at this point in the history
- The computed texture has the slope direction in its R & G components, and the strength in its B component
  • Loading branch information
Razakhel committed Oct 7, 2023
1 parent 293e02c commit 65c0b34
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 deletions.
5 changes: 5 additions & 0 deletions include/Midgard/DynamicTerrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class DynamicTerrain final : public Terrain {

const Raz::Texture2D& getNoiseMap() const noexcept { return *m_noiseMap; }
const Raz::Texture2D& getColorMap() const noexcept { return *m_colorMap; }
const Raz::Texture2D& getSlopeMap() const noexcept { return *m_slopeMap; }

void setMinTessellationLevel(float minTessLevel) { setParameters(minTessLevel, m_heightFactor, m_flatness); }
void setParameters(float heightFactor, float flatness) override { setParameters(m_minTessLevel, heightFactor, flatness); }
Expand All @@ -35,14 +36,18 @@ class DynamicTerrain final : public Terrain {
void generate(unsigned int width, unsigned int depth, float heightFactor, float flatness, float minTessLevel);
const Raz::Texture2D& computeNoiseMap(float factor);
const Raz::Texture2D& computeColorMap();
const Raz::Texture2D& computeSlopeMap();

private:
float m_minTessLevel {};

Raz::ComputeShaderProgram m_noiseProgram {};
Raz::ComputeShaderProgram m_colorProgram {};
Raz::ComputeShaderProgram m_slopeProgram {};

Raz::Texture2DPtr m_noiseMap {};
Raz::Texture2DPtr m_colorMap {};
Raz::Texture2DPtr m_slopeMap {};
};

#endif // MIDGARD_DYNAMICTERRAIN_HPP
16 changes: 11 additions & 5 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,24 +192,26 @@ int main() {
overlay.addSeparator();

#if !defined(USE_OPENGL_ES)
Raz::OverlayTexture& dynamicNoiseTexture = overlay.addTexture(dynamicTerrain.getNoiseMap(), 150, 150);
Raz::OverlayTexture& dynamicColorTexture = overlay.addTexture(dynamicTerrain.getColorMap(), 150, 150);
Raz::OverlayTexture& dynamicNoiseTexture = overlay.addTexture(dynamicTerrain.getNoiseMap(), 125, 125);
Raz::OverlayTexture& dynamicColorTexture = overlay.addTexture(dynamicTerrain.getColorMap(), 125, 125);
Raz::OverlayTexture& dynamicSlopeTexture = overlay.addTexture(dynamicTerrain.getSlopeMap(), 125, 125);
#endif

Raz::Texture2D colorTexture(colorMap, false);
Raz::Texture2D normalTexture(normalMap, false);
Raz::Texture2D slopeTexture(slopeMap, false);

[[maybe_unused]] Raz::OverlayTexture& staticColorTexture = overlay.addTexture(colorTexture, 150, 150);
[[maybe_unused]] Raz::OverlayTexture& staticNormalTexture = overlay.addTexture(normalTexture, 150, 150);
[[maybe_unused]] Raz::OverlayTexture& staticSlopeTexture = overlay.addTexture(slopeTexture, 150, 150);
[[maybe_unused]] Raz::OverlayTexture& staticColorTexture = overlay.addTexture(colorTexture, 125, 125);
[[maybe_unused]] Raz::OverlayTexture& staticNormalTexture = overlay.addTexture(normalTexture, 125, 125);
[[maybe_unused]] Raz::OverlayTexture& staticSlopeTexture = overlay.addTexture(slopeTexture, 125, 125);

overlay.addSeparator();

#if !defined(USE_OPENGL_ES)
Raz::OverlaySlider& dynamicNoiseMapFactorSlider = overlay.addSlider("Noise map factor", [&dynamicTerrain] (float value) {
dynamicTerrain.computeNoiseMap(value);
dynamicTerrain.computeColorMap();
dynamicTerrain.computeSlopeMap();
}, 0.001f, 0.1f, 0.01f);

Raz::OverlaySlider& dynamicMinTessLevelSlider = overlay.addSlider("Min tess. level", [&dynamicTerrain] (float value) {
Expand All @@ -218,10 +220,12 @@ int main() {

Raz::OverlaySlider& dynamicHeightFactorSlider = overlay.addSlider("Height factor", [&dynamicTerrain] (float value) {
dynamicTerrain.setHeightFactor(value);
dynamicTerrain.computeSlopeMap();
}, 0.001f, 50.f, 30.f);

Raz::OverlaySlider& dynamicFlatnessSlider = overlay.addSlider("Flatness", [&dynamicTerrain] (float value) {
dynamicTerrain.setFlatness(value);
dynamicTerrain.computeSlopeMap();
}, 1.f, 10.f, 3.f);
#endif

Expand Down Expand Up @@ -249,6 +253,7 @@ int main() {
dynamicTerrainEntity.enable();
dynamicNoiseTexture.enable();
dynamicColorTexture.enable();
dynamicSlopeTexture.enable();
dynamicNoiseMapFactorSlider.enable();
dynamicMinTessLevelSlider.enable();
dynamicHeightFactorSlider.enable();
Expand All @@ -271,6 +276,7 @@ int main() {
dynamicTerrainEntity.disable();
dynamicNoiseTexture.disable();
dynamicColorTexture.disable();
dynamicSlopeTexture.disable();
dynamicNoiseMapFactorSlider.disable();
dynamicMinTessLevelSlider.disable();
dynamicHeightFactorSlider.disable();
Expand Down
24 changes: 24 additions & 0 deletions shaders/slope.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

layout(r16f, binding = 0) uniform readonly restrict image2D uniHeightmap;
layout(rgba16f, binding = 1) uniform writeonly restrict image2D uniSlopeMap;

uniform float uniFlatness = 3.0;
uniform float uniHeightFactor = 30.0;

vec2 computeSlope(ivec2 pixelCoords) {
float leftHeight = pow(imageLoad(uniHeightmap, pixelCoords + ivec2(-1, 0)).r, uniFlatness) * uniHeightFactor;
float rightHeight = pow(imageLoad(uniHeightmap, pixelCoords + ivec2( 1, 0)).r, uniFlatness) * uniHeightFactor;
float topHeight = pow(imageLoad(uniHeightmap, pixelCoords + ivec2( 0, -1)).r, uniFlatness) * uniHeightFactor;
float botHeight = pow(imageLoad(uniHeightmap, pixelCoords + ivec2( 0, 1)).r, uniFlatness) * uniHeightFactor;

return vec2(leftHeight - rightHeight, topHeight - botHeight);
}

void main() {
ivec2 pixelCoords = ivec2(gl_GlobalInvocationID.xy);

vec2 slopeVec = computeSlope(pixelCoords);
float slopeStrength = length(slopeVec) * 0.5;
imageStore(uniSlopeMap, pixelCoords, vec4(normalize(slopeVec), slopeStrength, 1.0));
}
21 changes: 21 additions & 0 deletions src/Midgard/DynamicTerrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ constexpr std::string_view colorCompSource = {
#include "terrain_color.comp.embed"
};

constexpr std::string_view slopeCompSource = {
#include "slope.comp.embed"
};

inline void checkParameters(float& minTessLevel) {
if (minTessLevel <= 0.f) {
Raz::Logger::warn("[DynamicTerrain] The minimal tessellation level can't be 0 or negative; remapping to +epsilon.");
Expand All @@ -43,11 +47,13 @@ DynamicTerrain::DynamicTerrain(Raz::Entity& entity) : Terrain(entity) {

m_noiseMap = Raz::Texture2D::create(heightmapSize, heightmapSize, Raz::TextureColorspace::GRAY, Raz::TextureDataType::FLOAT16);
m_colorMap = Raz::Texture2D::create(heightmapSize, heightmapSize, Raz::TextureColorspace::RGBA, Raz::TextureDataType::BYTE);
m_slopeMap = Raz::Texture2D::create(heightmapSize, heightmapSize, Raz::TextureColorspace::RGBA, Raz::TextureDataType::FLOAT16);

#if !defined(USE_OPENGL_ES)
if (Raz::Renderer::checkVersion(4, 3)) {
Raz::Renderer::setLabel(Raz::RenderObjectType::TEXTURE, m_noiseMap->getIndex(), "Noise map");
Raz::Renderer::setLabel(Raz::RenderObjectType::TEXTURE, m_colorMap->getIndex(), "Color map");
Raz::Renderer::setLabel(Raz::RenderObjectType::TEXTURE, m_slopeMap->getIndex(), "Slope map");
}
#endif

Expand All @@ -59,10 +65,15 @@ DynamicTerrain::DynamicTerrain(Raz::Entity& entity) : Terrain(entity) {
m_colorProgram.setImageTexture(m_noiseMap, "uniHeightmap", Raz::ImageTextureUsage::READ);
m_colorProgram.setImageTexture(m_colorMap, "uniColorMap", Raz::ImageTextureUsage::WRITE);

m_slopeProgram.setShader(Raz::ComputeShader::loadFromSource(slopeCompSource));
m_slopeProgram.setImageTexture(m_noiseMap, "uniHeightmap", Raz::ImageTextureUsage::READ);
m_slopeProgram.setImageTexture(m_slopeMap, "uniSlopeMap", Raz::ImageTextureUsage::WRITE);

terrainProgram.setTexture(m_noiseMap, "uniHeightmap");
terrainProgram.setTexture(m_colorMap, Raz::MaterialTexture::BaseColor);

computeNoiseMap(0.01f);
computeSlopeMap();
computeColorMap();
}

Expand All @@ -86,6 +97,10 @@ void DynamicTerrain::setParameters(float minTessLevel, float heightFactor, float
terrainProgram.setAttribute(m_heightFactor, "uniHeightFactor");
terrainProgram.setAttribute(m_flatness, "uniFlatness");
terrainProgram.sendAttributes();

m_slopeProgram.setAttribute(m_heightFactor, "uniHeightFactor");
m_slopeProgram.setAttribute(m_flatness, "uniFlatness");
m_slopeProgram.sendAttributes();
}

void DynamicTerrain::generate(unsigned int width, unsigned int depth, float heightFactor, float flatness, float minTessLevel) {
Expand Down Expand Up @@ -158,3 +173,9 @@ const Raz::Texture2D& DynamicTerrain::computeColorMap() {

return *m_colorMap;
}

const Raz::Texture2D& DynamicTerrain::computeSlopeMap() {
m_slopeProgram.execute(heightmapSize, heightmapSize);

return *m_slopeMap;
}

0 comments on commit 65c0b34

Please sign in to comment.