Add stencil buffer usage with object layer information

#3080 #967
This commit is contained in:
Wojtek Figat
2025-10-07 18:07:23 +02:00
parent 823ed247d2
commit 361fc3ecfb
36 changed files with 291 additions and 65 deletions

View File

@@ -218,7 +218,7 @@ bool Mesh::Load(uint32 vertices, uint32 triangles, const void* vb0, const void*
return Init(vertices, triangles, vbData, ib, use16BitIndexBuffer, vbLayout);
}
void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, const Matrix& world, StaticFlags flags, bool receiveDecals, DrawPass drawModes, float perInstanceRandom, int8 sortOrder) const
void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, const Matrix& world, StaticFlags flags, bool receiveDecals, DrawPass drawModes, float perInstanceRandom, int8 sortOrder, uint8 stencilValue) const
{
if (!material || !material->IsSurface() || !IsInitialized())
return;
@@ -240,8 +240,8 @@ void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, cons
drawCall.ObjectRadius = (float)_sphere.Radius * drawCall.World.GetScaleVector().GetAbsolute().MaxValue();
drawCall.Surface.GeometrySize = _box.GetSize();
drawCall.Surface.PrevWorld = world;
drawCall.WorldDeterminantSign = RenderTools::GetWorldDeterminantSign(drawCall.World);
drawCall.PerInstanceRandom = perInstanceRandom;
drawCall.StencilValue = stencilValue;
#if USE_EDITOR
const ViewMode viewMode = renderContext.View.Mode;
if (viewMode == ViewMode::LightmapUVsDensity || viewMode == ViewMode::LODPreview)
@@ -307,8 +307,8 @@ void Mesh::Draw(const RenderContext& renderContext, const DrawInfo& info, float
drawCall.Surface.Lightmap = (info.Flags & StaticFlags::Lightmap) != StaticFlags::None ? info.Lightmap : nullptr;
drawCall.Surface.LightmapUVsArea = info.LightmapUVs ? *info.LightmapUVs : Rectangle::Empty;
drawCall.Surface.LODDitherFactor = lodDitherFactor;
drawCall.WorldDeterminantSign = RenderTools::GetWorldDeterminantSign(drawCall.World);
drawCall.PerInstanceRandom = info.PerInstanceRandom;
drawCall.StencilValue = info.StencilValue;
#if USE_EDITOR
const ViewMode viewMode = renderContext.View.Mode;
if (viewMode == ViewMode::LightmapUVsDensity || viewMode == ViewMode::LODPreview)
@@ -370,8 +370,8 @@ void Mesh::Draw(const RenderContextBatch& renderContextBatch, const DrawInfo& in
drawCall.Surface.Lightmap = (info.Flags & StaticFlags::Lightmap) != StaticFlags::None ? info.Lightmap : nullptr;
drawCall.Surface.LightmapUVsArea = info.LightmapUVs ? *info.LightmapUVs : Rectangle::Empty;
drawCall.Surface.LODDitherFactor = lodDitherFactor;
drawCall.WorldDeterminantSign = RenderTools::GetWorldDeterminantSign(drawCall.World);
drawCall.PerInstanceRandom = info.PerInstanceRandom;
drawCall.StencilValue = info.StencilValue;
#if USE_EDITOR
const ViewMode viewMode = renderContextBatch.GetMainContext().View.Mode;
if (viewMode == ViewMode::LightmapUVsDensity || viewMode == ViewMode::LODPreview)

View File

@@ -142,7 +142,8 @@ public:
/// <param name="drawModes">The draw passes to use for rendering this object.</param>
/// <param name="perInstanceRandom">The random per-instance value (normalized to range 0-1).</param>
/// <param name="sortOrder">Object sorting key.</param>
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f, int8 sortOrder = 0) const;
/// <param name="stencilValue">Object stencil value.</param>
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f, int8 sortOrder = 0, uint8 stencilValue = 0) const;
/// <summary>
/// Draws the mesh.

View File

@@ -404,6 +404,11 @@ public:
/// </summary>
float PerInstanceRandom;
/// <summary>
/// The 8-bit stencil value to write into Depth-Stencil Buffer.
/// </summary>
uint8 StencilValue;
/// <summary>
/// The LOD bias value.
/// </summary>
@@ -422,6 +427,12 @@ public:
#if USE_EDITOR
float LightmapScale = -1.0f;
#endif
// Packs object layer into the stencil bits.
FORCE_INLINE void SetStencilValue(int32 layer)
{
StencilValue = uint8(layer & 0x1f);
}
};
/// <summary>

View File

@@ -314,8 +314,8 @@ void SkinnedMesh::Draw(const RenderContext& renderContext, const DrawInfo& info,
drawCall.Surface.PrevWorld = info.DrawState->PrevWorld;
drawCall.Surface.Skinning = info.Skinning;
drawCall.Surface.LODDitherFactor = lodDitherFactor;
drawCall.WorldDeterminantSign = RenderTools::GetWorldDeterminantSign(drawCall.World);
drawCall.PerInstanceRandom = info.PerInstanceRandom;
drawCall.StencilValue = info.StencilValue;
// Push draw call to the render list
renderContext.List->AddDrawCall(renderContext, drawModes, StaticFlags::None, drawCall, entry.ReceiveDecals, info.SortOrder);
@@ -355,8 +355,8 @@ void SkinnedMesh::Draw(const RenderContextBatch& renderContextBatch, const DrawI
drawCall.Surface.PrevWorld = info.DrawState->PrevWorld;
drawCall.Surface.Skinning = info.Skinning;
drawCall.Surface.LODDitherFactor = lodDitherFactor;
drawCall.WorldDeterminantSign = RenderTools::GetWorldDeterminantSign(drawCall.World);
drawCall.PerInstanceRandom = info.PerInstanceRandom;
drawCall.StencilValue = info.StencilValue;
// Push draw call to the render lists
const auto shadowsMode = entry.ShadowsMode & slot.ShadowsMode;