BsLightRendering.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "BsLightRendering.h"
  2. #include "BsMaterial.h"
  3. #include "BsShader.h"
  4. #include "BsRenderBeast.h"
  5. #include "BsRenderTargets.h"
  6. #include "BsGpuParams.h"
  7. #include "BsLight.h"
  8. namespace BansheeEngine
  9. {
  10. void PerLightParams::setParameters(const LightCore* light)
  11. {
  12. // Note: I could just copy the data directly to the parameter buffer if I ensured the parameter
  13. // layout matches
  14. Vector4 positionAndType = (Vector4)light->getPosition();
  15. switch (light->getType())
  16. {
  17. case LightType::Directional:
  18. positionAndType.w = 0;
  19. break;
  20. case LightType::Point:
  21. positionAndType.w = 0.3f;
  22. break;
  23. case LightType::Spot:
  24. positionAndType.w = 0.8f;
  25. break;
  26. }
  27. mBuffer.gLightPositionAndType.set(positionAndType);
  28. Vector4 colorAndIntensity;
  29. colorAndIntensity.x = light->getColor().r;
  30. colorAndIntensity.y = light->getColor().g;
  31. colorAndIntensity.z = light->getColor().b;
  32. colorAndIntensity.w = light->getIntensity();
  33. mBuffer.gLightColorAndIntensity.set(colorAndIntensity);
  34. Radian spotAngle = Math::clamp(light->getSpotAngle() * 0.5f, Degree(1), Degree(90));
  35. Radian spotFalloffAngle = Math::clamp(light->getSpotFalloffAngle() * 0.5f, Degree(1), (Degree)spotAngle);
  36. Vector4 spotAnglesAndInvSqrdRadius;
  37. spotAnglesAndInvSqrdRadius.x = spotAngle.valueRadians();
  38. spotAnglesAndInvSqrdRadius.y = Math::cos(spotAnglesAndInvSqrdRadius.x);
  39. spotAnglesAndInvSqrdRadius.z = 1.0f / (Math::cos(spotFalloffAngle) - spotAnglesAndInvSqrdRadius.y);
  40. spotAnglesAndInvSqrdRadius.w = 1.0f / (light->getBounds().getRadius() * light->getBounds().getRadius());
  41. mBuffer.gLightSpotAnglesAndSqrdInvRadius.set(spotAnglesAndInvSqrdRadius);
  42. mBuffer.gLightDirection.set(-light->getRotation().zAxis());
  43. Vector4 lightGeometry;
  44. lightGeometry.x = light->getType() == LightType::Spot ? (float)LightCore::LIGHT_CONE_NUM_SIDES : 0;
  45. lightGeometry.y = (float)LightCore::LIGHT_CONE_NUM_SLICES;
  46. lightGeometry.z = light->getBounds().getRadius();
  47. float coneRadius = Math::sin(spotAngle) * light->getRange();
  48. lightGeometry.w = coneRadius;
  49. mBuffer.gLightGeometry.set(lightGeometry);
  50. Matrix4 transform = Matrix4::TRS(light->getPosition(), light->getRotation(), Vector3::ONE);
  51. mBuffer.gMatConeTransform.set(transform);
  52. }
  53. const SPtr<GpuParamBlockBufferCore>& PerLightParams::getBuffer() const
  54. {
  55. return mBuffer.getBuffer();
  56. }
  57. DirectionalLightMat::DirectionalLightMat()
  58. {
  59. mMaterial->setParamBlockBuffer("PerLight", mParams.getBuffer());
  60. auto& texParams = mMaterial->getShader()->getTextureParams();
  61. for (auto& entry : texParams)
  62. {
  63. if (entry.second.rendererSemantic == RPS_GBufferA)
  64. mGBufferA = mMaterial->getParamTexture(entry.second.name);
  65. else if (entry.second.rendererSemantic == RPS_GBufferB)
  66. mGBufferB = mMaterial->getParamTexture(entry.second.name);
  67. else if (entry.second.rendererSemantic == RPS_GBufferDepth)
  68. mGBufferDepth = mMaterial->getParamTexture(entry.second.name);
  69. }
  70. }
  71. void DirectionalLightMat::setStaticParameters(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBufferCore>& perCamera)
  72. {
  73. mGBufferA.set(gbuffer->getTextureA());
  74. mGBufferB.set(gbuffer->getTextureB());
  75. mGBufferDepth.set(gbuffer->getTextureDepth());
  76. mMaterial->setParamBlockBuffer("PerCamera", perCamera);
  77. }
  78. void DirectionalLightMat::setParameters(const LightCore* light)
  79. {
  80. mParams.setParameters(light);
  81. }
  82. PointLightMat::PointLightMat()
  83. {
  84. mMaterial->setParamBlockBuffer("PerLight", mParams.getBuffer());
  85. auto& texParams = mMaterial->getShader()->getTextureParams();
  86. for (auto& entry : texParams)
  87. {
  88. if (entry.second.rendererSemantic == RPS_GBufferA)
  89. mGBufferA = mMaterial->getParamTexture(entry.second.name);
  90. else if (entry.second.rendererSemantic == RPS_GBufferB)
  91. mGBufferB = mMaterial->getParamTexture(entry.second.name);
  92. else if (entry.second.rendererSemantic == RPS_GBufferDepth)
  93. mGBufferDepth = mMaterial->getParamTexture(entry.second.name);
  94. }
  95. }
  96. void PointLightMat::setStaticParameters(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBufferCore>& perCamera)
  97. {
  98. mGBufferA.set(gbuffer->getTextureA());
  99. mGBufferB.set(gbuffer->getTextureB());
  100. mGBufferDepth.set(gbuffer->getTextureDepth());
  101. mMaterial->setParamBlockBuffer("PerCamera", perCamera);
  102. }
  103. void PointLightMat::setParameters(const LightCore* light)
  104. {
  105. mParams.setParameters(light);
  106. }
  107. }