BsLightRendering.cpp 5.6 KB

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