示例#1
0
        public static Color[] ConverPixelsToLightMap(Color[] array, bool debug = false)
        {
            Color[] toReturn    = new Color[array.Length];
            Color   randomColor = Random.ColorHSV();

            for (int i = 0; i < toReturn.Length; i++)
            {
                if (debug)
                {
                    toReturn[i] = randomColor;
                }
                else
                {
                    toReturn[i] = WG_Helper.ConvertColorToLightmap(array[i]);
                }
            }

            return(toReturn);
        }
示例#2
0
        void PrepareMaterial(GameObject go)
        {
            //for material of the geometry we should get lightmap, save it, reassign material with all textures plus lightmap
            #if UNITY_EDITOR
            MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>();
            if (meshRenderer != null)
            {
                //get material
                Material originalMaterial = meshRenderer.sharedMaterial;
                //if material use lightMap texture, then does not save new texture and reassign material
                bool lmSlotExist       = IsMaterialContainsMap(originalMaterial, "_LightMap");
                bool bumpSlotExist     = IsMaterialContainsMap(originalMaterial, "_BumpMap");
                bool emissionSlotExist = IsMaterialContainsMap(originalMaterial, "_EmissionMap");
                bool diffuseSlotExist  = IsMaterialContainsMap(originalMaterial, "_MainTex");
                if (lmSlotExist)
                {
                    Texture t = originalMaterial.GetTexture("_LightMap");
                    if (t == null)
                    {
                        lmSlotExist = false;
                    }
                }
                if (!lmSlotExist)
                {//material does not contains slot for lightmap, so, we should save it and re-assign material
                    //get lightmap
                    string lmTextureAssetPath = "";
                    int    lmIndex            = meshRenderer.lightmapIndex;
                    bool   reAssignMaterial   = false;
                    if (lmIndex > -1 && lmIndex < LightmapSettings.lightmaps.Length)
                    {
                        LightmapData data      = LightmapSettings.lightmaps[lmIndex];
                        Texture2D    lmTexture = data.lightmapColor;
                        WG_Helper.SetTextureReadable(lmTexture, true);
                        //int width = (int)(lmTexture.width * Mathf.Min(1.0f, meshRenderer.lightmapScaleOffset.x));
                        //int height = (int)(lmTexture.height * Mathf.Min(1.0f, meshRenderer.lightmapScaleOffset.y));
                        int width  = (int)(lmTexture.width * meshRenderer.lightmapScaleOffset.x);
                        int height = (int)(lmTexture.height * meshRenderer.lightmapScaleOffset.y);

                        //int startX = Mathf.Max(0, (int)(lmTexture.width * meshRenderer.lightmapScaleOffset.z));
                        //int startY = Mathf.Max(0, (int)(lmTexture.height * meshRenderer.lightmapScaleOffset.w));
                        int startX = (int)(lmTexture.width * meshRenderer.lightmapScaleOffset.z);
                        int startY = (int)(lmTexture.height * meshRenderer.lightmapScaleOffset.w);

                        Texture2D newTexture = new Texture2D(width, height, isLightmapHDR ? DefaultFormat.HDR : DefaultFormat.LDR, TextureCreationFlags.MipChain);

                        int mapStartX = Mathf.Max(0, startX);
                        int mapStartY = Mathf.Max(0, startY);
                        int mapEndX   = Mathf.Min(lmTexture.width, startX + width);
                        int mapEndY   = Mathf.Min(lmTexture.height, startY + height);
                        int mapWidth  = mapEndX - mapStartX;
                        int mapHeight = mapEndY - mapStartY;

                        //fill the main rect
                        Color[] lmColorsRaw = lmTexture.GetPixels(mapStartX, mapStartY, mapWidth, mapHeight);
                        //WG_Helper.PrintMinMaxPixels(lmColorsRaw);

                        Color[] lmColors = WG_Helper.ConverPixelsToLightMap(lmColorsRaw);
                        //WG_Helper.PrintMinMaxPixels(lmColors);
                        //Debug.Log("main rect: " + (mapStartX - startX).ToString() + " " + (mapStartY - startY).ToString() + " " + mapWidth.ToString() + " " + mapHeight.ToString());
                        newTexture.SetPixels(mapStartX - startX, mapStartY - startY, mapWidth, mapHeight, isLightmapHDR ? lmColors : lmColorsRaw);

                        //next fill left area (if we need it)
                        Color[] leftColorsRaw = lmTexture.GetPixels(mapStartX, mapStartY, 1, mapHeight);
                        Color[] leftColors    = WG_Helper.ConverPixelsToLightMap(leftColorsRaw);
                        for (int column = 0; column < mapStartX - startX; column++)
                        {
                            newTexture.SetPixels(column, mapStartY - startY, 1, mapHeight, isLightmapHDR ? leftColors : leftColorsRaw);
                        }

                        //next right area
                        Color[] rightColorsRaw = lmTexture.GetPixels(mapEndX - 1, mapStartY, 1, mapHeight);
                        Color[] rightColors    = WG_Helper.ConverPixelsToLightMap(rightColorsRaw);
                        for (int column = 0; column < width + startX - mapEndX; column++)
                        {
                            newTexture.SetPixels(mapEndX - startX + column, mapStartY - startY, 1, mapHeight, isLightmapHDR ? rightColors: rightColorsRaw);
                        }

                        //bottom and top
                        Color[] bottomColorsRaw = lmTexture.GetPixels(mapStartX, mapStartY, mapWidth, 1);
                        Color[] bottomColors    = WG_Helper.ConverPixelsToLightMap(bottomColorsRaw);
                        for (int row = 0; row < mapStartY - startY; row++)
                        {
                            newTexture.SetPixels(mapStartX - startX, row, mapWidth, 1, isLightmapHDR ? bottomColors : bottomColorsRaw);
                        }
                        Color[] topColorsRaw = lmTexture.GetPixels(mapStartX, mapEndY - 1, mapWidth, 1);
                        Color[] topColors    = WG_Helper.ConverPixelsToLightMap(topColorsRaw);
                        for (int row = 0; row < height + startY - mapEndY; row++)
                        {
                            newTexture.SetPixels(mapStartX - startX, mapEndY - startY + row, mapWidth, 1, isLightmapHDR ? topColors : topColorsRaw);
                        }

                        //regions on corners
                        Color leftBootm  = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapStartX, mapStartY)) : lmTexture.GetPixel(mapStartX, mapStartY);
                        Color leftTop    = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapStartX, mapEndY - 1)) : lmTexture.GetPixel(mapStartX, mapEndY - 1);
                        Color rightBootm = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapEndX - 1, mapStartY)) : lmTexture.GetPixel(mapEndX - 1, mapStartY);
                        Color rightTop   = isLightmapHDR ? WG_Helper.ConvertColorToLightmap(lmTexture.GetPixel(mapEndX - 1, mapEndY - 1)) : lmTexture.GetPixel(mapEndX - 1, mapEndY - 1);

                        Color[] leftBottomColors  = WG_Helper.CreateArray(leftBootm, (mapStartX - startX) * (mapStartY - startY));
                        Color[] leftTopColors     = WG_Helper.CreateArray(leftTop, (mapStartX - startX) * (startY + height - mapEndY));
                        Color[] rightBottomColors = WG_Helper.CreateArray(rightBootm, (startX + width - mapEndX) * (mapStartY - startY));
                        Color[] rightTopColors    = WG_Helper.CreateArray(rightTop, (startX + width - mapEndX) * (startY + height - mapEndY));

                        newTexture.SetPixels(0, 0, mapStartX - startX, mapStartY - startY, leftBottomColors);
                        newTexture.SetPixels(0, mapEndY, mapStartX - startX, startY + height - mapEndY, leftTopColors);
                        //Debug.Log(rightBottomColors.Length.ToString() + " " + (startX + width - mapEndX).ToString() + " " + (mapStartY - startY).ToString());
                        try
                        {
                            newTexture.SetPixels(mapEndX, 0, startX + width - mapEndX, mapStartY - startY, rightBottomColors);
                        }
                        catch
                        {
                            Debug.Log(rightBottomColors.Length.ToString() + " " + (startX + width - mapEndX).ToString() + " " + (mapStartY - startY).ToString());
                        }
                        newTexture.SetPixels(mapEndX, mapEndY, startX + width - mapEndX, startY + height - mapEndY, rightTopColors);

                        newTexture.Apply();

                        //Debug.Log("isLightmapHDR=" + isLightmapHDR.ToString());
                        //Debug.Log("original pixel: " + lmTexture.GetPixel(mapStartX + width / 3, mapStartY + height / 3).ToString() + " "
                        //+ lmTexture.GetPixel(mapStartX + 2*width / 3, mapStartY + 2*height / 3).ToString());
                        //Debug.Log("saved pixel: " + newTexture.GetPixel(width / 3, height / 3).ToString() + " " + newTexture.GetPixel(2*width / 3, 2*height / 3).ToString());

                        lmTextureAssetPath = SaveTextureAsset(newTexture, isLightmapHDR);
                        WG_Helper.SetTextureLightmap(lmTextureAssetPath, isLightmapHDR);
                        reAssignMaterial = true;
                    }
                    else
                    {
                        Debug.Log("Object " + go.name + " does not have lightmaps or this data is invalid.");
                    }

                    //reassign material if we need it
                    if (reAssignMaterial)
                    {
                        if (true)
                        {
                            Material newMaterial = lmMode == LMShaderMode.LWRP ? new Material(lwrpShader) : new Material(GetStdShader(diffuseSlotExist, bumpSlotExist, emissionSlotExist));
                            //Material newMaterial = (lmMode == LMShaderMode.LWRP || (lmMode == LMShaderMode.Std && bumpSlotExist == false)) ? new Material(lmShader) : new Material(lmSecondShader);
                            //for LWRP we use only one uber-shader, for std shaders each different once from array
                            //assign all parameters from original material to the new one
                            Shader        originalShader   = originalMaterial.shader;
                            List <string> newMaterialNames = WG_Helper.GetShaderParameterNames(newMaterial.shader);
                            int           propsCount       = ShaderUtil.GetPropertyCount(originalShader);
                            for (int i = 0; i < propsCount; i++)
                            {
                                string propName = ShaderUtil.GetPropertyName(originalShader, i);
                                if (newMaterialNames.Contains(propName))
                                {
                                    ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(originalShader, i);
                                    if (type == ShaderUtil.ShaderPropertyType.Color)
                                    {
                                        newMaterial.SetColor(propName, originalMaterial.GetColor(propName));
                                    }
                                    else if (type == ShaderUtil.ShaderPropertyType.Float)
                                    {
                                        newMaterial.SetFloat(propName, originalMaterial.GetFloat(propName));
                                    }
                                    else if (type == ShaderUtil.ShaderPropertyType.Range)
                                    {
                                        newMaterial.SetFloat(propName, originalMaterial.GetFloat(propName));
                                    }
                                    else if (type == ShaderUtil.ShaderPropertyType.TexEnv)
                                    {
                                        newMaterial.SetTexture(propName, originalMaterial.GetTexture(propName));
                                        newMaterial.SetTextureOffset(propName, originalMaterial.GetTextureOffset(propName));
                                        newMaterial.SetTextureScale(propName, originalMaterial.GetTextureScale(propName));
                                    }
                                    else if (type == ShaderUtil.ShaderPropertyType.Vector)
                                    {
                                        newMaterial.SetVector(propName, originalMaterial.GetVector(propName));
                                    }
                                }
                                else
                                {
                                    Debug.Log("New material (" + newMaterial.shader.name + ") for the object " + go.name + " does not contains property " + propName + ". Skip it.");
                                }
                            }
                            //set gpu instancing
                            newMaterial.enableInstancing = originalMaterial.enableInstancing;
                            //finally assign lightMap texture
                            newMaterial.SetTexture("_LightMap", AssetDatabase.LoadAssetAtPath <Texture2D>(lmTextureAssetPath));
                            //set amibient, if we need it
                            if (!isLightmapHDR)
                            {
                                //--newMaterial.SetColor("_Ambient", ldrAmbient);  // <-- does not used in WebGL mode
                                newMaterial.SetFloat("_Multiplier", ldrLightmapMultiplier);
                            }
                            //enable all kewords
                            string[] originalKeyWords = originalMaterial.shaderKeywords;
                            for (int s = 0; s < originalKeyWords.Length; s++)
                            {
                                newMaterial.EnableKeyword(originalKeyWords[s]);
                            }
                            //CoreUtils.SetKeyword(newMaterial, "_EMISSION", originalMaterial.IsKeywordEnabled("_EMISSION"));
                            //assign material to the object
                            meshRenderer.sharedMaterial = newMaterial;
                            SaveMaterialAsset(newMaterial);
                        }
                        else
                        {
                        }
                    }
                    else
                    {
                        //string matAssetPath = SaveMaterialAsset(originalMaterial);
                        //Debug.Log("Create material asset " + matAssetPath);
                    }
                }
                else
                {
                    SaveMaterialAsset(originalMaterial);
                }
            }
            #endif
        }