From fb1994e21d0c6babbf82303aa5c282e1923a765c Mon Sep 17 00:00:00 2001 From: Moritz Roetner Date: Tue, 21 Jun 2022 09:57:58 +0200 Subject: [PATCH 1/2] Enable vertex colors --- src/Engine/Core/Effects/Attributes.cs | 4 +- src/Engine/Core/Effects/SurfaceEffect.cs | 15 ++++++ src/Engine/Core/Effects/SurfaceEffectInput.cs | 2 +- src/Engine/Core/MakeEffect.cs | 10 ++-- src/Engine/Core/ScenePicker.cs | 11 +++-- src/Engine/Core/SceneRayCaster.cs | 2 +- .../Core/ShaderShards/Fragment/FragShards.cs | 46 +++++++++++++++---- src/Engine/Core/ShaderShards/SurfaceOut.cs | 23 ++++++++++ .../ShaderShards/UniformNameDeclarations.cs | 10 +++- .../Core/ShaderShards/Vertex/VertShards.cs | 4 +- .../Fusee.ImGui.Desktop/ImGuiController.cs | 2 +- src/Xene/Visitor.cs | 24 +++++----- 12 files changed, 114 insertions(+), 39 deletions(-) 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..f02e651c9e 100644 --- a/src/Engine/Core/Effects/SurfaceEffect.cs +++ b/src/Engine/Core/Effects/SurfaceEffect.cs @@ -12,6 +12,21 @@ 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..5fa6577dc0 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(); From b261ad5deeeca3f3f5f7181e902fa056001006e1 Mon Sep 17 00:00:00 2001 From: wrestledBearOnce Date: Tue, 21 Jun 2022 08:01:43 +0000 Subject: [PATCH 2/2] Linting --- src/Engine/Core/Effects/SurfaceEffect.cs | 3 ++- src/Engine/Core/ShaderShards/Fragment/FragShards.cs | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Engine/Core/Effects/SurfaceEffect.cs b/src/Engine/Core/Effects/SurfaceEffect.cs index f02e651c9e..3d8c04fc70 100644 --- a/src/Engine/Core/Effects/SurfaceEffect.cs +++ b/src/Engine/Core/Effects/SurfaceEffect.cs @@ -17,7 +17,8 @@ public class SurfaceEffect : SurfaceEffectBase /// [FxShader(ShaderCategory.Fragment)] [FxShard(ShardCategory.Uniform)] - public ColorMode ColorMode { + public ColorMode ColorMode + { get { return _colorMode; } set { diff --git a/src/Engine/Core/ShaderShards/Fragment/FragShards.cs b/src/Engine/Core/ShaderShards/Fragment/FragShards.cs index 5fa6577dc0..35e064d6ae 100644 --- a/src/Engine/Core/ShaderShards/Fragment/FragShards.cs +++ b/src/Engine/Core/ShaderShards/Fragment/FragShards.cs @@ -13,9 +13,9 @@ public static class FragShards private static List ColorModeSwitch() => new() { - "vec4 resColor;", - $"switch({UniformNameDeclarations.ColorMode})", -@"{ + "vec4 resColor;", + $"switch({UniformNameDeclarations.ColorMode})", + @"{ case 0: resColor = IN.Albedo; break;