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.
o3de/Code/CryEngine/RenderDll/Common/PostProcess/PostProcessUtils.h

312 lines
10 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.
// Description : Post processing common utilities
#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTPROCESSUTILS_H
#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTPROCESSUTILS_H
#pragma once
struct SDepthTexture;
class CShader;
struct SPostEffectsUtils
{
enum EDepthDownsample
{
eDepthDownsample_None = 0,
eDepthDownsample_Min,
eDepthDownsample_Max,
};
// Create all resources
bool Create();
// Release all used resources
void Release();
// Create a render target
static bool CreateRenderTarget(const char* szTexName, CTexture*& pTex, int iWidth, int iHeight, const ColorF& cClear, bool bUseAlpha, bool bMipMaps = 0, ETEX_Format pTexFormat = eTF_R8G8B8A8, int nCustomID = -1, int nFlags = 0);
////////////////////////////////////////////////////////////////////////////////////////////////////
// Utilities to void some code duplication
////////////////////////////////////////////////////////////////////////////////////////////////////
// Begins render pass utility - for post process stuff only pass 0 assumed to be used
static bool ShBeginPass(CShader* pShader, const CCryNameTSCRC& TechName, uint32 nFlags = 0);
// Ends render pass utility
static void ShEndPass();
// Set vertex shader constant utility
static void ShSetParamVS(const CCryNameR& pParamName, const Vec4& pParam);
// Set pixel shader constant utility
static void ShSetParamPS(const CCryNameR& pParamName, const Vec4& pParam);
static void GetFullScreenTri(SVF_P3F_C4B_T2F pResult[3], int nTexWidth, int nTexHeight, float z = 0, const RECT * pSrcRegion = NULL);
static void GetFullScreenTriWPOS(SVF_P3F_T2F_T3F pResult[3], int nTexWidth, int nTexHeight, float z = 0, const RECT * pSrcRegion = NULL);
// Draws fullscreen aligned triangle
static void DrawFullScreenTri(int nTexWidth, int nTexHeight, float z = 0, const RECT* pSrcRegion = NULL);
static void DrawFullScreenTriWPOS(int nTexWidth, int nTexHeight, float z = 0, const RECT* pSrcRegion = NULL);
// Draws static quad. Uv/size offsets handled via vertex shader.
virtual void DrawQuadFS(CShader* pShader, bool bOutputCamVec, int nWidth, int nHeight, float x0 = 0, float y0 = 0, float x1 = 1, float y1 = 1, float z = 0) = 0;
// Deprecated - use DrawQuadFS. Draws screen aligned quad
static void DrawScreenQuad(int nTexWidth, int nTexHeight, float x0 = 0, float y0 = 0, float x1 = 1, float y1 = 1);
// Deprecated: Only used in GammaCorrection technique - Draws a generic, non-screen-aligned quad
static void DrawQuad(int nTexWidth, int nTexHeight,
const Vec2& vxA, const Vec2& vxB, const Vec2& vxC, const Vec2& vxD,
const Vec2& uvA = Vec2(0, 0), const Vec2& uvB = Vec2(0, 1), const Vec2& uvC = Vec2(1, 1), const Vec2& uvD = Vec2(1, 0));
// Sets a texture
static void SetTexture(CTexture* pTex, int nStage, int nFilter = FILTER_LINEAR, int nClamp = 1, bool bSRGBLookup = false, DWORD dwBorderColor = 0);
// Copy a texture into other texture
virtual void StretchRect(CTexture* pSrc, CTexture*& pDst, bool bClearAlpha = false, bool bDecodeSrcRGBK = false, bool bEncodeDstRGBK = false, bool bBigDownsample = false, EDepthDownsample depthDownsampleMode = eDepthDownsample_None, bool bBindMultisampled = false, const RECT* srcRegion = NULL) = 0;
// Copy screen into texture
virtual void CopyScreenToTexture(CTexture*& pDst, const RECT* pSrcRect) = 0;
// Apply Gaussian blur a texture
virtual void TexBlurGaussian(CTexture* pTex, int nAmount = 1, float fScale = 1.0f, float fDistribution = 5.0f, bool bAlphaOnly = false, CTexture* pMask = 0, bool bSRGB = false, CTexture* pBlurTmp = 0) = 0;
// Clear active render target region
static void ClearScreen(float r, float g, float b, float a);
static void UpdateFrustumCorners();
static void UpdateOverscanBorderAspectRatio();
// Special full screen pass utility functions used by GMEM path /////
static void PrepareGmemDeferredDecals();
static void ClearGmemGBuffer();
/////////////////////////////////////////////////////////////////////
// Log utility
static void Log(const char* pszMsg)
{
if (gRenDev->m_logFileHandle != AZ::IO::InvalidHandle && pszMsg)
{
gRenDev->Logv(SRendItem::m_RecurseLevel[gRenDev->m_pRT->GetThreadList()], pszMsg);
}
}
// Get current color matrix set up by global color parameters
Matrix44& GetColorMatrix();
////////////////////////////////////////////////////////////////////////////////////////////////////
// Math utils
////////////////////////////////////////////////////////////////////////////////////////////////////
// Linear interpolation
static float InterpolateLinear(float p1, float p2, float t)
{
return p1 + (p2 - p1) * t;
};
// Cubic interpolation
static float InterpolateCubic(float p1, float p2, float p3, float p4, float t)
{
float t2 = t * t;
return (((-p1 * 2.0f) + (p2 * 5.0f) - (p3 * 4.0f) + p4) / 6.0f) * t2 * t + (p1 + p3 - (2.0f * p2)) * t2 + (((-4.0f * p1) + p2 + (p3 * 4.0f) - p4) / 6.0f) * t + p2;
};
// Sine interpolation
static float InterpolateSine(float p1, float p2, float p3, float p4, float t)
{
return p2 + (t * (p3 - p2)) + (sinf(t * PI) * ((p2 + p2) - p1 - p3 + (t * (p1 - (p2 + p2 + p2) + (p3 + p3 + p3) - p4))) / 8.0f);
};
// Return normalized random number
static float randf()
{
return cry_random(0.0f, 1.0f);
}
// Return signed normalized random number
static float srandf()
{
return cry_random(-1.0f, 1.0f);
}
// Returns a quasi-random sequence of values; for 2d data (2, 3) is the recommended base
static float HaltonSequence(int index, int primeBase)
{
float invBase = 1.0f / (float)primeBase;
float f = invBase;
float result = 0;
for (int i = index; i > 0; i /= primeBase, f *= invBase)
{
result += f * (float)(i % primeBase);
}
return result;
}
// Returns closest power of 2 size
static int GetClosestPow2Size(int size)
{
float fPower = floorf(logf((float)size) / logf(2.0f));
int nResize = int(powf(2.0f, fPower));
// Clamp
if (nResize >= 512)
{
nResize = 512;
}
return nResize;
}
static void GetViewMatrix(Matrix44A& viewMatrix, bool bCameraSpace = false)
{
viewMatrix = gRenDev->m_ViewMatrix;
if (bCameraSpace)
{
viewMatrix.m30 = 0.0f;
viewMatrix.m31 = 0.0f;
viewMatrix.m32 = 0.0f;
}
}
static void GetTextureRect(CTexture* pTexture, RECT* pRect)
{
pRect->left = 0;
pRect->top = 0;
pRect->right = pTexture->GetWidth();
pRect->bottom = pTexture->GetHeight();
}
static float GaussianDistribution1D(float x, float rho)
{
float g = 1.0f / (rho * sqrtf(2.0f * PI));
g *= expf(-(x * x) / (2.0f * rho * rho));
return g;
}
static float GaussianDistribution2D(float x, float y, float rho)
{
float g = 1.0f / (2.0f * PI * rho * rho);
g *= expf(-(x * x + y * y) / (2 * rho * rho));
return g;
}
static CTexture* GetTemporalCurrentTarget()
{
return CTexture::s_ptexPrevBackBuffer[SPostEffectsUtils::m_iFrameCounter % 2][gRenDev->m_CurRenderEye];
}
static CTexture* GetTemporalHistoryTarget()
{
return CTexture::s_ptexPrevBackBuffer[(SPostEffectsUtils::m_iFrameCounter + 1) % 2][gRenDev->m_CurRenderEye];
}
static CTexture* GetCoCCurrentTarget()
{
return CTexture::s_ptexSceneCoCHistory[SPostEffectsUtils::m_iFrameCounter % 2];
}
static CTexture* GetCoCHistoryTarget()
{
return CTexture::s_ptexSceneCoCHistory[(SPostEffectsUtils::m_iFrameCounter + 1) % 2];
}
static CTexture* AcquireFinalCompositeTarget(bool bNeedHDRTarget)
{
if (bNeedHDRTarget)
{
m_UpscaleTarget = GetTemporalHistoryTarget();
}
else
{
m_UpscaleTarget = CTexture::s_ptexSceneDiffuse;
}
return m_UpscaleTarget;
}
static CTexture* GetFinalCompositeTarget()
{
return m_UpscaleTarget;
}
static CTexture* GetVelocityObjectRT()
{
return CTexture::s_ptexVelocityObjects[gRenDev->m_CurRenderEye];
}
static float GetOverscanBorderAspectRatio()
{
return m_fOverscanBorderAspectRatio;
}
public:
static SDepthTexture* m_pCurDepthSurface;
static RECT m_pScreenRect;
static ITimer* m_pTimer;
static int m_iFrameCounter;
static int m_nColorMatrixFrameID;
static CShader* m_pCurrShader;
Matrix44 m_pView;
Matrix44 m_pProj;
Matrix44 m_pViewProj;
Matrix44 m_pColorMat;
static Matrix44 m_pScaleBias;
static float m_fWaterLevel;
// frustrum corners
static Vec3 m_vRT, m_vLT, m_vLB, m_vRB;
static int m_nFrustrumFrameID;
protected:
SPostEffectsUtils()
{
m_pView.SetIdentity();
m_pProj.SetIdentity();
m_pViewProj.SetIdentity();
m_pColorMat.SetIdentity();
m_pCurDepthSurface = NULL;
m_pScreenRect.left = m_pScreenRect.top = 0;
m_pScreenRect.bottom = m_pScreenRect.right = 0;
m_pTimer = NULL;
m_iFrameCounter = 0;
m_nColorMatrixFrameID = -1;
m_pCurrShader = NULL;
m_fWaterLevel = 0.0;
m_vRT = m_vLT = m_vLB = m_vRB = Vec3(ZERO);
m_nFrustrumFrameID = -1;
}
virtual ~SPostEffectsUtils()
{
}
static float m_fOverscanBorderAspectRatio;
private:
static CTexture* m_UpscaleTarget;
};
#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTPROCESSUTILS_H