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); } }
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); }
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)); } }