!R (Renderer) Minor cleanup on PostEffects
[CRYENGINE.git] / Code / CryEngine / RenderDll / Common / RendElements / RootOpticsElement.cpp
blob298a6645fe35530eaf621326ecf60e7ee2a97165
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
5 #include "RootOpticsElement.h"
6 #include "FlareSoftOcclusionQuery.h"
7 #include "../Textures/Texture.h"
8 #include "D3DPostProcess.h"
9 #include "stdarg.h"
11 #include <Common/RenderDisplayContext.h>
13 enum EVisFader
15 VISFADER_FLARE = 0,
16 VISFADER_SHAFT,
17 VISFADER_NUM
20 const float RootOpticsElement::kExtendedFlareRadiusRatio = 1.3f;
22 #if defined(FLARES_SUPPORT_EDITING)
23 #define MFPtr(FUNC_NAME) (Optics_MFPtr)(&RootOpticsElement::FUNC_NAME)
24 void RootOpticsElement::InitEditorParamGroups(DynArray<FuncVariableGroup>& groups)
26 COpticsGroup::InitEditorParamGroups(groups);
28 FuncVariableGroup rootGroup;
29 rootGroup.SetName("GlobalSettings", "Global Settings");
30 rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable Occlusion", "Enable Occlusion", this, MFPtr(SetOcclusionEnabled), MFPtr(IsOcclusionEnabled)));
31 rootGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Occlusion Size", "The size for occlusion plane", this, MFPtr(SetOccSize), MFPtr(GetOccSize)));
32 rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable Invert Fade", "Enable Invert Fade", this, MFPtr(SetInvertFade), MFPtr(IsInvertFade)));
33 rootGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Flare fade time", "The duration of flare afterimage fading in seconds", this, MFPtr(SetFlareFadingDuration), MFPtr(GetFlareFadingDuration)));
34 rootGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Shaft fade time", "The duration of shaft afterimage fading in seconds", this, MFPtr(SetShaftFadingDuration), MFPtr(GetShaftFadingDuration)));
35 rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Affected by light color", "light color can affect flare color", this, MFPtr(SetAffectedByLightColor), MFPtr(IsAffectedByLightColor)));
36 rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Affected by light radius", "light radius can affect flare fading", this, MFPtr(SetAffectedByLightRadius), MFPtr(IsAffectedByLightRadius)));
37 rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Affected by light FOV", "light projection FOV can affect flare fading", this, MFPtr(SetAffectedByLightFOV), MFPtr(IsAffectedByLightFOV)));
38 rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Multiply Color", "Select one of between Multiply and Addition about color calculation. If true, Multiply will be chosen.", this, MFPtr(SetMultiplyColor), MFPtr(IsMultiplyColor)));
39 groups.push_back(rootGroup);
41 FuncVariableGroup sensorGroup;
42 sensorGroup.SetName("Sensor");
43 sensorGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Custom Sensor Variation Map", "Enable Custom Sensor Variation Map", this, MFPtr(SetCustomSensorVariationMapEnabled), MFPtr(IsCustomSensorVariationMapEnabled)));
44 sensorGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Effective Sensor Size", "The size of image-able part of the sensor", this, MFPtr(SetEffectiveSensorSize), MFPtr(GetEffectiveSensorSize)));
45 groups.push_back(sensorGroup);
47 #undef MFPtr
48 #endif
50 void RootOpticsElement::Load(IXmlNode* pNode)
52 COpticsElement::Load(pNode);
54 XmlNodeRef pGloabalSettingsNode = pNode->findChild("GlobalSettings");
55 if (pGloabalSettingsNode)
57 bool bOcclusionEnabled(m_bOcclusionEnabled);
58 if (pGloabalSettingsNode->getAttr("EnableOcclusion", bOcclusionEnabled))
59 SetOcclusionEnabled(bOcclusionEnabled);
61 Vec2 occlusionSize(m_OcclusionSize);
62 if (pGloabalSettingsNode->getAttr("OcclusionSize", occlusionSize))
63 SetOccSize(occlusionSize);
65 bool bInvertFade(m_bEnableInvertFade);
66 if (pGloabalSettingsNode->getAttr("EnableInvertFade", bInvertFade))
67 SetInvertFade(bInvertFade);
69 float fFlareTimelineDuration(m_fFlareTimelineDuration);
70 if (pGloabalSettingsNode->getAttr("Flarefadetime", fFlareTimelineDuration))
71 SetFlareFadingDuration(fFlareTimelineDuration);
73 float fShaftTimelineDuration(m_fShaftTimelineDuration);
74 if (pGloabalSettingsNode->getAttr("Flarefadetime", fShaftTimelineDuration))
75 SetShaftFadingDuration(fShaftTimelineDuration);
77 bool bAffectedByLightColor(m_bAffectedByLightColor);
78 if (pGloabalSettingsNode->getAttr("Affectedbylightcolor", bAffectedByLightColor))
79 SetAffectedByLightColor(bAffectedByLightColor);
81 bool bAffectedByLightRadius(m_bAffectedByLightRadius);
82 if (pGloabalSettingsNode->getAttr("Affectedbylightradius", bAffectedByLightRadius))
83 SetAffectedByLightRadius(bAffectedByLightRadius);
85 bool bAffectedByLightFOV(m_bAffectedByLightFOV);
86 if (pGloabalSettingsNode->getAttr("AffectedbylightFOV", bAffectedByLightFOV))
87 SetAffectedByLightFOV(bAffectedByLightFOV);
89 bool bMultiplyColor(m_bMultiplyColor);
90 if (pGloabalSettingsNode->getAttr("MultiplyColor", bMultiplyColor))
91 SetMultiplyColor(bMultiplyColor);
94 XmlNodeRef pSensorNode = pNode->findChild("Sensor");
95 if (pSensorNode)
97 bool bCustomSensorVariationMap(m_bCustomSensorVariationMap);
98 if (pSensorNode->getAttr("CustomSensorVariationMap", bCustomSensorVariationMap))
99 SetCustomSensorVariationMapEnabled(bCustomSensorVariationMap);
101 float fEffectiveSensorSize(m_fEffectiveSensorSize);
102 if (pSensorNode->getAttr("EffectiveSensorSize", fEffectiveSensorSize))
103 SetEffectiveSensorSize(fEffectiveSensorSize);
107 void RootOpticsElement::SetOcclusionQuery(CFlareSoftOcclusionQuery* query)
109 m_pOccQuery = query;
112 float RootOpticsElement::GetFlareVisibilityFactor() const
114 CSoftOcclusionVisiblityFader* pFader = m_pOccQuery ? m_pOccQuery->GetVisibilityFader(VISFADER_FLARE) : NULL;
115 return pFader ? pFader->m_fVisibilityFactor : 0.0f;
118 float RootOpticsElement::GetShaftVisibilityFactor() const
120 CSoftOcclusionVisiblityFader* pFader = m_pOccQuery ? m_pOccQuery->GetVisibilityFader(VISFADER_SHAFT) : NULL;
121 return pFader ? pFader->m_fVisibilityFactor : 0.0f;
124 void RootOpticsElement::SetVisibilityFactor(float f)
126 f = clamp_tpl(f, 0.f, 1.f);
128 if (m_pOccQuery)
130 for (uint i = 0; i < VISFADER_NUM; ++i)
132 if (CSoftOcclusionVisiblityFader* pFader = m_pOccQuery->GetVisibilityFader(i))
134 pFader->m_fVisibilityFactor = f;
140 CTexture* RootOpticsElement::GetOcclusionPattern()
142 return m_pOccQuery->GetGatherTexture();
145 void RootOpticsElement::validateGlobalVars(const SAuxParams& aux)
147 m_globalPerspectiveFactor = m_fPerspectiveFactor;
148 m_globalDistanceFadingFactor = m_flareLight.m_bAttachToSun ? 0.0f : m_fDistanceFadingFactor;
149 m_globalSensorBrightnessFactor = m_fSensorBrightnessFactor;
150 m_globalSensorSizeFactor = m_fSensorSizeFactor;
151 m_globalSize = m_fSize;
152 m_globalFlareBrightness = GetBrightness();
153 m_globalMovement = m_vMovement;
155 if (m_bAffectedByLightColor)
157 if (aux.bMultiplyColor)
158 m_globalColor = ColorF(m_Color.r * m_flareLight.m_cLdrClr.r, m_Color.g * m_flareLight.m_cLdrClr.g, m_Color.b * m_flareLight.m_cLdrClr.b, m_Color.a);
159 else
160 m_globalColor = ColorF(m_Color.r + m_flareLight.m_cLdrClr.r, m_Color.g + m_flareLight.m_cLdrClr.g, m_Color.b + m_flareLight.m_cLdrClr.b, m_Color.a);
162 m_globalFlareBrightness *= m_flareLight.m_fClrMultiplier;
164 else
166 m_globalColor = m_Color;
169 if (m_bAffectedByLightRadius)
171 if (m_bEnableInvertFade)
173 const float kRedundantRadiusRatio = kExtendedFlareRadiusRatio; //1.0f;
174 const float fExtendedRadius = m_flareLight.m_fRadius * kRedundantRadiusRatio;
176 if (aux.distance > m_flareLight.m_fRadius && aux.distance < fExtendedRadius)
178 const float fDistFromRadius = aux.distance - m_flareLight.m_fRadius;
179 const float fRedundantLength = fExtendedRadius - m_flareLight.m_fRadius;
180 m_globalFlareBrightness *= clamp_tpl(1.0f - fDistFromRadius / fRedundantLength, 0.0f, 1.0f);
182 else
184 m_globalFlareBrightness *= clamp_tpl(aux.distance / m_flareLight.m_fRadius, 0.0f, 1.0f);
187 else
189 m_globalFlareBrightness *= clamp_tpl(1.0f - aux.distance / m_flareLight.m_fRadius, 0.0f, 1.0f);
193 if (m_bAffectedByLightFOV)
195 m_globalFlareBrightness *= aux.viewAngleFalloff;
198 float fShaftVisibilityFactor = aux.bForceRender ? 1.0f : GetShaftVisibilityFactor();
199 float fFlareVisibilityFactor = aux.bForceRender ? 1.0f : GetFlareVisibilityFactor();
201 m_globalShaftBrightness = m_globalFlareBrightness * fShaftVisibilityFactor;
202 m_globalFlareBrightness *= fFlareVisibilityFactor;
204 m_globalOcclusionBokeh = m_bOcclusionBokeh & IsOcclusionEnabled();
205 m_globalOrbitAngle = m_fOrbitAngle;
206 m_globalTransform = m_mxTransform;
208 COpticsGroup::validateChildrenGlobalVars(aux);
211 void RootOpticsElement::RenderPreview(const SLensFlareRenderParam* pParam, const Vec3& vPos)
213 if (pParam == NULL)
214 return;
215 if (!pParam->IsValid())
216 return;
218 _smart_ptr<CRenderView> pRenderView = pParam->passInfo.GetRenderView();
220 if (gcpRendD3D->m_pRT->IsRenderThread())
222 return RT_RenderPreview(vPos, pParam);
225 gcpRendD3D->m_pRT->ExecuteRenderThreadCommand([=]
227 std::shared_ptr<CGraphicsPipeline> pGraphicsPipeline = pRenderView->GetGraphicsPipeline();
228 pGraphicsPipeline->SetCurrentRenderView(pRenderView.get());
229 RT_RenderPreview(vPos, pParam);
230 }, ERenderCommandFlags::None);
233 void RootOpticsElement::RT_RenderPreview(const Vec3& vPos, const SLensFlareRenderParam* pParam)
235 CRY_PROFILE_REGION(PROFILE_RENDERER, "RootOpticsElement::RT_RenderPreview")
237 SFlareLight light;
238 light.m_vPos = vPos;
239 light.m_fRadius = 10000.0f;
240 light.m_bAttachToSun = false;
241 light.m_cLdrClr = ColorF(1, 1, 1, 1);
242 light.m_fClrMultiplier = 1;
243 light.m_fViewAngleFalloff = 1;
245 const bool bIgnoreOcclusionQueries = true;
247 if (CTexture* pDstRT = gcpRendD3D->GetActiveDisplayContext()->GetCurrentBackBuffer())
249 CClearSurfacePass::Execute(pDstRT, Clr_Empty);
251 D3DViewPort viewport;
252 viewport.TopLeftX = viewport.TopLeftY = 0.0f;
253 viewport.Width = float(pDstRT->GetWidth());
254 viewport.Height = float(pDstRT->GetHeight());
255 viewport.MinDepth = 0.0f;
256 viewport.MaxDepth = 1.0f;
258 _smart_ptr<CRenderView> pRenderView = pParam->passInfo.GetRenderView();
259 SRenderViewInfo viewInfo[CCamera::eEye_eCount];
260 size_t viewInfoCount = pRenderView->GetGraphicsPipeline()->GenerateViewInfo(viewInfo);
262 std::vector<CPrimitiveRenderPass*> prePasses;
264 CPrimitiveRenderPass previewPass;
265 previewPass.SetRenderTarget(0, pDstRT);
266 previewPass.SetViewport(viewport);
267 previewPass.BeginAddingPrimitives();
269 if (ProcessAll(previewPass, prePasses, light, viewInfo, viewInfoCount, true, bIgnoreOcclusionQueries))
270 previewPass.Execute();
274 bool RootOpticsElement::ProcessAll(CPrimitiveRenderPass& targetPass, std::vector<CPrimitiveRenderPass*>& prePasses, const SFlareLight& light, const SRenderViewInfo* pViewInfo, int viewInfoCount, bool bForceRender, bool bUpdateOcclusion)
276 CRY_ASSERT(IsGroupEnabled() && (viewInfoCount > 0) && (viewInfoCount <= CCamera::eEye_eCount));
278 Vec3 vSrcWorldPos = light.m_vPos;
279 Vec3 vSrcProjPos;
281 m_flareLight = light;
282 float linearDepth = 0;
283 float distance = 0;
285 // Ideally we'd use the center camera here
286 const SRenderViewInfo& viewInfo = pViewInfo[0];
288 if (!CFlareSoftOcclusionQuery::ComputeProjPos(vSrcWorldPos, viewInfo.viewMatrix, viewInfo.projMatrix, vSrcProjPos))
289 return false;
291 if (viewInfo.flags & SRenderViewInfo::eFlags_ReverseDepth)
292 vSrcProjPos.z = 1.0f - vSrcProjPos.z;
294 linearDepth = clamp_tpl(CFlareSoftOcclusionQuery::ComputeLinearDepth(vSrcWorldPos, viewInfo.viewMatrix, viewInfo.nearClipPlane, viewInfo.farClipPlane), -1.0f, 0.99f);
295 distance = viewInfo.cameraOrigin.GetDistance(vSrcWorldPos);
297 if (!bForceRender && (linearDepth <= 0 || !IsVisibleBasedOnLight(light, distance)))
298 return false;
300 float fFade = 1 - 1000.f * m_fDistanceFadingFactor * linearDepth;
301 if (!light.m_bAttachToSun && fFade <= 0.001f)
302 return false;
304 if (!bForceRender && IsOcclusionEnabled())
306 float curTargetVisibility = 0.0f;
307 m_fFlareVisibilityFactor = m_fShaftVisibilityFactor = 0.0f;
309 if (m_pOccQuery)
311 curTargetVisibility = m_pOccQuery->GetVisibility();
313 if (CSoftOcclusionVisiblityFader* pFader = m_pOccQuery->GetVisibilityFader(VISFADER_FLARE))
314 m_fFlareVisibilityFactor = bUpdateOcclusion ? pFader->UpdateVisibility(curTargetVisibility, m_fFlareTimelineDuration) : pFader->m_fVisibilityFactor;
316 if (CSoftOcclusionVisiblityFader* pFader = m_pOccQuery->GetVisibilityFader(VISFADER_SHAFT))
317 m_fShaftVisibilityFactor = bUpdateOcclusion ? pFader->UpdateVisibility(curTargetVisibility, m_fShaftTimelineDuration) : pFader->m_fVisibilityFactor;
320 if (!IsVisible())
321 return true;
324 SPreparePrimitivesContext context(targetPass, prePasses);
325 context.pViewInfo = pViewInfo;
326 context.viewInfoCount = viewInfoCount;
327 context.lightWorldPos = vSrcWorldPos;
328 context.lightScreenPos[0] = vSrcProjPos;
330 for (int i = 1; i < viewInfoCount; ++i)
332 Vec3 projPos;
333 if (CFlareSoftOcclusionQuery::ComputeProjPos(vSrcWorldPos, pViewInfo[i].viewMatrix, pViewInfo[i].projMatrix, projPos))
335 if (pViewInfo[i].flags & SRenderViewInfo::eFlags_ReverseDepth)
336 projPos.z = 1.0f - projPos.z;
338 PREFAST_ASSUME(i > 0 && i < CCamera::eEye_eCount);
339 context.lightScreenPos[i] = projPos;
343 context.auxParams.linearDepth = linearDepth;
344 context.auxParams.distance = distance;
345 float x = vSrcProjPos.x * 2 - 1;
346 float y = vSrcProjPos.y * 2 - 1;
347 float unitLenSq = (x * x + y * y);
348 context.auxParams.sensorVariationValue = clamp_tpl((1 - powf(unitLenSq, 0.25f)) * 2 - 1, -1.0f, 1.0f);
349 context.auxParams.perspectiveShortening = clamp_tpl(10.f * (1.f - vSrcProjPos.z), 0.0f, 2.0f);
350 context.auxParams.viewAngleFalloff = light.m_fViewAngleFalloff;
351 context.auxParams.attachToSun = light.m_bAttachToSun;
352 context.auxParams.bMultiplyColor = IsMultiplyColor();
353 context.auxParams.bForceRender = bForceRender;
354 context.auxParams.bIgnoreOcclusionQueries = bUpdateOcclusion;
356 validateGlobalVars(context.auxParams);
357 if (bForceRender || m_globalFlareBrightness > 0.001f || m_globalShaftBrightness > 0.001f)
358 COpticsGroup::PreparePrimitives(context);
360 return true;