Add Transparent Lighting Modes for material with option to use non-directional shading

This commit is contained in:
Wojciech Figat
2022-07-14 09:21:09 +02:00
parent 047821f7d2
commit 85f351663b
14 changed files with 254 additions and 52 deletions

View File

@@ -355,6 +355,22 @@ API_ENUM() enum class MaterialDecalBlendingMode : byte
Emissive = 3,
};
/// <summary>
/// Transparent material lighting modes.
/// </summary>
API_ENUM() enum class MaterialTransparentLightingMode : byte
{
/// <summary>
/// Default directional lighting evaluated per-pixel at the material surface. Use it for semi-transparent surfaces - with both diffuse and specular lighting component active.
/// </summary>
Surface = 0,
/// <summary>
/// Non-directional lighting evaluated per-pixel at material surface. Use it for volumetric objects such as smoke, rain or dust - only diffuse lighting term is active (no specular highlights).
/// </summary>
SurfaceNonDirectional = 1,
};
/// <summary>
/// Material input scene textures. Special inputs from the graphics pipeline.
/// </summary>
@@ -441,6 +457,33 @@ struct MaterialInfo8
bool operator==(const MaterialInfo8& other) const;
};
/// <summary>
/// Material info structure - version 9
/// [Deprecated on 13.07.2022, expires on 13.07.2024]
/// </summary>
struct MaterialInfo9
{
MaterialDomain Domain;
MaterialBlendMode BlendMode;
MaterialShadingModel ShadingModel;
MaterialUsageFlags UsageFlags;
MaterialFeaturesFlags FeaturesFlags;
MaterialDecalBlendingMode DecalBlendingMode;
MaterialPostFxLocation PostFxLocation;
CullMode CullMode;
float MaskThreshold;
float OpacityThreshold;
TessellationMethod TessellationMode;
int32 MaxTessellationFactor;
MaterialInfo9()
{
}
MaterialInfo9(const MaterialInfo8& other);
bool operator==(const MaterialInfo9& other) const;
};
/// <summary>
/// Structure with basic information about the material surface. It describes how material is reacting on light and which graphical features of it requires to render.
/// </summary>
@@ -478,6 +521,11 @@ API_STRUCT() struct FLAXENGINE_API MaterialInfo
/// </summary>
API_FIELD() MaterialDecalBlendingMode DecalBlendingMode;
/// <summary>
/// The transparent material lighting mode.
/// </summary>
API_FIELD() MaterialTransparentLightingMode TransparentLightingMode;
/// <summary>
/// The post fx material rendering location.
/// </summary>
@@ -512,10 +560,10 @@ API_STRUCT() struct FLAXENGINE_API MaterialInfo
{
}
MaterialInfo(const MaterialInfo8& other);
MaterialInfo(const MaterialInfo9& other);
bool operator==(const MaterialInfo& other) const;
};
// The current material info descriptor version used by the material pipeline
typedef MaterialInfo MaterialInfo9;
#define MaterialInfo_Version 9
typedef MaterialInfo MaterialInfo10;
#define MaterialInfo_Version 10

View File

@@ -30,7 +30,7 @@ bool MaterialInfo8::operator==(const MaterialInfo8& other) const
&& MaxTessellationFactor == other.MaxTessellationFactor;
}
MaterialInfo::MaterialInfo(const MaterialInfo8& other)
MaterialInfo9::MaterialInfo9(const MaterialInfo8& other)
{
Domain = other.Domain;
BlendMode = other.BlendMode;
@@ -78,6 +78,39 @@ MaterialInfo::MaterialInfo(const MaterialInfo8& other)
MaxTessellationFactor = other.MaxTessellationFactor;
}
bool MaterialInfo9::operator==(const MaterialInfo9& other) const
{
return Domain == other.Domain
&& BlendMode == other.BlendMode
&& ShadingModel == other.ShadingModel
&& UsageFlags == other.UsageFlags
&& FeaturesFlags == other.FeaturesFlags
&& DecalBlendingMode == other.DecalBlendingMode
&& PostFxLocation == other.PostFxLocation
&& CullMode == other.CullMode
&& Math::NearEqual(MaskThreshold, other.MaskThreshold)
&& Math::NearEqual(OpacityThreshold, other.OpacityThreshold)
&& TessellationMode == other.TessellationMode
&& MaxTessellationFactor == other.MaxTessellationFactor;
}
MaterialInfo::MaterialInfo(const MaterialInfo9& other)
{
Domain = other.Domain;
BlendMode = other.BlendMode;
ShadingModel = other.ShadingModel;
UsageFlags = other.UsageFlags;
FeaturesFlags = other.FeaturesFlags;
DecalBlendingMode = other.DecalBlendingMode;
TransparentLightingMode = MaterialTransparentLightingMode::Surface;
PostFxLocation = other.PostFxLocation;
CullMode = other.CullMode;
MaskThreshold = other.MaskThreshold;
OpacityThreshold = other.OpacityThreshold;
TessellationMode = other.TessellationMode;
MaxTessellationFactor = other.MaxTessellationFactor;
}
bool MaterialInfo::operator==(const MaterialInfo& other) const
{
return Domain == other.Domain
@@ -86,6 +119,7 @@ bool MaterialInfo::operator==(const MaterialInfo& other) const
&& UsageFlags == other.UsageFlags
&& FeaturesFlags == other.FeaturesFlags
&& DecalBlendingMode == other.DecalBlendingMode
&& TransparentLightingMode == other.TransparentLightingMode
&& PostFxLocation == other.PostFxLocation
&& CullMode == other.CullMode
&& Math::NearEqual(MaskThreshold, other.MaskThreshold)

View File

@@ -76,7 +76,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
// Set reflection probe data
EnvironmentProbe* probe = nullptr;
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
const Vector3 drawCallOrigin = drawCall.World.GetTranslation() + view.Origin;
const Vector3 drawCallOrigin = drawCall.ObjectPosition + view.Origin;
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
{
const auto p = cache->EnvironmentProbes[i];
@@ -103,7 +103,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
for (int32 i = 0; i < cache->PointLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
{
const auto& light = cache->PointLights[i];
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.ObjectPosition) != ContainmentType::Disjoint)
{
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false);
data.LocalLightsCount++;
@@ -112,7 +112,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
for (int32 i = 0; i < cache->SpotLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
{
const auto& light = cache->SpotLights[i];
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.ObjectPosition) != ContainmentType::Disjoint)
{
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false);
data.LocalLightsCount++;