1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
5 #include "Shadow_Renderer.h"
7 #include "LightVolumeBuffer.h"
8 #include "ParticleBuffer.h"
10 #include "Common/Shaders/CShader.h"
11 #include "Common/Shaders/ShaderResources.h"
17 #define MAX_REND_SHADERS (1U << 12)
18 #define MAX_REND_SHADER_RES (1U << 14)
20 struct CRY_ALIGN(32) SRendItem
29 SRendItemSorter rendItemSorter
;
32 CRenderObject
* pRenderObject
;
33 CCompiledRenderObject
* pCompiledObject
;
35 CRenderElement
* pElem
;
36 //uint32 nStencRef : 8;
38 static uint32
EncodeObjFlagsValue(uint64 objFlags
)
40 return uint32(objFlags
) & (0xFFFF0000 & FOB_SORT_MASK
);
43 static uint16
EncodePriorityIntegerValue(CRenderObject
* pObj
)
45 return uint16(pObj
->m_nSort
);
48 static uint16
EncodeDistanceIntegerValue(float fDistance
)
50 return HalfFlip(CryConvertFloatToHalf(std::min(fDistance
, 65504.0f
)));
53 static float EncodeCustomDistanceSortingValue(CRenderObject
* pObj
, float fDistance
)
55 int nRenderAlways
= (pObj
->m_pRenderNode
) ? pObj
->m_pRenderNode
->GetRndFlags() & ERF_RENDER_ALWAYS
: 1;
56 float comp
= fDistance
+ pObj
->m_fSort
;
57 return nRenderAlways
? std::numeric_limits
<float>::lowest() + comp
: comp
;
60 static float EncodeDistanceSortingValue(CRenderObject
* pObj
, float fDistance
)
62 return fDistance
+ pObj
->m_fSort
;
65 static uint32
EncodeObjFlagsSortingValue(CRenderObject
* pObj
, uint64 objFlags
, float fDistance
)
67 return EncodeObjFlagsValue(objFlags
) + EncodeDistanceIntegerValue(fDistance
);
70 static uint32
EncodeObjFlagsSortingValue(CRenderObject
* pObj
, uint64 objFlags
)
72 return EncodeObjFlagsValue(objFlags
) + EncodePriorityIntegerValue(pObj
);
75 static inline void ExtractShaderItem(uint32 value
, uint32 batchFlags
, SShaderItem
& sh
)
77 uint32 nShaderId
= (value
>> 20) & (MAX_REND_SHADERS
- 1);
78 CShader
* pShader
= (CShader
*)(CShaderMan::s_pContainer
->m_RList
[CBaseResource::RListIndexFromId(nShaderId
)]);
79 sh
.m_pShader
= static_cast<IShader
*>(pShader
);
80 uint32 nTechnique
= ((value
>> 14) & 0x3f);
81 if (nTechnique
== 0x3f)
83 sh
.m_nTechnique
= nTechnique
;
84 int nResID
= (value
) & (MAX_REND_SHADER_RES
- 1);
85 sh
.m_pShaderResources
= (IRenderShaderResources
*)((nResID
) ? CShader::s_ShaderResources_known
[nResID
] : nullptr);
86 sh
.m_nPreprocessFlags
= batchFlags
;
89 static inline uint32
PackShaderItem(const SShaderItem
& shaderItem
)
91 uint32 nResID
= shaderItem
.m_pShaderResources
? ((CShaderResources
*)(shaderItem
.m_pShaderResources
))->m_Id
: 0;
92 uint32 nShaderId
= ((CShader
*)shaderItem
.m_pShader
)->mfGetID();
93 assert(nResID
< CShader::s_ShaderResources_known
.size());
94 assert(nShaderId
!= 0);
95 uint32 value
= (nShaderId
<< 20) | ((shaderItem
.m_nTechnique
& 0x3f) << 14) | (nResID
);
99 /////////////////////////////////////////////////////////////////////
101 static inline bool TestIndividualBatchFlags(uint32 batchFlags
, uint32 batchIncludeFilter
, uint32 batchExcludeFilter
)
103 // The tested field must have all included, and must _not_ have any excluded flags
104 return (((batchFlags
& batchIncludeFilter
) | (batchFlags
& batchExcludeFilter
)) == batchIncludeFilter
);
107 static inline bool TestCombinedBatchFlags(uint32 batchFlags
, uint32 batchIncludeFilter
)
109 // The tested field must have all included (the exclusion can't be tested on the combined bitfield)
110 return (((batchFlags
& batchIncludeFilter
)) == batchIncludeFilter
);
113 static inline bool TestIndividualObjFlag(uint32 objFlag
, uint32 objIncludeFilter
)
115 return ((objFlag
& objIncludeFilter
) == objIncludeFilter
);
118 /////////////////////////////////////////////////////////////////////
120 // Sort by SortVal member of RI
121 static void mfSortPreprocess(SRendItem
* First
, int Num
);
123 static void mfSortByDist(SRendItem
* First
, int Num
, bool bDecals
, bool InvertedOrder
= false);
125 static void mfSortByLight(SRendItem
* First
, int Num
, bool bSort
, const bool bIgnoreRePtr
, bool bSortDecals
);
126 // Special sorting for ZPass (compromise between depth and batching)
127 static void mfSortForZPass(SRendItem
* First
, int Num
, bool bZPre
);
128 static void mfSortForDepthPass(SRendItem
* First
, int Num
);
131 struct CMotionBlurPredicate
133 bool operator()(SRendItem
& item
)
135 // Assumes not set flags in order before set flags
136 return SRendItem::TestIndividualObjFlag(item
.ObjSort
, FOB_HAS_PREVMATRIX
) == 0;
140 struct CZPrePassPredicate
142 bool operator()(SRendItem
& item
)
144 // Assumes not set flags in order before set flags
145 return SRendItem::TestIndividualObjFlag(item
.ObjSort
, FOB_ZPREPASS
) == 0;
149 //==================================================================
152 //Note: If these are altered, g_StencilFuncLookup and g_StencilOpLookup arrays
153 // need to be updated in turn
154 enum EStencilStateFunction
156 FSS_STENCFUNC_ALWAYS
= 0x0,
157 FSS_STENCFUNC_NEVER
= 0x1,
158 FSS_STENCFUNC_LESS
= 0x2,
159 FSS_STENCFUNC_LEQUAL
= 0x3,
160 FSS_STENCFUNC_GREATER
= 0x4,
161 FSS_STENCFUNC_GEQUAL
= 0x5,
162 FSS_STENCFUNC_EQUAL
= 0x6,
163 FSS_STENCFUNC_NOTEQUAL
= 0x7,
164 FSS_STENCFUNC_MASK
= 0x7
167 #define FSS_STENCIL_TWOSIDED 0x8
169 #define FSS_CCW_SHIFT 16
173 FSS_STENCOP_KEEP
= 0x0,
174 FSS_STENCOP_REPLACE
= 0x1,
175 FSS_STENCOP_INCR
= 0x2,
176 FSS_STENCOP_DECR
= 0x3,
177 FSS_STENCOP_ZERO
= 0x4,
178 FSS_STENCOP_INCR_WRAP
= 0x5,
179 FSS_STENCOP_DECR_WRAP
= 0x6,
180 FSS_STENCOP_INVERT
= 0x7
183 #define FSS_STENCFAIL_SHIFT 4
184 #define FSS_STENCFAIL_MASK (0x7 << FSS_STENCFAIL_SHIFT)
186 #define FSS_STENCZFAIL_SHIFT 8
187 #define FSS_STENCZFAIL_MASK (0x7 << FSS_STENCZFAIL_SHIFT)
189 #define FSS_STENCPASS_SHIFT 12
190 #define FSS_STENCPASS_MASK (0x7 << FSS_STENCPASS_SHIFT)
192 #define STENC_FUNC(op) (op)
193 #define STENC_CCW_FUNC(op) (op << FSS_CCW_SHIFT)
194 #define STENCOP_FAIL(op) (op << FSS_STENCFAIL_SHIFT)
195 #define STENCOP_ZFAIL(op) (op << FSS_STENCZFAIL_SHIFT)
196 #define STENCOP_PASS(op) (op << FSS_STENCPASS_SHIFT)
197 #define STENCOP_CCW_FAIL(op) (op << (FSS_STENCFAIL_SHIFT + FSS_CCW_SHIFT))
198 #define STENCOP_CCW_ZFAIL(op) (op << (FSS_STENCZFAIL_SHIFT + FSS_CCW_SHIFT))
199 #define STENCOP_CCW_PASS(op) (op << (FSS_STENCPASS_SHIFT + FSS_CCW_SHIFT))
202 #define BIT_STENCIL_RESERVED 0x80
203 #define BIT_STENCIL_INSIDE_CLIPVOLUME 0x40
204 #define BIT_STENCIL_ALLOW_TERRAINLAYERBLEND 0x20
205 #define BIT_STENCIL_ALLOW_DECALBLEND 0x10
206 #define STENCIL_VALUE_OUTDOORS 0x0
208 #define STENC_VALID_BITS_NUM 7
209 #define STENC_MAX_REF ((1 << STENC_VALID_BITS_NUM) - 1)
215 FB_TRANSPARENT
= 0x2,
218 FB_BELOW_WATER
= 0x10,
220 FB_PREPROCESS
= 0x40,
221 FB_MOTIONBLUR
= 0x80,
222 FB_POST_3D_RENDER
= 0x100,
224 FB_COMPILED_OBJECT
= 0x400,
225 FB_CUSTOM_RENDER
= 0x800,
226 FB_RESOLVE_FULL
= 0x1000,
227 FB_LAYER_EFFECT
= 0x2000,
228 FB_WATER_REFL
= 0x4000,
229 FB_WATER_CAUSTIC
= 0x8000,
231 FB_TILED_FORWARD
= 0x20000,
232 FB_REFRACTION
= 0x40000,
233 FB_EYE_OVERLAY
= 0x80000,
235 FB_MASK
= 0xfffff //! FB flags cannot exceed 0xfffff
238 enum SRenderShaderLightMaskFlags
243 SLMF_TYPE_MASK
= (SLMF_POINT
| SLMF_PROJECTED
)
246 #define SLMF_LTYPE_SHIFT 8
247 #define SLMF_LTYPE_BITS 4
254 SHAPE_CLIP_PROJECTOR
,
255 SHAPE_CLIP_PROJECTOR1
,
256 SHAPE_CLIP_PROJECTOR2
,
257 SHAPE_SIMPLE_PROJECTOR
,