예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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),
            });
        }
예제 #3
0
        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));
        }
예제 #4
0
 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));
     }
 }
예제 #5
0
        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,
            });
        }
예제 #6
0
        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,
            });
        }
예제 #7
0
        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);
        }
예제 #8
0
        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));
        }
예제 #9
0
        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));
        }
예제 #10
0
        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);
        }
예제 #11
0
        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));
        }