예제 #1
0
        void    GenerateMaterial(AxFService.AxFFile.Material _material, System.IO.DirectoryInfo _targetDirectory, TEXTURE_TYPE[] _textureTypes, string[] _textureGUIDs)
        {
            string templateTexture = "    - <TEX_VARIABLE_NAME>:\n" +
                                     "        m_Texture: {fileID: <FILE ID>, guid: <GUID>, type: 3}\n" +
                                     "        m_Scale: {x: 1, y: 1}\n" +
                                     "        m_Offset: {x: 0, y: 0}\n";

            string materialContent = Properties.Resources.TemplateMaterial;

            //////////////////////////////////////////////////////////////////////////
            // Generate textures array
            bool   hasClearCoat            = false;
            bool   hasHeightMap            = false;
            string texturesArray           = "";
            float  specularLobeScaleFactor = 1.0f;
            float  BRDFColorScaleFactor    = 1.0f;
            float  BTFFlakeScaleFactor     = 1.0f;

            for (int textureIndex = 0; textureIndex < _textureTypes.Length; textureIndex++)
            {
                AxFService.AxFFile.Material.Texture texture = _material.Textures[textureIndex];
//				int		fileID = 2800000 + textureIndex;
                int    fileID       = 2800000;
                string GUID         = _textureGUIDs[textureIndex];
                string variableName = null;
                switch (_textureTypes[textureIndex])
                {
                case TEXTURE_TYPE.ANISOTROPY_ANGLE:             variableName = "_SVBRDF_AnisotropicRotationAngleMap"; break;

                case TEXTURE_TYPE.CLEARCOAT_COLOR:              variableName = "_SVBRDF_ClearCoatColorMap_sRGB"; hasClearCoat = true; break;

                case TEXTURE_TYPE.CLEARCOAT_IOR:                variableName = "_SVBRDF_ClearCoatIORMap_sRGB"; hasClearCoat = true; break;

                case TEXTURE_TYPE.CLEARCOAT_NORMAL:             variableName = "_SVBRDF_ClearCoatNormalMap"; hasClearCoat = true; break;

                case TEXTURE_TYPE.DIFFUSE_COLOR:                variableName = "_SVBRDF_DiffuseColorMap_sRGB"; break;

                case TEXTURE_TYPE.FRESNEL:                              variableName = "_SVBRDF_FresnelMap_sRGB"; break;

                case TEXTURE_TYPE.HEIGHT:                               variableName = "_SVBRDF_HeightMap"; hasHeightMap = true; break;

                case TEXTURE_TYPE.NORMAL:                               variableName = "_SVBRDF_NormalMap"; break;

                case TEXTURE_TYPE.OPACITY:                              variableName = "_SVBRDF_OpacityMap"; break;

                case TEXTURE_TYPE.SPECULAR_COLOR:               variableName = "_SVBRDF_SpecularColorMap_sRGB"; break;

                case TEXTURE_TYPE.SPECULAR_LOBE:                variableName = "_SVBRDF_SpecularLobeMap"; specularLobeScaleFactor = Mathf.Max(1, texture.MaxValue); break;

                // Car Paint
                case TEXTURE_TYPE.BRDF_COLOR:                   variableName = "_CarPaint_BRDFColorMap_sRGB"; BRDFColorScaleFactor = Mathf.Max(1, texture.MaxValue); break;

                case TEXTURE_TYPE.BTF_FLAKES:                   variableName = "_CarPaint_BTFFlakesMap_sRGB"; BTFFlakeScaleFactor = Mathf.Max(1, texture.MaxValue); break;

                default:
                    throw new Exception("Unsupported texture type! Can't match to variable name...");
                }
                string textureEntry = templateTexture.Replace("<FILE ID>", fileID.ToString());
                textureEntry   = textureEntry.Replace("<GUID>", GUID);
                textureEntry   = textureEntry.Replace("<TEX_VARIABLE_NAME>", variableName);
                texturesArray += textureEntry;
            }


            //////////////////////////////////////////////////////////////////////////
            // Generate uniforms array
            string uniformsArray = "";
            string colorsArray   = "";

            uniformsArray += "    - _materialSizeU_mm: 10\n";
            uniformsArray += "    - _materialSizeV_mm: 10\n";

            switch (_material.Type)
            {
            case AxFService.AxFFile.Material.TYPE.SVBRDF:   uniformsArray += "    - _AxF_BRDFType: 0\n"; break;

            case AxFService.AxFFile.Material.TYPE.CARPAINT: uniformsArray += "    - _AxF_BRDFType: 1\n"; break;

            case AxFService.AxFFile.Material.TYPE.BTF:              uniformsArray += "    - _AxF_BRDFType: 2\n"; break;
            }

            switch (_material.Type)
            {
            case AxFService.AxFFile.Material.TYPE.SVBRDF: {
                // Setup flags
                uint flags = 0;
                flags |= _material.IsAnisotropic ? 1U : 0;
                flags |= hasClearCoat ? 2U : 0;
                flags |= _material.GetPropertyInt("cc_no_refraction", 0) == 1 ? 0 : 4U;                                                 // Explicitly use no refraction
                flags |= hasHeightMap ? 8U : 0;

                uniformsArray += "    - _flags: " + flags + "\n";

                // Setup SVBRDF diffuse & specular types
                uint BRDFType = 0;
                BRDFType |= (uint)_material.DiffuseType;
                BRDFType |= ((uint)_material.SpecularType) << 1;

                uniformsArray += "    - _SVBRDF_BRDFType: " + BRDFType + "\n";

                // Setup SVBRDF fresnel and specular variants
                uint BRDFVariants = 0;
                BRDFVariants |= ((uint)_material.FresnelVariant & 3);
                switch (_material.SpecularVariant)
                {
                // Ward variants
                case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.GEISLERMORODER:        BRDFVariants |= 0U << 2; break;

                case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.DUER:                          BRDFVariants |= 1U << 2; break;

                case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.WARD:                          BRDFVariants |= 2U << 2; break;

                // Blinn variants
                case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.ASHIKHMIN_SHIRLEY:     BRDFVariants |= 0U << 4; break;

                case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.BLINN:                         BRDFVariants |= 1U << 4; break;

                case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.VRAY:                          BRDFVariants |= 2U << 4; break;

                case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.LEWIS:                         BRDFVariants |= 3U << 4; break;
                }

                uniformsArray += "    - _SVBRDF_BRDFVariants: " + BRDFVariants + "\n";

                // Write scale factor for specular lobe
                uniformsArray += "    - _SVBRDF_SpecularLobeMap_Scale: " + specularLobeScaleFactor + "\n";

                float heightMapSize_mm = 0.0f;                                  // @TODO!
                uniformsArray += "    - _SVBRDF_heightMapMax_mm: " + heightMapSize_mm + "\n";

                break;
            }

            case AxFService.AxFFile.Material.TYPE.CARPAINT: {
                // Setup flags
                uint flags = 0;
                flags |= _material.IsAnisotropic ? 1U : 0;
                flags |= hasClearCoat ? 2U : 0;
                flags |= _material.GetPropertyInt("cc_no_refraction", 0) == 1 ? 0 : 4U;                                                 // Explicitly use no refraction
//							flags |= hasHeightMap ? 8U : 0;

                uniformsArray += "    - _flags: " + flags + "\n";

                uniformsArray += "    - _CarPaint_CT_diffuse: " + _material.GetPropertyFloat("CT_diffuse", 0) + "\n";
                uniformsArray += "    - _CarPaint_IOR: " + _material.GetPropertyFloat("IOR", 1) + "\n";
                uniformsArray += "    - _CarPaint_maxThetaI: " + _material.GetPropertyInt("max_thetaI", 0) + "\n";
                uniformsArray += "    - _CarPaint_numThetaF: " + _material.GetPropertyInt("num_thetaF", 0) + "\n";
                uniformsArray += "    - _CarPaint_numThetaI: " + _material.GetPropertyInt("num_thetaI", 0) + "\n";

                // Write scale factor for BRDF color
                uniformsArray += "    - _CarPaint_BRDFColorMap_Scale: " + BRDFColorScaleFactor + "\n";
                uniformsArray += "    - _CarPaint_BTFFlakesMap_Scale: " + BTFFlakeScaleFactor + "\n";

                // =========================================================================================
                // Setup simple arrays as colors
                float[] CT_F0s = _material.GetPropertyRaw("CT_F0s") as float[];
                if (CT_F0s == null || CT_F0s.Length != 3)
                {
                    throw new Exception("Expected 3 float values for F0!");
                }

                float[] CT_coeffs = _material.GetPropertyRaw("CT_coeffs") as float[];
                if (CT_coeffs == null || CT_coeffs.Length != 3)
                {
                    throw new Exception("Expected 3 float values for coefficients!");
                }

                float[] CT_spreads = _material.GetPropertyRaw("CT_spreads") as float[];
                if (CT_spreads == null || CT_spreads.Length != 3)
                {
                    throw new Exception("Expected 3 float values for spreads!");
                }

                uniformsArray += "    - _CarPaint_lobesCount: " + CT_F0s.Length + "\n";

                colorsArray += "    - _CarPaint_CT_F0s: {r: " + CT_F0s[0] + ", g: " + CT_F0s[1] + ", b: " + CT_F0s[2] + ", a: 0 }\n";
                colorsArray += "    - _CarPaint_CT_coeffs: {r: " + CT_coeffs[0] + ", g: " + CT_coeffs[1] + ", b: " + CT_coeffs[2] + ", a: 0 }\n";
                colorsArray += "    - _CarPaint_CT_spreads: {r: " + CT_spreads[0] + ", g: " + CT_spreads[1] + ", b: " + CT_spreads[2] + ", a: 0 }\n";

                // =========================================================================================
                // Create a custom texture for sliceLUT
                int[] thetaFI_sliceLUT = _material.GetPropertyRaw("thetaFI_sliceLUT") as int[];
                if (thetaFI_sliceLUT == null)
                {
                    throw new Exception("Slice LUT not found!");
                }

                ImageUtility.ImageFile texSliceLUT = new ImageUtility.ImageFile((uint)thetaFI_sliceLUT.Length, 1, ImageUtility.PIXEL_FORMAT.R8, new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.LINEAR));
                texSliceLUT.WritePixels((uint _X, uint _Y, ref float4 _color) => {
                        _color.x = thetaFI_sliceLUT[_X] / 255.0f;
                    });

                System.IO.FileInfo targetTextureFileName = new System.IO.FileInfo(System.IO.Path.Combine(_targetDirectory.FullName, _material.Name, "sliceLUT.png"));
                texSliceLUT.Save(targetTextureFileName, ImageUtility.ImageFile.FILE_FORMAT.PNG);
                string GUID = GenerateMeta(targetTextureFileName, checkBoxGenerateMeta.Checked, checkBoxOverwriteExistingMeta.Checked, false, false, false, false);

                string textureEntry = templateTexture.Replace("<FILE ID>", 2800000.ToString());
                textureEntry   = textureEntry.Replace("<GUID>", GUID);
                textureEntry   = textureEntry.Replace("<TEX_VARIABLE_NAME>", "_CarPaint_thetaFI_sliceLUTMap");
                texturesArray += textureEntry;

                break;
            }

            default:
                throw new Exception("TODO! Support feeding variables to other BRDF types!");
            }


            //////////////////////////////////////////////////////////////////////////
            // Replace placeholders in template
            materialContent = materialContent.Replace("<TEXTURES ARRAY>", texturesArray);
            materialContent = materialContent.Replace("<UNIFORMS ARRAY>", uniformsArray);
            materialContent = materialContent.Replace("<COLORS ARRAY>", colorsArray);


            // Write target file
            System.IO.FileInfo materialFileName = new System.IO.FileInfo(System.IO.Path.Combine(_targetDirectory.FullName, _material.Name, "material.mat"));
            using (System.IO.StreamWriter S = materialFileName.CreateText())
                S.Write(materialContent);
        }
예제 #2
0
        void    DumpMaterial(AxFService.AxFFile.Material _material, System.IO.DirectoryInfo _targetDirectory)
        {
            System.IO.DirectoryInfo fullTargetDirectory = new System.IO.DirectoryInfo(System.IO.Path.Combine(_targetDirectory.FullName, _material.Name));
            if (!fullTargetDirectory.Exists)
            {
                fullTargetDirectory.Create();
            }

            AxFService.AxFFile.Material.Texture[] textures = _material.Textures;
            TEXTURE_TYPE[] textureTypes  = new TEXTURE_TYPE[textures.Length];
            string[]       GUIDs         = new string[textures.Length];
            bool           allGUIDsValid = true;

            for (int textureIndex = 0; textureIndex < textures.Length; textureIndex++)
            {
                AxFService.AxFFile.Material.Texture texture = textures[textureIndex];

                TEXTURE_TYPE textureType = TEXTURE_TYPE.UNKNOWN;
                switch (texture.Name.ToLower())
                {
                case "diffusecolor":    textureType = TEXTURE_TYPE.DIFFUSE_COLOR; break;

                case "specularcolor":   textureType = TEXTURE_TYPE.SPECULAR_COLOR; break;

                case "normal":                  textureType = TEXTURE_TYPE.NORMAL; break;

                case "fresnel":                 textureType = TEXTURE_TYPE.FRESNEL; break;

                case "specularlobe":    textureType = TEXTURE_TYPE.SPECULAR_LOBE; break;

                case "anisorotation":   textureType = TEXTURE_TYPE.ANISOTROPY_ANGLE; break;

                case "height":                  textureType = TEXTURE_TYPE.HEIGHT; break;

                case "opacity":                 textureType = TEXTURE_TYPE.OPACITY; break;

                case "clearcoatcolor":  textureType = TEXTURE_TYPE.CLEARCOAT_COLOR; break;

                case "clearcoatnormal": textureType = TEXTURE_TYPE.CLEARCOAT_NORMAL; break;

                case "clearcoatior":    textureType = TEXTURE_TYPE.CLEARCOAT_IOR; break;

                // Car Paint
                case "brdfcolors":              textureType = TEXTURE_TYPE.BRDF_COLOR; break;

                case "btfflakes":               textureType = TEXTURE_TYPE.BTF_FLAKES; break;

                default:
                    throw new Exception("Unsupported texture type \"" + texture.Name + "\"!");
                }

                textureTypes[textureIndex] = textureType;

                bool sRGB        = ((int)textureType & (int)TEXTURE_TYPE.FLAG_sRGB) != 0;
                bool isNormalMap = ((int)textureType & (int)TEXTURE_TYPE.FLAG_NORMAL) != 0;
                bool isIOR       = ((int)textureType & (int)TEXTURE_TYPE.FLAG_IOR) != 0;
                bool isAngle     = ((int)textureType & (int)TEXTURE_TYPE.FLAG_ANGLE) != 0;
                bool isArray     = ((int)textureType & (int)TEXTURE_TYPE.FLAG_2DARRAY) != 0;
                bool scale       = ((int)textureType & (int)TEXTURE_TYPE.FLAG_SCALE_BY_MAX) != 0 && texture.MaxValue > 1;

                System.IO.FileInfo targetTextureFileName = new System.IO.FileInfo(System.IO.Path.Combine(fullTargetDirectory.FullName, texture.Name + ".png"));

//*

//				// Dump as DDS
//				texture.Images.DDSSaveFile( new System.IO.FileInfo( @"D:\Workspaces\Unity Labs\AxF\AxF Shader\Assets\AxF Materials\X-Rite_14-LTH_Red_GoatLeather_4405_2479\" + texture.Name + ".dds" ), texture.ComponentFormat );

                // Individual dump as RGBA8 files
//              ImageUtility.ImageFile	source = texture.Images[0][0][0];
//              ImageUtility.ImageFile	temp = new ImageUtility.ImageFile();
//              //temp.ConvertFrom( source, ImageUtility.PIXEL_FORMAT.BGRA8 );
//              temp.ToneMapFrom( source, ( float3 _HDR, ref float3 _LDR ) => { _LDR =_HDR; } );
//              temp.Save( new System.IO.FileInfo( @"D:\Workspaces\Unity Labs\AxF\AxF Shader\Assets\AxF Materials\X-Rite_14-LTH_Red_GoatLeather_4405_2479\" + texture.Name + ".png" ), ImageUtility.ImageFile.FILE_FORMAT.PNG );

                uint mipsCount = texture.Images[0].MipLevelsCount;
                for (uint mipIndex = 0; mipIndex < mipsCount; mipIndex++)
                {
                    // Individual dump as RGBA16 files
                    ImageUtility.ImageFile source = texture.Images[0][mipIndex][0];

                    float factor = 1.0f;
                    if (scale)
                    {
                        factor = 1.0f / texture.MaxValue;                               // Apply scale
                    }

//                  if ( textureType == TEXTURE_TYPE.BRDF_COLOR ) {
//                      Random	R = new Random();
//                      source.ReadWritePixels( ( uint _X, uint _Y, ref float4 _color ) => {
//                          _color.x = (0.5f+_X) / 63.0f;
//                          _color.y = (0.5f+_X) / 63.0f;
//                          _color.z = (0.5f+_X) / 63.0f;
//                          _color.w = (float) R.NextDouble();
//
//                          // Apply sRGB
//                          _color.x = Mathf.Pow( Math.Max( 0.0f, _color.x ), 1.0f / 2.2f );
//                          _color.y = Mathf.Pow( Math.Max( 0.0f, _color.y ), 1.0f / 2.2f );
//                          _color.z = Mathf.Pow( Math.Max( 0.0f, _color.z ), 1.0f / 2.2f );
//
//                      } );
//                  } else
                    if (sRGB)
                    {
                        source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => {
                            _color.x = Mathf.Pow(Math.Max(0.0f, factor * _color.x), 1.0f / 2.2f);
                            _color.y = Mathf.Pow(Math.Max(0.0f, factor * _color.y), 1.0f / 2.2f);
                            _color.z = Mathf.Pow(Math.Max(0.0f, factor * _color.z), 1.0f / 2.2f);
                            //						_color.w = 1.0f;
                        });
                    }

                    if (isNormalMap)
                    {
                        source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => {
                            _color.x = 0.5f * (1.0f + _color.x);
                            _color.y = 0.5f * (1.0f + _color.y);
                            _color.z = 0.5f * (1.0f + _color.z);
                        });
                    }

                    if (isIOR)
                    {
                        // Transform into F0
                        source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => {
                            if (float.IsNaN(_color.x))
                            {
                                _color.x = 1.2f;
                            }
                            if (float.IsNaN(_color.y))
                            {
                                _color.y = 1.2f;
                            }
                            if (float.IsNaN(_color.z))
                            {
                                _color.z = 1.2f;
                            }

                            _color.x = (_color.x - 1.0f) / (_color.x + 1.0f);                                   // We apply the square below, during the sRGB conversion
                            _color.y = (_color.y - 1.0f) / (_color.y + 1.0f);
                            _color.z = (_color.z - 1.0f) / (_color.z + 1.0f);
                            _color.x = Mathf.Pow(Mathf.Max(0.0f, _color.x), 2.0f / 2.2f);                                               // <= Notice the 2/2.2 here!
                            _color.y = Mathf.Pow(Mathf.Max(0.0f, _color.y), 2.0f / 2.2f);
                            _color.z = Mathf.Pow(Mathf.Max(0.0f, _color.z), 2.0f / 2.2f);
                        });
                        sRGB = true;                            // Also encoded as sRGB now
                    }

                    if (isAngle)
                    {
                        // Renormalize
                        source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => {
                            _color.x = 0.5f * (1.0f + _color.x * Mathf.INVPI);
                            _color.y = 0.5f * (1.0f + _color.y * Mathf.INVPI);
                            _color.z = 0.5f * (1.0f + _color.z * Mathf.INVPI);
                        });
                    }

                    ImageUtility.ImageFile temp = new ImageUtility.ImageFile();
//					if ( texture.Name.ToLower() == "diffusecolor" )
//						temp.ToneMapFrom( source, ( float3 _HDR, ref float3 _LDR ) => { _LDR =_HDR; } );	// 8-bits for diffuse otherwise unity doesn't like it... :'(
//					else
                    temp.ConvertFrom(source, ImageUtility.PIXEL_FORMAT.RGBA16);

                    System.IO.FileInfo targetMipTextureFileName = mipIndex > 0 ? new System.IO.FileInfo(System.IO.Path.Combine(fullTargetDirectory.FullName, texture.Name + "_mip" + mipIndex + ".png"))
                                                                                                                                                                : targetTextureFileName;

                    temp.Save(targetMipTextureFileName, ImageUtility.ImageFile.FILE_FORMAT.PNG);
//                  System.IO.FileInfo	targetMipTextureFileName = new System.IO.FileInfo( System.IO.Path.Combine( fullTargetDirectory.FullName, texture.Name + ".tif" ) );
//                  temp.Save( targetMipTextureFileName, ImageUtility.ImageFile.FILE_FORMAT.TIFF );

                    // Generate or read meta file
                    string GUID = GenerateMeta(targetMipTextureFileName, checkBoxGenerateMeta.Checked, checkBoxOverwriteExistingMeta.Checked, sRGB, isNormalMap, isIOR, isArray);
                    if (mipIndex == 0)
                    {
                        GUIDs[textureIndex] = GUID;
                        allGUIDsValid      &= GUID != null;
                    }
                }
//*/
            }

            if (!checkBoxGenerateMat.Checked)
            {
                return;
            }
            if (!allGUIDsValid)
            {
                throw new Exception("Not all texture GUIDs are valid! Can't generate material file!");
            }

            GenerateMaterial(_material, _targetDirectory, textureTypes, GUIDs);
        }