mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-23 11:05:29 -05:00
Implements standard texture importing with shader
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
Shader "Hidden/UniGLTF/StandardMapImporter"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_GltfMetallicFactor ("glTF Metallic Factor", Float) = 0.0
|
||||
_GltfRoughnessFactor ("glTF Roughness Factor", Float) = 0.0
|
||||
_GltfMetallicRoughnessTexture ("glTF Metallic Roughness Texture", 2D) = "black" {}
|
||||
_GltfOcclusionTexture ("glTF Occlusion Texture", 2D) = "black" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
half _GltfMetallicFactor;
|
||||
half _GltfRoughnessFactor;
|
||||
sampler2D _GltfMetallicRoughnessTexture;
|
||||
sampler2D _GltfOcclusionTexture;
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
half4 metallicRoughness = tex2D(_GltfMetallicRoughnessTexture, i.uv);
|
||||
half metallic = metallicRoughness.b * _GltfMetallicFactor;
|
||||
half roughness = metallicRoughness.g * _GltfRoughnessFactor;
|
||||
half occlusion = tex2D(_GltfOcclusionTexture, i.uv).r;
|
||||
|
||||
fixed4 result;
|
||||
result.r = metallic; // R: Unity Metallic
|
||||
result.g = occlusion; // G: Unity Occlusion
|
||||
result.b = 0; // B: Unity Heightmap (no use)
|
||||
result.a = 1.0 - roughness; // A: Unity Smoothness
|
||||
|
||||
return result;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa5d94522a5d93442a7515698d7ab799
|
||||
timeCreated: 1533558728
|
||||
licenseType: Free
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -21,77 +21,42 @@ namespace VRMShaders
|
||||
/// </summary>
|
||||
public static class OcclusionMetallicRoughnessConverter
|
||||
{
|
||||
public static Texture2D Import(Texture2D metallicRoughnessTexture,
|
||||
float metallicFactor, float roughnessFactor, Texture2D occlusionTexture)
|
||||
private static Material exporter;
|
||||
private static Material Exporter
|
||||
{
|
||||
// TODO: Replace with Shader implementation
|
||||
if (metallicRoughnessTexture != null && occlusionTexture != null)
|
||||
get
|
||||
{
|
||||
if (metallicRoughnessTexture == occlusionTexture)
|
||||
if (exporter == null)
|
||||
{
|
||||
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null);
|
||||
var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32();
|
||||
for (int i = 0; i < metallicRoughnessPixels.Length; ++i)
|
||||
{
|
||||
metallicRoughnessPixels[i] = ImportPixel(metallicRoughnessPixels[i], metallicFactor, roughnessFactor, metallicRoughnessPixels[i]);
|
||||
}
|
||||
copyMetallicRoughness.SetPixels32(metallicRoughnessPixels);
|
||||
copyMetallicRoughness.Apply();
|
||||
copyMetallicRoughness.name = metallicRoughnessTexture.name;
|
||||
return copyMetallicRoughness;
|
||||
exporter = new Material(Shader.Find("Hidden/UniGLTF/StandardMapImporter"));
|
||||
}
|
||||
else
|
||||
{
|
||||
var copyMetallicRoughness = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null);
|
||||
var metallicRoughnessPixels = copyMetallicRoughness.GetPixels32();
|
||||
var copyOcclusion = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, false, null);
|
||||
var occlusionPixels = copyOcclusion.GetPixels32();
|
||||
if (metallicRoughnessPixels.Length != occlusionPixels.Length)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
for (int i = 0; i < metallicRoughnessPixels.Length; ++i)
|
||||
{
|
||||
metallicRoughnessPixels[i] = ImportPixel(metallicRoughnessPixels[i], metallicFactor, roughnessFactor, occlusionPixels[i]);
|
||||
}
|
||||
copyMetallicRoughness.SetPixels32(metallicRoughnessPixels);
|
||||
copyMetallicRoughness.Apply();
|
||||
copyMetallicRoughness.name = metallicRoughnessTexture.name;
|
||||
DestroyTexture(copyOcclusion);
|
||||
return copyMetallicRoughness;
|
||||
}
|
||||
}
|
||||
else if (metallicRoughnessTexture != null)
|
||||
{
|
||||
var copyTexture = TextureConverter.CopyTexture(metallicRoughnessTexture, ColorSpace.Linear, true, null);
|
||||
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(x, metallicFactor, roughnessFactor, default)).ToArray());
|
||||
copyTexture.Apply();
|
||||
copyTexture.name = metallicRoughnessTexture.name;
|
||||
return copyTexture;
|
||||
}
|
||||
else if (occlusionTexture != null)
|
||||
{
|
||||
var copyTexture = TextureConverter.CopyTexture(occlusionTexture, ColorSpace.Linear, true, null);
|
||||
copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => ImportPixel(default, metallicFactor, roughnessFactor, x)).ToArray());
|
||||
copyTexture.Apply();
|
||||
copyTexture.name = occlusionTexture.name;
|
||||
return copyTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentNullException("no texture");
|
||||
return exporter;
|
||||
}
|
||||
}
|
||||
|
||||
public static Color32 ImportPixel(Color32 metallicRoughness, float metallicFactor, float roughnessFactor, Color32 occlusion)
|
||||
public static Texture2D Import(Texture2D metallicRoughnessTexture,
|
||||
float metallicFactor, float roughnessFactor, Texture2D occlusionTexture)
|
||||
{
|
||||
var dst = new Color32
|
||||
if (metallicRoughnessTexture == null && occlusionTexture == null)
|
||||
{
|
||||
r = (byte)(metallicRoughness.b * metallicFactor), // Metallic
|
||||
g = occlusion.r, // Occlusion
|
||||
b = 0, // not used
|
||||
a = (byte)(255 - metallicRoughness.g * roughnessFactor), // Roughness to Smoothness
|
||||
};
|
||||
throw new ArgumentNullException("no texture");
|
||||
}
|
||||
|
||||
var src = metallicRoughnessTexture != null ? metallicRoughnessTexture : occlusionTexture;
|
||||
|
||||
Exporter.mainTexture = src;
|
||||
Exporter.SetTexture("_GltfMetallicRoughnessTexture", metallicRoughnessTexture);
|
||||
Exporter.SetTexture("_GltfOcclusionTexture", occlusionTexture);
|
||||
Exporter.SetFloat("_GltfMetallicFactor", metallicFactor);
|
||||
Exporter.SetFloat("_GltfRoughnessFactor", roughnessFactor);
|
||||
|
||||
var dst = TextureConverter.CopyTexture(src, ColorSpace.Linear, true, Exporter);
|
||||
|
||||
Exporter.mainTexture = null;
|
||||
Exporter.SetTexture("_GltfMetallicRoughnessTexture", null);
|
||||
Exporter.SetTexture("_GltfOcclusionTexture", null);
|
||||
Exporter.SetFloat("_GltfMetallicFactor", 0);
|
||||
Exporter.SetFloat("_GltfRoughnessFactor", 0);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -5,6 +6,32 @@ namespace VRMShaders
|
||||
{
|
||||
public class MetallicRoughnessConverterTests
|
||||
{
|
||||
private Color32 ImportPixel(Color32 metallicRoughnessPixel, float metallicFactor, float roughnessFactor, Color32 occlusionPixel)
|
||||
{
|
||||
var metallicRoughnessTexture = new Texture2D(4, 4, TextureFormat.ARGB32, mipChain: false, linear: true);
|
||||
metallicRoughnessTexture.SetPixels32(Enumerable.Range(0, 16).Select(_ => metallicRoughnessPixel).ToArray());
|
||||
metallicRoughnessTexture.Apply();
|
||||
|
||||
var occlusionTexture = new Texture2D(4, 4, TextureFormat.ARGB32, mipChain: false, linear: true);
|
||||
occlusionTexture.SetPixels32(Enumerable.Range(0, 16).Select(_ => occlusionPixel).ToArray());
|
||||
occlusionTexture.Apply();
|
||||
|
||||
var converted = OcclusionMetallicRoughnessConverter.Import(
|
||||
metallicRoughnessTexture,
|
||||
metallicFactor,
|
||||
roughnessFactor,
|
||||
occlusionTexture
|
||||
);
|
||||
|
||||
var result = converted.GetPixels32()[0];
|
||||
|
||||
UnityEngine.Object.DestroyImmediate(metallicRoughnessTexture);
|
||||
UnityEngine.Object.DestroyImmediate(occlusionTexture);
|
||||
UnityEngine.Object.DestroyImmediate(converted);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExportingColorTest()
|
||||
{
|
||||
@@ -48,7 +75,7 @@ namespace VRMShaders
|
||||
{
|
||||
var roughnessFactor = 1.0f;
|
||||
Assert.That(
|
||||
OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default),
|
||||
ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default),
|
||||
// r <- 255 : Same metallic (src.r)
|
||||
// g <- 0 : (Unused)
|
||||
// b <- 0 : (Unused)
|
||||
@@ -59,7 +86,7 @@ namespace VRMShaders
|
||||
{
|
||||
var roughnessFactor = 1.0f;
|
||||
Assert.That(
|
||||
OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 128, 255, 255), 1.0f, roughnessFactor, default),
|
||||
ImportPixel(new Color32(255, 128, 255, 255), 1.0f, roughnessFactor, default),
|
||||
// r <- 255 : Same metallic (src.r)
|
||||
// g <- 0 : (Unused)
|
||||
// b <- 0 : (Unused)
|
||||
@@ -70,7 +97,7 @@ namespace VRMShaders
|
||||
{
|
||||
var roughnessFactor = 0.5f;
|
||||
Assert.That(
|
||||
OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default),
|
||||
ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default),
|
||||
// r <- 255 : Same metallic (src.r)
|
||||
// g <- 0 : (Unused)
|
||||
// b <- 0 : (Unused)
|
||||
@@ -81,7 +108,7 @@ namespace VRMShaders
|
||||
{
|
||||
var roughnessFactor = 0.0f;
|
||||
Assert.That(
|
||||
OcclusionMetallicRoughnessConverter.ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default),
|
||||
ImportPixel(new Color32(255, 255, 255, 255), 1.0f, roughnessFactor, default),
|
||||
// r <- 255 : Same metallic (src.r)
|
||||
// g <- 0 : (Unused)
|
||||
// b <- 0 : (Unused)
|
||||
|
||||
Reference in New Issue
Block a user