Skip to content

Commit

Permalink
Merge pull request #74 from jm991/master
Browse files Browse the repository at this point in the history
KHR_materials_pbrSpecularGlossiness support
  • Loading branch information
Blake Gross committed Nov 6, 2017
2 parents f957fc2 + 70bad23 commit 516134c
Show file tree
Hide file tree
Showing 38 changed files with 2,104 additions and 788 deletions.
Binary file not shown.
525 changes: 525 additions & 0 deletions GLTFSerialization/External/glTF-pbrSpecularGlossiness/Lantern.gltf

Large diffs are not rendered by default.

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
116 changes: 116 additions & 0 deletions GLTFSerialization/GLTFSerialization/Extensions/GLTFJsonExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Collections.Generic;
using GLTF.Math;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using GLTF.Schema;

namespace GLTF.Extensions
{
Expand Down Expand Up @@ -64,6 +66,65 @@ public static List<T> ReadList<T>(this JsonReader reader, Func<T> deserializerFu
return list;
}

public static TextureInfo DeserializeAsTexture(this JToken token, GLTFRoot root)
{
TextureInfo textureInfo = null;

if (token != null)
{
JObject textureObject = token as JObject;
if (textureObject == null)
{
throw new Exception("JToken used for Texture deserialization was not a JObject. It was a " + token.Type.ToString());
}
System.Diagnostics.Debug.WriteLine("textureObject is " + textureObject.Type + " with a value of: " + textureObject[TextureInfo.INDEX].Type + " " + textureObject.ToString());

int indexVal = textureObject[TextureInfo.INDEX].DeserializeAsInt();
textureInfo = new TextureInfo()
{
Index = new TextureId()
{
Id = indexVal,
Root = root
}
};
}

return textureInfo;
}

public static int DeserializeAsInt(this JToken token)
{
if (token != null)
{
JValue intValue = token as JValue;
if (intValue == null)
{
throw new Exception("JToken used for int deserialization was not a JValue. It was a " + token.Type.ToString());
}

return (int)intValue;
}

return 0;
}

public static double DeserializeAsDouble(this JToken token)
{
if (token != null)
{
JValue doubleValue = token as JValue;
if (doubleValue == null)
{
throw new Exception("JToken used for double deserialization was not a JValue. It was a " + token.Type.ToString());
}

return (double)doubleValue;
}

return 0d;
}

public static Color ReadAsRGBAColor(this JsonReader reader)
{
if (reader.Read() && reader.TokenType != JsonToken.StartArray)
Expand All @@ -86,6 +147,34 @@ public static Color ReadAsRGBAColor(this JsonReader reader)

return color;
}

public static Color DeserializeAsColor(this JToken token)
{
Color color = Color.White;

if (token != null)
{
JArray colorArray = token as JArray;
if (colorArray == null)
{
throw new Exception("JToken used for Color deserialization was not a JArray. It was a " + token.Type.ToString());
}
if (colorArray.Count != 4)
{
throw new Exception("JArray used for Color deserialization did not have 4 entries for RGBA. It had " + colorArray.Count);
}

color = new Color
{
R = (float)colorArray[0].DeserializeAsDouble(),
G = (float)colorArray[1].DeserializeAsDouble(),
B = (float)colorArray[2].DeserializeAsDouble(),
A = (float)colorArray[3].DeserializeAsDouble()
};
}

return color;
}

public static Color ReadAsRGBColor(this JsonReader reader)
{
Expand Down Expand Up @@ -132,6 +221,33 @@ public static Vector3 ReadAsVector3(this JsonReader reader)
return vector;
}

public static Vector3 DeserializeAsVector3(this JToken token)
{
Vector3 vector = new Vector3();

if (token != null)
{
JArray vectorArray = token as JArray;
if (vectorArray == null)
{
throw new Exception("JToken used for Vector3 deserialization was not a JArray. It was a " + token.Type.ToString());
}
if (vectorArray.Count != 3)
{
throw new Exception("JArray used for Vector3 deserialization did not have 3 entries for XYZ. It had " + vectorArray.Count);
}

vector = new Vector3
{
X = (float)vectorArray[0].DeserializeAsDouble(),
Y = (float)vectorArray[1].DeserializeAsDouble(),
Z = (float)vectorArray[2].DeserializeAsDouble()
};
}

return vector;
}

public static Quaternion ReadAsQuaternion(this JsonReader reader)
{
if (reader.Read() && reader.TokenType != JsonToken.StartArray)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using GLTF.Math;
using GLTF.Schema;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace GLTF.Schema
{
/// <summary>
/// glTF extension that defines the specular-glossiness
/// material model from Physically-Based Rendering (PBR) methodology.
///
/// Spec can be found here:
/// https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_materials_pbrSpecularGlossiness
/// </summary>
public class KHR_materials_pbrSpecularGlossinessExtension : Extension
{
public static readonly Vector3 SPEC_FACTOR_DEFAULT = new Vector3(0.2f, 0.2f, 0.2f);
public static readonly double GLOSS_FACTOR_DEFAULT = 0.5d;

/// <summary>
/// The RGBA components of the reflected diffuse color of the material.
/// Metals have a diffuse value of [0.0, 0.0, 0.0].
/// The fourth component (A) is the alpha coverage of the material.
/// The <see cref="Material.AlphaMode"/> property specifies how alpha is interpreted.
/// The values are linear.
/// </summary>
public Color DiffuseFactor = Color.White;

/// <summary>
/// The diffuse texture.
/// This texture contains RGB(A) components of the reflected diffuse color of the material in sRGB color space.
/// If the fourth component (A) is present, it represents the alpha coverage of the
/// material. Otherwise, an alpha of 1.0 is assumed.
/// The <see cref="Material.AlphaMode"/> property specifies how alpha is interpreted.
/// The stored texels must not be premultiplied.
/// </summary>
public TextureInfo DiffuseTexture;

/// <summary>
/// The specular RGB color of the material. This value is linear
/// </summary>
public Vector3 SpecularFactor = SPEC_FACTOR_DEFAULT;

/// <summary>
/// The glossiness or smoothness of the material.
/// A value of 1.0 means the material has full glossiness or is perfectly smooth.
/// A value of 0.0 means the material has no glossiness or is completely rough.
/// This value is linear.
/// </summary>
public double GlossinessFactor = GLOSS_FACTOR_DEFAULT;

/// <summary>
/// The specular-glossiness texture is RGBA texture, containing the specular color of the material (RGB components) and its glossiness (A component).
/// The values are in sRGB space.
/// </summary>
public TextureInfo SpecularGlossinessTexture;

public KHR_materials_pbrSpecularGlossinessExtension(Color diffuseFactor, TextureInfo diffuseTexture, Vector3 specularFactor, double glossinessFactor, TextureInfo specularGlossinessTexture)
{
DiffuseFactor = diffuseFactor;
DiffuseTexture = diffuseTexture;
SpecularFactor = specularFactor;
GlossinessFactor = glossinessFactor;
SpecularGlossinessTexture = specularGlossinessTexture;
}

public JProperty Serialize()
{
JProperty jProperty =
new JProperty(KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME,
new JObject(
new JProperty(KHR_materials_pbrSpecularGlossinessExtensionFactory.DIFFUSE_FACTOR, DiffuseFactor),
new JProperty(KHR_materials_pbrSpecularGlossinessExtensionFactory.DIFFUSE_TEXTURE,
new JObject(
new JProperty(TextureInfo.INDEX, DiffuseTexture.Index.Id)
)
),
new JProperty(KHR_materials_pbrSpecularGlossinessExtensionFactory.SPECULAR_FACTOR, SpecularFactor),
new JProperty(KHR_materials_pbrSpecularGlossinessExtensionFactory.GLOSSINESS_FACTOR, GlossinessFactor),
new JProperty(KHR_materials_pbrSpecularGlossinessExtensionFactory.SPECULAR_GLOSSINESS_TEXTURE,
new JObject(
new JProperty(TextureInfo.INDEX, SpecularGlossinessTexture.Index.Id)
)
)
)
);

return jProperty;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using Newtonsoft.Json.Linq;
using GLTF.Math;
using Newtonsoft.Json;
using GLTF.Extensions;

namespace GLTF.Schema
{
public class KHR_materials_pbrSpecularGlossinessExtensionFactory : ExtensionFactory
{
public const string EXTENSION_NAME = "KHR_materials_pbrSpecularGlossiness";
public const string DIFFUSE_FACTOR = "diffuseFactor";
public const string DIFFUSE_TEXTURE = "diffuseTexture";
public const string SPECULAR_FACTOR = "specularFactor";
public const string GLOSSINESS_FACTOR = "glossinessFactor";
public const string SPECULAR_GLOSSINESS_TEXTURE = "specularGlossinessTexture";

public KHR_materials_pbrSpecularGlossinessExtensionFactory()
{
ExtensionName = EXTENSION_NAME;
}

public override Extension Deserialize(GLTFRoot root, JProperty extensionToken)
{
Color diffuseFactor = Color.White;
TextureInfo diffuseTextureInfo = new TextureInfo();
Vector3 specularFactor = KHR_materials_pbrSpecularGlossinessExtension.SPEC_FACTOR_DEFAULT;
double glossinessFactor = KHR_materials_pbrSpecularGlossinessExtension.GLOSS_FACTOR_DEFAULT;
TextureInfo specularGlossinessTextureInfo = new TextureInfo();

if (extensionToken != null)
{
System.Diagnostics.Debug.WriteLine(extensionToken.Value.ToString());
System.Diagnostics.Debug.WriteLine(extensionToken.Value.Type);

JToken diffuseFactorToken = extensionToken.Value[DIFFUSE_FACTOR];
diffuseFactor = diffuseFactorToken != null ? diffuseFactorToken.DeserializeAsColor() : diffuseFactor;
diffuseTextureInfo = extensionToken.Value[DIFFUSE_TEXTURE].DeserializeAsTexture(root);
JToken specularFactorToken = extensionToken.Value[SPECULAR_FACTOR];
specularFactor = specularFactorToken != null ? specularFactorToken.DeserializeAsVector3() : specularFactor;
JToken glossinessFactorToken = extensionToken.Value[GLOSSINESS_FACTOR];
glossinessFactor = glossinessFactorToken != null ? glossinessFactorToken.DeserializeAsDouble() : glossinessFactor;
specularGlossinessTextureInfo = extensionToken.Value[SPECULAR_GLOSSINESS_TEXTURE].DeserializeAsTexture(root);
}

return new KHR_materials_pbrSpecularGlossinessExtension(diffuseFactor, diffuseTextureInfo, specularFactor, glossinessFactor, specularGlossinessTextureInfo);
}
}
}
2 changes: 2 additions & 0 deletions GLTFSerialization/GLTFSerialization/GLTFSerialization.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@
<Compile Include="Schema\GLTFProperty.cs" />
<Compile Include="Schema\GLTFRoot.cs" />
<Compile Include="Schema\Image.cs" />
<Compile Include="Extensions\KHR_materials_pbrSpecularGlossinessExtension.cs" />
<Compile Include="Extensions\KHR_materials_pbrSpecularGlossinessExtensionFactory.cs" />
<Compile Include="Schema\Material.cs" />
<Compile Include="Schema\MaterialCommonConstant.cs" />
<Compile Include="Schema\MaterialNormalTextureInfo.cs" />
Expand Down
5 changes: 5 additions & 0 deletions GLTFSerialization/GLTFSerialization/Schema/GLTFProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class GLTFProperty
{
private static Dictionary<string, ExtensionFactory> _extensionRegistry = new Dictionary<string, ExtensionFactory>();
private static DefaultExtensionFactory _defaultExtensionFactory = new DefaultExtensionFactory();
private static KHR_materials_pbrSpecularGlossinessExtensionFactory _KHRExtensionFactory = new KHR_materials_pbrSpecularGlossinessExtensionFactory();

public static void RegisterExtension(ExtensionFactory extensionFactory)
{
Expand Down Expand Up @@ -105,6 +106,10 @@ private void SkipArray(JsonReader reader)
{
extensions.Add(extensionName, extensionFactory.Deserialize(root, (JProperty)extensionToken));
}
else if (extensionName.Equals(KHR_materials_pbrSpecularGlossinessExtensionFactory.EXTENSION_NAME))
{
extensions.Add(extensionName, _KHRExtensionFactory.Deserialize(root, (JProperty)extensionToken));
}
else
{
extensions.Add(extensionName, _defaultExtensionFactory.Deserialize(root, (JProperty)extensionToken));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace GLTF.Schema
{
public class NormalTextureInfo : TextureInfo
{
public const string SCALE = "scale";

/// <summary>
/// The scalar multiplier applied to each normal vector of the texture.
/// This value is ignored if normalTexture is not specified.
Expand All @@ -27,13 +29,13 @@ public static new NormalTextureInfo Deserialize(GLTFRoot root, JsonReader reader

switch (curProp)
{
case "index":
case INDEX:
textureInfo.Index = TextureId.Deserialize(root, reader);
break;
case "texCoord":
case TEXCOORD:
textureInfo.TexCoord = reader.ReadAsInt32().Value;
break;
case "scale":
case SCALE:
textureInfo.Scale = reader.ReadAsDouble().Value;
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace GLTF.Schema
{
public class OcclusionTextureInfo : TextureInfo
{
public const string STRENGTH = "strength";

/// <summary>
/// A scalar multiplier controlling the amount of occlusion applied.
/// A value of 0.0 means no occlusion.
Expand All @@ -31,13 +33,13 @@ public static new OcclusionTextureInfo Deserialize(GLTFRoot root, JsonReader rea

switch (curProp)
{
case "index":
case INDEX:
textureInfo.Index = TextureId.Deserialize(root, reader);
break;
case "texCoord":
case TEXCOORD:
textureInfo.TexCoord = reader.ReadAsInt32().Value;
break;
case "strength":
case STRENGTH:
textureInfo.Strength = reader.ReadAsDouble().Value;
break;
default:
Expand Down

0 comments on commit 516134c

Please sign in to comment.