You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
427 lines
16 KiB
C++
427 lines
16 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#include "RenderDll_precompiled.h"
|
|
#include "OpticsElement.h"
|
|
#include "../CryNameR.h"
|
|
#include "../../XRenderD3D9/DriverD3D.h"
|
|
#include "RootOpticsElement.h"
|
|
#include "../Textures/Texture.h"
|
|
#include "../Common/Textures/TextureManager.h"
|
|
#include "FlareSoftOcclusionQuery.h"
|
|
|
|
#if defined(FLARES_SUPPORT_EDITING)
|
|
AZStd::vector<FuncVariableGroup> COpticsElement::GetEditorParamGroups()
|
|
{
|
|
if (m_paramGroups.empty())
|
|
{
|
|
InitEditorParamGroups(m_paramGroups);
|
|
}
|
|
|
|
return m_paramGroups;
|
|
}
|
|
|
|
#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&COpticsElement::FUNC_NAME)
|
|
void COpticsElement::InitEditorParamGroups(AZStd::vector<FuncVariableGroup>& groups)
|
|
{
|
|
FuncVariableGroup baseGroup;
|
|
baseGroup.SetName("Common");
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Size", "Size", this, MFPtr(SetSize), MFPtr(GetSize)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Perspective factor", "Perspective factor", this, MFPtr(SetPerspectiveFactor), MFPtr(GetPerspectiveFactor)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Distance Fading factor", "Distance fading factor", this, MFPtr(SetDistanceFadingFactor), MFPtr(GetDistanceFadingFactor)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Brightness", "Brightness", this, MFPtr(SetBrightness), MFPtr(GetBrightness)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Position", "The relative position to light", this, MFPtr(SetMovement), MFPtr(GetMovement)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_COLOR, "Tint", "Basic tint", this, MFPtr(SetColor), MFPtr(GetColor)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Orbit angle", "The rotation angle of the virtual light source", this, MFPtr(SetOrbitAngle), MFPtr(GetOrbitAngle)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Occlusion Interaction", "Enable various flare interaction with the occlusion", this, MFPtr(SetOccBokehEnabled), MFPtr(IsOccBokehEnabled)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Auto Rotation", "Enable Auto Rotation around the pivot", this, MFPtr(SetAutoRotation), MFPtr(HasAutoRotation)));
|
|
baseGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Correct Aspect Ratio", "Correct aspect ratio", this, MFPtr(SetAspectRatioCorrection), MFPtr(HasAspectRatioCorrection)));
|
|
groups.push_back(baseGroup);
|
|
|
|
FuncVariableGroup sensorGroup;
|
|
sensorGroup.SetName("Sensor");
|
|
sensorGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Sensor image size variation factor", "sensor image size variation factor", this, MFPtr(SetSensorSizeFactor), MFPtr(GetSensorSizeFactor)));
|
|
sensorGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Sensor image brightness variation factor", "sensor image brightness variation factor", this, MFPtr(SetSensorBrightnessFactor), MFPtr(GetSensorBrightnessFactor)));
|
|
groups.push_back(sensorGroup);
|
|
|
|
FuncVariableGroup xformGroup;
|
|
xformGroup.SetName("Transformation");
|
|
xformGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Scale", "Scale", this, MFPtr(SetScale), MFPtr(GetScale)));
|
|
xformGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Translation", "Translation", this, MFPtr(SetTranslation), MFPtr(GetTranslation)));
|
|
xformGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Rotation", "Rotation", this, MFPtr(SetRotation), MFPtr(GetRotation)));
|
|
groups.push_back(xformGroup);
|
|
|
|
FuncVariableGroup dynamicsGroup;
|
|
dynamicsGroup.SetName("Dynamics");
|
|
dynamicsGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable", "Enable.", this, MFPtr(SetDynamicsEnabled), MFPtr(GetDynamicsEnabled)));
|
|
dynamicsGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Trigger Invert", "Invert the trigger area.", this, MFPtr(SetDynamicsInvert), MFPtr(GetDynamicsInvert)));
|
|
dynamicsGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Trigger Offset", "Offset from the center of the screen.", this, MFPtr(SetDynamicsOffset), MFPtr(GetDynamicsOffset)));
|
|
dynamicsGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Trigger Range", "How much influence the trigger has.", this, MFPtr(SetDynamicsRange), MFPtr(GetDynamicsRange)));
|
|
dynamicsGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Trigger Falloff", "Falloff strength of the trigger area.", this, MFPtr(SetDynamicsFalloff), MFPtr(GetDynamicsFalloff)));
|
|
groups.push_back(dynamicsGroup);
|
|
}
|
|
#undef MFPtr
|
|
#endif
|
|
|
|
void COpticsElement::Load(IXmlNode* pNode)
|
|
{
|
|
XmlNodeRef pCommonNode = pNode->findChild("Common");
|
|
if (pCommonNode)
|
|
{
|
|
float fSize(m_fSize);
|
|
if (pCommonNode->getAttr("Size", fSize))
|
|
{
|
|
SetSize(fSize);
|
|
}
|
|
|
|
float fPerspectiveFactor(m_fPerpectiveFactor);
|
|
if (pCommonNode->getAttr("Perspectivefactor", fPerspectiveFactor))
|
|
{
|
|
SetPerspectiveFactor(fPerspectiveFactor);
|
|
}
|
|
|
|
float fDistanceFadingFactor = m_fDistanceFadingFactor;
|
|
if (pCommonNode->getAttr("DistanceFadingfactor", fDistanceFadingFactor))
|
|
{
|
|
SetDistanceFadingFactor(fDistanceFadingFactor);
|
|
}
|
|
|
|
float fBrightness = m_fBrightness;
|
|
if (pCommonNode->getAttr("Brightness", fBrightness))
|
|
{
|
|
SetBrightness(fBrightness);
|
|
}
|
|
|
|
Vec2 vPos(m_vMovement);
|
|
if (pCommonNode->getAttr("Position", vPos))
|
|
{
|
|
SetMovement(vPos);
|
|
}
|
|
|
|
Vec3 color(m_Color.r, m_Color.g, m_Color.b);
|
|
int nAlpha((int)(m_Color.a * 255.0f));
|
|
if (pCommonNode->getAttr("Tint", color) && pCommonNode->getAttr("Tint.alpha", nAlpha))
|
|
{
|
|
SetColor(ColorF(color.x, color.y, color.z, (float)nAlpha / 255.0f));
|
|
}
|
|
|
|
float fOrbitAngle(m_fOrbitAngle);
|
|
if (pCommonNode->getAttr("Orbitangle", fOrbitAngle))
|
|
{
|
|
SetOrbitAngle(fOrbitAngle);
|
|
}
|
|
|
|
bool bOcclusionBokeh(m_bOcclusionBokeh);
|
|
if (pCommonNode->getAttr("OcclusionInteraction", bOcclusionBokeh))
|
|
{
|
|
SetOccBokehEnabled(bOcclusionBokeh);
|
|
}
|
|
|
|
bool bAutoRotation(m_bAutoRotation);
|
|
if (pCommonNode->getAttr("AutoRotation", bAutoRotation))
|
|
{
|
|
SetAutoRotation(bAutoRotation);
|
|
}
|
|
|
|
bool bCorrectAspectRatio(m_bCorrectAspectRatio);
|
|
if (pCommonNode->getAttr("CorrectAspectRatio", bCorrectAspectRatio))
|
|
{
|
|
SetAspectRatioCorrection(bCorrectAspectRatio);
|
|
}
|
|
}
|
|
|
|
XmlNodeRef pSensorNode = pNode->findChild("Sensor");
|
|
if (pSensorNode)
|
|
{
|
|
float fSensorSizeFactor(m_fSensorSizeFactor);
|
|
if (pSensorNode->getAttr("Sensorimagesizevariationfactor", fSensorSizeFactor))
|
|
{
|
|
SetSensorSizeFactor(fSensorSizeFactor);
|
|
}
|
|
|
|
float fSensorBrightnessFactor = m_fSensorBrightnessFactor;
|
|
if (pSensorNode->getAttr("Sensorimagebrightnessvariationfactor", fSensorBrightnessFactor))
|
|
{
|
|
SetSensorBrightnessFactor(fSensorBrightnessFactor);
|
|
}
|
|
}
|
|
|
|
XmlNodeRef pTransformationNode = pNode->findChild("Transformation");
|
|
if (pTransformationNode)
|
|
{
|
|
Vec2 vScale(xform_scale);
|
|
if (pTransformationNode->getAttr("Scale", vScale))
|
|
{
|
|
SetScale(vScale);
|
|
}
|
|
|
|
Vec2 vTranslation(xform_translate);
|
|
if (pTransformationNode->getAttr("Translation", vTranslation))
|
|
{
|
|
SetTranslation(vTranslation);
|
|
}
|
|
|
|
float fRotation(xform_rotation);
|
|
if (pTransformationNode->getAttr("Rotation", fRotation))
|
|
{
|
|
SetRotation(fRotation);
|
|
}
|
|
}
|
|
|
|
XmlNodeRef pDynamicsNode = pNode->findChild("Dynamics");
|
|
if (pDynamicsNode)
|
|
{
|
|
bool bEnable(m_bEnabled);
|
|
if (pDynamicsNode->getAttr("Enable", bEnable))
|
|
{
|
|
SetDynamicsEnabled(bEnable);
|
|
}
|
|
|
|
bool bDynamicInvert(m_bDynamicsInvert);
|
|
if (pDynamicsNode->getAttr("TriggerInvert", bDynamicInvert))
|
|
{
|
|
SetDynamicsInvert(bDynamicInvert);
|
|
}
|
|
|
|
Vec2 vDynamicsOffset(m_vDynamicsOffset);
|
|
if (pDynamicsNode->getAttr("TriggerOffset", vDynamicsOffset))
|
|
{
|
|
SetDynamicsOffset(vDynamicsOffset);
|
|
}
|
|
|
|
float fDynamicsRange(m_fDynamicsRange);
|
|
if (pDynamicsNode->getAttr("TriggerRange", fDynamicsRange))
|
|
{
|
|
SetDynamicsRange(fDynamicsRange);
|
|
}
|
|
|
|
float fDynamicsFalloff(m_fDynamicsFalloff);
|
|
if (pDynamicsNode->getAttr("TriggerFalloff", fDynamicsFalloff))
|
|
{
|
|
SetDynamicsFalloff(fDynamicsFalloff);
|
|
}
|
|
}
|
|
}
|
|
|
|
RootOpticsElement* COpticsElement::GetRoot()
|
|
{
|
|
IOpticsElementBase* parent = this;
|
|
do
|
|
{
|
|
parent = parent->GetParent();
|
|
if (parent == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
} while (parent->GetType() != eFT_Root);
|
|
return (RootOpticsElement*)parent;
|
|
}
|
|
|
|
void COpticsElement::validateGlobalVars(SAuxParams& aux)
|
|
{
|
|
if (m_pParent)
|
|
{
|
|
m_globalPerpectiveFactor = m_fPerpectiveFactor * m_pParent->m_globalPerpectiveFactor;
|
|
m_globalDistanceFadingFactor = m_fDistanceFadingFactor * m_pParent->m_globalDistanceFadingFactor;
|
|
m_globalSensorSizeFactor = m_fSensorSizeFactor * m_pParent->m_globalSensorSizeFactor;
|
|
float sensorSizeFactor = 1 + m_globalSensorSizeFactor * aux.sensorVariationValue;
|
|
|
|
m_globalSensorBrightnessFactor = m_fSensorBrightnessFactor * m_pParent->m_globalSensorBrightnessFactor;
|
|
float sensorBrightnessFactor = fabs(1 + m_globalSensorBrightnessFactor * aux.sensorVariationValue);
|
|
|
|
float perspectiveShortening = 1 + m_globalPerpectiveFactor * (aux.perspectiveShortening - 1);
|
|
m_globalSize = m_fSize * m_pParent->m_globalSize * perspectiveShortening * sensorSizeFactor; // remember to multiply the additional perspective factor
|
|
|
|
if (aux.bMultiplyColor)
|
|
{
|
|
m_globalColor = m_Color * m_pParent->m_globalColor;
|
|
}
|
|
else
|
|
{
|
|
m_globalColor = ColorF(m_Color.r + m_pParent->m_globalColor.r,
|
|
m_Color.g + m_pParent->m_globalColor.g,
|
|
m_Color.b + m_pParent->m_globalColor.b,
|
|
m_Color.a * m_pParent->m_globalColor.a);
|
|
}
|
|
|
|
float fading = clamp_tpl(1 - 1000.f * m_globalDistanceFadingFactor * aux.linearDepth, 0.0f, 1.f);
|
|
float brightness = m_fBrightness * sensorBrightnessFactor * fading;
|
|
m_globalFlareBrightness = brightness * m_pParent->m_globalFlareBrightness;
|
|
m_globalShaftBrightness = brightness * m_pParent->m_globalShaftBrightness;
|
|
|
|
m_globalMovement.x = m_vMovement.x * m_pParent->m_globalMovement.x;
|
|
m_globalMovement.y = m_vMovement.y * m_pParent->m_globalMovement.y;
|
|
|
|
if (!m_pParent->m_globalTransform.IsIdentity())
|
|
{
|
|
m_globalTransform = m_mxTransform * m_pParent->m_globalTransform;
|
|
}
|
|
else
|
|
{
|
|
m_globalTransform = m_mxTransform;
|
|
}
|
|
|
|
m_globalOrbitAngle = m_fOrbitAngle + m_pParent->m_globalOrbitAngle;
|
|
m_globalOcclusionBokeh = m_bOcclusionBokeh & m_pParent->m_globalOcclusionBokeh;
|
|
m_globalAutoRotation = m_bAutoRotation & m_pParent->m_bAutoRotation;
|
|
m_globalCorrectAspectRatio = m_bCorrectAspectRatio & m_pParent->m_bCorrectAspectRatio;
|
|
}
|
|
}
|
|
|
|
void COpticsElement::updateXformMatrix()
|
|
{
|
|
Matrix33 scaleMx;
|
|
scaleMx.SetScale(Vec3(xform_scale.x, xform_scale.y, 1));
|
|
Matrix33 rotMx;
|
|
rotMx.SetRotationAA(xform_rotation * 2.0f * PI, Vec3(0, 0, 1));
|
|
Matrix33 combine = rotMx * scaleMx;
|
|
combine.SetColumn(2, Vec3(xform_translate.x, xform_translate.y, 1));
|
|
SetTransform(combine);
|
|
}
|
|
|
|
const Vec3 COpticsElement::computeOrbitPos(const Vec3& vSrcProjPos, float orbitAngle)
|
|
{
|
|
if (orbitAngle < 0.01f && orbitAngle > -0.01f)
|
|
{
|
|
return vSrcProjPos;
|
|
}
|
|
|
|
const Vec2 oriVec (vSrcProjPos.x - 0.5f, vSrcProjPos.y - 0.5f);
|
|
float orbitSin = 0.0f, orbitCos = 0.0f;
|
|
sincos_tpl(orbitAngle, &orbitSin, &orbitCos);
|
|
const Vec2 resultVec = Vec2(oriVec.x * orbitCos - oriVec.y * orbitSin, oriVec.y * orbitCos + oriVec.x * orbitSin);
|
|
return Vec3(resultVec.x + 0.5f, resultVec.y + 0.5f, vSrcProjPos.z);
|
|
}
|
|
|
|
void COpticsElement::ApplyVSParam_WPosAndSize(CShader* shader, const Vec3& wpos)
|
|
{
|
|
static CCryNameR wPosAndSizeName("wposAndSize");
|
|
Vec4 wPosAndSizeParam(wpos, m_globalSize);
|
|
shader->FXSetVSFloat(wPosAndSizeName, &wPosAndSizeParam, 1);
|
|
}
|
|
|
|
void COpticsElement::ApplyOcclusionPattern(CShader* shader)
|
|
{
|
|
if (GetRoot() == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
static STexState bilinearTS(FILTER_LINEAR, true);
|
|
|
|
CFlareSoftOcclusionQuery* pSoftOcclusionQuery = GetRoot()->GetOcclusionQuery();
|
|
if (pSoftOcclusionQuery && pSoftOcclusionQuery->GetGatherTexture())
|
|
{
|
|
CTexture* pGatherTex = pSoftOcclusionQuery->GetGatherTexture();
|
|
pGatherTex->Apply(5, CTexture::GetTexState(bilinearTS));
|
|
|
|
float x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
|
pSoftOcclusionQuery->GetDomainInTexture(x0, y0, x1, y1);
|
|
float width, height;
|
|
pSoftOcclusionQuery->GetSectorSize(width, height);
|
|
|
|
static CCryNameR occPatternInfoName("occPatternInfo");
|
|
const Vec4 occPatternInfo((x0 + x1) * 0.5f, (y0 + y1) * 0.5f, width, height);
|
|
shader->FXSetPSFloat(occPatternInfoName, &occPatternInfo, 1);
|
|
}
|
|
else
|
|
{
|
|
CTextureManager::Instance()->GetBlackTexture()->Apply(5, CTexture::GetTexState(bilinearTS));
|
|
}
|
|
}
|
|
|
|
void COpticsElement::ApplyOcclusionBokehFlag([[maybe_unused]] CShader* shader)
|
|
{
|
|
if (m_globalOcclusionBokeh)
|
|
{
|
|
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE3];
|
|
}
|
|
}
|
|
|
|
void COpticsElement::ApplySpectrumTexFlag([[maybe_unused]] CShader* shader, bool enabled)
|
|
{
|
|
if (enabled)
|
|
{
|
|
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2];
|
|
}
|
|
}
|
|
|
|
void COpticsElement::ApplyExternTintAndBrightnessVS(CShader* shader, ColorF& cExTint, float fExBrt)
|
|
{
|
|
static CCryNameR exTintName("externTint");
|
|
Vec4 exTintParam(cExTint.r * fExBrt, cExTint.g * fExBrt, cExTint.b * fExBrt, cExTint.a);
|
|
shader->FXSetVSFloat(exTintName, &exTintParam, 1);
|
|
}
|
|
|
|
void COpticsElement::ApplyVSParam_Xform(CShader* shader, Matrix33& mx33)
|
|
{
|
|
static CCryNameR xformName("xform");
|
|
Matrix44 mx44(mx33);
|
|
mx44.Transpose();
|
|
shader->FXSetVSFloat(xformName, reinterpret_cast<Vec4*>(mx44.GetData()), 3);
|
|
}
|
|
|
|
void COpticsElement::ApplyVSParam_Dynamics(CShader* shader, const Vec3& lightProjPos)
|
|
{
|
|
static CCryNameR dynamicsName("dynamics");
|
|
|
|
float fTriggerArea = 1.0f;
|
|
if (m_bDynamics)
|
|
{
|
|
float fRange = 1.0f / max(0.01f, m_fDynamicsRange);
|
|
float fFalloff = m_fDynamicsFalloff;
|
|
|
|
Vec2 vProjPos;
|
|
vProjPos.x = (lightProjPos.x * 2.f - 1.f) + m_vDynamicsOffset.x;
|
|
vProjPos.y = (lightProjPos.y * 2.f - 1.f) + m_vDynamicsOffset.y;
|
|
|
|
fTriggerArea = vProjPos.GetLength();
|
|
fTriggerArea = m_bDynamicsInvert ? 1.0f - fTriggerArea : fTriggerArea;
|
|
fTriggerArea = powf(clamp_tpl(1.f - fTriggerArea * fRange, 0.f, 1.f), fFalloff);
|
|
}
|
|
|
|
Vec4 dynamicsParam(fTriggerArea, 1, 1, 1);
|
|
shader->FXSetVSFloat(dynamicsName, &dynamicsParam, 1);
|
|
}
|
|
|
|
void COpticsElement::ApplyGeneralFlags([[maybe_unused]] CShader* shader)
|
|
{
|
|
if (m_globalAutoRotation)
|
|
{
|
|
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0];
|
|
}
|
|
if (m_globalCorrectAspectRatio)
|
|
{
|
|
gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5];
|
|
}
|
|
}
|
|
|
|
void COpticsElement::ApplyVSParam_LightProjPos(CShader* shader, const Vec3& lightProjPos)
|
|
{
|
|
static CCryNameR ccrName("lightProjPos");
|
|
Vec4 lpposParam(lightProjPos.x, lightProjPos.y, lightProjPos.z, 0);
|
|
shader->FXSetVSFloat(ccrName, &lpposParam, 1);
|
|
}
|
|
|
|
void COpticsElement::ApplyPSParam_LightProjPos(CShader* shader, const Vec3& lightProjPos)
|
|
{
|
|
static CCryNameR ccrName("lightProjPos");
|
|
Vec4 lpposParam(lightProjPos.x, lightProjPos.y, lightProjPos.z, 0);
|
|
shader->FXSetPSFloat(ccrName, &lpposParam, 1);
|
|
}
|
|
|
|
void COpticsElement::GetMemoryUsage(ICrySizer* pSizer) const
|
|
{
|
|
pSizer->AddObject(this, sizeof(*this));
|
|
}
|