| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsStandardDeferredLighting.h"
- #include "Renderer/BsRendererUtility.h"
- #include "BsRendererView.h"
- #include "Material/BsGpuParamsSet.h"
- #include "Mesh/BsMesh.h"
- namespace bs { namespace ct {
- PerLightParamDef gPerLightParamDef;
- ShaderVariation DirectionalLightMat::VAR_FullMSAA = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 2),
- ShaderVariation::Param("MSAA", true)
- });
- ShaderVariation DirectionalLightMat::VAR_SingleMSAA = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 2),
- ShaderVariation::Param("MSAA", true),
- ShaderVariation::Param("MSAA_RESOLVE_0TH", true)
- });
- ShaderVariation DirectionalLightMat::VAR_NoMSAA = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 1)
- });
- DirectionalLightMat::DirectionalLightMat()
- :mGBufferParams(mMaterial, mParamsSet)
- {
- const GpuParams& gpuParams = *mParamsSet->getGpuParams();
- gpuParams.getTextureParam(GPT_FRAGMENT_PROGRAM, "gLightOcclusionTex", mLightOcclusionTexParam);
- }
- void DirectionalLightMat::_initVariations(ShaderVariations& variations)
- {
- variations.add(VAR_FullMSAA);
- variations.add(VAR_SingleMSAA);
- variations.add(VAR_NoMSAA);
- }
- void DirectionalLightMat::bind(const GBufferTextures& gBufferInput, const SPtr<Texture>& lightOcclusion,
- const SPtr<GpuParamBlockBuffer>& perCamera)
- {
- RendererUtility::instance().setPass(mMaterial, 0);
- mGBufferParams.bind(gBufferInput);
- mLightOcclusionTexParam.set(lightOcclusion);
- mParamsSet->getGpuParams()->setParamBlockBuffer("PerCamera", perCamera);
- }
- void DirectionalLightMat::setPerLightParams(const SPtr<GpuParamBlockBuffer>& perLight)
- {
- mParamsSet->getGpuParams()->setParamBlockBuffer("PerLight", perLight);
-
- gRendererUtility().setPassParams(mParamsSet);
- }
- DirectionalLightMat* DirectionalLightMat::getVariation(bool msaa, bool singleSampleMSAA)
- {
- if (msaa)
- {
- if (singleSampleMSAA)
- return get(VAR_SingleMSAA);
- else
- return get(VAR_FullMSAA);
- }
- return get(VAR_NoMSAA);
- }
- ShaderVariation PointLightMat::VAR_FullMSAA_Inside = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 2),
- ShaderVariation::Param("MSAA", true),
- ShaderVariation::Param("INSIDE_GEOMETRY", true)
- });
- ShaderVariation PointLightMat::VAR_SingleMSAA_Inside = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 2),
- ShaderVariation::Param("MSAA", true),
- ShaderVariation::Param("INSIDE_GEOMETRY", true),
- ShaderVariation::Param("MSAA_RESOLVE_0TH", true)
- });
- ShaderVariation PointLightMat::VAR_FullMSAA_Outside = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 2),
- ShaderVariation::Param("MSAA", true)
- });
- ShaderVariation PointLightMat::VAR_SingleMSAA_Outside = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 2),
- ShaderVariation::Param("MSAA", true),
- ShaderVariation::Param("MSAA_RESOLVE_0TH", true)
- });
- ShaderVariation PointLightMat::VAR_NoMSAA_Inside = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 1),
- ShaderVariation::Param("INSIDE_GEOMETRY", true)
- });
- ShaderVariation PointLightMat::VAR_NoMSAA_Outside = ShaderVariation({
- ShaderVariation::Param("MSAA_COUNT", 1)
- });
- PointLightMat::PointLightMat()
- :mGBufferParams(mMaterial, mParamsSet)
- {
- const GpuParams& gpuParams = *mParamsSet->getGpuParams();
- gpuParams.getTextureParam(GPT_FRAGMENT_PROGRAM, "gLightOcclusionTex", mLightOcclusionTexParam);
- }
- void PointLightMat::_initVariations(ShaderVariations& variations)
- {
- variations.add(VAR_FullMSAA_Inside);
- variations.add(VAR_SingleMSAA_Inside);
- variations.add(VAR_FullMSAA_Outside);
- variations.add(VAR_SingleMSAA_Outside);
- variations.add(VAR_NoMSAA_Inside);
- variations.add(VAR_NoMSAA_Outside);
- }
- void PointLightMat::bind(const GBufferTextures& gBufferInput, const SPtr<Texture>& lightOcclusion,
- const SPtr<GpuParamBlockBuffer>& perCamera)
- {
- RendererUtility::instance().setPass(mMaterial, 0);
- mGBufferParams.bind(gBufferInput);
- mLightOcclusionTexParam.set(lightOcclusion);
- mParamsSet->getGpuParams()->setParamBlockBuffer("PerCamera", perCamera);
- }
- void PointLightMat::setPerLightParams(const SPtr<GpuParamBlockBuffer>& perLight)
- {
- mParamsSet->getGpuParams()->setParamBlockBuffer("PerLight", perLight);
-
- gRendererUtility().setPassParams(mParamsSet);
- }
- PointLightMat* PointLightMat::getVariation(bool inside, bool msaa, bool singleSampleMSAA)
- {
- if(msaa)
- {
- if (inside)
- {
- if (singleSampleMSAA)
- return get(VAR_SingleMSAA_Inside);
- return get(VAR_FullMSAA_Inside);
- }
- else
- {
- if (singleSampleMSAA)
- return get(VAR_SingleMSAA_Outside);
- return get(VAR_FullMSAA_Outside);
- }
- }
- else
- {
- if (inside)
- return get(VAR_NoMSAA_Inside);
- else
- return get(VAR_NoMSAA_Outside);
- }
- }
- StandardDeferred::StandardDeferred()
- {
- mPerLightBuffer = gPerLightParamDef.createBuffer();
- }
- void StandardDeferred::renderLight(LightType lightType, const RendererLight& light, const RendererView& view,
- const GBufferTextures& gBufferInput, const SPtr<Texture>& lightOcclusion)
- {
- const auto& viewProps = view.getProperties();
- bool isMSAA = view.getProperties().numSamples > 1;
- SPtr<GpuParamBlockBuffer> perViewBuffer = view.getPerViewBuffer();
- light.getParameters(mPerLightBuffer);
- if (lightType == LightType::Directional)
- {
- DirectionalLightMat* material = DirectionalLightMat::getVariation(isMSAA, true);
- material->bind(gBufferInput, lightOcclusion, perViewBuffer);
- material->setPerLightParams(mPerLightBuffer);
- gRendererUtility().drawScreenQuad();
- // Draw pixels requiring per-sample evaluation
- if(isMSAA)
- {
- DirectionalLightMat* msaaMaterial = DirectionalLightMat::getVariation(true, false);
- msaaMaterial->bind(gBufferInput, lightOcclusion, perViewBuffer);
- msaaMaterial->setPerLightParams(mPerLightBuffer);
- gRendererUtility().drawScreenQuad();
- }
- }
- else // Radial or spot
- {
- // Check if viewer is inside the light volume
- float distSqrd = (light.internal->getBounds().getCenter() - viewProps.viewOrigin).squaredLength();
- // Extend the bounds slighty to cover the case when the viewer is outside, but the near plane is intersecting
- // the light bounds. We need to be conservative since the material for rendering outside will not properly
- // render the inside of the light volume.
- float boundRadius = light.internal->getBounds().getRadius() + viewProps.nearPlane * 3.0f;
- bool isInside = distSqrd < (boundRadius * boundRadius);
- SPtr<Mesh> stencilMesh;
- if(lightType == LightType::Radial)
- stencilMesh = RendererUtility::instance().getRadialLightStencil();
- else // Spot
- stencilMesh = RendererUtility::instance().getSpotLightStencil();
- PointLightMat* material = PointLightMat::getVariation(isInside, isMSAA, true);
- material->bind(gBufferInput, lightOcclusion, perViewBuffer);
- material->setPerLightParams(mPerLightBuffer);
- // Note: If MSAA is enabled this will be rendered multisampled (on polygon edges), see if this can be avoided
- gRendererUtility().draw(stencilMesh);
- // Draw pixels requiring per-sample evaluation
- if(isMSAA)
- {
- PointLightMat* msaaMaterial = PointLightMat::getVariation(isInside, true, false);
- msaaMaterial->bind(gBufferInput, lightOcclusion, perViewBuffer);
- msaaMaterial->setPerLightParams(mPerLightBuffer);
- gRendererUtility().draw(stencilMesh);
- }
- }
- }
- }}
|