protected string GetScaledNormalTextureName(Texture bump, float bumpScale, UrhoPBRMaterial material) { var normalTexture = Engine.EvaluateTextrueName(bump); if (bumpScale < 0.999f) { normalTexture = ExportUtils.ReplaceExtension(normalTexture, string.Format(CultureInfo.InvariantCulture, "{0:0.000}.dds", bumpScale)); } return(normalTexture); }
private void WriteTerrainMaterial(TerrainData terrain, PrefabContext prefabContext) { using (var writer = _engine.TryCreateXml(terrain.GetKey(), EvaluateMaterial(terrain), ExportUtils.GetLastWriteTimeUtc(terrain))) { if (writer == null) { return; } var layers = terrain.terrainLayers; var layerIndices = GetTerrainLayersByPopularity(terrain).Take(_maxLayers).ToArray(); var material = new UrhoPBRMaterial(); material.Technique = "Techniques/PBR/PBRTerrainBlend.xml"; material.TextureUnits.Add(EvaluateWeightsMap(terrain)); Vector2 detailTiling = new Vector2(1, 1); for (var layerIndex = 0; layerIndex < layerIndices.Length; ++layerIndex) { var layer = layers[layerIndices[layerIndex]]; detailTiling = new Vector2(terrain.size.x / layer.tileSize.x, terrain.size.z / layer.tileSize.y); if (layer.diffuseTexture != null) { _engine.ScheduleTexture(layer.diffuseTexture); var urhoAssetName = _engine.EvaluateTextrueName(layer.diffuseTexture); material.TextureUnits.Add(urhoAssetName); } else { material.TextureUnits.Add(null); } } material.MatSpecColor = new Color(0.0f, 0.0f, 0.0f, 1.0f); material.Roughness = 1; material.Metallic = 0; material.ExtraParameters.Add("DetailTiling", detailTiling); material.PixelShaderDefines.Add("TERRAINLAYERS" + layerIndices.Length.ToString(CultureInfo.InvariantCulture)); StandardMaterialExporter.WriteMaterial(writer, material, prefabContext); } }
public void ExportPBRTextures(MetallicGlossinessShaderArguments arguments, UrhoPBRMaterial urhoMaterial) { if (!_engine.Options.ExportTextures) { return; } if (!string.IsNullOrWhiteSpace(urhoMaterial.MetallicRoughnessTexture)) { TransformMetallicGlossiness(arguments, urhoMaterial.MetallicRoughnessTexture); } if (!string.IsNullOrWhiteSpace(urhoMaterial.AOTexture)) { TransformAOTexture(arguments, urhoMaterial.AOTexture); } if (!string.IsNullOrWhiteSpace(urhoMaterial.NormalTexture)) { TransformNormal(arguments.Bump, arguments.BumpScale, urhoMaterial.NormalTexture); } }
public void SchedulePBRTextures(SpecularGlossinessShaderArguments arguments, UrhoPBRMaterial urhoMaterial) { EditorTaskScheduler.Default.ScheduleForegroundTask( () => _textureExporter.ExportPBRTextures(arguments, urhoMaterial), urhoMaterial.MetallicRoughnessTexture); }
protected virtual UrhoPBRMaterial FromMetallicGlossiness(Material mat, MetallicGlossinessShaderArguments arguments) { var material = new UrhoPBRMaterial(); material.NormalTexture = GetScaledNormalTextureName(arguments.Bump, arguments.BumpScale, material); material.EmissiveTexture = Engine.EvaluateTextrueName(arguments.Emission); material.AOTexture = BuildAOTextureName(arguments.Occlusion, arguments.OcclusionStrength); material.BaseColorTexture = Engine.EvaluateTextrueName(arguments.BaseColor); var metalicGlossinesTexture = Engine.EvaluateTextrueName(arguments.MetallicGloss); var smoothnessTexture = Engine.EvaluateTextrueName(arguments.Smoothness); var linearMetallic = new Color(arguments.Metallic, 0, 0, 1).linear.r; if (string.IsNullOrWhiteSpace(metalicGlossinesTexture) && string.IsNullOrWhiteSpace(smoothnessTexture)) { material.Metallic = linearMetallic; material.Roughness = 1.0f - arguments.Glossiness; } else { var texNameBuilder = new StringBuilder(); if (!string.IsNullOrWhiteSpace(metalicGlossinesTexture)) { texNameBuilder.Append(Path.GetDirectoryName(metalicGlossinesTexture).FixAssetSeparator()); } else { texNameBuilder.Append(Path.GetDirectoryName(smoothnessTexture).FixAssetSeparator()); } if (texNameBuilder.Length > 0) { texNameBuilder.Append('/'); } if (!string.IsNullOrWhiteSpace(metalicGlossinesTexture)) { texNameBuilder.Append(Path.GetFileNameWithoutExtension(metalicGlossinesTexture)); } else { texNameBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0:0.00}", linearMetallic); } if (smoothnessTexture != metalicGlossinesTexture) { texNameBuilder.Append('.'); texNameBuilder.Append(Path.GetFileNameWithoutExtension(smoothnessTexture)); } if (arguments.SmoothnessRemapMax < 0.999f) { texNameBuilder.Append('.'); texNameBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0:0.000}", arguments.SmoothnessRemapMax); } texNameBuilder.Append(".MetallicRoughness.png"); material.MetallicRoughnessTexture = texNameBuilder.ToString(); } material.BaseColor = arguments.BaseColorColor.linear; material.AlphaBlend = arguments.Transparent; material.Cull = Urho3DCulling.ccw; material.ShadowCull = Urho3DCulling.ccw; if (arguments.AlphaTest) { material.PixelShaderDefines.Add("ALPHAMASK"); } 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); }
public static void WriteMaterial(XmlWriter writer, UrhoPBRMaterial urhoMaterial, PrefabContext prefabContext) { writer.WriteStartElement("material"); writer.WriteWhitespace(Environment.NewLine); WriteTechnique(writer, urhoMaterial.Technique); WriteTexture(urhoMaterial.BaseColorTexture, writer, "diffuse", prefabContext); WriteTexture(urhoMaterial.NormalTexture, writer, "normal", prefabContext); WriteTexture(urhoMaterial.MetallicRoughnessTexture, writer, "specular", prefabContext); if (!string.IsNullOrWhiteSpace(urhoMaterial.EmissiveTexture)) { WriteTexture(urhoMaterial.EmissiveTexture, writer, "emissive", prefabContext); } else { WriteTexture(urhoMaterial.AOTexture, writer, "emissive", prefabContext); } for (var index = 0; index < urhoMaterial.TextureUnits.Count; index++) { if (!string.IsNullOrWhiteSpace(urhoMaterial.TextureUnits[index])) { WriteTexture(urhoMaterial.TextureUnits[index], writer, index, prefabContext); } } writer.WriteParameter("MatEmissiveColor", urhoMaterial.EmissiveColor); writer.WriteParameter("MatDiffColor", urhoMaterial.BaseColor); writer.WriteParameter("MatEnvMapColor", urhoMaterial.MatEnvMapColor); writer.WriteParameter("MatSpecColor", urhoMaterial.MatSpecColor); writer.WriteParameter("Roughness", urhoMaterial.Roughness); writer.WriteParameter("Metallic", urhoMaterial.Metallic); writer.WriteParameter("UOffset", urhoMaterial.UOffset); writer.WriteParameter("VOffset", urhoMaterial.VOffset); writer.WriteElementParameter("cull", "value", urhoMaterial.Cull.ToString()); writer.WriteElementParameter("shadowcull", "value", urhoMaterial.ShadowCull.ToString()); foreach (var extraParameter in urhoMaterial.ExtraParameters) { var val = extraParameter.Value; if (val is float floatValue) { writer.WriteParameter(extraParameter.Key, floatValue); } else if (val is Vector2 vec2Value) { writer.WriteParameter(extraParameter.Key, vec2Value); } else if (val is Vector3 vec3Value) { writer.WriteParameter(extraParameter.Key, vec3Value); } else if (val is Vector4 vec4Value) { writer.WriteParameter(extraParameter.Key, vec4Value); } else if (val is Quaternion quatValue) { writer.WriteParameter(extraParameter.Key, quatValue); } else if (val is Color colorValue) { writer.WriteParameter(extraParameter.Key, colorValue); } else if (val is Color32 color32Value) { writer.WriteParameter(extraParameter.Key, color32Value); } else if (val is string strValue) { writer.WriteParameter(extraParameter.Key, strValue); } } if (urhoMaterial.PixelShaderDefines.Count != 0 || urhoMaterial.VertexShaderDefines.Count != 0) { writer.WriteWhitespace("\t"); writer.WriteStartElement("shader"); writer.WriteAttributeString("psdefines", string.Join(" ", urhoMaterial.PixelShaderDefines)); writer.WriteAttributeString("vsdefines", string.Join(" ", urhoMaterial.VertexShaderDefines)); writer.WriteEndElement(); writer.WriteWhitespace(Environment.NewLine); } writer.WriteEndElement(); }
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); }