Force copy texture if texture type was "Normal map".

This commit is contained in:
Masataka SUMI 2021-05-21 20:51:13 +09:00
parent 890e410d26
commit 9fcd2abc58
3 changed files with 34 additions and 41 deletions

View File

@ -13,13 +13,16 @@ namespace UniGLTF
private static readonly string AssetPath = "Assets/UniGLTF/Tests/UniGLTF";
private static readonly string SrgbGrayImageName = "4x4_gray_import_as_srgb";
private static readonly string LinearGrayImageName = "4x4_gray_import_as_linear";
private static readonly string NormalMapGrayImageName = "4x4_gray_import_as_normal_map";
private static readonly Texture2D SrgbGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{SrgbGrayImageName}.png");
private static readonly Texture2D LinearGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{LinearGrayImageName}.png");
private static readonly Texture2D NormalMapGrayTex = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/{NormalMapGrayImageName}.png");
private static readonly Color32 JustGray = new Color32(127, 127, 127, 255);
private static readonly Color32 SrgbGrayInSrgb = JustGray;
private static readonly Color32 SrgbGrayInLinear = ((Color) SrgbGrayInSrgb).linear;
private static readonly Color32 LinearGrayInLinear = JustGray;
private static readonly Color32 LinearGrayInSrgb = ((Color) LinearGrayInLinear).gamma;
private static readonly Color32 NormalizedLinearGrayInLinear = new Color32(127, 127, 255, 255);
[Test]
public void InputAssetsRawImage()
@ -77,31 +80,37 @@ namespace UniGLTF
[Test]
public void AssignSrgbImageToLinearTextureProperty()
{
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_BumpMap");
Assert.AreEqual(SrgbGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r);
Assert.AreEqual(SrgbGrayInLinear.g, GetFirstPixelInTexture2D(exportedTex).g);
// B channel is different. Because it will be normalized as normal vector.
UnityEngine.Object.DestroyImmediate(exportedTex);
var exportedTex2 = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_OcclusionMap");
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(SrgbGrayTex, SrgbGrayImageName, "_OcclusionMap");
// R channel is occlusion in glTF spec.
Assert.AreEqual(SrgbGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex2).r);
UnityEngine.Object.DestroyImmediate(exportedTex2);
Assert.AreEqual(SrgbGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r);
UnityEngine.Object.DestroyImmediate(exportedTex);
}
[Test]
public void AssignLinearImageToLinearTextureProperty()
{
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_BumpMap");
Assert.AreEqual(LinearGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r);
Assert.AreEqual(LinearGrayInLinear.g, GetFirstPixelInTexture2D(exportedTex).g);
// B channel is different. Because it will be normalized as normal vector.
UnityEngine.Object.DestroyImmediate(exportedTex);
var exportedTex2 = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_OcclusionMap");
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_OcclusionMap");
// R channel is occlusion in glTF spec.
Assert.AreEqual(LinearGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex2).r);
UnityEngine.Object.DestroyImmediate(exportedTex2);
Assert.AreEqual(LinearGrayInLinear.r, GetFirstPixelInTexture2D(exportedTex).r);
UnityEngine.Object.DestroyImmediate(exportedTex);
}
[Test]
public void AssignLinearImageToNormalTextureProperty()
{
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(LinearGrayTex, LinearGrayImageName, "_BumpMap");
Assert.AreEqual(NormalizedLinearGrayInLinear, GetFirstPixelInTexture2D(exportedTex));
// B channel is different from 127. Because it will be normalized as normal vector.
UnityEngine.Object.DestroyImmediate(exportedTex);
}
[Test]
public void AssignLinearImageAsNormalMapSettingsToNormalTextureProperty()
{
var exportedTex = AssignTextureToMaterialPropertyAndExportAndExtract(NormalMapGrayTex, NormalMapGrayImageName, "_BumpMap");
Assert.AreEqual(NormalizedLinearGrayInLinear, GetFirstPixelInTexture2D(exportedTex));
// B channel is different from 127. Because it will be normalized as normal vector.
UnityEngine.Object.DestroyImmediate(exportedTex);
}
private static Texture2D AssignTextureToMaterialPropertyAndExportAndExtract(Texture2D srcTex, string srcImageName, string propertyName)

View File

@ -19,6 +19,7 @@ namespace VRMShaders
/// * TextureAsset が存在する
/// * TextureImporter の maxSize が画像の縦横サイズ以上
/// * TextureImporter の色空間設定が exportColorSpace と一致する
/// * 各 Texture Type ごとの判定
///
/// Unity の Texture2D のデータは、その参照元であるテクスチャアセットファイルのデータと一致することはむしろ稀。
/// </summary>
@ -39,8 +40,9 @@ namespace VRMShaders
case TextureImporterType.Default:
break;
case TextureImporterType.NormalMap:
if (!IsCorrectNormalMap(texture2D, textureImporter)) return false;
break;
// A texture has "Normal map" TextureType is ALWAYS converted into normalized normal pixel by Unity.
// So we must copy it.
return false;
case TextureImporterType.GUI:
case TextureImporterType.Sprite:
case TextureImporterType.Cursor:
@ -162,15 +164,5 @@ namespace VRMShaders
throw new ArgumentOutOfRangeException(nameof(colorSpace), colorSpace, null);
}
}
private bool IsCorrectNormalMap(Texture2D texture, TextureImporter textureImporter)
{
if (textureImporter.textureType != TextureImporterType.NormalMap) return false;
// Is Not generated from HeightMap ?
if (textureImporter.convertToNormalmap) return false;
return true;
}
}
}

View File

@ -168,18 +168,10 @@ namespace VRMShaders
return index;
}
// get Texture2D
index = m_exported.Count;
var texture2D = src as Texture2D;
if (m_textureSerializer.CanExportAsEditorAssetFile(texture2D, ColorSpace.Linear))
{
// EditorAsset を使うので変換不要
}
else
{
// 後で Bitmap を使うために変換する
texture2D = NormalConverter.Export(src);
}
// NormalMap Property のテクスチャは必ず NormalMap として解釈してコピーする。
// Texture Asset の設定に依らず、Standard Shader で得られる見た目と同じ結果を得るため。
var texture2D = NormalConverter.Export(src);
m_exported.Add((texture2D, ColorSpace.Linear));
m_exportMap.Add(new ExportKey(src, ExportTypes.Normal), index);