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); }
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 }