698 lines
23 KiB
C++
698 lines
23 KiB
C++
#include "Renderable3DComponent.h"
|
|
#include "wiRenderer.h"
|
|
#include "wiImage.h"
|
|
#include "wiImageEffects.h"
|
|
#include "wiHelper.h"
|
|
#include "wiTextureHelper.h"
|
|
#include "wiLoader.h"
|
|
#include "ResourceMapping.h"
|
|
#include "wiProfiler.h"
|
|
|
|
using namespace wiGraphicsTypes;
|
|
|
|
Renderable3DComponent::Renderable3DComponent() : Renderable2DComponent()
|
|
{
|
|
}
|
|
Renderable3DComponent::~Renderable3DComponent()
|
|
{
|
|
for (auto& wt : workerThreads)
|
|
{
|
|
delete wt;
|
|
}
|
|
}
|
|
|
|
wiRenderTarget
|
|
Renderable3DComponent::rtReflection
|
|
, Renderable3DComponent::rtSSR
|
|
, Renderable3DComponent::rtMotionBlur
|
|
, Renderable3DComponent::rtSceneCopy
|
|
, Renderable3DComponent::rtWaterRipple
|
|
, Renderable3DComponent::rtLinearDepth
|
|
, Renderable3DComponent::rtParticle
|
|
, Renderable3DComponent::rtParticleAdditive
|
|
, Renderable3DComponent::rtFinal[2]
|
|
, Renderable3DComponent::rtDof[3]
|
|
, Renderable3DComponent::rtTemporalAA[2]
|
|
;
|
|
std::vector<wiRenderTarget> Renderable3DComponent::rtSun, Renderable3DComponent::rtBloom, Renderable3DComponent::rtSSAO;
|
|
wiDepthTarget Renderable3DComponent::dtDepthCopy;
|
|
Texture2D* Renderable3DComponent::smallDepth = nullptr;
|
|
void Renderable3DComponent::ResizeBuffers()
|
|
{
|
|
Renderable2DComponent::ResizeBuffers();
|
|
|
|
FORMAT defaultTextureFormat = GraphicsDevice::GetBackBufferFormat();
|
|
|
|
// Protect against multiple buffer resizes when there is no change!
|
|
static UINT lastBufferResWidth = 0, lastBufferResHeight = 0, lastBufferMSAA = 0;
|
|
static FORMAT lastBufferFormat = FORMAT_UNKNOWN;
|
|
if (lastBufferResWidth == wiRenderer::GetInternalResolution().x &&
|
|
lastBufferResHeight == wiRenderer::GetInternalResolution().y &&
|
|
lastBufferMSAA == getMSAASampleCount() &&
|
|
lastBufferFormat == defaultTextureFormat)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
lastBufferResWidth = wiRenderer::GetInternalResolution().x;
|
|
lastBufferResHeight = wiRenderer::GetInternalResolution().y;
|
|
lastBufferMSAA = getMSAASampleCount();
|
|
lastBufferFormat = defaultTextureFormat;
|
|
}
|
|
|
|
rtSSR.Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, FORMAT_R16G16B16A16_FLOAT);
|
|
rtMotionBlur.Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, FORMAT_R16G16B16A16_FLOAT);
|
|
rtLinearDepth.Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, FORMAT_R32_FLOAT);
|
|
rtParticle.Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x*getAlphaParticleDownSample()), (UINT)(wiRenderer::GetInternalResolution().y*getAlphaParticleDownSample())
|
|
, false, FORMAT_R16G16B16A16_FLOAT);
|
|
rtParticleAdditive.Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x*getAdditiveParticleDownSample()), (UINT)(wiRenderer::GetInternalResolution().y*getAdditiveParticleDownSample())
|
|
, false, FORMAT_R16G16B16A16_FLOAT);
|
|
rtWaterRipple.Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, FORMAT_R8G8B8A8_SNORM);
|
|
rtSceneCopy.Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, FORMAT_R16G16B16A16_FLOAT, 8);
|
|
rtReflection.Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x * getReflectionQuality())
|
|
, (UINT)(wiRenderer::GetInternalResolution().y * getReflectionQuality())
|
|
, true, FORMAT_R16G16B16A16_FLOAT);
|
|
rtFinal[0].Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, defaultTextureFormat);
|
|
rtFinal[1].Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, defaultTextureFormat, 1);
|
|
|
|
rtDof[0].Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x*0.5f), (UINT)(wiRenderer::GetInternalResolution().y*0.5f)
|
|
, false, defaultTextureFormat);
|
|
rtDof[1].Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x*0.5f), (UINT)(wiRenderer::GetInternalResolution().y*0.5f)
|
|
, false, defaultTextureFormat);
|
|
rtDof[2].Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, defaultTextureFormat);
|
|
|
|
dtDepthCopy.Initialize(wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y, getMSAASampleCount());
|
|
//dtSmallDepth.Initialize(wiRenderer::GetInternalResolution().x / 4, wiRenderer::GetInternalResolution().y / 4, 1);
|
|
|
|
rtSSAO.resize(3);
|
|
for (unsigned int i = 0; i<rtSSAO.size(); i++)
|
|
rtSSAO[i].Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x*getSSAOQuality()), (UINT)(wiRenderer::GetInternalResolution().y*getSSAOQuality())
|
|
, false, FORMAT_R8_UNORM);
|
|
|
|
|
|
rtSun.resize(2);
|
|
rtSun[0].Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, true, defaultTextureFormat, 1, getMSAASampleCount()
|
|
);
|
|
rtSun[1].Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x*getLightShaftQuality())
|
|
, (UINT)(wiRenderer::GetInternalResolution().y*getLightShaftQuality())
|
|
, false, defaultTextureFormat
|
|
);
|
|
|
|
rtBloom.resize(3);
|
|
rtBloom[0].Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, defaultTextureFormat, 0);
|
|
for (unsigned int i = 1; i<rtBloom.size(); ++i)
|
|
rtBloom[i].Initialize(
|
|
(UINT)(wiRenderer::GetInternalResolution().x / getBloomDownSample())
|
|
, (UINT)(wiRenderer::GetInternalResolution().y / getBloomDownSample())
|
|
, false, defaultTextureFormat);
|
|
|
|
rtTemporalAA[0].Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, FORMAT_R16G16B16A16_FLOAT);
|
|
rtTemporalAA[1].Initialize(
|
|
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
|
, false, FORMAT_R16G16B16A16_FLOAT);
|
|
|
|
|
|
SAFE_DELETE(smallDepth);
|
|
Texture2DDesc desc;
|
|
desc.ArraySize = 1;
|
|
desc.BindFlags = BIND_DEPTH_STENCIL;
|
|
desc.CPUAccessFlags = 0;
|
|
desc.Format = FORMAT_D16_UNORM;
|
|
desc.Width = wiRenderer::GetInternalResolution().x / 4;
|
|
desc.Height = wiRenderer::GetInternalResolution().y / 4;
|
|
desc.MipLevels = 1;
|
|
desc.MiscFlags = 0;
|
|
desc.SampleDesc.Count = 1;
|
|
desc.SampleDesc.Quality = 0;
|
|
desc.Usage = USAGE_DEFAULT;
|
|
wiRenderer::GetDevice()->CreateTexture2D(&desc, nullptr, &smallDepth);
|
|
}
|
|
|
|
void Renderable3DComponent::setProperties()
|
|
{
|
|
setLightShaftQuality(0.4f);
|
|
setBloomDownSample(4.0f);
|
|
setAlphaParticleDownSample(1.0f);
|
|
setAdditiveParticleDownSample(1.0f);
|
|
setReflectionQuality(0.5f);
|
|
setSSAOQuality(0.5f);
|
|
setSSAOBlur(2.3f);
|
|
setBloomStrength(19.3f);
|
|
setBloomThreshold(0.99f);
|
|
setBloomSaturation(-3.86f);
|
|
setDepthOfFieldFocus(10.f);
|
|
setDepthOfFieldStrength(2.2f);
|
|
setSharpenFilterAmount(0.28f);
|
|
|
|
setSSAOEnabled(true);
|
|
setSSREnabled(true);
|
|
setReflectionsEnabled(false);
|
|
setShadowsEnabled(true);
|
|
setFXAAEnabled(true);
|
|
setBloomEnabled(true);
|
|
setColorGradingEnabled(true);
|
|
setEmitterParticlesEnabled(true);
|
|
setHairParticlesEnabled(true);
|
|
setHairParticlesReflectionEnabled(false);
|
|
setVolumeLightsEnabled(true);
|
|
setLightShaftsEnabled(true);
|
|
setLensFlareEnabled(true);
|
|
setMotionBlurEnabled(true);
|
|
setSSSEnabled(true);
|
|
setDepthOfFieldEnabled(false);
|
|
setStereogramEnabled(false);
|
|
setEyeAdaptionEnabled(false);
|
|
setTessellationEnabled(false);
|
|
setSharpenFilterEnabled(false);
|
|
|
|
setMSAASampleCount(1);
|
|
|
|
setPreferredThreadingCount(0);
|
|
}
|
|
|
|
void Renderable3DComponent::Initialize()
|
|
{
|
|
Renderable2DComponent::Initialize();
|
|
}
|
|
|
|
void Renderable3DComponent::Load()
|
|
{
|
|
Renderable2DComponent::Load();
|
|
|
|
wiRenderer::HAIRPARTICLEENABLED = getHairParticlesEnabled();
|
|
wiRenderer::EMITTERSENABLED = getEmittedParticlesEnabled();
|
|
}
|
|
|
|
void Renderable3DComponent::Start()
|
|
{
|
|
Renderable2DComponent::Start();
|
|
}
|
|
|
|
void Renderable3DComponent::FixedUpdate()
|
|
{
|
|
wiRenderer::FixedUpdate();
|
|
wiRenderer::UpdateImages();
|
|
|
|
Renderable2DComponent::FixedUpdate();
|
|
}
|
|
|
|
void Renderable3DComponent::Update(float dt)
|
|
{
|
|
wiRenderer::UpdatePerFrameData(dt);
|
|
|
|
Renderable2DComponent::Update(dt);
|
|
}
|
|
|
|
void Renderable3DComponent::Compose()
|
|
{
|
|
RenderableComponent::Compose();
|
|
|
|
RenderColorGradedComposition();
|
|
|
|
if (wiRenderer::GetDebugLightCulling())
|
|
{
|
|
wiImage::Draw((Texture2D*)wiRenderer::textures[TEXTYPE_2D_DEBUGUAV], wiImageEffects((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight()), GRAPHICSTHREAD_IMMEDIATE);
|
|
}
|
|
|
|
Renderable2DComponent::Compose();
|
|
}
|
|
|
|
void Renderable3DComponent::RenderFrameSetUp(GRAPHICSTHREAD threadID)
|
|
{
|
|
wiRenderer::UpdateRenderData(threadID);
|
|
|
|
ViewPort viewPort;
|
|
viewPort.TopLeftX = 0.0f;
|
|
viewPort.TopLeftY = 0.0f;
|
|
viewPort.Width = (float)smallDepth->GetDesc().Width;
|
|
viewPort.Height = (float)smallDepth->GetDesc().Height;
|
|
viewPort.MinDepth = 0.0f;
|
|
viewPort.MaxDepth = 1.0f;
|
|
wiRenderer::GetDevice()->BindViewports(1, &viewPort, threadID);
|
|
wiRenderer::GetDevice()->BindRenderTargets(0, nullptr, smallDepth, threadID);
|
|
|
|
wiRenderer::OcclusionCulling_Render(threadID);
|
|
}
|
|
void Renderable3DComponent::RenderReflections(GRAPHICSTHREAD threadID)
|
|
{
|
|
if (getStereogramEnabled())
|
|
{
|
|
// We don't need the following for stereograms...
|
|
return;
|
|
}
|
|
|
|
if (!getReflectionsEnabled() || getReflectionQuality() < 0.01f)
|
|
{
|
|
return;
|
|
}
|
|
wiProfiler::GetInstance().BeginRange("Reflection rendering", wiProfiler::DOMAIN_GPU, threadID);
|
|
|
|
if (wiRenderer::IsRequestedReflectionRendering())
|
|
{
|
|
wiRenderer::UpdateCameraCB(wiRenderer::getRefCamera(), threadID);
|
|
|
|
rtReflection.Activate(threadID); {
|
|
// reverse clipping if underwater
|
|
XMFLOAT4 water = wiRenderer::GetWaterPlane().getXMFLOAT4();
|
|
if (XMVectorGetX(XMPlaneDot(XMLoadFloat4(&water), wiRenderer::getCamera()->GetEye())) < 0)
|
|
{
|
|
water.x *= -1;
|
|
water.y *= -1;
|
|
water.z *= -1;
|
|
}
|
|
|
|
wiRenderer::SetClipPlane(water, threadID);
|
|
|
|
wiRenderer::DrawWorld(wiRenderer::getRefCamera(), false, threadID, SHADERTYPE_TEXTURE, nullptr, getHairParticlesReflectionEnabled(), false);
|
|
wiRenderer::DrawSky(threadID);
|
|
|
|
wiRenderer::SetClipPlane(XMFLOAT4(0, 0, 0, 0), threadID);
|
|
}
|
|
}
|
|
|
|
wiProfiler::GetInstance().EndRange(); // Reflection Rendering
|
|
}
|
|
void Renderable3DComponent::RenderShadows(GRAPHICSTHREAD threadID)
|
|
{
|
|
if (getStereogramEnabled())
|
|
{
|
|
// We don't need the following for stereograms...
|
|
return;
|
|
}
|
|
|
|
if (getShadowsEnabled())
|
|
{
|
|
wiRenderer::DrawForShadowMap(threadID);
|
|
}
|
|
|
|
wiRenderer::VoxelRadiance(threadID);
|
|
}
|
|
void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRenderTarget& shadedSceneRT, GRAPHICSTHREAD threadID)
|
|
{
|
|
wiImageEffects fx((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y);
|
|
|
|
wiRenderer::GetDevice()->EventBegin("Downsample Depth Buffer", threadID);
|
|
{
|
|
// Downsample the depth buffer for the occlusion culling phase...
|
|
ViewPort viewPort;
|
|
viewPort.TopLeftX = 0.0f;
|
|
viewPort.TopLeftY = 0.0f;
|
|
viewPort.Width = (float)smallDepth->GetDesc().Width;
|
|
viewPort.Height = (float)smallDepth->GetDesc().Height;
|
|
viewPort.MinDepth = 0.0f;
|
|
viewPort.MaxDepth = 1.0f;
|
|
wiRenderer::GetDevice()->BindViewports(1, &viewPort, threadID);
|
|
wiRenderer::GetDevice()->BindRenderTargets(0, nullptr, smallDepth, threadID);
|
|
// This depth buffer is not cleared because we don't have to (we overwrite it anyway because depthfunc is ALWAYS)
|
|
|
|
fx.process.setDepthBufferDownsampling(true);
|
|
wiImage::Draw(dtDepthCopy.GetTextureResolvedMSAA(threadID), fx, threadID);
|
|
fx.process.clear();
|
|
}
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
|
|
wiRenderer::UpdateCameraCB(wiRenderer::getCamera(), threadID);
|
|
|
|
if (getStereogramEnabled())
|
|
{
|
|
// We don't need the following for stereograms...
|
|
return;
|
|
}
|
|
wiProfiler::GetInstance().BeginRange("Secondary Scene", wiProfiler::DOMAIN_GPU, threadID);
|
|
|
|
if (getLightShaftsEnabled() && XMVectorGetX(XMVector3Dot(wiRenderer::GetSunPosition(), wiRenderer::getCamera()->GetAt())) > 0)
|
|
{
|
|
wiRenderer::GetDevice()->EventBegin("Light Shafts", threadID);
|
|
wiRenderer::GetDevice()->UnBindResources(TEXSLOT_ONDEMAND0, TEXSLOT_ONDEMAND_COUNT, threadID);
|
|
rtSun[0].Activate(threadID, mainRT.depth); {
|
|
wiRenderer::DrawSun(threadID);
|
|
}
|
|
|
|
rtSun[1].Activate(threadID); {
|
|
wiImageEffects fxs = fx;
|
|
fxs.blendFlag = BLENDMODE_ADDITIVE;
|
|
XMVECTOR sunPos = XMVector3Project(wiRenderer::GetSunPosition() * 100000, 0, 0,
|
|
(float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 1.0f,
|
|
wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
|
|
{
|
|
XMStoreFloat2(&fxs.sunPos, sunPos);
|
|
wiImage::Draw(rtSun[0].GetTextureResolvedMSAA(threadID), fxs, threadID);
|
|
}
|
|
}
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
}
|
|
|
|
if (getEmittedParticlesEnabled())
|
|
{
|
|
rtParticle.Activate(threadID, 0, 0, 0, 0); //OFFSCREEN RENDER ALPHAPARTICLES
|
|
wiRenderer::DrawSoftParticles(wiRenderer::getCamera(), threadID);
|
|
|
|
rtParticleAdditive.Activate(threadID, 0, 0, 0, 1); //OFFSCREEN RENDER ADDITIVEPARTICLES
|
|
wiRenderer::DrawSoftPremulParticles(wiRenderer::getCamera(), threadID);
|
|
}
|
|
|
|
rtWaterRipple.Activate(threadID, 0, 0, 0, 0); {
|
|
wiRenderer::DrawWaterRipples(threadID);
|
|
}
|
|
|
|
rtSceneCopy.Activate(threadID, 0, 0, 0, 0); {
|
|
wiRenderer::GetDevice()->EventBegin("Refraction Target", threadID);
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
fx.quality = QUALITY_NEAREST;
|
|
fx.presentFullScreen = true;
|
|
wiImage::Draw(shadedSceneRT.GetTextureResolvedMSAA(threadID), fx, threadID);
|
|
if (getVolumeLightsEnabled())
|
|
{
|
|
// first draw light volumes to refraction target
|
|
wiRenderer::DrawVolumeLights(wiRenderer::getCamera(), threadID);
|
|
}
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
}
|
|
|
|
wiRenderer::GetDevice()->UnBindResources(TEXSLOT_GBUFFER0, 1, threadID);
|
|
wiRenderer::GetDevice()->UnBindResources(TEXSLOT_ONDEMAND0, TEXSLOT_ONDEMAND_COUNT, threadID);
|
|
wiRenderer::GenerateMipChain(rtSceneCopy.GetTexture(), wiRenderer::MIPGENFILTER_GAUSSIAN, threadID);
|
|
shadedSceneRT.Set(threadID, mainRT.depth, false, 0);{
|
|
RenderTransparentScene(rtSceneCopy, threadID);
|
|
|
|
wiRenderer::DrawTrails(threadID, rtSceneCopy.GetTexture());
|
|
if (getVolumeLightsEnabled())
|
|
{
|
|
// second draw volume lights on top of transparent scene
|
|
wiRenderer::DrawVolumeLights(wiRenderer::getCamera(), threadID);
|
|
}
|
|
|
|
wiRenderer::GetDevice()->EventBegin("Contribute Emitters", threadID);
|
|
fx.presentFullScreen = true;
|
|
fx.blendFlag = BLENDMODE_ALPHA;
|
|
if (getEmittedParticlesEnabled()) {
|
|
wiImage::Draw(rtParticle.GetTexture(), fx, threadID);
|
|
}
|
|
|
|
fx.blendFlag = BLENDMODE_ADDITIVE;
|
|
if (getEmittedParticlesEnabled()) {
|
|
wiImage::Draw(rtParticleAdditive.GetTexture(), fx, threadID);
|
|
}
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
|
|
wiRenderer::GetDevice()->EventBegin("Contribute LightShafts", threadID);
|
|
if (getLightShaftsEnabled()) {
|
|
wiImage::Draw(rtSun.back().GetTexture(), fx, threadID);
|
|
}
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
|
|
if (getLensFlareEnabled())
|
|
{
|
|
if (!wiRenderer::IsWireRender())
|
|
wiRenderer::DrawLensFlares(threadID);
|
|
}
|
|
|
|
wiRenderer::GetDevice()->EventBegin("Debug Geometry", threadID);
|
|
wiRenderer::DrawDebugGridHelper(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::DrawDebugVoxels(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::DrawDebugEnvProbes(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::DrawDebugBoneLines(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::DrawDebugLines(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::DrawDebugBoxes(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::DrawDebugEmitters(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::DrawTranslators(wiRenderer::getCamera(), threadID);
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
}
|
|
|
|
if (wiRenderer::GetTemporalAAEnabled() && !wiRenderer::GetTemporalAADebugEnabled())
|
|
{
|
|
wiRenderer::GetDevice()->EventBegin("Temporal AA Resolve", threadID);
|
|
wiProfiler::GetInstance().BeginRange("Temporal AA Resolve", wiProfiler::DOMAIN_GPU, threadID);
|
|
int current = wiRenderer::GetDevice()->GetFrameCount() % 2 == 0 ? 0 : 1;
|
|
int history = 1 - current;
|
|
rtTemporalAA[current].Activate(threadID); {
|
|
wiRenderer::UpdateGBuffer(mainRT.GetTextureResolvedMSAA(threadID, 0), mainRT.GetTextureResolvedMSAA(threadID, 1), nullptr, nullptr, nullptr, threadID);
|
|
fx.presentFullScreen = false;
|
|
fx.process.setTemporalAAResolve(true);
|
|
fx.setMaskMap(rtTemporalAA[history].GetTexture());
|
|
wiImage::Draw(shadedSceneRT.GetTextureResolvedMSAA(threadID), fx, threadID);
|
|
fx.process.clear();
|
|
}
|
|
wiRenderer::GetDevice()->UnBindResources(TEXSLOT_GBUFFER0, 1, threadID);
|
|
wiRenderer::GetDevice()->UnBindResources(TEXSLOT_ONDEMAND0, 1, threadID);
|
|
shadedSceneRT.Set(threadID, nullptr, false, 0); {
|
|
fx.presentFullScreen = true;
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
fx.quality = QUALITY_NEAREST;
|
|
wiImage::Draw(rtTemporalAA[current].GetTexture(), fx, threadID);
|
|
fx.presentFullScreen = false;
|
|
}
|
|
wiProfiler::GetInstance().EndRange(threadID);
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
}
|
|
|
|
wiProfiler::GetInstance().EndRange(); // Secondary Scene
|
|
}
|
|
void Renderable3DComponent::RenderTransparentScene(wiRenderTarget& refractionRT, GRAPHICSTHREAD threadID)
|
|
{
|
|
wiProfiler::GetInstance().BeginRange("Transparent Scene", wiProfiler::DOMAIN_GPU, threadID);
|
|
|
|
wiRenderer::DrawWorldTransparent(wiRenderer::getCamera(), SHADERTYPE_FORWARD, refractionRT.GetTexture(), rtReflection.GetTexture()
|
|
, rtWaterRipple.GetTexture(), threadID, false, true);
|
|
|
|
wiProfiler::GetInstance().EndRange(); // Transparent Scene
|
|
}
|
|
void Renderable3DComponent::RenderComposition(wiRenderTarget& shadedSceneRT, wiRenderTarget& mainRT, GRAPHICSTHREAD threadID)
|
|
{
|
|
if (getStereogramEnabled())
|
|
{
|
|
// We don't need the following for stereograms...
|
|
return;
|
|
}
|
|
wiProfiler::GetInstance().BeginRange("Post Processing", wiProfiler::DOMAIN_GPU, threadID);
|
|
|
|
wiImageEffects fx((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y);
|
|
|
|
if (getBloomEnabled())
|
|
{
|
|
wiRenderer::GetDevice()->EventBegin("Bloom", threadID);
|
|
fx.process.clear();
|
|
fx.presentFullScreen = false;
|
|
rtBloom[0].Activate(threadID); // separate bright parts
|
|
{
|
|
fx.bloom.separate = true;
|
|
fx.bloom.saturation = getBloomSaturation();
|
|
fx.bloom.threshold = getBloomThreshold();
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
fx.sampleFlag = SAMPLEMODE_CLAMP;
|
|
wiImage::Draw(shadedSceneRT.GetTextureResolvedMSAA(threadID), fx, threadID);
|
|
}
|
|
|
|
rtBloom[1].Activate(threadID); //horizontal
|
|
{
|
|
wiRenderer::GetDevice()->GenerateMips(rtBloom[0].GetTexture(), threadID);
|
|
fx.mipLevel = 5.32f;
|
|
fx.blur = getBloomStrength();
|
|
fx.blurDir = 0;
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
wiImage::Draw(rtBloom[0].GetTexture(), fx, threadID);
|
|
}
|
|
rtBloom[2].Activate(threadID); //vertical
|
|
{
|
|
fx.blur = getBloomStrength();
|
|
fx.blurDir = 1;
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
wiImage::Draw(rtBloom[1].GetTexture(), fx, threadID);
|
|
}
|
|
fx.bloom.clear();
|
|
fx.blur = 0;
|
|
fx.blurDir = 0;
|
|
|
|
shadedSceneRT.Set(threadID, false, 0); { // add to the scene
|
|
fx.blendFlag = BLENDMODE_ADDITIVE;
|
|
fx.presentFullScreen = true;
|
|
fx.process.clear();
|
|
wiImage::Draw(rtBloom.back().GetTexture(), fx, threadID);
|
|
fx.presentFullScreen = false;
|
|
}
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
}
|
|
|
|
if (getMotionBlurEnabled()) {
|
|
wiRenderer::GetDevice()->EventBegin("Motion Blur", threadID);
|
|
rtMotionBlur.Activate(threadID);
|
|
fx.process.setMotionBlur(true);
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
fx.presentFullScreen = false;
|
|
wiImage::Draw(shadedSceneRT.GetTextureResolvedMSAA(threadID), fx, threadID);
|
|
fx.process.clear();
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
}
|
|
|
|
|
|
wiRenderer::GetDevice()->EventBegin("Tone Mapping", threadID);
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
rtFinal[0].Activate(threadID);
|
|
fx.process.setToneMap(true);
|
|
if (getEyeAdaptionEnabled())
|
|
{
|
|
fx.setMaskMap(wiRenderer::GetLuminance(shadedSceneRT.GetTextureResolvedMSAA(threadID), threadID));
|
|
}
|
|
else
|
|
{
|
|
fx.setMaskMap(wiTextureHelper::getInstance()->getColor(wiColor::Gray));
|
|
}
|
|
if (getMotionBlurEnabled())
|
|
{
|
|
wiImage::Draw(rtMotionBlur.GetTexture(), fx, threadID);
|
|
}
|
|
else
|
|
{
|
|
wiImage::Draw(shadedSceneRT.GetTextureResolvedMSAA(threadID), fx, threadID);
|
|
}
|
|
fx.process.clear();
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
|
|
wiRenderTarget* rt0 = &rtFinal[0];
|
|
wiRenderTarget* rt1 = &rtFinal[1];
|
|
if (getSharpenFilterEnabled())
|
|
{
|
|
rt1->Activate(threadID);
|
|
fx.process.setSharpen(getSharpenFilterAmount());
|
|
wiImage::Draw(rt0->GetTexture(), fx, threadID);
|
|
fx.process.clear();
|
|
wiRenderer::GetDevice()->UnBindResources(TEXSLOT_ONDEMAND0, 1, threadID);
|
|
|
|
SwapPtr(rt0, rt1);
|
|
}
|
|
|
|
if (getDepthOfFieldEnabled())
|
|
{
|
|
wiRenderer::GetDevice()->EventBegin("Depth Of Field", threadID);
|
|
// downsample + blur
|
|
rtDof[0].Activate(threadID);
|
|
fx.blur = getDepthOfFieldStrength();
|
|
fx.blurDir = 0;
|
|
wiImage::Draw(rt0->GetTexture(), fx, threadID);
|
|
|
|
rtDof[1].Activate(threadID);
|
|
fx.blurDir = 1;
|
|
wiImage::Draw(rtDof[0].GetTexture(), fx, threadID);
|
|
fx.blur = 0;
|
|
fx.process.clear();
|
|
|
|
// depth of field compose pass
|
|
rtDof[2].Activate(threadID);
|
|
fx.process.setDOF(getDepthOfFieldFocus());
|
|
fx.setMaskMap(rtDof[1].GetTexture());
|
|
//fx.setDepthMap(rtLinearDepth.shaderResource.back());
|
|
wiImage::Draw(rt0->GetTexture(), fx, threadID);
|
|
fx.setMaskMap(nullptr);
|
|
//fx.setDepthMap(nullptr);
|
|
fx.process.clear();
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
}
|
|
|
|
|
|
rt1->Activate(threadID);
|
|
wiRenderer::GetDevice()->EventBegin("FXAA", threadID);
|
|
if (getFXAAEnabled())
|
|
{
|
|
fx.process.setFXAA(true);
|
|
}
|
|
else
|
|
{
|
|
fx.presentFullScreen = true;
|
|
}
|
|
if (getDepthOfFieldEnabled())
|
|
wiImage::Draw(rtDof[2].GetTexture(), fx, threadID);
|
|
else
|
|
wiImage::Draw(rt0->GetTexture(), fx, threadID);
|
|
fx.process.clear();
|
|
wiRenderer::GetDevice()->EventEnd(threadID);
|
|
|
|
|
|
wiProfiler::GetInstance().EndRange(); // Post Processing 1
|
|
}
|
|
void Renderable3DComponent::RenderColorGradedComposition()
|
|
{
|
|
wiImageEffects fx((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight());
|
|
fx.blendFlag = BLENDMODE_OPAQUE;
|
|
fx.quality = QUALITY_BILINEAR;
|
|
|
|
if (getStereogramEnabled())
|
|
{
|
|
wiRenderer::GetDevice()->EventBegin("Stereogram", GRAPHICSTHREAD_IMMEDIATE);
|
|
fx.presentFullScreen = false;
|
|
fx.process.clear();
|
|
fx.process.setStereogram(true);
|
|
wiImage::Draw(wiTextureHelper::getInstance()->getRandom64x64(), fx, GRAPHICSTHREAD_IMMEDIATE);
|
|
wiRenderer::GetDevice()->EventEnd(GRAPHICSTHREAD_IMMEDIATE);
|
|
return;
|
|
}
|
|
|
|
if (getColorGradingEnabled())
|
|
{
|
|
wiRenderer::GetDevice()->EventBegin("Color Graded Composition", GRAPHICSTHREAD_IMMEDIATE);
|
|
if (wiRenderer::GetColorGrading() != nullptr){
|
|
fx.process.setColorGrade(true);
|
|
fx.setMaskMap(wiRenderer::GetColorGrading());
|
|
}
|
|
else
|
|
{
|
|
fx.process.setColorGrade(true);
|
|
fx.setMaskMap(wiTextureHelper::getInstance()->getColorGradeDefault());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wiRenderer::GetDevice()->EventBegin("Composition", GRAPHICSTHREAD_IMMEDIATE);
|
|
fx.presentFullScreen = true;
|
|
}
|
|
|
|
if (getSharpenFilterEnabled())
|
|
{
|
|
wiImage::Draw(rtFinal[0].GetTexture(), fx, GRAPHICSTHREAD_IMMEDIATE);
|
|
}
|
|
else
|
|
{
|
|
wiImage::Draw(rtFinal[1].GetTexture(), fx, GRAPHICSTHREAD_IMMEDIATE);
|
|
}
|
|
wiRenderer::GetDevice()->EventEnd(GRAPHICSTHREAD_IMMEDIATE);
|
|
}
|
|
|
|
|
|
void Renderable3DComponent::setPreferredThreadingCount(unsigned short value)
|
|
{
|
|
for (auto& wt : workerThreads)
|
|
{
|
|
delete wt;
|
|
}
|
|
|
|
workerThreads.clear();
|
|
} |