BsLightRendering.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsLightRendering.h"
  4. #include "BsMaterial.h"
  5. #include "BsShader.h"
  6. #include "BsRenderBeast.h"
  7. #include "BsRenderTargets.h"
  8. #include "BsGpuParams.h"
  9. #include "BsLight.h"
  10. #include "BsRendererUtility.h"
  11. namespace BansheeEngine
  12. {
  13. LightRenderingParams::LightRenderingParams(const SPtr<MaterialCore>& material)
  14. :mMaterial(material)
  15. {
  16. auto& texParams = material->getShader()->getTextureParams();
  17. for (auto& entry : texParams)
  18. {
  19. if (entry.second.rendererSemantic == RPS_GBufferA)
  20. mGBufferA = material->getParamTexture(entry.second.name);
  21. else if (entry.second.rendererSemantic == RPS_GBufferB)
  22. mGBufferB = material->getParamTexture(entry.second.name);
  23. else if (entry.second.rendererSemantic == RPS_GBufferDepth)
  24. mGBufferDepth = material->getParamTexture(entry.second.name);
  25. }
  26. }
  27. void LightRenderingParams::setStaticParameters(const SPtr<RenderTargets>& gbuffer,
  28. const SPtr<GpuParamBlockBufferCore>& perCamera)
  29. {
  30. mGBufferA.set(gbuffer->getTextureA());
  31. mGBufferB.set(gbuffer->getTextureB());
  32. mGBufferDepth.set(gbuffer->getTextureDepth());
  33. mMaterial->setParamBlockBuffer("PerLight", getBuffer());
  34. mMaterial->setParamBlockBuffer("PerCamera", perCamera);
  35. gRendererUtility().setPassParams(mMaterial);
  36. }
  37. void LightRenderingParams::setParameters(const LightCore* light)
  38. {
  39. // Note: I could just copy the data directly to the parameter buffer if I ensured the parameter
  40. // layout matches
  41. Vector4 positionAndType = (Vector4)light->getPosition();
  42. switch (light->getType())
  43. {
  44. case LightType::Directional:
  45. positionAndType.w = 0;
  46. break;
  47. case LightType::Point:
  48. positionAndType.w = 0.3f;
  49. break;
  50. case LightType::Spot:
  51. positionAndType.w = 0.8f;
  52. break;
  53. }
  54. mBuffer.gLightPositionAndType.set(positionAndType);
  55. Vector4 colorAndIntensity;
  56. colorAndIntensity.x = light->getColor().r;
  57. colorAndIntensity.y = light->getColor().g;
  58. colorAndIntensity.z = light->getColor().b;
  59. colorAndIntensity.w = light->getIntensity();
  60. mBuffer.gLightColorAndIntensity.set(colorAndIntensity);
  61. Radian spotAngle = Math::clamp(light->getSpotAngle() * 0.5f, Degree(1), Degree(90));
  62. Radian spotFalloffAngle = Math::clamp(light->getSpotFalloffAngle() * 0.5f, Degree(1), (Degree)spotAngle);
  63. Vector4 spotAnglesAndInvSqrdRadius;
  64. spotAnglesAndInvSqrdRadius.x = spotAngle.valueRadians();
  65. spotAnglesAndInvSqrdRadius.y = Math::cos(spotAnglesAndInvSqrdRadius.x);
  66. spotAnglesAndInvSqrdRadius.z = 1.0f / (Math::cos(spotFalloffAngle) - spotAnglesAndInvSqrdRadius.y);
  67. spotAnglesAndInvSqrdRadius.w = 1.0f / (light->getBounds().getRadius() * light->getBounds().getRadius());
  68. mBuffer.gLightSpotAnglesAndSqrdInvRadius.set(spotAnglesAndInvSqrdRadius);
  69. mBuffer.gLightDirection.set(-light->getRotation().zAxis());
  70. Vector4 lightGeometry;
  71. lightGeometry.x = light->getType() == LightType::Spot ? (float)LightCore::LIGHT_CONE_NUM_SIDES : 0;
  72. lightGeometry.y = (float)LightCore::LIGHT_CONE_NUM_SLICES;
  73. lightGeometry.z = light->getBounds().getRadius();
  74. float coneRadius = Math::sin(spotAngle) * light->getRange();
  75. lightGeometry.w = coneRadius;
  76. mBuffer.gLightGeometry.set(lightGeometry);
  77. Matrix4 transform = Matrix4::TRS(light->getPosition(), light->getRotation(), Vector3::ONE);
  78. mBuffer.gMatConeTransform.set(transform);
  79. mBuffer.flushToGPU();
  80. }
  81. const SPtr<GpuParamBlockBufferCore>& LightRenderingParams::getBuffer() const
  82. {
  83. return mBuffer.getBuffer();
  84. }
  85. DirectionalLightMat::DirectionalLightMat()
  86. :mParams(mMaterial)
  87. {
  88. }
  89. void DirectionalLightMat::_initDefines(ShaderDefines& defines)
  90. {
  91. // Do nothing
  92. }
  93. void DirectionalLightMat::bind(const SPtr<RenderTargets>& gbuffer,
  94. const SPtr<GpuParamBlockBufferCore>& perCamera)
  95. {
  96. RendererUtility::instance().setPass(mMaterial, 0, false);
  97. mParams.setStaticParameters(gbuffer, perCamera);
  98. }
  99. void DirectionalLightMat::setPerLightParams(const LightCore* light)
  100. {
  101. mParams.setParameters(light);
  102. }
  103. PointLightInMat::PointLightInMat()
  104. :mParams(mMaterial)
  105. {
  106. }
  107. void PointLightInMat::_initDefines(ShaderDefines& defines)
  108. {
  109. // Do nothing
  110. }
  111. void PointLightInMat::bind(const SPtr<RenderTargets>& gbuffer,
  112. const SPtr<GpuParamBlockBufferCore>& perCamera)
  113. {
  114. RendererUtility::instance().setPass(mMaterial, 0, false);
  115. mParams.setStaticParameters(gbuffer, perCamera);
  116. }
  117. void PointLightInMat::setPerLightParams(const LightCore* light)
  118. {
  119. mParams.setParameters(light);
  120. }
  121. PointLightOutMat::PointLightOutMat()
  122. :mParams(mMaterial)
  123. {
  124. }
  125. void PointLightOutMat::_initDefines(ShaderDefines& defines)
  126. {
  127. // Do nothing
  128. }
  129. void PointLightOutMat::bind(const SPtr<RenderTargets>& gbuffer,
  130. const SPtr<GpuParamBlockBufferCore>& perCamera)
  131. {
  132. RendererUtility::instance().setPass(mMaterial, 0, false);
  133. mParams.setStaticParameters(gbuffer, perCamera);
  134. }
  135. void PointLightOutMat::setPerLightParams(const LightCore* light)
  136. {
  137. mParams.setParameters(light);
  138. }
  139. }