diff --git a/Effects/PBREffect.cs b/Effects/PBREffect.cs index b50d027..4472bd7 100644 --- a/Effects/PBREffect.cs +++ b/Effects/PBREffect.cs @@ -47,7 +47,6 @@ namespace Smuggler float occlusionStrength; Vector2 metallicRoughnessValue; Vector4 baseColorFactor; - Vector3 cameraLook; public Matrix World { @@ -66,6 +65,11 @@ namespace Smuggler { view = value; viewParam.SetValue(view); + cameraLookParam.SetValue(-new Vector3( + view.M13, + view.M23, + view.M33 + )); } } @@ -140,16 +144,6 @@ namespace Smuggler } } - public Vector3 CameraLook - { - get { return cameraLook; } - set - { - cameraLook = value; - cameraLookParam.SetValue(cameraLook); - } - } - public Texture2D BaseColourTexture { get { return baseColourTextureParam.GetValueTexture2D(); } @@ -198,11 +192,11 @@ namespace Smuggler set { envSpecularTextureParam.SetValue(value); } } - public PBREffect(GraphicsDevice graphicsDevice, byte[] effectCode) : base(graphicsDevice, effectCode) + public PBREffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.PBREffect) { modelParam = Parameters["model"]; viewParam = Parameters["view"]; - projectionParam = Parameters["param"]; + projectionParam = Parameters["projection"]; lightDirParam = Parameters["lightDir"]; lightColourParam = Parameters["lightColour"]; @@ -260,7 +254,6 @@ namespace Smuggler OcclusionStrength = cloneSource.OcclusionStrength; MetallicRoughnessValue = cloneSource.MetallicRoughnessValue; BaseColorFactor = cloneSource.BaseColorFactor; - CameraLook = cloneSource.CameraLook; BaseColourTexture = cloneSource.BaseColourTexture; NormalTexture = cloneSource.NormalTexture; diff --git a/Effects/pbr.fx b/Effects/PBREffect.fx similarity index 100% rename from Effects/pbr.fx rename to Effects/PBREffect.fx diff --git a/Effects/pbr.fxo b/Effects/PBREffect.fxb similarity index 100% rename from Effects/pbr.fxo rename to Effects/PBREffect.fxb diff --git a/Importer.cs b/Importer.cs index 43ae13c..8cda1cc 100644 --- a/Importer.cs +++ b/Importer.cs @@ -32,14 +32,6 @@ namespace Smuggler var model = new Model(meshes.ToArray()); - /* TODO: BasicEffect only supports one texture but GLTF supports several */ - - if (sharpModel.LogicalTextures.Count > 0) - { - var fnaTexture = Texture2D.FromStream(graphicsDevice, sharpModel.LogicalTextures[0].PrimaryImage.Content.Open()); - model.SetTexture(fnaTexture); - } - return model; } @@ -145,9 +137,114 @@ namespace Smuggler ImportVertexPositionTexture(primitive, vertexBuffer, indices, positions); } - /* TODO: We need a new Effect subclass to support some GLTF features */ + var effect = new PBREffect(graphicsDevice); - var effect = new PBREffect(graphicsDevice, File.ReadAllBytes("Effects/pbr.fxo")); + if (primitive.Material != null) + { + var normalChannel = primitive.Material.FindChannel("Normal"); + if (normalChannel.HasValue) + { + if (normalChannel.Value.Texture != null) + { + effect.NormalTexture = Texture2D.FromStream( + graphicsDevice, + normalChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + + effect.NormalScale = normalChannel.Value.Parameter.X; + } + + var occlusionChannel = primitive.Material.FindChannel("Occlusion"); + if (occlusionChannel.HasValue) + { + if (occlusionChannel.Value.Texture != null) + { + effect.OcclusionTexture = Texture2D.FromStream( + graphicsDevice, + occlusionChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + + effect.OcclusionStrength = occlusionChannel.Value.Parameter.X; + } + + var emissiveChannel = primitive.Material.FindChannel("Emissive"); + if (emissiveChannel.HasValue) + { + if (emissiveChannel.Value.Texture != null) + { + effect.EmissionTexture = Texture2D.FromStream( + graphicsDevice, + emissiveChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + + var parameter = emissiveChannel.Value.Parameter; + + effect.EmissiveFactor = new Vector3( + parameter.X, + parameter.Y, + parameter.Z + ); + } + + var baseColorChannel = primitive.Material.FindChannel("BaseColor"); + if (baseColorChannel.HasValue) + { + if (baseColorChannel.Value.Texture != null) + { + effect.BaseColourTexture = Texture2D.FromStream( + graphicsDevice, + baseColorChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + + var parameter = emissiveChannel.Value.Parameter; + + effect.BaseColorFactor = new Vector4( + parameter.X, + parameter.Y, + parameter.Z, + parameter.W + ); + } + + var metallicRoughnessChannel = primitive.Material.FindChannel("MetallicRoughness"); + if (metallicRoughnessChannel.HasValue) + { + if (metallicRoughnessChannel.Value.Texture != null) + { + effect.MetallicRoughnessTexture = Texture2D.FromStream( + graphicsDevice, + metallicRoughnessChannel.Value.Texture.PrimaryImage.Content.Open() + ); + } + + var parameter = metallicRoughnessChannel.Value.Parameter; + + effect.MetallicRoughnessValue = new Vector2( + parameter.X, + parameter.Y + ); + } + } + + effect.Light = new PBRLight(new Vector3(-0.5f, -0.5f, -0.5f), Color.White.ToVector3()); + + /* FIXME: how to load cube maps from GLTF? */ + /* + var diffuseChannel = primitive.Material.FindChannel("Diffuse"); + if (diffuseChannel.HasValue) + { + } + + var specularChannel = primitive.Material.FindChannel("SpecularGlossiness"); + if (specularChannel.HasValue) + { + } + */ + return new MeshPart( vertexBuffer, diff --git a/Model.cs b/Model.cs index ed3ec25..eeba250 100644 --- a/Model.cs +++ b/Model.cs @@ -13,18 +13,6 @@ namespace Smuggler Meshes = meshes; } - public void SetTexture(Texture2D texture) - { - foreach (var mesh in Meshes) - { - foreach (var meshPart in mesh.MeshParts) - { - meshPart.Effect.TextureEnabled = true; - meshPart.Effect.Texture = texture; - } - } - } - public void Draw(GraphicsDevice graphicsDevice, Matrix world, Matrix view, Matrix projection) { foreach (var mesh in Meshes) diff --git a/Resources.cs b/Resources.cs new file mode 100644 index 0000000..53fc5ea --- /dev/null +++ b/Resources.cs @@ -0,0 +1,33 @@ +using System.IO; + +namespace Smuggler +{ + internal class Resources + { + public static byte[] PBREffect + { + get + { + if (pbrEffect == null) + { + pbrEffect = GetResource("PBREffect"); + } + return pbrEffect; + } + } + + private static byte[] pbrEffect; + + private static byte[] GetResource(string name) + { + Stream stream = typeof(Resources).Assembly.GetManifestResourceStream( + "Smuggler.Resources." + name + ".fxb" + ); + using (MemoryStream ms = new MemoryStream()) + { + stream.CopyTo(ms); + return ms.ToArray(); + } + } + } +} diff --git a/Smuggler.csproj b/Smuggler.csproj index fafb0a4..59eef25 100644 --- a/Smuggler.csproj +++ b/Smuggler.csproj @@ -17,5 +17,11 @@ + + + + Smuggler.Resources.PBREffect.fxb + +