1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsRenderBeastPrerequisites.h"
6#include "Renderer/BsRenderElement.h"
7#include "Renderer/BsParamBlocks.h"
8#include "Material/BsMaterialParam.h"
9#include "RenderAPI/BsGpuPipelineParamInfo.h"
10#include "Renderer/BsRendererMaterial.h"
11
12namespace bs { namespace ct
13{
14 class Decal;
15
16 /** @addtogroup RenderBeast
17 * @{
18 */
19
20 BS_PARAM_BLOCK_BEGIN(DecalParamDef)
21 BS_PARAM_BLOCK_ENTRY(Matrix4, gWorldToDecal)
22 BS_PARAM_BLOCK_ENTRY(Vector3, gDecalNormal)
23 BS_PARAM_BLOCK_ENTRY(float, gNormalTolerance)
24 BS_PARAM_BLOCK_ENTRY(float, gFlipDerivatives)
25 BS_PARAM_BLOCK_ENTRY(INT32, gLayerMask)
26 BS_PARAM_BLOCK_END
27
28 extern DecalParamDef gDecalParamDef;
29
30 struct MaterialSamplerOverrides;
31
32 /** Default material used for rendering decals, when no other is available. */
33 class DefaultDecalMat : public RendererMaterial<DefaultDecalMat> { RMAT_DEF("Decal.bsl"); };
34
35 /** Determines how is decal blended with the underlying surface. */
36 enum class DecalBlendMode
37 {
38 /** All decal textures are blended with the underlying surface, using alpha to determine blend amount. */
39 Transparent,
40 /** Albedo texture is multiplied with the underlying surface albedo, while all other textures are blended. */
41 Stain,
42 /** Only the normal texture is blended with the underlying surface. */
43 Normal,
44 /** Adds light contribution directly, without writing any other surface data. */
45 Emissive
46 };
47
48 /** Returns a specific decal shader variation. */
49 template<bool INSIDE_GEOMETRY, MSAAMode MSAA_MODE>
50 static const ShaderVariation& getDecalShaderVariation()
51 {
52 static ShaderVariation variation = ShaderVariation(
53 {
54 ShaderVariation::Param("INSIDE_GEOMETRY", INSIDE_GEOMETRY),
55 ShaderVariation::Param("MSAA_MODE", (INT32)MSAA_MODE),
56 });
57
58 return variation;
59 }
60
61 /** Contains information required for rendering a single Decal. */
62 class DecalRenderElement : public RenderElement
63 {
64 public:
65 /**
66 * Optional overrides for material sampler states. Used when renderer wants to override certain sampling properties
67 * on a global scale (for example filtering most commonly).
68 */
69 MaterialSamplerOverrides* samplerOverrides;
70
71 /** Binding indices representing where should the per-camera param block buffer be bound to. */
72 GpuParamBinding perCameraBindings[GPT_COUNT];
73
74 /** Indices for different variations of the used material. */
75 UINT32 techniqueIndices[2][3];
76
77 /** Time to used for evaluating material animation. */
78 float materialAnimationTime = 0.0f;
79
80 /** Texture input for the depth buffer. */
81 GpuParamTexture depthInputTexture;
82
83 /** Texture input for the mask buffer. */
84 GpuParamTexture maskInputTexture;
85
86 /** @copydoc RenderElement::draw */
87 void draw() const override;
88 };
89
90 /** Contains information about a Decal, used by the Renderer. */
91 struct RendererDecal
92 {
93 RendererDecal();
94
95 /** Updates the per-object GPU buffer according to the currently set properties. */
96 void updatePerObjectBuffer();
97
98 /**
99 * Updates the per-call GPU buffer according to the provided parameters.
100 *
101 * @param[in] viewProj Combined view-projection matrix of the current camera.
102 * @param[in] flush True if the buffer contents should be immediately flushed to the GPU.
103 */
104 void updatePerCallBuffer(const Matrix4& viewProj, bool flush = true) const;
105
106 Decal* decal;
107 mutable DecalRenderElement renderElement;
108
109 SPtr<GpuParamBlockBuffer> decalParamBuffer;
110 SPtr<GpuParamBlockBuffer> perObjectParamBuffer;
111 SPtr<GpuParamBlockBuffer> perCallParamBuffer;
112 };
113
114 /** @} */
115}}
116