Nick Kastellanos 4 lat temu
rodzic
commit
084378b50d

+ 7 - 2
Aether.Extras.NET4.XNA.sln

@@ -33,6 +33,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VoxelImporters.NET4.XNA", "
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Tilemap.NET4.XNA", "Tilemap\Aether.Tilemap.NET4.XNA.csproj", "{746551BA-FB64-43B0-8479-0506B930D3E5}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.Lighting.NET4.XNA", "Shaders\Lighting\Aether.Shaders.Lighting.NET4.XNA.csproj", "{F2849C39-6298-4AF1-84F6-C47AC11B2258}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
@@ -95,8 +97,10 @@ Global
 		{746551BA-FB64-43B0-8479-0506B930D3E5}.Debug|x86.Build.0 = Debug|x86
 		{746551BA-FB64-43B0-8479-0506B930D3E5}.Release|x86.ActiveCfg = Release|x86
 		{746551BA-FB64-43B0-8479-0506B930D3E5}.Release|x86.Build.0 = Release|x86
-		
-		
+		{F2849C39-6298-4AF1-84F6-C47AC11B2258}.Debug|x86.ActiveCfg = Debug|x86
+		{F2849C39-6298-4AF1-84F6-C47AC11B2258}.Debug|x86.Build.0 = Debug|x86
+		{F2849C39-6298-4AF1-84F6-C47AC11B2258}.Release|x86.ActiveCfg = Release|x86
+		{F2849C39-6298-4AF1-84F6-C47AC11B2258}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -112,5 +116,6 @@ Global
 		{B82B862D-C728-4A10-8A56-65D688E022C8} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
 		{908EC8FF-B0ED-478A-B486-702E578AF64A} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
 		{AB2B4C7E-0FCA-4CFE-8837-E3E3374249F6} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
+		{F2849C39-6298-4AF1-84F6-C47AC11B2258} = {EFC7A27C-C20B-4BE7-8B3A-2B109991D704}
 	EndGlobalSection
 EndGlobal

+ 7 - 0
Aether.Extras.NET4.sln

@@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VoxelImporters.NET4", "Cont
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Tilemap.NET4", "Tilemap\Aether.Tilemap.NET4.csproj", "{7BD9F460-F3F9-40A0-B298-066EA975C06C}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Shaders.Lighting.NET4", "Shaders\Lighting\Aether.Shaders.Lighting.NET4.csproj", "{5E31EE65-EEE7-400F-A31F-3D0EAF0CC416}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -115,6 +117,10 @@ Global
 		{7BD9F460-F3F9-40A0-B298-066EA975C06C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{7BD9F460-F3F9-40A0-B298-066EA975C06C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{7BD9F460-F3F9-40A0-B298-066EA975C06C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5E31EE65-EEE7-400F-A31F-3D0EAF0CC416}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5E31EE65-EEE7-400F-A31F-3D0EAF0CC416}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5E31EE65-EEE7-400F-A31F-3D0EAF0CC416}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5E31EE65-EEE7-400F-A31F-3D0EAF0CC416}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -132,5 +138,6 @@ Global
 		{6721CD07-0880-4154-85AF-EBE6043EF178} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
 		{C9FA924B-DA91-4641-8B7D-CBC09E5560AE} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{AA15CF95-0AF2-4346-9465-CB6EDBE22ED9} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
+		{5E31EE65-EEE7-400F-A31F-3D0EAF0CC416} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
 	EndGlobalSection
 EndGlobal

+ 7 - 0
Aether.Extras.NETSTANDARD.sln

@@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aether.Shaders.FXAA.NETSTAN
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aether.Shaders.Deferred.NETSTANDARD", "Shaders\Deferred\Aether.Shaders.Deferred.NETSTANDARD.csproj", "{96105100-20DB-4187-9BCA-0A20AC9F1298}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aether.Shaders.Lighting.NETSTANDARD", "Shaders\Lighting\Aether.Shaders.Lighting.NETSTANDARD.csproj", "{146A2F6C-E83F-4A45-B2DF-5CD9C88C187F}"
+EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtlasImporter.NETSTANDARD", "Content.Pipeline\AtlasImporter\AtlasImporter.NETSTANDARD.csproj", "{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aether.Atlas.NETSTANDARD", "Atlas\Aether.Atlas.NETSTANDARD.csproj", "{C7522B5E-B255-4FB6-A17A-9E6D217AEBD2}"
@@ -87,6 +89,10 @@ Global
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{96105100-20DB-4187-9BCA-0A20AC9F1298}.Release|Any CPU.Build.0 = Release|Any CPU
+		{146A2F6C-E83F-4A45-B2DF-5CD9C88C187F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{146A2F6C-E83F-4A45-B2DF-5CD9C88C187F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{146A2F6C-E83F-4A45-B2DF-5CD9C88C187F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{146A2F6C-E83F-4A45-B2DF-5CD9C88C187F}.Release|Any CPU.Build.0 = Release|Any CPU
 		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -127,6 +133,7 @@ Global
 		{9B0F9C6B-3C43-472D-B0C1-91E11A9FDE89} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{FBBDE2BA-F9F3-4041-8584-2C912C235E26} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
 		{96105100-20DB-4187-9BCA-0A20AC9F1298} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
+		{146A2F6C-E83F-4A45-B2DF-5CD9C88C187F} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
 		{E710FBEA-8C75-405D-B6B4-CFC82CB48FB5} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{08296A2E-BECF-4DB9-A518-8A613D07B80E} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}
 		{6721CD07-0880-4154-85AF-EBE6043EF178} = {13D47E11-4A7C-49C8-942E-2543E9C0098A}

+ 62 - 0
Shaders/Lighting/Aether.Shaders.Lighting.NET4.XNA.csproj

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <ProjectGuid>{F2849C39-6298-4AF1-84F6-C47AC11B2258}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>nkast.Aether.Shaders</RootNamespace>
+    <AssemblyName>Aether.Shaders.Lighting</AssemblyName>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <XnaPlatform>Windows</XnaPlatform>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\Artifacts\Debug\Libraries\net4.XNA\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\Artifacts\Release\Libraries\net4.XNA\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DepthMapEffect.cs" />
+    <Compile Include="LightingEffect.cs" />
+    <Compile Include="EffectHelpers.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Shaders\Common.fxh" />
+    <None Include="Shaders\DepthMapEffect.fx" />
+    <None Include="Shaders\LightingEffect.fx" />
+    <None Include="Shaders\Lighting.fxh" />
+    <None Include="Shaders\Macros.fxh" />
+    <None Include="Shaders\Structures.fxh" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Resources\LightingEffect.xna" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.ContentPipelineExtensions.targets" />
+</Project>

+ 59 - 0
Shaders/Lighting/Aether.Shaders.Lighting.NET4.csproj

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{5E31EE65-EEE7-400F-A31F-3D0EAF0CC416}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>nkast.Aether.Shaders</RootNamespace>
+    <AssemblyName>Aether.Shaders.Lighting</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\Artifacts\Debug\Libraries\net4\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS MG</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\Artifacts\Release\Libraries\net4\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DepthMapEffect.cs" />
+    <Compile Include="LightingEffect.cs" />
+    <Compile Include="EffectHelpers.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Shaders\Common.fxh" />
+    <None Include="Shaders\DepthMapEffect.fx" />
+    <None Include="Shaders\LightingEffect.fx" />
+    <None Include="Shaders\Lighting.fxh" />
+    <None Include="Shaders\Macros.fxh" />
+    <None Include="Shaders\Structures.fxh" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Resources\LightingEffect.dx11.fxo.10" />
+    <EmbeddedResource Include="Resources\LightingEffect.ogl.fxo.10" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.Portable.9000" Version="3.8.9101">
+      <PrivateAssets>all</PrivateAssets>
+      <ExcludeAssets>runtime</ExcludeAssets>
+    </PackageReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 45 - 0
Shaders/Lighting/Aether.Shaders.Lighting.NETSTANDARD.csproj

@@ -0,0 +1,45 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <EnableDefaultItems>false</EnableDefaultItems>
+    <TargetFramework>netstandard2.0</TargetFramework>
+    <OutputType>Library</OutputType>
+    <RootNamespace>nkast.Aether.Shaders</RootNamespace>
+    <AssemblyName>Aether.Shaders.Lighting</AssemblyName>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+	<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
+    <OutputPath>..\..\Artifacts\$(Configuration)\Libraries\netstandard2.0\</OutputPath>
+    <BaseIntermediateOutputPath>obj\netstandard2.0\</BaseIntermediateOutputPath>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DefineConstants>TRACE;DEBUG;WINDOWS MG</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="DepthMapEffect.cs" />
+    <Compile Include="LightingEffect.cs" />
+    <Compile Include="EffectHelpers.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Shaders\Common.fxh" />
+    <None Include="Shaders\DepthMapEffect.fx" />
+    <None Include="Shaders\LightingEffect.fx" />
+    <None Include="Shaders\Lighting.fxh" />
+    <None Include="Shaders\Macros.fxh" />
+    <None Include="Shaders\Structures.fxh" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Resources\LightingEffect.dx11.fxo.10" />
+    <EmbeddedResource Include="Resources\LightingEffect.ogl.fxo.10" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.Portable.9000" Version="3.8.9101">
+      <PrivateAssets>all</PrivateAssets>
+      <ExcludeAssets>runtime</ExcludeAssets>
+    </PackageReference>
+  </ItemGroup>
+</Project>

+ 143 - 0
Shaders/Lighting/DepthMapEffect.cs

@@ -0,0 +1,143 @@
+#region License
+//   Copyright 2020-2021 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.Reflection;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace tainicom.Aether.Shaders
+{
+    public class DepthMapEffect : Effect, IEffectMatrices
+    {
+        #region Effect Parameters
+            
+        // IEffectMatrices
+        EffectParameter projectionParam;
+        EffectParameter viewParam;
+        EffectParameter worldParam;
+
+        #endregion
+
+        #region Fields
+
+
+
+        static readonly String ResourceName = "tainicom.Aether.Shaders.Resources.DepthMapEffect";
+#if XNA
+        static readonly String PlatformName = ".xna";
+#elif ((MG && WINDOWS) || W8_1 || W10)
+        static readonly String PlatformName = ".dx11.mgfxo";
+#endif
+
+        private static string GetResourceName(GraphicsDevice graphicsDevice)
+        {
+            string profileName = (graphicsDevice.GraphicsProfile == GraphicsProfile.Reach) ? ".Reach" : ".HiDef";
+
+
+            // Detect MG version     
+            var version = "";
+#if !XNA
+            version = ".9";
+            var mgVersion = GetAssembly(typeof(Effect)).GetName().Version;
+            if (mgVersion.Major == 3)
+            {
+                if (mgVersion.Minor == 6)
+                    version = ".8";
+                if (mgVersion.Minor == 7)
+                    version = ".8";
+                if (mgVersion.Minor == 8)
+                    version = ".9";
+            }
+#endif
+
+            return ResourceName + profileName + PlatformName + version;
+        }
+
+        internal static byte[] LoadEffectResource(string name)
+        {
+            using (var stream = GetAssembly(typeof(LightingEffect)).GetManifestResourceStream(name))
+            {
+                var bytecode = new byte[stream.Length];
+                stream.Read(bytecode, 0, (int)stream.Length);
+                return bytecode;
+        }
+        }
+
+        private static Assembly GetAssembly(Type type)
+        {            
+#if W8_1 || W10
+            return type.GetTypeInfo().Assembly;
+#else
+            return type.Assembly;
+#endif
+        }
+
+
+        #endregion
+        
+        #region Public Properties
+
+        public Matrix Projection
+        {
+            get { return projectionParam.GetValueMatrix(); }
+            set { projectionParam.SetValue(value); }
+        }
+
+        public Matrix View
+        {
+            get { return viewParam.GetValueMatrix(); }
+            set { viewParam.SetValue(value); }
+        }
+
+        public Matrix World
+        {
+            get { return worldParam.GetValueMatrix(); }
+            set { worldParam.SetValue(value); }
+        }
+
+        #endregion
+
+        #region Methods
+
+         public DepthMapEffect(GraphicsDevice graphicsDevice)
+            : base(graphicsDevice, LoadEffectResource(GetResourceName(graphicsDevice)))
+        {    
+            CacheEffectParameters(null);
+        }
+
+        protected DepthMapEffect(DepthMapEffect cloneSource)
+            : base(cloneSource)
+        {
+            CacheEffectParameters(cloneSource);
+        }
+        
+        public override Effect Clone()
+        {
+            return new DepthMapEffect(this);
+        }
+
+        void CacheEffectParameters(DepthMapEffect cloneSource)
+        {
+            // IEffectMatrices
+            projectionParam = Parameters["Projection"];
+            viewParam = Parameters["View"];
+            worldParam = Parameters["World"];
+        }
+        
+        #endregion
+    }
+}

+ 242 - 0
Shaders/Lighting/EffectHelpers.cs

@@ -0,0 +1,242 @@
+//#region File Description
+//-----------------------------------------------------------------------------
+// EffectHelpers.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+//#endregion
+
+//#region Using Statements
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+//#endregion
+
+namespace tainicom.Aether.Shaders
+{
+    /// <summary>
+    /// Track which effect parameters need to be recomputed during the next OnApply.
+    /// </summary>
+    [Flags]
+    internal enum EffectDirtyFlags
+    {
+        WorldViewProj   = 1,
+        World           = 2,
+        EyePosition     = 4,
+        MaterialColor   = 8,
+        Fog             = 16,
+        FogEnable       = 32,
+        AlphaTest       = 64,
+        All             = -1
+    }
+
+
+    /// <summary>
+    /// Helper code shared between the various built-in effects.
+    /// </summary>
+    internal static class EffectHelpers
+    {
+        /// <summary>
+        /// Sets up the standard key/fill/back lighting rig.
+        /// </summary>
+        internal static Vector3 EnableDefaultLighting(DirectionalLight light0, DirectionalLight light1, DirectionalLight light2)
+        {
+            // Key light.
+            light0.Direction = new Vector3(-0.5265408f, -0.5735765f, -0.6275069f);
+            light0.DiffuseColor = new Vector3(1, 0.9607844f, 0.8078432f);
+            light0.SpecularColor = new Vector3(1, 0.9607844f, 0.8078432f);
+            light0.Enabled = true;
+
+            // Fill light.
+            light1.Direction = new Vector3(0.7198464f, 0.3420201f, 0.6040227f);
+            light1.DiffuseColor = new Vector3(0.9647059f, 0.7607844f, 0.4078432f);
+            light1.SpecularColor = Vector3.Zero;
+            light1.Enabled = true;
+
+            // Back light.
+            light2.Direction = new Vector3(0.4545195f, -0.7660444f, 0.4545195f);
+            light2.DiffuseColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
+            light2.SpecularColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
+            light2.Enabled = true;
+
+            // Ambient light.
+            return new Vector3(0.05333332f, 0.09882354f, 0.1819608f);
+        }
+
+
+        /// <summary>
+        /// Lazily recomputes the world+view+projection matrix and
+        /// fog vector based on the current effect parameter settings.
+        /// </summary>
+        internal static EffectDirtyFlags SetWorldViewProjAndFog(EffectDirtyFlags dirtyFlags,
+                                                                ref Matrix world, ref Matrix view, ref Matrix projection, ref Matrix worldView,
+                                                                bool fogEnabled, float fogStart, float fogEnd,
+                                                                EffectParameter worldViewProjParam, EffectParameter fogVectorParam)
+        {
+            // Recompute the world+view+projection matrix?
+            if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
+            {
+                Matrix worldViewProj;
+                
+                Matrix.Multiply(ref world, ref view, out worldView);
+                Matrix.Multiply(ref worldView, ref projection, out worldViewProj);
+                
+                worldViewProjParam.SetValue(worldViewProj);
+                
+                dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
+            }
+
+            if (fogEnabled)
+            {
+                // Recompute the fog vector?
+                if ((dirtyFlags & (EffectDirtyFlags.Fog | EffectDirtyFlags.FogEnable)) != 0)
+                {
+                    SetFogVector(ref worldView, fogStart, fogEnd, fogVectorParam);
+
+                    dirtyFlags &= ~(EffectDirtyFlags.Fog | EffectDirtyFlags.FogEnable);
+                }
+            }
+            else
+            {
+                // When fog is disabled, make sure the fog vector is reset to zero.
+                if ((dirtyFlags & EffectDirtyFlags.FogEnable) != 0)
+                {
+                    fogVectorParam.SetValue(Vector4.Zero);
+
+                    dirtyFlags &= ~EffectDirtyFlags.FogEnable;
+                }
+            }
+
+            return dirtyFlags;
+        }
+
+
+        /// <summary>
+        /// Sets a vector which can be dotted with the object space vertex position to compute fog amount.
+        /// </summary>
+        static void SetFogVector(ref Matrix worldView, float fogStart, float fogEnd, EffectParameter fogVectorParam)
+        {
+            if (fogStart == fogEnd)
+            {
+                // Degenerate case: force everything to 100% fogged if start and end are the same.
+                fogVectorParam.SetValue(new Vector4(0, 0, 0, 1));
+            }
+            else
+            {
+                // We want to transform vertex positions into view space, take the resulting
+                // Z value, then scale and offset according to the fog start/end distances.
+                // Because we only care about the Z component, the shader can do all this
+                // with a single dot product, using only the Z row of the world+view matrix.
+                
+                float scale = 1f / (fogStart - fogEnd);
+
+                Vector4 fogVector = new Vector4();
+
+                fogVector.X = worldView.M13 * scale;
+                fogVector.Y = worldView.M23 * scale;
+                fogVector.Z = worldView.M33 * scale;
+                fogVector.W = (worldView.M43 + fogStart) * scale;
+
+                fogVectorParam.SetValue(fogVector);
+            }
+        }
+
+
+        /// <summary>
+        /// Lazily recomputes the world inverse transpose matrix and
+        /// eye position based on the current effect parameter settings.
+        /// </summary>
+        internal static EffectDirtyFlags SetLightingMatrices(EffectDirtyFlags dirtyFlags, ref Matrix world, ref Matrix view,
+                                                             EffectParameter worldParam, EffectParameter worldInverseTransposeParam, EffectParameter eyePositionParam)
+        {
+            // Set the world and world inverse transpose matrices.
+            if ((dirtyFlags & EffectDirtyFlags.World) != 0)
+            {
+                Matrix worldTranspose;
+                Matrix worldInverseTranspose;
+                
+                Matrix.Invert(ref world, out worldTranspose);
+                Matrix.Transpose(ref worldTranspose, out worldInverseTranspose);
+                
+                worldParam.SetValue(world);
+                worldInverseTransposeParam.SetValue(worldInverseTranspose);
+                
+                dirtyFlags &= ~EffectDirtyFlags.World;
+            }
+
+            // Set the eye position.
+            if ((dirtyFlags & EffectDirtyFlags.EyePosition) != 0)
+            {
+                Matrix viewInverse;
+                
+                Matrix.Invert(ref view, out viewInverse);
+
+                eyePositionParam.SetValue(viewInverse.Translation);
+
+                dirtyFlags &= ~EffectDirtyFlags.EyePosition;
+            }
+
+            return dirtyFlags;
+        }
+
+
+        /// <summary>
+        /// Sets the diffuse/emissive/alpha material color parameters.
+        /// </summary>
+        internal static void SetMaterialColor(bool lightingEnabled, float alpha,
+                                              ref Vector3 diffuseColor, ref Vector3 emissiveColor, ref Vector3 ambientLightColor,
+                                              EffectParameter diffuseColorParam, EffectParameter emissiveColorParam)
+        {
+            // Desired lighting model:
+            //
+            //     ((AmbientLightColor + sum(diffuse directional light)) * DiffuseColor) + EmissiveColor
+            //
+            // When lighting is disabled, ambient and directional lights are ignored, leaving:
+            //
+            //     DiffuseColor + EmissiveColor
+            //
+            // For the lighting disabled case, we can save one shader instruction by precomputing
+            // diffuse+emissive on the CPU, after which the shader can use DiffuseColor directly,
+            // ignoring its emissive parameter.
+            //
+            // When lighting is enabled, we can merge the ambient and emissive settings. If we
+            // set our emissive parameter to emissive+(ambient*diffuse), the shader no longer
+            // needs to bother adding the ambient contribution, simplifying its computation to:
+            //
+            //     (sum(diffuse directional light) * DiffuseColor) + EmissiveColor
+            //
+            // For futher optimization goodness, we merge material alpha with the diffuse
+            // color parameter, and premultiply all color values by this alpha.
+            
+            if (lightingEnabled)
+            {
+                Vector4 diffuse = new Vector4();
+                Vector3 emissive = new Vector3();
+                
+                diffuse.X = diffuseColor.X * alpha;
+                diffuse.Y = diffuseColor.Y * alpha;
+                diffuse.Z = diffuseColor.Z * alpha;
+                diffuse.W = alpha;
+
+                emissive.X = (emissiveColor.X + ambientLightColor.X * diffuseColor.X) * alpha;
+                emissive.Y = (emissiveColor.Y + ambientLightColor.Y * diffuseColor.Y) * alpha;
+                emissive.Z = (emissiveColor.Z + ambientLightColor.Z * diffuseColor.Z) * alpha;
+
+                diffuseColorParam.SetValue(diffuse);
+                emissiveColorParam.SetValue(emissive);
+            }
+            else
+            {
+                Vector4 diffuse = new Vector4();
+                
+                diffuse.X = (diffuseColor.X + emissiveColor.X) * alpha;
+                diffuse.Y = (diffuseColor.Y + emissiveColor.Y) * alpha;
+                diffuse.Z = (diffuseColor.Z + emissiveColor.Z) * alpha;
+                diffuse.W = alpha;
+
+                diffuseColorParam.SetValue(diffuse);
+            }
+        }
+    }
+}

+ 482 - 0
Shaders/Lighting/LightingEffect.cs

@@ -0,0 +1,482 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// BasicEffect.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+using System;
+using System.Reflection;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace tainicom.Aether.Shaders
+{
+    public class LightingEffect : Effect, IEffectMatrices, IEffectLights, IEffectFog
+    {
+        #region Effect Parameters
+
+        EffectParameter textureParam;
+        EffectParameter diffuseColorParam;
+        EffectParameter emissiveColorParam;
+        EffectParameter specularColorParam;
+        EffectParameter specularPowerParam;
+        EffectParameter eyePositionParam;
+        EffectParameter fogColorParam;
+        EffectParameter fogVectorParam;
+        EffectParameter worldParam;
+        EffectParameter worldInverseTransposeParam;
+        EffectParameter worldViewProjParam;
+
+        #endregion
+
+        #region Fields
+
+        bool lightingEnabled;
+        bool preferPerPixelLighting;
+        bool oneLight;
+        bool fogEnabled;
+        bool textureEnabled;
+        bool vertexColorEnabled;
+
+        Matrix world = Matrix.Identity;
+        Matrix view = Matrix.Identity;
+        Matrix projection = Matrix.Identity;
+
+        Matrix worldView;
+
+        Vector3 diffuseColor = Vector3.One;
+        Vector3 emissiveColor = Vector3.Zero;
+        Vector3 ambientLightColor = Vector3.Zero;
+
+        float alpha = 1;
+
+        DirectionalLight light0;
+        DirectionalLight light1;
+        DirectionalLight light2;
+
+        float fogStart = 0;
+        float fogEnd = 1;
+
+        EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
+
+
+        static readonly String ResourceName = "tainicom.Aether.Shaders.Resources.LightingEffect";
+#if XNA
+        static readonly String PlatformName = ".xna";
+#elif ((MG && WINDOWS) || W8_1 || W10)
+        static readonly String PlatformName = ".dx11.mgfxo";
+#endif
+
+        private static string GetResourceName(GraphicsDevice graphicsDevice)
+        {
+            string profileName = (graphicsDevice.GraphicsProfile == GraphicsProfile.Reach) ? ".Reach" : ".HiDef";
+
+
+            // Detect MG version
+            var version = "";
+#if !XNA
+            version = ".9";
+            var mgVersion = GetAssembly(typeof(Effect)).GetName().Version;
+            if (mgVersion.Major == 3)
+            {                
+                if (mgVersion.Minor == 6)
+                    version = ".8";
+                if (mgVersion.Minor == 7)
+                    version = ".8";
+                if (mgVersion.Minor == 8)
+                    version = ".9";
+            }
+#endif
+
+            return ResourceName + profileName + PlatformName + version;
+        }
+
+        internal static byte[] LoadEffectResource(string name)
+        {
+            using (var stream = GetAssembly(typeof(LightingEffect)).GetManifestResourceStream(name))
+            {
+                var bytecode = new byte[stream.Length];
+                stream.Read(bytecode, 0, (int)stream.Length);
+                return bytecode;
+            }
+        }
+
+        private static Assembly GetAssembly(Type type)
+        {
+#if W8_1 || W10
+            return type.GetTypeInfo().Assembly;
+#else
+            return type.Assembly;
+#endif
+        }
+
+
+        #endregion
+
+        #region Public Properties
+
+        /// <summary>
+        /// Gets or sets the world matrix.
+        /// </summary>
+        public Matrix World
+        {
+            get { return world; }
+            set
+            {
+                world = value;
+                dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the view matrix.
+        /// </summary>
+        public Matrix View
+        {
+            get { return view; }
+            set
+            {
+                view = value;
+                dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition | EffectDirtyFlags.Fog;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the projection matrix.
+        /// </summary>
+        public Matrix Projection
+        {
+            get { return projection; }
+            set
+            {
+                projection = value;
+                dirtyFlags |= EffectDirtyFlags.WorldViewProj;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the material diffuse color (range 0 to 1).
+        /// </summary>
+        public Vector3 DiffuseColor
+        {
+            get { return diffuseColor; }
+            set
+            {
+                diffuseColor = value;
+                dirtyFlags |= EffectDirtyFlags.MaterialColor;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the material emissive color (range 0 to 1).
+        /// </summary>
+        public Vector3 EmissiveColor
+        {
+            get { return emissiveColor; }
+            set
+            {
+                emissiveColor = value;
+                dirtyFlags |= EffectDirtyFlags.MaterialColor;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the material specular color (range 0 to 1).
+        /// </summary>
+        public Vector3 SpecularColor
+        {
+            get { return specularColorParam.GetValueVector3(); }
+            set { specularColorParam.SetValue(value); }
+        }
+
+        /// <summary>
+        /// Gets or sets the material specular power.
+        /// </summary>
+        public float SpecularPower
+        {
+            get { return specularPowerParam.GetValueSingle(); }
+            set { specularPowerParam.SetValue(value); }
+        }
+
+        /// <summary>
+        /// Gets or sets the material alpha.
+        /// </summary>
+        public float Alpha
+        {
+            get { return alpha; }
+            set
+            {
+                alpha = value;
+                dirtyFlags |= EffectDirtyFlags.MaterialColor;
+            }
+        }
+
+        public bool LightingEnabled
+        {
+            get { return lightingEnabled; }
+            set
+            {
+                if (lightingEnabled != value)
+                {
+                    lightingEnabled = value;
+                    dirtyFlags |= EffectDirtyFlags.MaterialColor;
+                    UpdateCurrentTechnique();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the per-pixel lighting prefer flag.
+        /// </summary>
+        public bool PreferPerPixelLighting
+        {
+            get { return preferPerPixelLighting; }
+            set
+            {
+                if (preferPerPixelLighting != value)
+                {
+                    preferPerPixelLighting = value;
+                    UpdateCurrentTechnique();
+                }
+            }
+        }
+
+        public Vector3 AmbientLightColor
+        {
+            get { return ambientLightColor; }
+            set
+            {
+                ambientLightColor = value;
+                dirtyFlags |= EffectDirtyFlags.MaterialColor;
+            }
+        }
+        
+        public DirectionalLight DirectionalLight0 { get { return light0; } }
+        
+        public DirectionalLight DirectionalLight1 { get { return light1; } }
+        
+        public DirectionalLight DirectionalLight2 { get { return light2; } }
+        
+        public bool FogEnabled
+        {
+            get { return fogEnabled; }            
+            set
+            {
+                if (fogEnabled != value)
+                {
+                    fogEnabled = value;
+                    dirtyFlags |= EffectDirtyFlags.FogEnable;
+                    UpdateCurrentTechnique();
+                }
+            }
+        }
+        
+        /// <inheritdoc/>
+        public float FogStart
+        {
+            get { return fogStart; }            
+            set
+            {
+                fogStart = value;
+                dirtyFlags |= EffectDirtyFlags.Fog;
+            }
+        }
+
+        public float FogEnd
+        {
+            get { return fogEnd; }            
+            set
+            {
+                fogEnd = value;
+                dirtyFlags |= EffectDirtyFlags.Fog;
+            }
+        }
+
+        public Vector3 FogColor
+        {
+            get { return fogColorParam.GetValueVector3(); }
+            set { fogColorParam.SetValue(value); }
+        }
+
+        /// <summary>
+        /// Gets or sets whether texturing is enabled.
+        /// </summary>
+        public bool TextureEnabled
+        {
+            get { return textureEnabled; }            
+            set
+            {
+                if (textureEnabled != value)
+                {
+                    textureEnabled = value;
+                    UpdateCurrentTechnique();
+                }
+            }
+        }
+
+        public Texture2D Texture
+        {
+            get { return textureParam.GetValueTexture2D(); }
+            set { textureParam.SetValue(value); }
+        }
+
+        /// <summary>
+        /// Gets or sets whether vertex color is enabled.
+        /// </summary>
+        public bool VertexColorEnabled
+        {
+            get { return vertexColorEnabled; }
+            set
+            {
+                if (vertexColorEnabled != value)
+                {
+                    vertexColorEnabled = value;
+                    UpdateCurrentTechnique();
+                }
+            }
+        }
+
+        #endregion
+
+        #region Methods
+
+        public LightingEffect(GraphicsDevice graphicsDevice)
+            : base(graphicsDevice, LoadEffectResource(GetResourceName(graphicsDevice)))
+        {
+            CacheEffectParameters(null);
+
+            DirectionalLight0.Enabled = true;
+            SpecularColor = Vector3.One;
+            SpecularPower = 16;
+        }
+
+        protected LightingEffect(LightingEffect cloneSource)
+            : base(cloneSource)
+        {
+            CacheEffectParameters(cloneSource);
+
+            lightingEnabled = cloneSource.lightingEnabled;
+            preferPerPixelLighting = cloneSource.preferPerPixelLighting;
+            fogEnabled = cloneSource.fogEnabled;            
+            textureEnabled = cloneSource.textureEnabled;
+            vertexColorEnabled = cloneSource.vertexColorEnabled;
+
+            world = cloneSource.world;
+            view = cloneSource.view;
+            projection = cloneSource.projection;
+
+            diffuseColor = cloneSource.diffuseColor;
+            emissiveColor = cloneSource.emissiveColor;
+            ambientLightColor = cloneSource.ambientLightColor;
+
+            alpha = cloneSource.alpha;
+
+            fogStart = cloneSource.fogStart;
+            fogEnd = cloneSource.fogEnd;
+        }
+
+        public override Effect Clone()
+        {
+            return new LightingEffect(this);
+        }
+
+
+        public void EnableDefaultLighting()
+        {
+            LightingEnabled = true;
+
+            AmbientLightColor = EffectHelpers.EnableDefaultLighting(light0, light1, light2);
+        }
+
+        void CacheEffectParameters(LightingEffect cloneSource)
+        {
+            textureParam                = Parameters["Texture"];
+            diffuseColorParam           = Parameters["DiffuseColor"];
+            emissiveColorParam          = Parameters["EmissiveColor"];
+            specularColorParam          = Parameters["SpecularColor"];
+            specularPowerParam          = Parameters["SpecularPower"];
+            eyePositionParam            = Parameters["EyePosition"];
+            fogColorParam               = Parameters["FogColor"];
+            fogVectorParam              = Parameters["FogVector"];
+            worldParam                  = Parameters["World"];
+            worldInverseTransposeParam  = Parameters["WorldInverseTranspose"];
+            worldViewProjParam          = Parameters["WorldViewProj"];
+
+            light0 = new DirectionalLight(Parameters["DirLight0Direction"],
+                                          Parameters["DirLight0DiffuseColor"],
+                                          Parameters["DirLight0SpecularColor"],
+                                          (cloneSource != null) ? cloneSource.light0 : null);
+
+            light1 = new DirectionalLight(Parameters["DirLight1Direction"],
+                                          Parameters["DirLight1DiffuseColor"],
+                                          Parameters["DirLight1SpecularColor"],
+                                          (cloneSource != null) ? cloneSource.light1 : null);
+
+            light2 = new DirectionalLight(Parameters["DirLight2Direction"],
+                                          Parameters["DirLight2DiffuseColor"],
+                                          Parameters["DirLight2SpecularColor"],
+                                          (cloneSource != null) ? cloneSource.light2 : null);
+
+            //light1.EnabledChanged += Light_EnabledChanged;
+            //light2.EnabledChanged += Light_EnabledChanged;
+        }
+
+        private void Light_EnabledChanged(object sender, EventArgs e)
+        {
+            oneLight = !light1.Enabled && !light2.Enabled;
+            UpdateCurrentTechnique();
+        }
+
+        protected override void OnApply()
+        {
+            // Recompute the world+view+projection matrix or fog vector?
+            dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);
+            
+            // Recompute the diffuse/emissive/alpha material color parameters?
+            if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0)
+            {
+                EffectHelpers.SetMaterialColor(lightingEnabled, alpha, ref diffuseColor, ref emissiveColor, ref ambientLightColor, diffuseColorParam, emissiveColorParam);
+
+                dirtyFlags &= ~EffectDirtyFlags.MaterialColor;
+            }
+
+            if (lightingEnabled)
+            {
+                // Recompute the world inverse transpose and eye position?
+                dirtyFlags = EffectHelpers.SetLightingMatrices(dirtyFlags, ref world, ref view, worldParam, worldInverseTransposeParam, eyePositionParam);                              
+            }
+        }
+
+        private void UpdateCurrentTechnique()
+        {
+            int shaderIndex = 0;
+
+            if (!fogEnabled)
+                shaderIndex += 1;
+
+            if (vertexColorEnabled)
+                shaderIndex += 2;
+
+            if (textureEnabled)
+                shaderIndex += 4;
+
+            if (lightingEnabled)
+            {
+                if (preferPerPixelLighting)
+                    shaderIndex += 24;
+                else if (oneLight)
+                    shaderIndex += 16;
+                else
+                    shaderIndex += 8;
+            }
+
+            CurrentTechnique = Techniques[shaderIndex];
+        }
+
+
+        #endregion
+    }
+}

+ 37 - 0
Shaders/Lighting/Properties/AssemblyInfo.cs

@@ -0,0 +1,37 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Aether.Shaders.Lighting")]
+[assembly: AssemblyProduct("Aether.Shaders.Lighting")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright © Kastellanos Nikolaos 2021-2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type. Only Windows
+// assemblies support COM.
+[assembly: ComVisible(false)]
+
+// On Windows, the following GUID is for the ID of the typelib if this
+// project is exposed to COM. On other platforms, it unique identifies the
+// title storage container when deploying this assembly to the device.
+[assembly: Guid("8CFF8662-F7BA-462E-B986-911FF1B86914")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
+

BIN
Shaders/Lighting/Resources/LightingEffect.dx11.fxo.10


BIN
Shaders/Lighting/Resources/LightingEffect.ogl.fxo.10


BIN
Shaders/Lighting/Resources/LightingEffect.xna


+ 25 - 0
Shaders/Lighting/Shaders/BuildShaders.bat

@@ -0,0 +1,25 @@
+@echo off
+setlocal
+
+cd %~dp0
+
+SET MGFX="C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\2mgfx.exe"
+SET XNAFX="..\..\Tools\CompileEffect\CompileEffect.exe"
+
+@echo Build dx11
+@for /f %%f IN ('dir /b *.fx') do (
+    call %MGFX% %%~nf.fx ..\Resources\%%~nf.dx11.fxo /Platform:Windows
+)
+
+@echo Build ogl
+@for /f %%f IN ('dir /b *.fx') do (
+    call %MGFX% %%~nf.fx ..\Resources\%%~nf.ogl.fxo /Platform:DesktopGL
+)
+
+@echo Build dx9/xna Reach
+@for /f %%f IN ('dir /b *.fx') do (
+    call %XNAFX% Windows Reach %%~nf.fx ..\Resources\%%~nf.xna
+)
+
+endlocal
+@pause

+ 58 - 0
Shaders/Lighting/Shaders/Common.fxh

@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+// Common.fxh
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+
+float ComputeFogFactor(float4 position)
+{
+    return saturate(dot(position, FogVector));
+}
+
+
+void ApplyFog(inout float4 color, float fogFactor)
+{
+    color.rgb = lerp(color.rgb, FogColor * color.a, fogFactor);
+}
+
+
+void AddSpecular(inout float4 color, float3 specular)
+{
+    color.rgb += specular * color.a;
+}
+
+
+struct CommonVSOutput
+{
+    float4 Pos_ps;
+    float4 Diffuse;
+    float3 Specular;
+    float  FogFactor;
+};
+
+
+CommonVSOutput ComputeCommonVSOutput(float4 position)
+{
+    CommonVSOutput vout;
+    
+    vout.Pos_ps = mul(position, WorldViewProj);
+    vout.Diffuse = DiffuseColor;
+    vout.Specular = 0;
+    vout.FogFactor = ComputeFogFactor(position);
+    
+    return vout;
+}
+
+
+#define SetCommonVSOutputParams \
+    vout.PositionPS = cout.Pos_ps; \
+    vout.Diffuse = cout.Diffuse; \
+    vout.Specular = float4(cout.Specular, cout.FogFactor);
+
+
+#define SetCommonVSOutputParamsNoFog \
+    vout.PositionPS = cout.Pos_ps; \
+    vout.Diffuse = cout.Diffuse;
+

+ 38 - 0
Shaders/Lighting/Shaders/DepthMapEffect.fx

@@ -0,0 +1,38 @@
+#include "Macros.fxh"
+
+float4x4 World;
+float4x4 View;
+float4x4 Projection;
+
+struct VertexShaderInput
+{
+    float4 Position : POSITION0;
+};
+
+struct VertexShaderOutput
+{
+    float2 Depth : TEXCOORD0;
+};
+
+VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
+{
+    VertexShaderOutput output;
+    
+    output.Depth.xy = input.Position.zw;
+
+    return output;
+}
+struct PixelShaderOutput
+{
+    half4 Depth : COLOR0;
+};
+
+PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
+{
+    PixelShaderOutput output;
+
+    output.Depth = input.Depth.x / input.Depth.y;
+    return output;
+}
+
+TECHNIQUE( Standard, VertexShaderFunction, PixelShaderFunction );

+ 94 - 0
Shaders/Lighting/Shaders/Lighting.fxh

@@ -0,0 +1,94 @@
+//-----------------------------------------------------------------------------
+// Lighting.fxh
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+
+struct ColorPair
+{
+    float3 Diffuse;
+    float3 Specular;
+};
+
+
+ColorPair ComputeLights(float3 eyeVector, float3 worldNormal, uniform int numLights)
+{
+    float3x3 lightDirections = 0;
+    float3x3 lightDiffuse = 0;
+    float3x3 lightSpecular = 0;
+    float3x3 halfVectors = 0;
+    
+    [unroll]
+    for (int i = 0; i < numLights; i++)
+    {
+        lightDirections[i] = float3x3(DirLight0Direction,     DirLight1Direction,     DirLight2Direction)    [i];
+        lightDiffuse[i]    = float3x3(DirLight0DiffuseColor,  DirLight1DiffuseColor,  DirLight2DiffuseColor) [i];
+        lightSpecular[i]   = float3x3(DirLight0SpecularColor, DirLight1SpecularColor, DirLight2SpecularColor)[i];
+        
+        halfVectors[i] = normalize(eyeVector - lightDirections[i]);
+    }
+
+    float3 dotL = mul(-lightDirections, worldNormal);
+    float3 dotH = mul(halfVectors, worldNormal);
+    
+    float3 zeroL = step(float3(0,0,0), dotL);
+
+    float3 diffuse  = zeroL * dotL;
+    float3 specular = pow(max(dotH, 0) * zeroL, SpecularPower);
+
+    ColorPair result;
+    
+    result.Diffuse  = mul(diffuse,  lightDiffuse)  * DiffuseColor.rgb + EmissiveColor;
+    result.Specular = mul(specular, lightSpecular) * SpecularColor;
+
+    return result;
+}
+
+
+CommonVSOutput ComputeCommonVSOutputWithLighting(float4 position, float3 normal, uniform int numLights)
+{
+    CommonVSOutput vout;
+    
+    float4 pos_ws = mul(position, World);
+    float3 eyeVector = normalize(EyePosition - pos_ws.xyz);
+    float3 worldNormal = normalize(mul(normal, WorldInverseTranspose));
+
+    ColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights);
+    
+    vout.Pos_ps = mul(position, WorldViewProj);
+    vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a);
+    vout.Specular = lightResult.Specular;
+    vout.FogFactor = ComputeFogFactor(position);
+    
+    return vout;
+}
+
+
+struct CommonVSOutputPixelLighting
+{
+    float4 Pos_ps;
+    float3 Pos_ws;
+    float3 Normal_ws;
+    float  FogFactor;
+};
+
+
+CommonVSOutputPixelLighting ComputeCommonVSOutputPixelLighting(float4 position, float3 normal)
+{
+    CommonVSOutputPixelLighting vout;
+    
+    vout.Pos_ps = mul(position, WorldViewProj);
+    vout.Pos_ws = mul(position, World).xyz;
+    vout.Normal_ws = normalize(mul(normal, WorldInverseTranspose));
+    vout.FogFactor = ComputeFogFactor(position);
+    
+    return vout;
+}
+
+
+#define SetCommonVSOutputParamsPixelLighting \
+    vout.PositionPS = cout.Pos_ps; \
+    vout.PositionWS = float4(cout.Pos_ws, cout.FogFactor); \
+    vout.NormalWS = cout.Normal_ws;

+ 490 - 0
Shaders/Lighting/Shaders/LightingEffect.fx

@@ -0,0 +1,490 @@
+//-----------------------------------------------------------------------------
+// BasicEffect.fx
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+#include "Macros.fxh"
+
+
+DECLARE_TEXTURE(Texture, 0);
+
+
+BEGIN_CONSTANTS
+
+    float4 DiffuseColor             _vs(c0)  _ps(c1)  _cb(c0);
+    float3 EmissiveColor            _vs(c1)  _ps(c2)  _cb(c1);
+    float3 SpecularColor            _vs(c2)  _ps(c3)  _cb(c2);
+    float  SpecularPower            _vs(c3)  _ps(c4)  _cb(c2.w);
+
+    float3 DirLight0Direction       _vs(c4)  _ps(c5)  _cb(c3);
+    float3 DirLight0DiffuseColor    _vs(c5)  _ps(c6)  _cb(c4);
+    float3 DirLight0SpecularColor   _vs(c6)  _ps(c7)  _cb(c5);
+
+    float3 DirLight1Direction       _vs(c7)  _ps(c8)  _cb(c6);
+    float3 DirLight1DiffuseColor    _vs(c8)  _ps(c9)  _cb(c7);
+    float3 DirLight1SpecularColor   _vs(c9)  _ps(c10) _cb(c8);
+
+    float3 DirLight2Direction       _vs(c10) _ps(c11) _cb(c9);
+    float3 DirLight2DiffuseColor    _vs(c11) _ps(c12) _cb(c10);
+    float3 DirLight2SpecularColor   _vs(c12) _ps(c13) _cb(c11);
+
+    float3 EyePosition              _vs(c13) _ps(c14) _cb(c12);
+
+    float3 FogColor                          _ps(c0)  _cb(c13);
+    float4 FogVector                _vs(c14)          _cb(c14);
+
+    float4x4 World                  _vs(c19)          _cb(c15);
+    float3x3 WorldInverseTranspose  _vs(c23)          _cb(c19);
+
+MATRIX_CONSTANTS
+
+    float4x4 WorldViewProj          _vs(c15)          _cb(c0);
+
+END_CONSTANTS
+
+
+#include "Structures.fxh"
+#include "Common.fxh"
+#include "Lighting.fxh"
+
+
+// Vertex shader: basic.
+VSOutput VSBasic(VSInput vin)
+{
+    VSOutput vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParams;
+    
+    return vout;
+}
+
+
+// Vertex shader: no fog.
+VSOutputNoFog VSBasicNoFog(VSInput vin)
+{
+    VSOutputNoFog vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParamsNoFog;
+    
+    return vout;
+}
+
+
+// Vertex shader: vertex color.
+VSOutput VSBasicVc(VSInputVc vin)
+{
+    VSOutput vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParams;
+    
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: vertex color, no fog.
+VSOutputNoFog VSBasicVcNoFog(VSInputVc vin)
+{
+    VSOutputNoFog vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParamsNoFog;
+    
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: texture.
+VSOutputTx VSBasicTx(VSInputTx vin)
+{
+    VSOutputTx vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParams;
+    
+    vout.TexCoord = vin.TexCoord;
+
+    return vout;
+}
+
+
+// Vertex shader: texture, no fog.
+VSOutputTxNoFog VSBasicTxNoFog(VSInputTx vin)
+{
+    VSOutputTxNoFog vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParamsNoFog;
+    
+    vout.TexCoord = vin.TexCoord;
+
+    return vout;
+}
+
+
+// Vertex shader: texture + vertex color.
+VSOutputTx VSBasicTxVc(VSInputTxVc vin)
+{
+    VSOutputTx vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParams;
+    
+    vout.TexCoord = vin.TexCoord;
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: texture + vertex color, no fog.
+VSOutputTxNoFog VSBasicTxVcNoFog(VSInputTxVc vin)
+{
+    VSOutputTxNoFog vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
+    SetCommonVSOutputParamsNoFog;
+    
+    vout.TexCoord = vin.TexCoord;
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: vertex lighting.
+VSOutput VSBasicVertexLighting(VSInputNm vin)
+{
+    VSOutput vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
+    SetCommonVSOutputParams;
+    
+    return vout;
+}
+
+
+// Vertex shader: vertex lighting + vertex color.
+VSOutput VSBasicVertexLightingVc(VSInputNmVc vin)
+{
+    VSOutput vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
+    SetCommonVSOutputParams;
+    
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: vertex lighting + texture.
+VSOutputTx VSBasicVertexLightingTx(VSInputNmTx vin)
+{
+    VSOutputTx vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
+    SetCommonVSOutputParams;
+    
+    vout.TexCoord = vin.TexCoord;
+
+    return vout;
+}
+
+
+// Vertex shader: vertex lighting + texture + vertex color.
+VSOutputTx VSBasicVertexLightingTxVc(VSInputNmTxVc vin)
+{
+    VSOutputTx vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
+    SetCommonVSOutputParams;
+    
+    vout.TexCoord = vin.TexCoord;
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: one light.
+VSOutput VSBasicOneLight(VSInputNm vin)
+{
+    VSOutput vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
+    SetCommonVSOutputParams;
+    
+    return vout;
+}
+
+
+// Vertex shader: one light + vertex color.
+VSOutput VSBasicOneLightVc(VSInputNmVc vin)
+{
+    VSOutput vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
+    SetCommonVSOutputParams;
+    
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: one light + texture.
+VSOutputTx VSBasicOneLightTx(VSInputNmTx vin)
+{
+    VSOutputTx vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
+    SetCommonVSOutputParams;
+    
+    vout.TexCoord = vin.TexCoord;
+
+    return vout;
+}
+
+
+// Vertex shader: one light + texture + vertex color.
+VSOutputTx VSBasicOneLightTxVc(VSInputNmTxVc vin)
+{
+    VSOutputTx vout;
+    
+    CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
+    SetCommonVSOutputParams;
+    
+    vout.TexCoord = vin.TexCoord;
+    vout.Diffuse *= vin.Color;
+    
+    return vout;
+}
+
+
+// Vertex shader: pixel lighting.
+VSOutputPixelLighting VSBasicPixelLighting(VSInputNm vin)
+{
+    VSOutputPixelLighting vout;
+    
+    CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
+    SetCommonVSOutputParamsPixelLighting;
+
+    vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
+    
+    return vout;
+}
+
+
+// Vertex shader: pixel lighting + vertex color.
+VSOutputPixelLighting VSBasicPixelLightingVc(VSInputNmVc vin)
+{
+    VSOutputPixelLighting vout;
+    
+    CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
+    SetCommonVSOutputParamsPixelLighting;
+    
+    vout.Diffuse.rgb = vin.Color.rgb;
+    vout.Diffuse.a = vin.Color.a * DiffuseColor.a;
+    
+    return vout;
+}
+
+
+// Vertex shader: pixel lighting + texture.
+VSOutputPixelLightingTx VSBasicPixelLightingTx(VSInputNmTx vin)
+{
+    VSOutputPixelLightingTx vout;
+    
+    CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
+    SetCommonVSOutputParamsPixelLighting;
+    
+    vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
+    vout.TexCoord = vin.TexCoord;
+
+    return vout;
+}
+
+
+// Vertex shader: pixel lighting + texture + vertex color.
+VSOutputPixelLightingTx VSBasicPixelLightingTxVc(VSInputNmTxVc vin)
+{
+    VSOutputPixelLightingTx vout;
+    
+    CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
+    SetCommonVSOutputParamsPixelLighting;
+    
+    vout.Diffuse.rgb = vin.Color.rgb;
+    vout.Diffuse.a = vin.Color.a * DiffuseColor.a;
+    vout.TexCoord = vin.TexCoord;
+    
+    return vout;
+}
+
+
+// Pixel shader: basic.
+float4 PSBasic(VSOutput pin) : SV_Target0
+{
+    float4 color = pin.Diffuse;
+    
+    ApplyFog(color, pin.Specular.w);
+    
+    return color;
+}
+
+
+// Pixel shader: no fog.
+float4 PSBasicNoFog(VSOutputNoFog pin) : SV_Target0
+{
+    return pin.Diffuse;
+}
+
+
+// Pixel shader: texture.
+float4 PSBasicTx(VSOutputTx pin) : SV_Target0
+{
+    float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
+    
+    ApplyFog(color, pin.Specular.w);
+    
+    return color;
+}
+
+
+// Pixel shader: texture, no fog.
+float4 PSBasicTxNoFog(VSOutputTxNoFog pin) : SV_Target0
+{
+    return SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
+}
+
+
+// Pixel shader: vertex lighting.
+float4 PSBasicVertexLighting(VSOutput pin) : SV_Target0
+{
+    float4 color = pin.Diffuse;
+
+    AddSpecular(color, pin.Specular.rgb);
+    ApplyFog(color, pin.Specular.w);
+    
+    return color;
+}
+
+
+// Pixel shader: vertex lighting, no fog.
+float4 PSBasicVertexLightingNoFog(VSOutput pin) : SV_Target0
+{
+    float4 color = pin.Diffuse;
+    
+    AddSpecular(color, pin.Specular.rgb);
+    
+    return color;
+}
+
+
+// Pixel shader: vertex lighting + texture.
+float4 PSBasicVertexLightingTx(VSOutputTx pin) : SV_Target0
+{
+    float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
+    
+    AddSpecular(color, pin.Specular.rgb);
+    ApplyFog(color, pin.Specular.w);
+    
+    return color;
+}
+
+
+// Pixel shader: vertex lighting + texture, no fog.
+float4 PSBasicVertexLightingTxNoFog(VSOutputTx pin) : SV_Target0
+{
+    float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
+    
+    AddSpecular(color, pin.Specular.rgb);
+    
+    return color;
+}
+
+
+// Pixel shader: pixel lighting.
+float4 PSBasicPixelLighting(VSOutputPixelLighting pin) : SV_Target0
+{
+    float4 color = pin.Diffuse;
+
+    float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz);
+    float3 worldNormal = normalize(pin.NormalWS);
+    
+    ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3);
+
+    color.rgb *= lightResult.Diffuse;
+    
+    AddSpecular(color, lightResult.Specular);
+    ApplyFog(color, pin.PositionWS.w);
+    
+    return color;
+}
+
+
+// Pixel shader: pixel lighting + texture.
+float4 PSBasicPixelLightingTx(VSOutputPixelLightingTx pin) : SV_Target0
+{
+    float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
+    
+    float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz);
+    float3 worldNormal = normalize(pin.NormalWS);
+    
+    ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3);
+    
+    color.rgb *= lightResult.Diffuse;
+
+    AddSpecular(color, lightResult.Specular);
+    ApplyFog(color, pin.PositionWS.w);
+    
+    return color;
+}
+
+
+// NOTE: The order of the techniques here are
+// defined to match the indexing in LightingEffect.cs.
+
+TECHNIQUE( BasicEffect,								VSBasic,			PSBasic );
+TECHNIQUE( BasicEffect_NoFog,						VSBasicNoFog,		PSBasicNoFog );
+TECHNIQUE( BasicEffect_VertexColor,					VSBasicVc,			PSBasic );
+TECHNIQUE( BasicEffect_VertexColor_NoFog,			VSBasicVcNoFog,		PSBasicNoFog );
+TECHNIQUE( BasicEffect_Texture,						VSBasicTx,			PSBasicTx );
+TECHNIQUE( BasicEffect_Texture_NoFog,				VSBasicTxNoFog,		PSBasicTxNoFog );
+TECHNIQUE( BasicEffect_Texture_VertexColor,			VSBasicTxVc,		PSBasicTx );
+TECHNIQUE( BasicEffect_Texture_VertexColor_NoFog,	VSBasicTxVcNoFog,	PSBasicTxNoFog );
+
+TECHNIQUE( BasicEffect_VertexLighting,								VSBasicVertexLighting,		PSBasicVertexLighting );
+TECHNIQUE( BasicEffect_VertexLighting_NoFog,						VSBasicVertexLighting,		PSBasicVertexLightingNoFog );
+TECHNIQUE( BasicEffect_VertexLighting_VertexColor,					VSBasicVertexLightingVc,	PSBasicVertexLighting );
+TECHNIQUE( BasicEffect_VertexLighting_VertexColor_NoFog,			VSBasicVertexLightingVc,	PSBasicVertexLightingNoFog );
+TECHNIQUE( BasicEffect_VertexLighting_Texture,						VSBasicVertexLightingTx,	PSBasicVertexLightingTx );
+TECHNIQUE( BasicEffect_VertexLighting_Texture_NoFog,				VSBasicVertexLightingTx,	PSBasicVertexLightingTxNoFog );
+TECHNIQUE( BasicEffect_VertexLighting_Texture_VertexColor,			VSBasicVertexLightingTxVc,	PSBasicVertexLightingTx );
+TECHNIQUE( BasicEffect_VertexLighting_Texture_VertexColor_NoFog,	VSBasicVertexLightingTxVc,	PSBasicVertexLightingTxNoFog );
+
+TECHNIQUE( BasicEffect_OneLight,							VSBasicOneLight,		PSBasicVertexLighting );
+TECHNIQUE( BasicEffect_OneLight_NoFog,						VSBasicOneLight,		PSBasicVertexLightingNoFog );
+TECHNIQUE( BasicEffect_OneLight_VertexColor,				VSBasicOneLightVc,		PSBasicVertexLighting );
+TECHNIQUE( BasicEffect_OneLight_VertexColor_NoFog,			VSBasicOneLightVc,		PSBasicVertexLightingNoFog );
+TECHNIQUE( BasicEffect_OneLight_Texture,					VSBasicOneLightTx,		PSBasicVertexLightingTx );
+TECHNIQUE( BasicEffect_OneLight_Texture_NoFog,				VSBasicOneLightTx,		PSBasicVertexLightingTxNoFog );
+TECHNIQUE( BasicEffect_OneLight_Texture_VertexColor,		VSBasicOneLightTxVc,	PSBasicVertexLightingTx );
+TECHNIQUE( BasicEffect_OneLight_Texture_VertexColor_NoFog,	VSBasicOneLightTxVc,	PSBasicVertexLightingTxNoFog );
+
+TECHNIQUE( BasicEffect_PixelLighting,							VSBasicPixelLighting,		PSBasicPixelLighting );
+TECHNIQUE( BasicEffect_PixelLighting_NoFog,						VSBasicPixelLighting,		PSBasicPixelLighting );
+TECHNIQUE( BasicEffect_PixelLighting_VertexColor,				VSBasicPixelLightingVc,		PSBasicPixelLighting );
+TECHNIQUE( BasicEffect_PixelLighting_VertexColor_NoFog,			VSBasicPixelLightingVc,		PSBasicPixelLighting );
+TECHNIQUE( BasicEffect_PixelLighting_Texture,					VSBasicPixelLightingTx,		PSBasicPixelLightingTx );
+TECHNIQUE( BasicEffect_PixelLighting_Texture_NoFog,				VSBasicPixelLightingTx,		PSBasicPixelLightingTx );
+TECHNIQUE( BasicEffect_PixelLighting_Texture_VertexColor,		VSBasicPixelLightingTxVc,	PSBasicPixelLightingTx );
+TECHNIQUE( BasicEffect_PixelLighting_Texture_VertexColor_NoFog,	VSBasicPixelLightingTxVc,	PSBasicPixelLightingTx );

+ 67 - 0
Shaders/Lighting/Shaders/Macros.fxh

@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------------
+// Macros.fxh
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+#ifdef SM4
+
+// Macros for targetting shader model 4.0 (DX11)
+
+#define TECHNIQUE(name, vsname, psname ) \
+	technique name { pass { VertexShader = compile vs_4_0_level_9_1 vsname (); PixelShader = compile ps_4_0_level_9_1 psname(); } }
+
+#define TECHNIQUE_9_3(name, vsname, psname ) \
+	technique name { pass { VertexShader = compile vs_4_0_level_9_3 vsname (); PixelShader = compile ps_4_0_level_9_3 psname(); } }
+
+#define BEGIN_CONSTANTS     cbuffer Parameters : register(b0) {
+#define MATRIX_CONSTANTS
+#define END_CONSTANTS       };
+
+#define _vs(r)
+#define _ps(r)
+#define _cb(r)
+
+#define DECLARE_TEXTURE(Name, index) \
+    Texture2D<float4> Name : register(t##index); \
+    sampler Name##Sampler : register(s##index)
+
+#define DECLARE_CUBEMAP(Name, index) \
+    TextureCube<float4> Name : register(t##index); \
+    sampler Name##Sampler : register(s##index)
+
+#define SAMPLE_TEXTURE(Name, texCoord)  Name.Sample(Name##Sampler, texCoord)
+#define SAMPLE_CUBEMAP(Name, texCoord)  Name.Sample(Name##Sampler, texCoord)
+
+
+#else
+
+
+// Macros for targetting shader model 2.0 (DX9)
+
+#define TECHNIQUE(name, vsname, psname ) \
+	technique name { pass { VertexShader = compile vs_2_0 vsname (); PixelShader = compile ps_2_0 psname(); } }
+
+#define TECHNIQUE_9_3(name, vsname, psname ) \
+	technique name { pass { VertexShader = compile vs_3_0 vsname (); PixelShader = compile ps_3_0 psname(); } }
+
+#define BEGIN_CONSTANTS
+#define MATRIX_CONSTANTS
+#define END_CONSTANTS
+
+#define _vs(r)  : register(vs, r)
+#define _ps(r)  : register(ps, r)
+#define _cb(r)
+
+#define DECLARE_TEXTURE(Name, index) \
+    sampler2D Name : register(s##index);
+
+#define DECLARE_CUBEMAP(Name, index) \
+    samplerCUBE Name : register(s##index);
+
+#define SAMPLE_TEXTURE(Name, texCoord)  tex2D(Name, texCoord)
+#define SAMPLE_CUBEMAP(Name, texCoord)  texCUBE(Name, texCoord)
+
+
+#endif

+ 161 - 0
Shaders/Lighting/Shaders/Structures.fxh

@@ -0,0 +1,161 @@
+//-----------------------------------------------------------------------------
+// Structurs.fxh
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+
+// Vertex shader input structures.
+
+struct VSInput
+{
+    float4 Position : POSITION;
+};
+
+struct VSInputVc
+{
+    float4 Position : POSITION;
+    float4 Color    : COLOR;
+};
+
+struct VSInputTx
+{
+    float4 Position : POSITION;
+    float2 TexCoord : TEXCOORD;
+};
+
+struct VSInputTxVc
+{
+    float4 Position : POSITION;
+    float2 TexCoord : TEXCOORD;
+    float4 Color    : COLOR;
+};
+
+struct VSInputNm
+{
+    float4 Position : POSITION;
+    float3 Normal   : NORMAL;
+};
+
+struct VSInputNmVc
+{
+    float4 Position : POSITION;
+    float3 Normal   : NORMAL;
+    float4 Color    : COLOR;
+};
+
+struct VSInputNmTx
+{
+    float4 Position : POSITION;
+    float3 Normal   : NORMAL;
+    float2 TexCoord : TEXCOORD;
+};
+
+struct VSInputNmTxVc
+{
+    float4 Position : POSITION;
+    float3 Normal   : NORMAL;
+    float2 TexCoord : TEXCOORD;
+    float4 Color    : COLOR;
+};
+
+struct VSInputTx2
+{
+    float4 Position  : POSITION0;
+    float2 TexCoord  : TEXCOORD0;
+    float2 TexCoord2 : TEXCOORD1;
+};
+
+struct VSInputTx2Vc
+{
+    float4 Position  : POSITION0;
+    float2 TexCoord  : TEXCOORD0;
+    float2 TexCoord2 : TEXCOORD1;
+    float4 Color     : COLOR;
+};
+
+struct VSInputNmTxWeights
+{
+    float4 Position : POSITION0;
+    float3 Normal   : NORMAL0;
+    float2 TexCoord : TEXCOORD0;
+    uint4  Indices  : BLENDINDICES0;
+    float4 Weights  : BLENDWEIGHT0;
+};
+
+
+
+// Vertex shader output structures.
+
+struct VSOutput
+{
+    float4 PositionPS : SV_Position;
+    float4 Diffuse    : COLOR0;
+    float4 Specular   : COLOR1;
+};
+
+struct VSOutputNoFog
+{
+    float4 PositionPS : SV_Position;
+    float4 Diffuse    : COLOR0;
+};
+
+struct VSOutputTx
+{
+    float4 PositionPS : SV_Position;
+    float4 Diffuse    : COLOR0;
+    float4 Specular   : COLOR1;
+    float2 TexCoord   : TEXCOORD0;
+};
+
+struct VSOutputTxNoFog
+{
+    float4 PositionPS : SV_Position;
+    float4 Diffuse    : COLOR0;
+    float2 TexCoord   : TEXCOORD0;
+};
+
+struct VSOutputPixelLighting
+{
+    float4 PositionPS : SV_Position;
+    float4 PositionWS : TEXCOORD0;
+    float3 NormalWS   : TEXCOORD1;
+    float4 Diffuse    : COLOR0;
+};
+
+struct VSOutputPixelLightingTx
+{
+    float4 PositionPS : SV_Position;
+    float2 TexCoord   : TEXCOORD0;
+    float4 PositionWS : TEXCOORD1;
+    float3 NormalWS   : TEXCOORD2;
+    float4 Diffuse    : COLOR0;
+};
+
+struct VSOutputTx2
+{
+    float4 PositionPS : SV_Position;
+    float4 Diffuse    : COLOR0;
+    float4 Specular   : COLOR1;
+    float2 TexCoord   : TEXCOORD0;
+    float2 TexCoord2  : TEXCOORD1;
+};
+
+struct VSOutputTx2NoFog
+{
+    float4 PositionPS : SV_Position;
+    float4 Diffuse    : COLOR0;
+    float2 TexCoord   : TEXCOORD0;
+    float2 TexCoord2  : TEXCOORD1;
+};
+
+struct VSOutputTxEnvMap
+{
+    float4 PositionPS : SV_Position;
+    float4 Diffuse    : COLOR0;
+    float4 Specular   : COLOR1;
+    float2 TexCoord   : TEXCOORD0;
+    float3 EnvCoord   : TEXCOORD1;
+};
+