public Awaitable <Material> CreateMaterial(glTF gltf, int i, GetTextureAsyncFunc getTexture) { if (i == 0 && m_materials.Count == 0) { // dummy return(MaterialFactory.DefaultCreateMaterialAsync(gltf, i, getTexture)); } return(MToonMaterialItem.CreateAsync(gltf, i, m_materials[i], getTexture)); }
public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor) { if (getTexture == null) { getTexture = (_x, _y, _z) => Task.FromResult <Texture2D>(default);
public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, GltfParser parser, int i, GetTextureAsyncFunc getTexture) { if (getTexture == null) { getTexture = (IAwaitCaller _awaitCaller, glTF _gltf, TextureImportParam _param) => Task.FromResult <Texture2D>(null); } var material = new Material(Shader.Find(ShaderName)); if (i < 0 || i >= parser.GLTF.materials.Count) { material.name = MaterialFactory.MaterialName(i, null); return(material); } var src = parser.GLTF.materials[i]; material.name = MaterialFactory.MaterialName(i, src); var standardParam = default(TextureImportParam); if (src.pbrMetallicRoughness != null || src.occlusionTexture != null) { if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null) { standardParam = StandardTexture(parser, src); } if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) { var color = src.pbrMetallicRoughness.baseColorFactor; material.color = (new Color(color[0], color[1], color[2], color[3])).gamma; } if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1) { var param = BaseColorTexture(parser, src); material.mainTexture = await getTexture(awaitCaller, parser.GLTF, param); // Texture Offset and Scale MaterialFactory.SetTextureOffsetAndScale(material, "_MainTex", param.Offset, param.Scale); } if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) { material.EnableKeyword("_METALLICGLOSSMAP"); var texture = await getTexture(awaitCaller, parser.GLTF, standardParam); if (texture != null) { material.SetTexture(TextureImportParam.METALLIC_GLOSS_PROP, texture); } material.SetFloat("_Metallic", 1.0f); // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. material.SetFloat("_GlossMapScale", 1.0f); // Texture Offset and Scale var(offset, scale) = MaterialFactory.GetTextureOffsetAndScale(src.pbrMetallicRoughness.metallicRoughnessTexture); MaterialFactory.SetTextureOffsetAndScale(material, "_MetallicGlossMap", offset, scale); } else { material.SetFloat("_Metallic", src.pbrMetallicRoughness.metallicFactor); material.SetFloat("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); } } if (src.normalTexture != null && src.normalTexture.index != -1) { material.EnableKeyword("_NORMALMAP"); var param = NormalTexture(parser, src); var texture = await getTexture(awaitCaller, parser.GLTF, param); if (texture != null) { material.SetTexture(TextureImportParam.NORMAL_PROP, texture); material.SetFloat("_BumpScale", src.normalTexture.scale); } // Texture Offset and Scale MaterialFactory.SetTextureOffsetAndScale(material, "_BumpMap", param.Offset, param.Scale); } if (src.occlusionTexture != null && src.occlusionTexture.index != -1) { var texture = await getTexture(awaitCaller, parser.GLTF, standardParam); if (texture != null) { material.SetTexture(TextureImportParam.OCCLUSION_PROP, texture); material.SetFloat("_OcclusionStrength", src.occlusionTexture.strength); } // Texture Offset and Scale var(offset, scale) = MaterialFactory.GetTextureOffsetAndScale(src.occlusionTexture); MaterialFactory.SetTextureOffsetAndScale(material, "_OcclusionMap", offset, scale); } if (src.emissiveFactor != null || (src.emissiveTexture != null && src.emissiveTexture.index != -1)) { material.EnableKeyword("_EMISSION"); material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; if (src.emissiveFactor != null && src.emissiveFactor.Length == 3) { material.SetColor("_EmissionColor", new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2])); } if (src.emissiveTexture != null && src.emissiveTexture.index != -1) { var(offset, scale) = MaterialFactory.GetTextureOffsetAndScale(src.emissiveTexture); var param = TextureFactory.CreateSRGB(parser, src.emissiveTexture.index, offset, scale); var texture = await getTexture(awaitCaller, parser.GLTF, param); if (texture != null) { material.SetTexture("_EmissionMap", texture); } // Texture Offset and Scale MaterialFactory.SetTextureOffsetAndScale(material, "_EmissionMap", param.Offset, param.Scale); } } BlendMode blendMode = BlendMode.Opaque; // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 switch (src.alphaMode) { case "BLEND": blendMode = BlendMode.Fade; material.SetOverrideTag("RenderType", "Transparent"); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetInt("_ZWrite", 0); material.DisableKeyword("_ALPHATEST_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; break; case "MASK": blendMode = BlendMode.Cutout; material.SetOverrideTag("RenderType", "TransparentCutout"); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.SetFloat("_Cutoff", src.alphaCutoff); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; break; default: // OPAQUE blendMode = BlendMode.Opaque; material.SetOverrideTag("RenderType", ""); material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = -1; break; } material.SetFloat("_Mode", (float)blendMode); return(material); }
public async Task <Material> LoadAsync(MaterialDescriptor matDesc, GetTextureAsyncFunc getTexture, IAwaitCaller awaitCaller) { if (m_externalMap.TryGetValue(matDesc.SubAssetKey, out Material material)) { m_materials.Add(new MaterialLoadInfo(matDesc.SubAssetKey, material, true)); return(material); } if (getTexture == null) { getTexture = (x, y) => Task.FromResult <Texture>(null); } var shaderName = matDesc.ShaderName; if (String.IsNullOrEmpty(shaderName)) { throw new Exception("no shader name"); } if (m_fallbackShaders.TryGetValue(shaderName, out string fallback)) { Debug.LogWarning($"fallback: {shaderName} => {fallback}"); shaderName = fallback; } var shader = Shader.Find(shaderName); if (shader == null) { throw new Exception($"shader: {shaderName} not found"); } material = new Material(shader); material.name = matDesc.SubAssetKey.Name; foreach (var kv in matDesc.TextureSlots) { var texture = await getTexture(kv.Value, awaitCaller); if (texture != null) { material.SetTexture(kv.Key, texture); SetTextureOffsetAndScale(material, kv.Key, kv.Value.Offset, kv.Value.Scale); } } foreach (var kv in matDesc.Colors) { material.SetColor(kv.Key, kv.Value); } foreach (var kv in matDesc.Vectors) { material.SetVector(kv.Key, kv.Value); } foreach (var kv in matDesc.FloatValues) { material.SetFloat(kv.Key, kv.Value); } if (matDesc.RenderQueue.HasValue) { material.renderQueue = matDesc.RenderQueue.Value; } foreach (var action in matDesc.Actions) { action(material); } m_materials.Add(new MaterialLoadInfo(matDesc.SubAssetKey, material, false)); return(material); }
public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture) { var item = vrmMaterial; var shaderName = item.shader; var shader = Shader.Find(shaderName); if (shader == null) { // // no shader // if (VRM_SHADER_NAMES.Contains(shaderName)) { Debug.LogErrorFormat("shader {0} not found. set Assets/VRM/Shaders/VRMShaders to Edit - project setting - Graphics - preloaded shaders", shaderName); } else { // #if VRM_DEVELOP // Debug.LogWarningFormat("unknown shader {0}.", shaderName); // #endif } return(await MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, gltf, m_index, getTexture)); } // // restore VRM material // var material = new Material(shader); // use material.name, because material name may renamed in GltfParser. material.name = gltf.materials[m_index].name; material.renderQueue = item.renderQueue; foreach (var kv in item.floatProperties) { material.SetFloat(kv.Key, kv.Value); } foreach (var kv in item.vectorProperties) { if (item.textureProperties.ContainsKey(kv.Key)) { // texture offset & scale material.SetTextureOffset(kv.Key, new Vector2(kv.Value[0], kv.Value[1])); material.SetTextureScale(kv.Key, new Vector2(kv.Value[2], kv.Value[3])); } else { // vector4 var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]); material.SetVector(kv.Key, v); } } foreach (var kv in item.textureProperties) { var param = GetTextureParam.Create(gltf, kv.Value, kv.Key, 1, 1); var texture = await getTexture(awaitCaller, gltf, param); if (texture != null) { material.SetTexture(kv.Key, texture); } } foreach (var kv in item.keywordMap) { if (kv.Value) { material.EnableKeyword(kv.Key); } else { material.DisableKeyword(kv.Key); } } foreach (var kv in item.tagMap) { material.SetOverrideTag(kv.Key, kv.Value); } if (shaderName == MToon.Utils.ShaderName) { // TODO: Material拡張にMToonの項目が追加されたら旧バージョンのshaderPropから変換をかける // インポート時にUniVRMに含まれるMToonのバージョンに上書きする material.SetFloat(MToon.Utils.PropVersion, MToon.Utils.VersionNumber); } return(material); }
public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, GltfParser parser, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture) { var item = vrmMaterial; var shaderName = item.shader; var shader = Shader.Find(shaderName); if (shader == null) { // // no shader // if (VRM_SHADER_NAMES.Contains(shaderName)) { Debug.LogErrorFormat("shader {0} not found. set Assets/VRM/Shaders/VRMShaders to Edit - project setting - Graphics - preloaded shaders", shaderName); } else { // #if VRM_DEVELOP // Debug.LogWarningFormat("unknown shader {0}.", shaderName); // #endif } return(await MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, parser, m_index, getTexture)); } // // restore VRM material // var material = new Material(shader); // use material.name, because material name may renamed in GltfParser. material.name = parser.GLTF.materials[m_index].name; material.renderQueue = item.renderQueue; foreach (var kv in item.floatProperties) { material.SetFloat(kv.Key, kv.Value); } var offsetScaleMap = new Dictionary <string, float[]>(); foreach (var kv in item.vectorProperties) { if (item.textureProperties.ContainsKey(kv.Key)) { // texture offset & scale offsetScaleMap.Add(kv.Key, kv.Value); } else { // vector4 var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]); material.SetVector(kv.Key, v); } } foreach (var kv in item.textureProperties) { var(offset, scale) = (Vector2.zero, Vector2.one); if (offsetScaleMap.TryGetValue(kv.Key, out float[] value))
public Task <Material> CreateMaterialAsync(IAwaitCaller awaitCaller, GltfParser parser, int i, GetTextureAsyncFunc getTexture) { if (i == 0 && m_materials.Count == 0) { // dummy return(MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, parser, i, getTexture)); } return(MToonMaterialItem.CreateAsync(awaitCaller, parser, i, m_materials[i], getTexture)); }
public static async Awaitable <Material> CreateAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor) { if (getTexture == null) { getTexture = (_x, _y) => Awaitable.FromResult <Texture2D>(default);