2
0

BsLightRendering.cpp 5.4 KB

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