ground_renderer.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "ground_renderer.h"
  2. #include "../draw_queue.h"
  3. #include "../gl/resources.h"
  4. #include "../scene_renderer.h"
  5. #include <algorithm>
  6. #include <cmath>
  7. namespace Render {
  8. namespace GL {
  9. namespace {
  10. const QMatrix4x4 kIdentityMatrix;
  11. inline QVector3D saturate(const QVector3D &c) {
  12. return QVector3D(std::clamp(c.x(), 0.0f, 1.0f), std::clamp(c.y(), 0.0f, 1.0f),
  13. std::clamp(c.z(), 0.0f, 1.0f));
  14. }
  15. } // namespace
  16. static QVector3D clamp01(const QVector3D &c) { return saturate(c); }
  17. void GroundRenderer::recomputeModel() {
  18. QMatrix4x4 newModel = kIdentityMatrix;
  19. newModel.translate(0.0f, -0.5f, 0.0f);
  20. if (m_width > 0 && m_height > 0) {
  21. const float scaleX = float(m_width) * m_tileSize;
  22. const float scaleZ = float(m_height) * m_tileSize;
  23. newModel.scale(scaleX, 1.0f, scaleZ);
  24. } else {
  25. newModel.scale(m_extent, 1.0f, m_extent);
  26. }
  27. if (newModel != m_model) {
  28. m_model = newModel;
  29. m_modelDirty = true;
  30. }
  31. }
  32. void GroundRenderer::updateNoiseOffset() {
  33. const float spanX = (m_width > 0 ? float(m_width) * m_tileSize : m_extent);
  34. const float spanZ = (m_height > 0 ? float(m_height) * m_tileSize : m_extent);
  35. const float seed = static_cast<float>(m_biomeSettings.seed % 1024u);
  36. QVector2D newOffset;
  37. newOffset.setX(spanX * 0.37f + seed * 0.21f);
  38. newOffset.setY(spanZ * 0.43f + seed * 0.17f);
  39. if (newOffset != m_noiseOffset) {
  40. m_noiseOffset = newOffset;
  41. invalidateParamsCache();
  42. }
  43. }
  44. TerrainChunkParams GroundRenderer::buildParams() const {
  45. if (m_cachedParamsValid) {
  46. return m_cachedParams;
  47. }
  48. TerrainChunkParams params;
  49. const QVector3D primary = m_biomeSettings.grassPrimary * 0.97f;
  50. const QVector3D secondary = m_biomeSettings.grassSecondary * 0.93f;
  51. const QVector3D dry = m_biomeSettings.grassDry * 0.90f;
  52. const QVector3D soil = m_biomeSettings.soilColor * 0.68f;
  53. params.grassPrimary = saturate(primary);
  54. params.grassSecondary = saturate(secondary);
  55. params.grassDry = saturate(dry);
  56. params.soilColor = saturate(soil);
  57. params.rockLow = saturate(m_biomeSettings.rockLow);
  58. params.rockHigh = saturate(m_biomeSettings.rockHigh);
  59. params.tint = QVector3D(0.96f, 0.98f, 0.96f);
  60. params.tileSize = std::max(0.25f, m_tileSize);
  61. params.macroNoiseScale =
  62. std::max(0.012f, m_biomeSettings.terrainMacroNoiseScale * 0.60f);
  63. params.detailNoiseScale =
  64. std::max(0.045f, m_biomeSettings.terrainDetailNoiseScale * 0.75f);
  65. params.slopeRockThreshold = 0.72f;
  66. params.slopeRockSharpness = 4.5f;
  67. params.soilBlendHeight = -0.38f;
  68. params.soilBlendSharpness = 2.6f;
  69. params.noiseOffset = m_noiseOffset;
  70. params.heightNoiseStrength = m_biomeSettings.heightNoiseAmplitude * 0.22f;
  71. params.heightNoiseFrequency = m_biomeSettings.heightNoiseFrequency * 1.05f;
  72. params.ambientBoost = m_biomeSettings.terrainAmbientBoost * 0.92f;
  73. params.rockDetailStrength = m_biomeSettings.terrainRockDetailStrength * 0.18f;
  74. QVector3D L(0.35f, 0.85f, 0.42f);
  75. params.lightDirection = L.normalized();
  76. m_cachedParams = params;
  77. m_cachedParamsValid = true;
  78. return params;
  79. }
  80. void GroundRenderer::submit(Renderer &renderer, ResourceManager &resources) {
  81. if (m_hasBiome) {
  82. Mesh *plane = resources.ground();
  83. if (plane) {
  84. const TerrainChunkParams params = buildParams();
  85. const bool modelChanged =
  86. m_modelDirty || (m_lastSubmittedModel != m_model);
  87. const bool stateChanged = (m_lastSubmittedStateVersion != m_stateVersion);
  88. renderer.terrainChunk(plane, m_model, params, 0x0100u, false, 0.0f);
  89. m_lastSubmittedModel = m_model;
  90. m_modelDirty = false;
  91. m_lastSubmittedStateVersion = m_stateVersion;
  92. return;
  93. }
  94. }
  95. const float cell = (m_tileSize > 0.0f ? m_tileSize : 1.0f);
  96. const float extent = (m_width > 0 && m_height > 0)
  97. ? std::max(m_width, m_height) * m_tileSize * 0.5f
  98. : m_extent;
  99. renderer.grid(m_model, m_color, cell, 0.06f, extent);
  100. }
  101. } // namespace GL
  102. } // namespace Render