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)
		{
			DeferredDirectionalLightMat* material = DeferredDirectionalLightMat::getVariation(isMSAA, true);
			material->bind(gBufferInput, lightOcclusion, perViewBuffer, mPerLightBuffer);

			gRendererUtility().drawScreenQuad();

			// Draw pixels requiring per-sample evaluation
			if(isMSAA)
			{
				DeferredDirectionalLightMat* msaaMaterial = DeferredDirectionalLightMat::getVariation(true, false);
				msaaMaterial->bind(gBufferInput, lightOcclusion, perViewBuffer, 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().getSphereStencil();
			else // Spot
				stencilMesh = RendererUtility::instance().getSpotLightStencil();

			DeferredPointLightMat* material = DeferredPointLightMat::getVariation(isInside, isMSAA, true);
			material->bind(gBufferInput, lightOcclusion, perViewBuffer, 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)
			{
				DeferredPointLightMat* msaaMaterial = DeferredPointLightMat::getVariation(isInside, true, false);
				msaaMaterial->bind(gBufferInput, lightOcclusion, perViewBuffer, mPerLightBuffer);

				gRendererUtility().draw(stencilMesh);
			}
		}
	}
	void TiledDeferredImageBasedLightingMat::execute(const RendererView& view, const SceneInfo& sceneInfo, 
		const VisibleReflProbeData& probeData, const Inputs& inputs)
	{
		const RendererViewProperties& viewProps = view.getProperties();
		UINT32 width = viewProps.viewRect.width;
		UINT32 height = viewProps.viewRect.height;

		Vector2I framebufferSize;
		framebufferSize[0] = width;
		framebufferSize[1] = height;
		gTiledImageBasedLightingParamDef.gFramebufferSize.set(mParamBuffer, framebufferSize);

		mReflProbeParamBuffer.populate(sceneInfo.skybox, probeData, sceneInfo.reflProbeCubemapsTex, 
			viewProps.renderingReflections);

		mParamBuffer->flushToGPU();
		mReflProbeParamBuffer.buffer->flushToGPU();

		mGBufferA.set(inputs.gbuffer.albedo);
		mGBufferB.set(inputs.gbuffer.normals);
		mGBufferC.set(inputs.gbuffer.roughMetal);
		mGBufferDepth.set(inputs.gbuffer.depth);

		SPtr<Texture> skyFilteredRadiance;
		SPtr<Texture> skyIrradiance;
		if(sceneInfo.skybox)
		{
			skyFilteredRadiance = sceneInfo.skybox->getFilteredRadiance();
			skyIrradiance = sceneInfo.skybox->getIrradiance();
		}

		mImageBasedParams.preintegratedEnvBRDFParam.set(inputs.preIntegratedGF);
		mImageBasedParams.reflectionProbesParam.set(probeData.getProbeBuffer());
		mImageBasedParams.reflectionProbeCubemapsTexParam.set(sceneInfo.reflProbeCubemapsTex);
		mImageBasedParams.skyReflectionsTexParam.set(skyFilteredRadiance);

		mParamsSet->setParamBlockBuffer("PerCamera", view.getPerViewBuffer(), true);

		mInColorTextureParam.set(inputs.lightAccumulation);
		if (mSampleCount > 1)
			mOutputBufferParam.set(inputs.sceneColorBuffer);
		else
			mOutputTextureParam.set(inputs.sceneColorTex);

		UINT32 numTilesX = (UINT32)Math::ceilToInt(width / (float)TILE_SIZE);
		UINT32 numTilesY = (UINT32)Math::ceilToInt(height / (float)TILE_SIZE);

		gRendererUtility().setComputePass(mMaterial, 0);
		gRendererUtility().setPassParams(mParamsSet);

		RenderAPI::instance().dispatchCompute(numTilesX, numTilesY);
	}
	void StandardDeferred::renderReflProbe(const ReflProbeData& probeData, const RendererView& view,
		const GBufferTextures& gBufferInput, const SceneInfo& sceneInfo, const SPtr<GpuParamBlockBuffer>& reflProbeParams)
	{
		const auto& viewProps = view.getProperties();
		bool isMSAA = viewProps.numSamples > 1;

		SPtr<GpuParamBlockBuffer> perViewBuffer = view.getPerViewBuffer();

		// When checking if viewer is inside the volume extend the bounds slighty to cover the case when the viewer is
		// outside, but the near plane is intersecting the bounds. We need to be conservative since the material for
		// rendering outside will not properly render the inside of the volume.
		float radiusBuffer = viewProps.nearPlane * 3.0f;

		SPtr<Mesh> stencilMesh;
		bool isInside;
		if(probeData.type == 0) // Sphere
		{
			// Check if viewer is inside the light volume
			float distSqrd = (probeData.position - viewProps.viewOrigin).squaredLength();
			float boundRadius = probeData.radius + radiusBuffer;
			
			isInside = distSqrd < (boundRadius * boundRadius);
			stencilMesh = RendererUtility::instance().getSphereStencil();
		} 
		else // Box
		{
			Vector3 extents = probeData.boxExtents + radiusBuffer;
			AABox box(probeData.position - extents, probeData.position + extents);

			isInside = box.contains(viewProps.viewOrigin);
			stencilMesh = RendererUtility::instance().getBoxStencil();
		}

		DeferredIBLProbeMat* material = DeferredIBLProbeMat::getVariation(isInside, isMSAA, true);
		material->bind(gBufferInput, perViewBuffer, sceneInfo, probeData, reflProbeParams);

		// 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)
		{
			DeferredIBLProbeMat* msaaMaterial = DeferredIBLProbeMat::getVariation(isInside, true, false);
			msaaMaterial->bind(gBufferInput, perViewBuffer, sceneInfo, probeData, reflProbeParams);

			gRendererUtility().draw(stencilMesh);
		}
	}
Exemple #4
0
	void DebugDrawMat::execute(const SPtr<GpuParamBlockBuffer>& params, const SPtr<Mesh>& mesh, const SubMesh& subMesh)
	{
		BS_RENMAT_PROFILE_BLOCK

		mParams->setParamBlockBuffer("Params", params);

		bind();
		gRendererUtility().draw(mesh, subMesh);
	}
Exemple #5
0
	void SelectionRendererCore::render(const Camera& camera)
	{
		THROW_IF_NOT_CORE_THREAD;

		const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
		Matrix4 viewProjMat = mCamera->getProjectionMatrixRS() * mCamera->getViewMatrix();

		SPtr<Renderer> renderer = gRenderer();

		for (auto& renderable : mObjects)
		{
			SPtr<Mesh> mesh = renderable->getMesh();
			if (mesh == nullptr)
				continue;

			SPtr<GpuBuffer> boneMatrixBuffer = renderable->getBoneMatrixBuffer();
			SPtr<VertexBuffer> morphShapeBuffer = renderable->getMorphShapeBuffer();
			SPtr<VertexDeclaration> morphVertexDeclaration = renderable->getMorphVertexDeclaration();

			Matrix4 worldViewProjMat = viewProjMat * renderable->getTransform();
			UINT32 techniqueIdx = mTechniqueIndices[(int)renderable->getAnimType()];

			mMatWorldViewProj[techniqueIdx].set(worldViewProjMat);
			mColor[techniqueIdx].set(SELECTION_COLOR);
			mBoneMatrices[techniqueIdx].set(boneMatrixBuffer);

			gRendererUtility().setPass(mMaterial, 0, techniqueIdx);
			gRendererUtility().setPassParams(mParams[techniqueIdx], 0);

			UINT32 numSubmeshes = mesh->getProperties().getNumSubMeshes();

			for (UINT32 i = 0; i < numSubmeshes; i++)
			{
				if (morphVertexDeclaration == nullptr)
					gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(i));
				else
					gRendererUtility().drawMorph(mesh, mesh->getProperties().getSubMesh(i), morphShapeBuffer,
						morphVertexDeclaration);
			}
		}
	}
	void LightRenderingParams::setStaticParameters(const SPtr<RenderTargets>& gbuffer, 
		const SPtr<GpuParamBlockBufferCore>& perCamera)
	{
		mGBufferA.set(gbuffer->getTextureA());
		mGBufferB.set(gbuffer->getTextureB());
		mGBufferDepth.set(gbuffer->getTextureDepth());

		mMaterial->setParamBlockBuffer("PerLight", getBuffer());
		mMaterial->setParamBlockBuffer("PerCamera", perCamera);

		gRendererUtility().setPassParams(mMaterial);
	}
	void SelectionRendererCore::render()
	{
		THROW_IF_NOT_CORE_THREAD;

		if (mCamera == nullptr)
			return;

		Matrix4 viewProjMat = mCamera->getProjectionMatrixRS() * mCamera->getViewMatrix();

		for (auto& objData : mObjects)
		{
			Matrix4 worldViewProjMat = viewProjMat * objData.worldTfrm;

			mMatWorldViewProj.set(worldViewProjMat);
			mColor.set(SELECTION_COLOR);

			gRendererUtility().setPass(mMaterial, 0);

			UINT32 numSubmeshes = objData.mesh->getProperties().getNumSubMeshes();

			for (UINT32 i = 0; i < numSubmeshes; i++)
				gRendererUtility().draw(objData.mesh, objData.mesh->getProperties().getSubMesh(i));
		}
	}