BsLightRendering.cpp 5.9 KB

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