void HandleBaseColor(Rhino.DocObjects.Material rhinoMaterial, glTFLoader.Schema.Material gltfMaterial) { Rhino.DocObjects.Texture baseColorDoc = rhinoMaterial.GetTexture(TextureType.PBR_BaseColor); Rhino.DocObjects.Texture alphaTextureDoc = rhinoMaterial.GetTexture(TextureType.PBR_Alpha); RenderTexture baseColorTexture = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrBaseColor); RenderTexture alphaTexture = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrAlpha); bool baseColorLinear = baseColorTexture == null ? false : IsLinear(baseColorTexture); bool hasBaseColorTexture = baseColorDoc == null ? false : baseColorDoc.Enabled; bool hasAlphaTexture = alphaTextureDoc == null ? false : alphaTextureDoc.Enabled; bool baseColorDiffuseAlphaForTransparency = rhinoMaterial.PhysicallyBased.UseBaseColorTextureAlphaForObjectAlphaTransparencyTexture; Color4f baseColor = rhinoMaterial.PhysicallyBased.BaseColor; if (workflow.PreProcessColors) { baseColor = Color4f.ApplyGamma(baseColor, workflow.PreProcessGamma); } if (!hasBaseColorTexture && !hasAlphaTexture) { gltfMaterial.PbrMetallicRoughness.BaseColorFactor = new float[] { baseColor.R, baseColor.G, baseColor.B, (float)rhinoMaterial.PhysicallyBased.Alpha, }; if (rhinoMaterial.PhysicallyBased.Alpha == 1.0) { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.OPAQUE; } else { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.BLEND; } } else { gltfMaterial.PbrMetallicRoughness.BaseColorTexture = CombineBaseColorAndAlphaTexture(baseColorTexture, alphaTexture, baseColorDiffuseAlphaForTransparency, baseColor, baseColorLinear, (float)rhinoMaterial.PhysicallyBased.Alpha, out bool hasAlpha); if (hasAlpha) { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.BLEND; } else { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.OPAQUE; } } }
private glTFLoader.Schema.MaterialOcclusionTextureInfo AddTextureOcclusion(Rhino.DocObjects.Texture texture) { int textureIdx = AddTextureToBuffers(texture.FileReference.FullPath); return(new glTFLoader.Schema.MaterialOcclusionTextureInfo() { Index = textureIdx, TexCoord = 0, Strength = GetTextureWeight(texture), }); }
private int AddNormalTexture(Rhino.DocObjects.Texture normalTexture) { Bitmap bmp = new Bitmap(normalTexture.FileReference.FullPath); if (!Rhino.BitmapExtensions.IsNormalMap(bmp, true, out bool pZ)) { bmp = Rhino.BitmapExtensions.ConvertToNormalMap(bmp, true, out pZ); } return(GetTextureFromBitmap(bmp)); }
private int AddNormalTexture(Rhino.DocObjects.Texture normalTexture, RenderTexture normalRenderTexture) { if (normalRenderTexture.IsNormalMap()) { return(AddTextureToBuffers(normalTexture.FileReference.FullPath)); } else { Bitmap bmp = ConvertBumpToNormal(normalRenderTexture); return(GetTextureFromBitmap(bmp)); } }
private glTFLoader.Schema.MaterialNormalTextureInfo AddTextureNormal(Rhino.DocObjects.Texture normalTexture) { int textureIdx = AddNormalTexture(normalTexture); float weight = GetTextureWeight(normalTexture); return(new glTFLoader.Schema.MaterialNormalTextureInfo() { Index = textureIdx, TexCoord = 0, Scale = weight, }); }
private glTFLoader.Schema.MaterialNormalTextureInfo AddTextureNormal(Rhino.DocObjects.Texture normalTexture) { Rhino.Render.RenderTexture normalRenderTexture = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.Bump); int textureIdx = AddNormalTexture(normalTexture, normalRenderTexture); double scale = rhinoMaterial.RenderMaterial.GetTextureAmountFromUsage(RenderMaterial.StandardChildSlots.Bump) / 100.0; return(new glTFLoader.Schema.MaterialNormalTextureInfo() { Index = textureIdx, TexCoord = 0, Scale = (float)scale, }); }
glTFLoader.Schema.TextureInfo GetSingleChannelTexture(Rhino.DocObjects.Texture texture, RgbaChannel channel, bool invert) { string path = texture.FileReference.FullPath; Bitmap bmp = new Bitmap(path); Bitmap final = new Bitmap(bmp.Width, bmp.Height); for (int i = 0; i < bmp.Width; i++) { for (int j = 0; j < bmp.Height; j++) { Color4f color = new Color4f(bmp.GetPixel(i, j)); float value = color.L; if (invert) { value = 1.0f - value; } Color colorFinal = GetSingleChannelColor(value, channel); final.SetPixel(i, j, colorFinal); } } int textureIndex = GetTextureFromBitmap(final); glTFLoader.Schema.TextureInfo textureInfo = new glTFLoader.Schema.TextureInfo() { Index = textureIndex, TexCoord = 0, }; return(textureInfo); }
public glTFLoader.Schema.TextureInfo AddMetallicRoughnessTexture(Rhino.DocObjects.Material rhinoMaterial) { Rhino.DocObjects.Texture metalTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Metallic); Rhino.DocObjects.Texture roughnessTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Roughness); bool hasMetalTexture = metalTexture == null ? false : metalTexture.Enabled; bool hasRoughnessTexture = roughnessTexture == null ? false : roughnessTexture.Enabled; RenderTexture renderTextureMetal = null; RenderTexture renderTextureRoughness = null; int mWidth = 0; int mHeight = 0; int rWidth = 0; int rHeight = 0; // Get the textures if (hasMetalTexture) { renderTextureMetal = rhinoMaterial.RenderMaterial.GetTextureFromUsage(Rhino.Render.RenderMaterial.StandardChildSlots.PbrMetallic); renderTextureMetal.PixelSize(out mWidth, out mHeight, out int _w0); } if (hasRoughnessTexture) { renderTextureRoughness = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrRoughness); renderTextureRoughness.PixelSize(out rWidth, out rHeight, out int _w1); } int width = Math.Max(mWidth, rWidth); int height = Math.Max(mHeight, rHeight); TextureEvaluator evalMetal = null; TextureEvaluator evalRoughness = null; // Metal if (hasMetalTexture) { evalMetal = renderTextureMetal.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); } // Roughness if (hasRoughnessTexture) { evalRoughness = renderTextureRoughness.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); } // Copy Metal to the blue channel, roughness to the green var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); float metallic = (float)rhinoMaterial.PhysicallyBased.Metallic; float roughness = (float)rhinoMaterial.PhysicallyBased.Roughness; for (var j = 0; j < height - 1; j += 1) { for (var i = 0; i < width - 1; i += 1) { double x = (double)i / (double)(width - 1); double y = (double)j / (double)(height - 1); Point3d uvw = new Point3d(x, y, 0.0); float g = 0; float b = 0; if (hasMetalTexture) { Color4f metal = evalMetal.GetColor(uvw, Vector3d.Zero, Vector3d.Zero); b = metal.L; //grayscale maps, so we want lumonosity } else { b = metallic; } if (hasRoughnessTexture) { Color4f roughnessColor = evalRoughness.GetColor(uvw, Vector3d.ZAxis, Vector3d.Zero); g = roughnessColor.L; //grayscale maps, so we want lumonosity } else { g = roughness; } Color4f color = new Color4f(0.0f, g, b, 1.0f); bitmap.SetPixel(i, height - j - 1, color.AsSystemColor()); } } return(GetTextureInfoFromBitmap(bitmap)); }
public int AddMaterial() { // Prep glTFLoader.Schema.Material material = new glTFLoader.Schema.Material() { Name = rhinoMaterial.Name, PbrMetallicRoughness = new MaterialPbrMetallicRoughness(), }; if (!rhinoMaterial.IsPhysicallyBased) { rhinoMaterial.ToPhysicallyBased(); } // Textures Rhino.DocObjects.Texture metallicTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Metallic); Rhino.DocObjects.Texture roughnessTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Roughness); Rhino.DocObjects.Texture normalTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.Bump); Rhino.DocObjects.Texture occlusionTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_AmbientOcclusion); Rhino.DocObjects.Texture emissiveTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Emission); HandleBaseColor(rhinoMaterial, material); if (metallicTexture != null || roughnessTexture != null) { material.PbrMetallicRoughness.MetallicRoughnessTexture = AddMetallicRoughnessTexture(rhinoMaterial); material.PbrMetallicRoughness.MetallicFactor = 1.0f; material.PbrMetallicRoughness.RoughnessFactor = 1.0f; } else { material.PbrMetallicRoughness.MetallicFactor = (float)rhinoMaterial.PhysicallyBased.Metallic; material.PbrMetallicRoughness.RoughnessFactor = (float)rhinoMaterial.PhysicallyBased.Roughness; } if (normalTexture != null && normalTexture.Enabled) { material.NormalTexture = AddTextureNormal(normalTexture); } if (occlusionTexture != null && occlusionTexture.Enabled) { material.OcclusionTexture = AddTextureOcclusion(occlusionTexture.FileReference.FullPath); } if (emissiveTexture != null && emissiveTexture.Enabled) { material.EmissiveTexture = AddTexture(emissiveTexture.FileReference.FullPath); float emissionMultiplier = 1.0f; var param = rhinoMaterial.RenderMaterial.GetParameter("emission-multiplier"); if (param != null) { emissionMultiplier = (float)Convert.ToDouble(param); } material.EmissiveFactor = new float[] { emissionMultiplier, emissionMultiplier, emissionMultiplier, }; } else { material.EmissiveFactor = new float[] { rhinoMaterial.PhysicallyBased.Emission.R, rhinoMaterial.PhysicallyBased.Emission.G, rhinoMaterial.PhysicallyBased.Emission.B, }; } return(dummy.Materials.AddAndReturnIndex(material)); }
private float GetTextureWeight(Rhino.DocObjects.Texture texture) { texture.GetAlphaBlendValues(out double constant, out double a0, out double a1, out double a2, out double a3); return((float)constant); }
public int AddMaterial() { // Prep glTFLoader.Schema.Material material = new glTFLoader.Schema.Material() { Name = renderMaterial.Name, PbrMetallicRoughness = new glTFLoader.Schema.MaterialPbrMetallicRoughness(), }; if (!rhinoMaterial.IsPhysicallyBased) { rhinoMaterial.ToPhysicallyBased(); } Rhino.DocObjects.PhysicallyBasedMaterial pbr = rhinoMaterial.PhysicallyBased; // Textures Rhino.DocObjects.Texture metallicTexture = pbr.GetTexture(TextureType.PBR_Metallic); Rhino.DocObjects.Texture roughnessTexture = pbr.GetTexture(TextureType.PBR_Roughness); Rhino.DocObjects.Texture normalTexture = pbr.GetTexture(TextureType.Bump); Rhino.DocObjects.Texture occlusionTexture = pbr.GetTexture(TextureType.PBR_AmbientOcclusion); Rhino.DocObjects.Texture emissiveTexture = pbr.GetTexture(TextureType.PBR_Emission); Rhino.DocObjects.Texture opacityTexture = pbr.GetTexture(TextureType.Opacity); Rhino.DocObjects.Texture clearcoatTexture = pbr.GetTexture(TextureType.PBR_Clearcoat); Rhino.DocObjects.Texture clearcoatRoughessTexture = pbr.GetTexture(TextureType.PBR_ClearcoatRoughness); Rhino.DocObjects.Texture clearcoatNormalTexture = pbr.GetTexture(TextureType.PBR_ClearcoatBump); Rhino.DocObjects.Texture specularTexture = pbr.GetTexture(TextureType.PBR_Specular); HandleBaseColor(rhinoMaterial, material); bool hasMetalTexture = metallicTexture == null ? false : metallicTexture.Enabled; bool hasRoughnessTexture = roughnessTexture == null ? false : roughnessTexture.Enabled; if (hasMetalTexture || hasRoughnessTexture) { material.PbrMetallicRoughness.MetallicRoughnessTexture = AddMetallicRoughnessTexture(rhinoMaterial); float metallic = metallicTexture == null ? (float)pbr.Metallic : GetTextureWeight(metallicTexture); float roughness = roughnessTexture == null ? (float)pbr.Roughness : GetTextureWeight(roughnessTexture); material.PbrMetallicRoughness.MetallicFactor = metallic; material.PbrMetallicRoughness.RoughnessFactor = roughness; } else { material.PbrMetallicRoughness.MetallicFactor = (float)pbr.Metallic; material.PbrMetallicRoughness.RoughnessFactor = (float)pbr.Roughness; } if (normalTexture != null && normalTexture.Enabled) { material.NormalTexture = AddTextureNormal(normalTexture); } if (occlusionTexture != null && occlusionTexture.Enabled) { material.OcclusionTexture = AddTextureOcclusion(occlusionTexture); } if (emissiveTexture != null && emissiveTexture.Enabled) { material.EmissiveTexture = AddTexture(emissiveTexture.FileReference.FullPath); float emissionMultiplier = 1.0f; var param = rhinoMaterial.RenderMaterial.GetParameter("emission-multiplier"); if (param != null) { emissionMultiplier = (float)Convert.ToDouble(param); } material.EmissiveFactor = new float[] { emissionMultiplier, emissionMultiplier, emissionMultiplier, }; } else { material.EmissiveFactor = new float[] { rhinoMaterial.PhysicallyBased.Emission.R, rhinoMaterial.PhysicallyBased.Emission.G, rhinoMaterial.PhysicallyBased.Emission.B, }; } //Extensions material.Extensions = new Dictionary <string, object>(); //Opacity => Transmission https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_transmission/README.md glTFExtensions.KHR_materials_transmission transmission = new glTFExtensions.KHR_materials_transmission(); if (opacityTexture != null && opacityTexture.Enabled) { //Transmission texture is stored in an images R channel //https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_transmission/README.md#properties transmission.TransmissionTexture = GetSingleChannelTexture(opacityTexture, RgbaChannel.Red, true); transmission.TransmissionFactor = GetTextureWeight(opacityTexture); } else { transmission.TransmissionFactor = 1.0f - (float)pbr.Opacity; } material.Extensions.Add(glTFExtensions.KHR_materials_transmission.Tag, transmission); //Clearcoat => Clearcoat https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md glTFExtensions.KHR_materials_clearcoat clearcoat = new glTFExtensions.KHR_materials_clearcoat(); if (clearcoatTexture != null && clearcoatTexture.Enabled) { clearcoat.ClearcoatTexture = AddTexture(clearcoatTexture.FileReference.FullPath); clearcoat.ClearcoatFactor = GetTextureWeight(clearcoatTexture); } else { clearcoat.ClearcoatFactor = (float)pbr.Clearcoat; } if (clearcoatRoughessTexture != null && clearcoatRoughessTexture.Enabled) { clearcoat.ClearcoatRoughnessTexture = AddTexture(clearcoatRoughessTexture.FileReference.FullPath); clearcoat.ClearcoatRoughnessFactor = GetTextureWeight(clearcoatRoughessTexture); } else { clearcoat.ClearcoatRoughnessFactor = (float)pbr.ClearcoatRoughness; } if (clearcoatNormalTexture != null && clearcoatNormalTexture.Enabled) { clearcoat.ClearcoatNormalTexture = AddTextureNormal(clearcoatNormalTexture); } material.Extensions.Add(glTFExtensions.KHR_materials_clearcoat.Tag, clearcoat); //Opacity IOR -> IOR https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior glTFExtensions.KHR_materials_ior ior = new glTFExtensions.KHR_materials_ior() { Ior = (float)pbr.OpacityIOR, }; material.Extensions.Add(glTFExtensions.KHR_materials_ior.Tag, ior); //Specular -> Specular https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular glTFExtensions.KHR_materials_specular specular = new glTFExtensions.KHR_materials_specular(); if (specularTexture != null && specularTexture.Enabled) { //Specular is stored in the textures alpha channel specular.SpecularTexture = GetSingleChannelTexture(specularTexture, RgbaChannel.Alpha, false); specular.SpecularFactor = GetTextureWeight(specularTexture); } else { specular.SpecularFactor = (float)pbr.Specular; } material.Extensions.Add(glTFExtensions.KHR_materials_specular.Tag, specular); return(dummy.Materials.AddAndReturnIndex(material)); }