private void TransformSpecularGlossiness(AssetContext asset, Texture texture, TextureReferences reference) { var specularGloss = texture as Texture2D; EnsureReadableTexture(specularGloss); var diffuse = reference.SmoothnessSource as Texture2D; EnsureReadableTexture(diffuse); var smoothnessSource = reference.SmoothnessTextureChannel == SmoothnessTextureChannel.MetallicOrSpecularAlpha ? specularGloss : diffuse; var metallicRoughMapName = GetTextureOutputName(asset.UrhoAssetName, reference); using (var fileStream = asset.DestinationFolder.Create(metallicRoughMapName)) { if (fileStream != null) { var tmpTexture = CreateTargetTexture(specularGloss, diffuse); var specularColors = new PixelSource(specularGloss, tmpTexture.width, tmpTexture.height, Color.black); var diffuseColors = new PixelSource(diffuse, tmpTexture.width, tmpTexture.height, Color.white); var smoothnessColors = specularGloss == smoothnessSource ? specularColors : diffuseColors; var pixels = new Color32[tmpTexture.width * tmpTexture.height]; var index = 0; for (var y = 0; y < tmpTexture.height; ++y) { for (var x = 0; x < tmpTexture.width; ++x) { var mr = PBRUtils.ConvertToMetallicRoughness(new PBRUtils.SpecularGlossiness { diffuse = diffuseColors.GetAt(x, y), specular = specularColors.GetAt(x, y), glossiness = smoothnessColors.GetAt(x, y).a, opacity = 1.0f }); pixels[index] = new Color(mr.roughness, mr.metallic, 0, 1); ++index; } } tmpTexture.SetPixels32(pixels, 0); var bytes = tmpTexture.EncodeToPNG(); fileStream.Write(bytes, 0, bytes.Length); } } }
public void ConvertPBRArguments(float dielectricSpecular) { var mr = new PBRUtils.MetallicRoughness() { baseColor = new Color(0.1f, 0.2f, 0.3f, 0.5f), opacity = 0.5f, roughness = 0.6f, metallic = 0.4f }; var sp = PBRUtils.ConvertToSpecularGlossiness(mr); var mr2 = PBRUtils.ConvertToMetallicRoughness(sp); Assert.AreApproximatelyEqual(mr.opacity, mr2.opacity, 1e-6f); Assert.AreApproximatelyEqual(mr.metallic, mr2.metallic, 1e-6f); Assert.AreApproximatelyEqual(mr.roughness, mr2.roughness, 1e-6f); Assert.AreApproximatelyEqual(mr.baseColor.a, mr2.baseColor.a, 1e-6f); Assert.AreApproximatelyEqual(mr.baseColor.r, mr2.baseColor.r, 1e-6f); Assert.AreApproximatelyEqual(mr.baseColor.g, mr2.baseColor.g, 1e-6f); Assert.AreApproximatelyEqual(mr.baseColor.b, mr2.baseColor.b, 1e-6f); }
public UrhoPBRMaterial FromSpecularGlossiness(SpecularGlossinessShaderArguments arguments) { var material = new UrhoPBRMaterial(); material.NormalTexture = GetScaledNormalTextureName(arguments.Bump, arguments.BumpScale); material.EmissiveTexture = Engine.EvaluateTextrueName(arguments.Emission); material.AOTexture = BuildAOTextureName(arguments.Occlusion, arguments.OcclusionStrength); var diffuseTextrueName = Engine.EvaluateTextrueName(arguments.Diffuse); var specularTexture = Engine.EvaluateTextrueName(arguments.PBRSpecular.Texture); string smoothnessTexture; if (arguments.Smoothness.Texture == arguments.Diffuse) { smoothnessTexture = diffuseTextrueName; } else { smoothnessTexture = specularTexture; } if (string.IsNullOrWhiteSpace(specularTexture) && string.IsNullOrWhiteSpace(diffuseTextrueName)) { var pbrValues = PBRUtils.ConvertToMetallicRoughnessSRGB(new PBRUtils.SpecularGlossiness { diffuse = arguments.DiffuseColor, specular = arguments.PBRSpecular.Color, opacity = arguments.DiffuseColor.a, glossiness = arguments.Glossiness }).linear(); material.BaseColor = pbrValues.baseColor; material.Metallic = pbrValues.metallic; material.Roughness = pbrValues.roughness; } else { { var baseColorTextureNameBuilder = new StringBuilder(); if (!string.IsNullOrWhiteSpace(diffuseTextrueName)) { baseColorTextureNameBuilder.Append( Path.GetDirectoryName(diffuseTextrueName).FixAssetSeparator()); } else { baseColorTextureNameBuilder.Append(Path.GetDirectoryName(specularTexture).FixAssetSeparator()); } if (baseColorTextureNameBuilder.Length > 0) { baseColorTextureNameBuilder.Append('/'); } if (!string.IsNullOrWhiteSpace(diffuseTextrueName)) { baseColorTextureNameBuilder.Append(Path.GetFileNameWithoutExtension(diffuseTextrueName)); } else { baseColorTextureNameBuilder.Append(FormatRGB(arguments.DiffuseColor.linear)); } baseColorTextureNameBuilder.Append('.'); if (!string.IsNullOrWhiteSpace(specularTexture)) { baseColorTextureNameBuilder.Append(Path.GetFileNameWithoutExtension(specularTexture)); } else { baseColorTextureNameBuilder.Append(FormatRGB(arguments.PBRSpecular.Color.linear)); } baseColorTextureNameBuilder.Append(".BaseColor.dds"); material.BaseColorTexture = baseColorTextureNameBuilder.ToString(); } { var metallicTextureNameBuilder = new StringBuilder(); if (!string.IsNullOrWhiteSpace(specularTexture)) { metallicTextureNameBuilder.Append(Path.GetDirectoryName(specularTexture).FixAssetSeparator()); } else { metallicTextureNameBuilder.Append(Path.GetDirectoryName(diffuseTextrueName) .FixAssetSeparator()); } if (metallicTextureNameBuilder.Length > 0) { metallicTextureNameBuilder.Append('/'); } if (!string.IsNullOrWhiteSpace(specularTexture)) { metallicTextureNameBuilder.Append(Path.GetFileNameWithoutExtension(specularTexture)); } else { metallicTextureNameBuilder.Append(FormatRGB(arguments.PBRSpecular.Color.linear)); } metallicTextureNameBuilder.Append('.'); if (!string.IsNullOrWhiteSpace(diffuseTextrueName)) { metallicTextureNameBuilder.Append(Path.GetFileNameWithoutExtension(diffuseTextrueName)); } else { metallicTextureNameBuilder.Append(FormatRGB(arguments.DiffuseColor.linear)); } if (!string.IsNullOrWhiteSpace(smoothnessTexture)) { if (arguments.GlossinessTextureScale < 0.999f) { metallicTextureNameBuilder.Append('.'); metallicTextureNameBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0:0.000}", arguments.GlossinessTextureScale); } } else { if (arguments.Glossiness > 0) { metallicTextureNameBuilder.Append('.'); metallicTextureNameBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0:0.000}", arguments.Glossiness); } } metallicTextureNameBuilder.Append(".MetallicRoughness.dds"); material.MetallicRoughnessTexture = metallicTextureNameBuilder.ToString(); } if (arguments.Diffuse != null) { material.BaseColor = arguments.DiffuseColor.linear; } else { material.BaseColor = Color.white; } } material.AlphaBlend = arguments.Transparent; if (arguments.AlphaTest) { material.PixelShaderDefines.Add("ALPHAMASK"); } if (arguments.Emission != null) { material.EmissiveColor = Color.white; } else { material.EmissiveColor = arguments.EmissiveColor.linear; } material.MatSpecColor = new Color(1, 1, 1, 0); material.UOffset = new Vector4(arguments.MainTextureScale.x, 0, 0, arguments.MainTextureOffset.x); material.VOffset = new Vector4(0, arguments.MainTextureScale.y, 0, arguments.MainTextureOffset.y); material.EvaluateTechnique(); return(material); }