Bloom.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
  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::initInternal(const ConfigSet& config)
  22. {
  23. GrManager& gr = getGrManager();
  24. m_upscale.m_width = m_r->getWidth() / BLOOM_FRACTION;
  25. m_upscale.m_height = m_r->getHeight() / BLOOM_FRACTION;
  26. m_extractExposure.m_width =
  27. m_r->getWidth() >> (m_r->getIs().getRtMipmapCount() - 2);
  28. m_extractExposure.m_height =
  29. m_r->getHeight() >> (m_r->getIs().getRtMipmapCount() - 2);
  30. m_threshold = config.getNumber("bloom.threshold");
  31. m_scale = config.getNumber("bloom.scale");
  32. // Create RTs
  33. m_r->createRenderTarget(m_extractExposure.m_width,
  34. m_extractExposure.m_height,
  35. RT_PIXEL_FORMAT,
  36. TextureUsageBit::SAMPLED_FRAGMENT
  37. | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
  38. SamplingFilter::LINEAR,
  39. 1,
  40. m_extractExposure.m_rt);
  41. m_r->createRenderTarget(m_upscale.m_width,
  42. m_upscale.m_height,
  43. RT_PIXEL_FORMAT,
  44. TextureUsageBit::SAMPLED_FRAGMENT
  45. | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  46. SamplingFilter::LINEAR,
  47. 1,
  48. m_upscale.m_rt);
  49. // Create FBs
  50. FramebufferInitInfo fbInit;
  51. fbInit.m_colorAttachmentCount = 1;
  52. fbInit.m_colorAttachments[0].m_texture = m_extractExposure.m_rt;
  53. fbInit.m_colorAttachments[0].m_loadOperation =
  54. AttachmentLoadOperation::DONT_CARE;
  55. fbInit.m_colorAttachments[0].m_usageInsideRenderPass =
  56. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
  57. m_extractExposure.m_fb = gr.newInstance<Framebuffer>(fbInit);
  58. fbInit.m_colorAttachments[0].m_texture = m_upscale.m_rt;
  59. fbInit.m_colorAttachments[0].m_usageInsideRenderPass =
  60. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE;
  61. m_upscale.m_fb = gr.newInstance<Framebuffer>(fbInit);
  62. // init shaders
  63. StringAuto pps(getAllocator());
  64. pps.sprintf("#define WIDTH %u\n"
  65. "#define HEIGHT %u\n"
  66. "#define MIPMAP %u.0\n",
  67. m_r->getWidth() >> (m_r->getIs().getRtMipmapCount() - 1),
  68. m_r->getHeight() >> (m_r->getIs().getRtMipmapCount() - 1),
  69. m_r->getIs().getRtMipmapCount() - 1);
  70. ANKI_CHECK(
  71. getResourceManager().loadResourceToCache(m_extractExposure.m_frag,
  72. "shaders/Bloom.frag.glsl",
  73. pps.toCString(),
  74. "r_"));
  75. pps.destroy();
  76. pps.sprintf("#define WIDTH %u\n"
  77. "#define HEIGHT %u\n",
  78. m_extractExposure.m_width,
  79. m_extractExposure.m_height);
  80. ANKI_CHECK(getResourceManager().loadResourceToCache(m_upscale.m_frag,
  81. "shaders/BloomUpscale.frag.glsl",
  82. pps.toCString(),
  83. "r_"));
  84. // Init pplines
  85. ColorStateInfo colorInf;
  86. colorInf.m_attachmentCount = 1;
  87. colorInf.m_attachments[0].m_format = RT_PIXEL_FORMAT;
  88. m_r->createDrawQuadPipeline(m_extractExposure.m_frag->getGrShader(),
  89. colorInf,
  90. m_extractExposure.m_ppline);
  91. m_r->createDrawQuadPipeline(
  92. m_upscale.m_frag->getGrShader(), colorInf, m_upscale.m_ppline);
  93. // Set descriptors
  94. {
  95. ResourceGroupInitInfo descInit;
  96. descInit.m_textures[0].m_texture = m_r->getIs().getRt();
  97. descInit.m_uniformBuffers[0].m_uploadedMemory = true;
  98. descInit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_FRAGMENT;
  99. descInit.m_storageBuffers[0].m_buffer =
  100. m_r->getTm().getAverageLuminanceBuffer();
  101. descInit.m_storageBuffers[0].m_usage = BufferUsageBit::STORAGE_FRAGMENT;
  102. m_extractExposure.m_rsrc = gr.newInstance<ResourceGroup>(descInit);
  103. }
  104. {
  105. ResourceGroupInitInfo descInit;
  106. descInit.m_textures[0].m_texture = m_extractExposure.m_rt;
  107. m_upscale.m_rsrc = gr.newInstance<ResourceGroup>(descInit);
  108. }
  109. return ErrorCode::NONE;
  110. }
  111. //==============================================================================
  112. Error Bloom::init(const ConfigSet& config)
  113. {
  114. Error err = initInternal(config);
  115. if(err)
  116. {
  117. ANKI_LOGE("Failed to init PPS bloom");
  118. }
  119. return err;
  120. }
  121. //==============================================================================
  122. void Bloom::run(RenderingContext& ctx)
  123. {
  124. CommandBufferPtr& cmdb = ctx.m_commandBuffer;
  125. // pass 0
  126. cmdb->beginRenderPass(m_extractExposure.m_fb);
  127. cmdb->setViewport(
  128. 0, 0, m_extractExposure.m_width, m_extractExposure.m_height);
  129. cmdb->bindPipeline(m_extractExposure.m_ppline);
  130. TransientMemoryInfo dyn;
  131. Vec4* uniforms = static_cast<Vec4*>(
  132. getGrManager().allocateFrameTransientMemory(sizeof(Vec4),
  133. BufferUsageBit::UNIFORM_ALL,
  134. dyn.m_uniformBuffers[0]));
  135. *uniforms = Vec4(m_threshold, m_scale, 0.0, 0.0);
  136. cmdb->bindResourceGroup(m_extractExposure.m_rsrc, 0, &dyn);
  137. m_r->drawQuad(cmdb);
  138. cmdb->endRenderPass();
  139. // pass 1
  140. cmdb->setTextureBarrier(m_extractExposure.m_rt,
  141. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
  142. TextureUsageBit::SAMPLED_FRAGMENT,
  143. TextureSurfaceInfo(0, 0, 0, 0));
  144. cmdb->setTextureBarrier(m_upscale.m_rt,
  145. TextureUsageBit::NONE,
  146. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  147. TextureSurfaceInfo(0, 0, 0, 0));
  148. cmdb->setViewport(0, 0, m_upscale.m_width, m_upscale.m_height);
  149. cmdb->beginRenderPass(m_upscale.m_fb);
  150. cmdb->bindPipeline(m_upscale.m_ppline);
  151. cmdb->bindResourceGroup(m_upscale.m_rsrc, 0, nullptr);
  152. m_r->drawQuad(cmdb);
  153. }
  154. //==============================================================================
  155. void Bloom::setPreRunBarriers(RenderingContext& ctx)
  156. {
  157. ctx.m_commandBuffer->setTextureBarrier(m_extractExposure.m_rt,
  158. TextureUsageBit::NONE,
  159. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
  160. TextureSurfaceInfo(0, 0, 0, 0));
  161. }
  162. //==============================================================================
  163. void Bloom::setPostRunBarriers(RenderingContext& ctx)
  164. {
  165. ctx.m_commandBuffer->setTextureBarrier(m_upscale.m_rt,
  166. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
  167. TextureUsageBit::SAMPLED_FRAGMENT,
  168. TextureSurfaceInfo(0, 0, 0, 0));
  169. }
  170. } // end namespace anki