Sm.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "anki/renderer/Sm.h"
  2. #include "anki/renderer/Renderer.h"
  3. #include "anki/core/App.h"
  4. #include "anki/resource/LightRsrc.h"
  5. #include "anki/scene/Scene.h"
  6. #include "anki/scene/Camera.h"
  7. #include "anki/scene/Light.h"
  8. namespace anki {
  9. //==============================================================================
  10. void Sm::init(const RendererInitializer& initializer)
  11. {
  12. enabled = initializer.is.sm.enabled;
  13. if(!enabled)
  14. {
  15. return;
  16. }
  17. pcfEnabled = initializer.is.sm.pcfEnabled;
  18. bilinearEnabled = initializer.is.sm.bilinearEnabled;
  19. resolution = initializer.is.sm.resolution;
  20. level0Distance = initializer.is.sm.level0Distance;
  21. // Init the levels
  22. initLevel(resolution, level0Distance, bilinearEnabled, levels[0]);
  23. for(uint32_t i = 1; i < levels.size(); i++)
  24. {
  25. initLevel(levels[i - 1].resolution / 2,
  26. levels[i - 1].distance * 2.0,
  27. bilinearEnabled,
  28. levels[i]);
  29. }
  30. }
  31. //==============================================================================
  32. void Sm::initLevel(uint32_t resolution, float distance, bool bilinear,
  33. Level& level)
  34. {
  35. level.resolution = resolution;
  36. level.distance = distance;
  37. level.bilinear = bilinear;
  38. try
  39. {
  40. // Init texture
  41. Renderer::createFai(level.resolution, level.resolution,
  42. GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, level.shadowMap);
  43. if(level.bilinear)
  44. {
  45. level.shadowMap.setFiltering(Texture::TFT_LINEAR);
  46. }
  47. else
  48. {
  49. level.shadowMap.setFiltering(Texture::TFT_NEAREST);
  50. }
  51. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
  52. GL_COMPARE_R_TO_TEXTURE);
  53. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  54. /*If you dont want to use the FFP for comparing the shadowmap
  55. (the above two lines) then you can make the comparison
  56. inside the glsl shader. The GL_LEQUAL means that:
  57. shadow = (R <= Dt) ? 1.0 : 0.0; . The R is given by:
  58. R = _tex_coord2.z/_tex_coord2.w; and the
  59. Dt = shadow2D(shadow_depth_map, _shadow_uv).r (see lp_generic.frag).
  60. Hardware filters like GL_LINEAR cannot be applied.*/
  61. // create FBO
  62. level.fbo.create();
  63. level.fbo.setOtherAttachment(GL_DEPTH_ATTACHMENT, level.shadowMap);
  64. }
  65. catch(std::exception& e)
  66. {
  67. throw ANKI_EXCEPTION("Cannot create shadowmapping FBO") << e;
  68. }
  69. }
  70. //==============================================================================
  71. void Sm::run(Light& light, float distance)
  72. {
  73. if(!enabled || !light.getShadowEnabled()
  74. || light.getLightType() == Light::LT_POINT)
  75. {
  76. return;
  77. }
  78. // Determine the level
  79. //
  80. for(Level& level : levels)
  81. {
  82. crntLevel = &level;
  83. if(distance < level.distance)
  84. {
  85. break;
  86. }
  87. }
  88. // Render
  89. //
  90. // FBO
  91. crntLevel->fbo.bind();
  92. // set GL
  93. GlStateSingleton::get().setViewport(0, 0,
  94. crntLevel->resolution, crntLevel->resolution);
  95. glClear(GL_DEPTH_BUFFER_BIT);
  96. // disable color & blend & enable depth test
  97. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  98. GlStateSingleton::get().enable(GL_DEPTH_TEST);
  99. GlStateSingleton::get().disable(GL_BLEND);
  100. // for artifacts
  101. glPolygonOffset(2.0, 2.0); // keep the values as low as possible!!!!
  102. GlStateSingleton::get().enable(GL_POLYGON_OFFSET_FILL);
  103. // Visibility tests
  104. SpotLight& slight = static_cast<SpotLight&>(light);
  105. VisibilityInfo vi;
  106. VisibilityTester vt;
  107. vt.test(slight, r->getScene(), vi);
  108. // render all
  109. for(Renderable* node : vi.getRenderables())
  110. {
  111. r->getSceneDrawer().render(r->getScene().getActiveCamera(), 1, *node);
  112. }
  113. // restore GL
  114. GlStateSingleton::get().disable(GL_POLYGON_OFFSET_FILL);
  115. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  116. }
  117. } // end namespace