Bloom.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <anki/renderer/Bloom.h>
  6. #include <anki/renderer/Is.h>
  7. #include <anki/renderer/Pps.h>
  8. #include <anki/renderer/Renderer.h>
  9. #include <anki/renderer/Tm.h>
  10. #include <anki/misc/ConfigSet.h>
  11. namespace anki
  12. {
  13. //==============================================================================
  14. const PixelFormat Bloom::RT_PIXEL_FORMAT(
  15. ComponentFormat::R8G8B8, TransformFormat::UNORM);
  16. //==============================================================================
  17. Bloom::~Bloom()
  18. {
  19. }
  20. //==============================================================================
  21. Error Bloom::initFb(FramebufferPtr& fb, TexturePtr& rt)
  22. {
  23. // Set to bilinear because the blurring techniques take advantage of that
  24. m_r->createRenderTarget(
  25. m_width, m_height, RT_PIXEL_FORMAT, 1, SamplingFilter::LINEAR, 1, rt);
  26. // Create FB
  27. FramebufferInitializer fbInit;
  28. fbInit.m_colorAttachmentsCount = 1;
  29. fbInit.m_colorAttachments[0].m_texture = rt;
  30. fbInit.m_colorAttachments[0].m_loadOperation =
  31. AttachmentLoadOperation::DONT_CARE;
  32. fb = getGrManager().newInstance<Framebuffer>(fbInit);
  33. return ErrorCode::NONE;
  34. }
  35. //==============================================================================
  36. Error Bloom::initInternal(const ConfigSet& config)
  37. {
  38. const F32 renderingQuality = config.getNumber("bloom.renderingQuality");
  39. m_width = renderingQuality * F32(m_r->getWidth());
  40. alignRoundDown(16, m_width);
  41. m_height = renderingQuality * F32(m_r->getHeight());
  42. alignRoundDown(16, m_height);
  43. m_threshold = config.getNumber("bloom.threshold");
  44. m_scale = config.getNumber("bloom.scale");
  45. m_blurringDist = config.getNumber("bloom.blurringDist");
  46. m_blurringIterationsCount =
  47. config.getNumber("bloom.blurringIterationsCount");
  48. ANKI_CHECK(initFb(m_hblurFb, m_hblurRt));
  49. ANKI_CHECK(initFb(m_vblurFb, m_vblurRt));
  50. // init shaders & pplines
  51. GrManager& gl = getGrManager();
  52. ColorStateInfo colorState;
  53. colorState.m_attachmentCount = 1;
  54. colorState.m_attachments[0].m_format = RT_PIXEL_FORMAT;
  55. StringAuto pps(getAllocator());
  56. pps.sprintf("#define ANKI_RENDERER_WIDTH %u\n"
  57. "#define ANKI_RENDERER_HEIGHT %u\n",
  58. m_r->getWidth(),
  59. m_r->getHeight());
  60. ANKI_CHECK(getResourceManager().loadResourceToCache(
  61. m_toneFrag, "shaders/Bloom.frag.glsl", pps.toCString(), "r_"));
  62. m_r->createDrawQuadPipeline(
  63. m_toneFrag->getGrShader(), colorState, m_tonePpline);
  64. const char* SHADER_FILENAME =
  65. "shaders/VariableSamplingBlurGeneric.frag.glsl";
  66. pps.destroy();
  67. pps.sprintf("#define HPASS\n"
  68. "#define COL_RGB\n"
  69. "#define BLURRING_DIST float(1.1)\n"
  70. "#define IMG_DIMENSION %u\n"
  71. "#define SAMPLES 17\n",
  72. m_height);
  73. ANKI_CHECK(getResourceManager().loadResourceToCache(
  74. m_hblurFrag, SHADER_FILENAME, pps.toCString(), "r_"));
  75. m_r->createDrawQuadPipeline(
  76. m_hblurFrag->getGrShader(), colorState, m_hblurPpline);
  77. pps.destroy();
  78. pps.sprintf("#define VPASS\n"
  79. "#define COL_RGB\n"
  80. "#define BLURRING_DIST float(1.0)\n"
  81. "#define IMG_DIMENSION %u\n"
  82. "#define SAMPLES 15\n",
  83. m_width);
  84. ANKI_CHECK(getResourceManager().loadResourceToCache(
  85. m_vblurFrag, SHADER_FILENAME, pps.toCString(), "r_"));
  86. m_r->createDrawQuadPipeline(
  87. m_vblurFrag->getGrShader(), colorState, m_vblurPpline);
  88. // Set descriptors
  89. {
  90. ResourceGroupInitializer descInit;
  91. descInit.m_textures[0].m_texture = m_r->getIs().getRt();
  92. descInit.m_uniformBuffers[0].m_dynamic = true;
  93. descInit.m_storageBuffers[0].m_buffer =
  94. m_r->getTm().getAverageLuminanceBuffer();
  95. m_firstDescrGroup = gl.newInstance<ResourceGroup>(descInit);
  96. }
  97. {
  98. ResourceGroupInitializer descInit;
  99. descInit.m_textures[0].m_texture = m_vblurRt;
  100. m_hDescrGroup = gl.newInstance<ResourceGroup>(descInit);
  101. }
  102. {
  103. ResourceGroupInitializer descInit;
  104. descInit.m_textures[0].m_texture = m_hblurRt;
  105. m_vDescrGroup = gl.newInstance<ResourceGroup>(descInit);
  106. }
  107. getGrManager().finish();
  108. return ErrorCode::NONE;
  109. }
  110. //==============================================================================
  111. Error Bloom::init(const ConfigSet& config)
  112. {
  113. Error err = initInternal(config);
  114. if(err)
  115. {
  116. ANKI_LOGE("Failed to init PPS bloom");
  117. }
  118. return err;
  119. }
  120. //==============================================================================
  121. void Bloom::run(CommandBufferPtr& cmdb)
  122. {
  123. // For the passes it should be NEAREST_BASE
  124. // vblurFai.setFiltering(Texture::TFrustumType::NEAREST_BASE);
  125. // pass 0
  126. cmdb->bindFramebuffer(m_vblurFb);
  127. cmdb->setViewport(0, 0, m_width, m_height);
  128. cmdb->bindPipeline(m_tonePpline);
  129. DynamicBufferInfo dyn;
  130. Vec4* uniforms =
  131. static_cast<Vec4*>(getGrManager().allocateFrameHostVisibleMemory(
  132. sizeof(Vec4), BufferUsage::UNIFORM, dyn.m_uniformBuffers[0]));
  133. *uniforms = Vec4(m_threshold, m_scale, 0.0, 0.0);
  134. cmdb->bindResourceGroup(m_firstDescrGroup, 0, &dyn);
  135. m_r->drawQuad(cmdb);
  136. // Blurring passes
  137. for(U i = 0; i < m_blurringIterationsCount; i++)
  138. {
  139. // hpass
  140. cmdb->bindFramebuffer(m_hblurFb);
  141. cmdb->bindResourceGroup(m_hDescrGroup, 0, nullptr);
  142. cmdb->bindPipeline(m_hblurPpline);
  143. m_r->drawQuad(cmdb);
  144. // vpass
  145. cmdb->bindFramebuffer(m_vblurFb);
  146. cmdb->bindResourceGroup(m_vDescrGroup, 0, nullptr);
  147. cmdb->bindPipeline(m_vblurPpline);
  148. m_r->drawQuad(cmdb);
  149. }
  150. }
  151. } // end namespace anki