diff --git a/src/Engine/Core/Effects/Attributes.cs b/src/Engine/Core/Effects/Attributes.cs
index 5f78314cab..551e013ee6 100644
--- a/src/Engine/Core/Effects/Attributes.cs
+++ b/src/Engine/Core/Effects/Attributes.cs
@@ -31,7 +31,7 @@ public FxShardAttribute(ShardCategory category)
}
///
- /// Used to flag which shader type a property belongs to.
+ /// Used to flag which shader type a property belongs to.
/// Supports vertex, pixel and geometry shaders.
///
[Flags]
@@ -102,7 +102,7 @@ public enum ShardCategory : ushort
///
Main = 128,
- ///
+ ///
/// Those are uniforms in the shader code but should not be properties of a because they will be updated by the SceneRenderer.
///
InternalUniform = 256
diff --git a/src/Engine/Core/Effects/SurfaceEffect.cs b/src/Engine/Core/Effects/SurfaceEffect.cs
index f380dc191d..3d8c04fc70 100644
--- a/src/Engine/Core/Effects/SurfaceEffect.cs
+++ b/src/Engine/Core/Effects/SurfaceEffect.cs
@@ -12,6 +12,22 @@ namespace Fusee.Engine.Core.Effects
///
public class SurfaceEffect : SurfaceEffectBase
{
+ ///
+ /// Specify for lighting calculation.
+ ///
+ [FxShader(ShaderCategory.Fragment)]
+ [FxShard(ShardCategory.Uniform)]
+ public ColorMode ColorMode
+ {
+ get { return _colorMode; }
+ set
+ {
+ _colorMode = value;
+ SetFxParam(nameof(ColorMode), _colorMode);
+ }
+ }
+ private ColorMode _colorMode;
+
#region Internal/Global Uniforms (set by the Engine)
///
diff --git a/src/Engine/Core/Effects/SurfaceEffectInput.cs b/src/Engine/Core/Effects/SurfaceEffectInput.cs
index 0bb8a4269b..ab7983f286 100644
--- a/src/Engine/Core/Effects/SurfaceEffectInput.cs
+++ b/src/Engine/Core/Effects/SurfaceEffectInput.cs
@@ -1,4 +1,4 @@
-using Fusee.Engine.Common;
+using Fusee.Engine.Common;
using Fusee.Engine.Core.ShaderShards;
using Fusee.Math.Core;
using System;
diff --git a/src/Engine/Core/MakeEffect.cs b/src/Engine/Core/MakeEffect.cs
index ac47575d9a..3ce7eb4dd2 100644
--- a/src/Engine/Core/MakeEffect.cs
+++ b/src/Engine/Core/MakeEffect.cs
@@ -19,7 +19,7 @@ public static class MakeEffect
///
/// The default , that is used if a has a mesh but no effect.
///
- public static SurfaceEffectBase Default() => FromDiffuseSpecular(new float4(0.5f, 0.5f, 0.5f, 1.0f), 0f, 22, 1.0f);
+ public static SurfaceEffect Default() => FromDiffuseSpecular(new float4(0.5f, 0.5f, 0.5f, 1.0f), 0f, 22, 1.0f);
#region Deferred
@@ -142,11 +142,11 @@ public static ShaderEffect SSAORenderTargetBlurEffect(WritableTexture ssaoRender
///
/// ShaderEffect that performs the lighting calculation according to the textures from the Geometry Pass.
- ///
+ ///
/// The source render target.
/// The light component.
/// The shadow map.
- /// Sets the background color. Could be replaced with a texture or other sky color calculations in the future.
+ /// Sets the background color. Could be replaced with a texture or other sky color calculations in the future.
///
public static ShaderEffect DeferredLightingPassEffect(IRenderTarget srcRenderTarget, Light lc, float4 backgroundColor, IWritableTexture shadowMap = null)
{
@@ -187,7 +187,7 @@ public static ShaderEffect DeferredLightingPassEffect(IRenderTarget srcRenderTar
///
/// [Parallel light only] ShaderEffect that performs the lighting calculation according to the textures from the Geometry Pass. Shadow is calculated with cascaded shadow maps.
- ///
+ ///
/// The source render target.
/// The light component.
/// The cascaded shadow maps.
@@ -580,7 +580,7 @@ private static string CreateDeferredLightingPixelShader(Light lc, bool isCascade
frag.Append(FragProperties.ColorOut());
//Shadow calculation methods
- //--------------------------------------
+ //--------------------------------------
if (isCascaded)
frag.Append(Lighting.ShadowCalculationCascaded());
else if (lc.Type == LightType.Point)
diff --git a/src/Engine/Core/ScenePicker.cs b/src/Engine/Core/ScenePicker.cs
index b5b5ab3103..9aafc9fcc2 100644
--- a/src/Engine/Core/ScenePicker.cs
+++ b/src/Engine/Core/ScenePicker.cs
@@ -61,6 +61,7 @@ public void GetTriangle(out float3 a, out float3 b, out float3 c)
b = Mesh.Vertices[Mesh.Triangles[Triangle + 1]];
c = Mesh.Vertices[Mesh.Triangles[Triangle + 2]];
}
+
///
/// Returns the center of the picked triangle.
///
@@ -148,7 +149,7 @@ public float3 CameraPos
}
}
///
- ///
+ ///
///
public float2 UV
{
@@ -315,8 +316,8 @@ public void RenderCanvasTransform(CanvasTransform ctc)
var frustumCorners = new float4[4];
frustumCorners[0] = invProj * new float4(-1, -1, -1, 1); //nbl
- frustumCorners[1] = invProj * new float4(1, -1, -1, 1); //nbr
- frustumCorners[2] = invProj * new float4(-1, 1, -1, 1); //ntl
+ frustumCorners[1] = invProj * new float4(1, -1, -1, 1); //nbr
+ frustumCorners[2] = invProj * new float4(-1, 1, -1, 1); //ntl
frustumCorners[3] = invProj * new float4(1, 1, -1, 1); //ntr
for (var i = 0; i < frustumCorners.Length; i++)
@@ -499,7 +500,7 @@ public void RenderXFormText(XFormText xfc)
///
/// If a TransformComponent is visited the model matrix of the and is updated.
/// It additionally updates the view matrix of the RenderContext.
- ///
+ ///
/// The TransformComponent.
[VisitMethod]
public void RenderTransform(Transform transform)
@@ -521,6 +522,7 @@ public void PickMesh(Mesh mesh)
mesh.MeshType != PrimitiveType.TriangleStrip)) return;
var mvp = Projection * View * State.Model;
+
for (var i = 0; i < mesh.Triangles.Length; i += 3)
{
// a, b c: current triangle's vertices in clip coordinates
@@ -536,6 +538,7 @@ public void PickMesh(Mesh mesh)
// Point-in-Triangle-Test
if (float2.PointInTriangle(a.xy, b.xy, c.xy, PickPosClip, out var u, out var v))
{
+
var pickPos = float3.Barycentric(a.xyz, b.xyz, c.xyz, u, v);
if (pickPos.z >= -1 && pickPos.z <= 1)
diff --git a/src/Engine/Core/SceneRayCaster.cs b/src/Engine/Core/SceneRayCaster.cs
index c52dc293d6..07391d61df 100644
--- a/src/Engine/Core/SceneRayCaster.cs
+++ b/src/Engine/Core/SceneRayCaster.cs
@@ -227,7 +227,7 @@ public IEnumerable RayPick(RenderContext rc, float2 pickPos)
///
/// If a TransformComponent is visited the model matrix of the and is updated.
- ///
+ ///
/// The TransformComponent.
[VisitMethod]
public void RenderTransform(Transform transform)
diff --git a/src/Engine/Core/ShaderShards/Fragment/FragShards.cs b/src/Engine/Core/ShaderShards/Fragment/FragShards.cs
index 2e47c9b81a..35e064d6ae 100644
--- a/src/Engine/Core/ShaderShards/Fragment/FragShards.cs
+++ b/src/Engine/Core/ShaderShards/Fragment/FragShards.cs
@@ -5,11 +5,33 @@
namespace Fusee.Engine.Core.ShaderShards.Fragment
{
///
- /// Contains pre-defined Shader Shards =
- /// content of the Fragment Shader's method that lets us change values of the "out"-struct that is used for the lighting calculation.
+ /// Contains pre-defined Shader Shards =
+ /// content of the Fragment Shader's method that lets us change values of the "out"-struct that is used for the lighting calculation.
///
public static class FragShards
{
+
+ private static List ColorModeSwitch() => new()
+ {
+ "vec4 resColor;",
+ $"switch({UniformNameDeclarations.ColorMode})",
+ @"{
+ case 0:
+ resColor = IN.Albedo;
+ break;
+ case 1:
+ resColor = vColor;
+ break;
+ case 2:
+ resColor = vColor1;
+ break;
+ case 3:
+ resColor = vColor2;
+ break;
+ }"
+ };
+
+
///
/// Returns a default method body for a given lighting calculation.
/// The surface input class. Needed to receive the shading model and texture setup.
@@ -18,6 +40,8 @@ internal static List SurfOutBody(SurfaceInput surfInput)
{
var res = new List();
+ res.AddRange(ColorModeSwitch());
+
switch (surfInput.ShadingModel)
{
case ShadingModel.Edl:
@@ -56,13 +80,13 @@ internal static List SurfOutBody(SurfaceInput surfInput)
res.Add($"vec4 texCol = texture(IN.AlbedoTex, {VaryingNameDeclarations.TextureCoordinates} * IN.TexTiles);");
res.Add($"texCol = vec4(DecodeSRGB(texCol.rgb), texCol.a);");
res.Add("float linearLuminance = (0.2126 * texCol.r) + (0.7152 * texCol.g) + (0.0722 * texCol.b);");
- res.Add($"vec3 mix = mix(IN.Albedo.rgb * linearLuminance, texCol.xyz, IN.AlbedoMix);");
+ res.Add($"vec3 mix = mix(resColor.rgb * linearLuminance, texCol.xyz, IN.AlbedoMix);");
res.Add($"OUT.albedo = vec4(mix, texCol.a);");
}
else
{
if (surfInput.ShadingModel != ShadingModel.Edl)
- res.Add("OUT.albedo = IN.Albedo;");
+ res.Add("OUT.albedo = resColor;");
else
{
res.Add("if(ColorMode == 0)");
@@ -71,7 +95,7 @@ internal static List SurfOutBody(SurfaceInput surfInput)
res.Add("}");
res.Add("else");
res.Add("{");
- res.Add(" OUT.albedo = IN.Albedo;");
+ res.Add(" OUT.albedo = resColor;");
res.Add("}");
}
}
@@ -89,7 +113,7 @@ internal static List SurfOutBody(SurfaceInput surfInput)
if (surfInput.ShadingModel != ShadingModel.BRDF) return res;
if (surfInput.TextureSetup.HasFlag(TextureSetup.ThicknessMap))
- res.Add($"OUT.{SurfaceOut.Thickness.Item2} = texture(IN.ThicknessMap, { VaryingNameDeclarations.TextureCoordinates}).r;");
+ res.Add($"OUT.{SurfaceOut.Thickness.Item2} = texture(IN.ThicknessMap, {VaryingNameDeclarations.TextureCoordinates}).r;");
else
res.Add($"OUT.{SurfaceOut.Thickness.Item2} = 1.0;");
return res;
@@ -102,6 +126,8 @@ internal static List SurfOutBody(ShadingModel shadingModel, TextureSetup
{
var res = new List();
+ res.AddRange(ColorModeSwitch());
+
switch (shadingModel)
{
case ShadingModel.Unlit:
@@ -136,13 +162,13 @@ internal static List SurfOutBody(ShadingModel shadingModel, TextureSetup
res.Add($"vec4 texCol = texture(IN.AlbedoTex, {VaryingNameDeclarations.TextureCoordinates} * IN.TexTiles);");
res.Add($"texCol = vec4(DecodeSRGB(texCol.rgb), texCol.a);");
res.Add("float linearLuminance = (0.2126 * texCol.r) + (0.7152 * texCol.g) + (0.0722 * texCol.b);");
- res.Add($"vec3 mix = mix(IN.Albedo.rgb * linearLuminance, texCol.xyz, IN.AlbedoMix);");
+ res.Add($"vec3 mix = mix(resColor.rgb * linearLuminance, texCol.xyz, IN.AlbedoMix);");
res.Add($"OUT.albedo = vec4(mix, texCol.a);");
}
else
{
if (shadingModel != ShadingModel.Edl)
- res.Add("OUT.albedo = IN.Albedo;");
+ res.Add("OUT.albedo = resColor;");
else
{
res.Add("if(ColorMode == 0)");
@@ -159,7 +185,7 @@ internal static List SurfOutBody(ShadingModel shadingModel, TextureSetup
res.Add("}");
res.Add("else if(ColorMode == 3)");
res.Add("{");
- res.Add(" OUT.albedo = IN.Albedo;");
+ res.Add(" OUT.albedo = resColor;");
res.Add("}");
}
}
@@ -178,7 +204,7 @@ internal static List SurfOutBody(ShadingModel shadingModel, TextureSetup
if (shadingModel != ShadingModel.BRDF) return res;
if (texSetup.HasFlag(TextureSetup.ThicknessMap))
- res.Add($"OUT.{SurfaceOut.Thickness.Item2} = texture(IN.ThicknessMap, { VaryingNameDeclarations.TextureCoordinates}).r;");
+ res.Add($"OUT.{SurfaceOut.Thickness.Item2} = texture(IN.ThicknessMap, {VaryingNameDeclarations.TextureCoordinates}).r;");
else
res.Add($"OUT.{SurfaceOut.Thickness.Item2} = 1.0;");
return res;
diff --git a/src/Engine/Core/ShaderShards/SurfaceOut.cs b/src/Engine/Core/ShaderShards/SurfaceOut.cs
index 6ef95aa207..daef8bd2bc 100644
--- a/src/Engine/Core/ShaderShards/SurfaceOut.cs
+++ b/src/Engine/Core/ShaderShards/SurfaceOut.cs
@@ -47,6 +47,29 @@ public enum TextureSetup
}
+ ///
+ /// Used to specify which color is used for lighting calculation.
+ /// ///
+ public enum ColorMode
+ {
+ ///
+ /// Use basic Albedo color (from uniform)
+ ///
+ BaseColor = 0,
+ ///
+ /// Use
+ ///
+ VertexColor0,
+ ///
+ /// Use
+ ///
+ VertexColor1,
+ ///
+ /// Use
+ ///
+ VertexColor2
+ }
+
///
/// Used to create the correct Surface Effect for a given lighting calculation.
///
diff --git a/src/Engine/Core/ShaderShards/UniformNameDeclarations.cs b/src/Engine/Core/ShaderShards/UniformNameDeclarations.cs
index 1dc8249940..e2624b3f6e 100644
--- a/src/Engine/Core/ShaderShards/UniformNameDeclarations.cs
+++ b/src/Engine/Core/ShaderShards/UniformNameDeclarations.cs
@@ -452,7 +452,6 @@ public static class UniformNameDeclarations
#endregion
-
///
/// The var name for the uniform ClippingPlanes variable.
///
@@ -480,6 +479,15 @@ public static class UniformNameDeclarations
///
public static int BackgroundColorHash = BackgroundColor.GetHashCode();
+ ///
+ /// The var name for the uniform ColorMode.
+ ///
+ public const string ColorMode = "ColorMode";
+ ///
+ /// Hash code for the parameter.
+ ///
+ public static int ColorModeHash = ColorMode.GetHashCode();
+
///
/// The var name for the uniform ScreenParams (width and height of the window).
///
diff --git a/src/Engine/Core/ShaderShards/Vertex/VertShards.cs b/src/Engine/Core/ShaderShards/Vertex/VertShards.cs
index bf73a80929..27136ae34d 100644
--- a/src/Engine/Core/ShaderShards/Vertex/VertShards.cs
+++ b/src/Engine/Core/ShaderShards/Vertex/VertShards.cs
@@ -5,8 +5,8 @@
namespace Fusee.Engine.Core.ShaderShards.Vertex
{
///
- /// Contains pre-defined Shader Shards.
- /// Those are the content of the Vertex Shader's method that lets us change values of the "out"-struct that is used for the position calculation.
+ /// Contains pre-defined Shader Shards.
+ /// Those are the content of the Vertex Shader's method that lets us change values of the "out"-struct that is used for the position calculation.
///
public static class VertShards
{
diff --git a/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs b/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs
index 1bcba6de90..072b885d48 100644
--- a/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs
+++ b/src/ImGui/Desktop/Fusee.ImGui.Desktop/ImGuiController.cs
@@ -1,4 +1,4 @@
-using Fusee.Base.Core;
+using Fusee.Base.Core;
using Fusee.Engine.Core;
using Fusee.Math.Core;
using ImGuiNET;
diff --git a/src/Xene/Visitor.cs b/src/Xene/Visitor.cs
index 65b247d887..506be045d4 100644
--- a/src/Xene/Visitor.cs
+++ b/src/Xene/Visitor.cs
@@ -6,7 +6,7 @@
namespace Fusee.Xene
{
///
- /// Use this attribute to identify visitor methods. Visitor methods are called during traversal on
+ /// Use this attribute to identify visitor methods. Visitor methods are called during traversal on
/// nodes or components with the specified type.
///
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
@@ -82,13 +82,13 @@ public static VisitNodeMethodOfModule MakeNodeVistorForModule
/// - As building block for enumerators. Visitor methods can yield an enumeration.
/// - As a tool set to implement transformations on scenes. Transformations operate on scenes and alter their structure.
///
- ///
+ ///
/// Visitors derived from this class may implement
/// their own Visit methods for all kinds of scene graph elements. Visitor methods can be defined for scene nodes (although many implementations
/// will most likely NOT have a very big inheritance tree for nodes) as well as for scene components.
/// A Visitor method can be any instance method (not static) taking one parameter either derived from or derived from
- /// . To mark such a method as a Visitor method it needs to be decorated with the
- /// attribute. Visitor methods can have arbitrary names and don't necessarily need to be virtual.
+ /// . To mark such a method as a Visitor method it needs to be decorated with the
+ /// attribute. Visitor methods can have arbitrary names and don't necessarily need to be virtual.
///
public class Visitor where TNode : class, INode where TComponent : class, IComponent
{
@@ -117,7 +117,7 @@ internal class VisitorSet
#region Public Traversal Methods
///
- /// Start traversing a scene graph starting with the given root node. Performs a recursive depth-first
+ /// Start traversing a scene graph starting with the given root node. Performs a recursive depth-first
/// traversal from the specified root.
///
/// The root node where to start the traversal.
@@ -136,7 +136,7 @@ public void Traverse(TNode rootNode)
}
///
- /// Start traversing a list of nodes. Performs a recursive depth-first traversal
+ /// Start traversing a list of nodes. Performs a recursive depth-first traversal
/// over the list starting with the first node in the list.
///
/// The list of nodes to traverse over.
@@ -165,7 +165,7 @@ public void Traverse(IEnumerable children)
}
#endregion
- #region Useful Stuff within Traversal
+ #region Useful Stuff within Traversal
///
/// Method is called when traversal starts to initialize the traversal state. Override this method in derived classes to initialize any state.
@@ -239,7 +239,7 @@ protected virtual void PopState()
///
- /// Enumerator Building Block to be called in derived Visitors acting as enumerators. Use this to
+ /// Enumerator Building Block to be called in derived Visitors acting as enumerators. Use this to
/// initialize the traversing enumeration on a list of (root) nodes.
///
/// The list of nodes.
@@ -262,7 +262,7 @@ protected void EnumInit(IEnumerator nodes)
// ===============================================================================================
// no need to Reset() IEnumerators on start. In Fact, compiler-generated enumerators using yield
// will throw a NotSupportedException."
- // See https://docs.microsoft.com/en-us/dotnet/api/system.collections.ienumerator.reset?view=netcore-3.1:
+ // See https://docs.microsoft.com/en-us/dotnet/api/system.collections.ienumerator.reset?view=netcore-3.1:
// nodes.Reset(); // TODO (MR) -> This is needed for the picking.cs? => CMl??
_curNodeEnumerator = nodes;
@@ -283,13 +283,13 @@ protected bool EnumMoveNext()
// Precondition: We are BEFORE the next node or the next component
if (_curCompEnumerator != null)
{
- // Traverse components
+ // Traverse components
if (!_curCompEnumerator.MoveNext())
{
_curCompEnumerator = null;
CurrentComponent = null;
- // At the end of a Component List: If this node hasn't any children, PopState right now.
+ // At the end of a Component List: If this node hasn't any children, PopState right now.
// Otherwise PopState will be called after traversing the children list (see below).
if (CurrentNode.EnumChildren == null)
PopState();
@@ -399,7 +399,7 @@ protected bool EnumMoveNextNoComponent()
// Traverse nodes
DoVisitNode(CurrentNode);
- // If this node hasn't any children, PopState right now.
+ // If this node hasn't any children, PopState right now.
// Otherwise PopState will be called after traversing the children list (see while statement above).
if (CurrentNode.EnumChildren == null)
PopState();