Material broken after updating from 2019.1.0b3 to 2019.1.0f2

Hi,

I’m running into an issue with my materials when I update my project from 2019.1.0b3 to 2019.1.0f2: they are missing the albedo texture and the color attribute is wrong as well. The materials are using the standard “Lightweight Render Pipeline/Lit” shader.

New .mat file

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
  serializedVersion: 6
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: acorn_mat
  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
  m_ShaderKeywords:
  m_LightmapFlags: 4
  m_EnableInstancingVariants: 1
  m_DoubleSidedGI: 0
  m_CustomRenderQueue: -1
  stringTagMap: {}
  disabledShaderPasses: []
  m_SavedProperties:
    serializedVersion: 3
    m_TexEnvs:
    - _BumpMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _EmissionMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _MainTex:
        m_Texture: {fileID: 2800000, guid: bb65d3758d81f9f4eb202e539110dd78, type: 3}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _MetallicGlossMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _OcclusionMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _SpecGlossMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    m_Floats:
    - _AlphaClip: 0
    - _Blend: 0
    - _BumpScale: 1
    - _Cull: 2
    - _Cutoff: 0.5
    - _DstBlend: 0
    - _EnvironmentReflections: 1
    - _GlossMapScale: 1
    - _Glossiness: 0.5
    - _GlossyReflections: 1
    - _Metallic: 0
    - _OcclusionStrength: 1
    - _QueueOffset: 0
    - _ReceiveShadows: 1
    - _Smoothness: 0.5
    - _SmoothnessTextureChannel: 0
    - _SpecularHighlights: 1
    - _SrcBlend: 1
    - _Surface: 0
    - _WorkflowMode: 1
    - _ZWrite: 1
    m_Colors:
    - _BaseColor: {r: 1, g: 1, b: 1, a: 1}
    - _Color: {r: 1, g: 1, b: 1, a: 1}
    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}

Old .mat file

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
  serializedVersion: 6
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: acorn_mat
  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
  m_ShaderKeywords:
  m_LightmapFlags: 4
  m_EnableInstancingVariants: 1
  m_DoubleSidedGI: 0
  m_CustomRenderQueue: 2050
  stringTagMap:
    RenderType: Opaque
  disabledShaderPasses: []
  m_SavedProperties:
    serializedVersion: 3
    m_TexEnvs:
    - _BumpMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _EmissionMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _MainTex:
        m_Texture: {fileID: 2800000, guid: bb65d3758d81f9f4eb202e539110dd78, type: 3}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _MetallicGlossMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _OcclusionMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _SpecGlossMap:
        m_Texture: {fileID: 0}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    m_Floats:
    - _AlphaClip: 0
    - _Blend: 0
    - _BumpScale: 1
    - _Cull: 2
    - _Cutoff: 0.5
    - _DstBlend: 0
    - _GlossMapScale: 1
    - _Glossiness: 0.5
    - _GlossyReflections: 1
    - _Metallic: 0
    - _OcclusionStrength: 1
    - _ReceiveShadows: 1
    - _SmoothnessTextureChannel: 0
    - _SpecularHighlights: 1
    - _SrcBlend: 1
    - _Surface: 0
    - _WorkflowMode: 1
    - _ZWrite: 1
    m_Colors:
    - _Color: {r: 1, g: 1, b: 1, a: 1}
    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}

When you compare the old and new materials, these are the new entries while nothing got deleted:

    - _BaseMap:
        m_Texture: {fileID: 2800000, guid: bb65d3758d81f9f4eb202e539110dd78, type: 3}
        m_Scale: {x: 1, y: 1}
        m_Offset: {x: 0, y: 0}
    - _EnvironmentReflections: 1
    - _QueueOffset: 0
    - _Smoothness: 0.5
    - _BaseColor: {r: 1, g: 1, b: 1, a: 1}

It seems the names have just changed and Unity doesn’t doesn’t convert them? For example, the texture is now part of _BaseMap and before it was part of _MainTex.

Thanks,
Alex

This is most likely a bug with LWRP package, I have processed it as a bug (Unity Issue Tracker - [LWRP] Upgrading LWRP 5.2.3 to 5.3.1 causes all materials to lose their albedo texture).

I’ve got this happening too, coming from 2018.3.12 to 2019.1.0f2. Basically, every material in my project is destroyed.

I guess our workaround is to roll back to the old version for now and wait for a bug fix? Thanks for inputting the bug, I voted it up.

If it doesn’t get resolved soon, I’ll create a simple, hacky script to do the conversion offline (assuming ascii material files).

Hey,

Just saw this, but we indeed have an upgrader for this, and it just doesn’t get kicked off as expected, we have it as a improvement to make sure it kicks off when upgrading from an earlier package. This reply to the LWRP thread explains in more detail [LWRP: 4.6.0-preview (18.3) & 5.2.1 (19.1) are out]( https://discussions.unity.com/t/716433 page-11#post-4459627)

Thanks @Andre_Mcgrail , I tried to reimport my materials (LWRP/Lit) but the issue remains. Is there another way to trigger the upgrader?

@Andre_Mcgrail , I tried reimport more materials. A bit more happened but it’s still not really working:

  1. Some materials get fixed (2 out of 50) but the majority is still broken.
  2. For some materials I get a debug log (3 out of 50) though they aren’t the materials which got fixed.
LWRP Material log:
football_mat initialized. upgrading:v0 to v1
UnityEditor.AssetPostprocessingInternal:PostprocessAllAssets(String[], String[], String[], String[], String[])
  1. Checking the git diff, the upgrader might process all(?) of the materials but doesn’t necessarily fix them:
     - _MainTex:
-        m_Texture: {fileID: 2800000, guid: f31b2ebf9418acd44bd267cff48507f8, type: 3}
+        m_Texture: {fileID: 0}

Here the texture reference got deleted although the texture with the guid f31b2ebf9418acd44bd267cff48507f8 still exists! So be careful when reimporting materials! Luckily I can roll back all those materials.

I wrote a simple python script to fix the materials for me. It did the job for me so it might help others but be careful. It’s not very pretty, it doesn’t create backups and it’s not fail safe so use with caution. git is your friend!

  • Copy MainTex to BaseMap
  • Copy Color to BaseColor
  • Add QueueOffset
  • Add Smoothness
  • Add EnvironmentReflections

conversion script

from __future__ import print_function

import argparse
import os
import pprint
from shutil import copyfile
import io


class MaterialFixer(object):

    def __init__(self):
        self._filePaths = []
        self._directories = []
        self._logProcessedDirectories = set()
        self._logInvalidDirectories = set()
        self._logInvalidFiles = set()
        self._logConvertedFiles = set()
        self._logNothingToDoFiles = set()

        self._parseArgs()

    def _parseArgs(self):
        parser = argparse.ArgumentParser()
        parser.add_argument(
            "-d",
            "--directory",
            nargs='*',
            help="Convert all materials in directory")
        parser.add_argument(
            "-f",
            "--file",
            nargs='*',
            help="Convert given material")
        args = parser.parse_args()

        if args.file:
            self._filePaths = args.file if isinstance(args.file, list) else [args.file]

        if args.directory:
            self._directories = args.directory if isinstance(args.directory, list) else [args.directory]

    def run(self):
        for filePath in self._filePaths:
            self._convertFile(filePath)

        for directory in self._directories:
            self._processDirectory(directory)

        self._printLog()
   
    def _printLog(self):
        print("Processed directories: ")
        pprint.pprint(self._logProcessedDirectories)
        print("Converted files: ")
        pprint.pprint(self._logConvertedFiles)
        print("Already converted files: ")
        pprint.pprint(self._logNothingToDoFiles)
        print("Invalid directories: ")
        pprint.pprint(self._logInvalidDirectories)
        print("Invalid files: ")
        pprint.pprint(self._logInvalidFiles)
       
    def _processDirectory(self, directory):
        if not directory:
            return

        if (not os.path.isdir(directory) or
           not os.path.exists(directory)):
            self._logInvalidDirectories.add(directory)
            return

        self._logProcessedDirectories.add(directory)
        for root, dirs, files in os.walk(directory):
            self._logProcessedDirectories.add(root)
            for filename in files:
                if os.path.splitext(filename)[1] == (".mat"):
                    materialFile = os.path.join(root, filename)
                    self._convertFile(materialFile)

    def _convertFile(self, filePath):
        if not filePath:
            return

        if not self._isValidFile(filePath):
            self._logInvalidFiles.add(filePath)
            return

        f = io.open(filePath, 'r', newline='\n')
        lines = [line for line in f]
        f.close()

        line_count = len(lines)
        lines = self._processMainTex(lines)
        lines = self._processEnvironmentReflections(lines)
        lines = self._processQueueOffset(lines)
        lines = self._processSmoothness(lines)
        lines = self._processBaseColor(lines)

        if len(lines) != line_count:
            self._logConvertedFiles.add(filePath)

            new_f = io.open(filePath, 'w', newline='\n')
            new_f.writelines(lines)
        else:
            self._logNothingToDoFiles.add(filePath)

    def _processMainTex(self, lines):
        mainTexIdx = -1
        for idx, line in enumerate(lines):
            if line.startswith("    - _BaseMap:"):
                return lines

            if line.startswith("    - _MainTex:"):
                mainTexIdx = idx
       
        if mainTexIdx == -1:
            return lines
       
        texture_entry = lines[mainTexIdx + 1]
        scale_entry = lines[mainTexIdx + 2]
        offset_entry = lines[mainTexIdx + 3]

        lines.insert(mainTexIdx, offset_entry)
        lines.insert(mainTexIdx, scale_entry)
        lines.insert(mainTexIdx, texture_entry)
        lines.insert(mainTexIdx, u"    - _BaseMap:\n")

        return lines

    def _processEnvironmentReflections(self, lines):
        floatsIdx = -1
        for idx, line in enumerate(lines):
            if line.startswith("    - _EnvironmentReflections:"):
                return lines

            if line.startswith("    m_Floats:"):
                floatsIdx = idx
       
        lines.insert(floatsIdx + 1, u"    - _EnvironmentReflections: 1\n")
        return lines

    def _processSmoothness(self, lines):
        floatsIdx = -1
        for idx, line in enumerate(lines):
            if line.startswith("    - _Smoothness:"):
                return lines

            if line.startswith("    m_Floats:"):
                floatsIdx = idx
       
        lines.insert(floatsIdx + 1, u"    - _Smoothness: 0.5\n")
        return lines

    def _processQueueOffset(self, lines):
        floatsIdx = -1
        for idx, line in enumerate(lines):
            if line.startswith("    - _QueueOffset:"):
                return lines

            if line.startswith("    m_Floats:"):
                floatsIdx = idx
       
        lines.insert(floatsIdx + 1, u"    - _QueueOffset: 0\n")
        return lines

    def _processBaseColor(self, lines):
        colorLineIdx = -1
        colorLine = ""
        for idx, line in enumerate(lines):
            if line.startswith("    - _BaseColor:"):
                return lines

            if line.startswith("    - _Color:"):
                colorLine = line
                colorLineIdx = idx
       
        lines.insert(idx, colorLine.replace("_Color", "_BaseColor"))
        return lines

    @staticmethod
    def _isValidFile(filePath):
        if (not os.path.exists(filePath) or
           not os.path.isfile(filePath)):
            return False

        return os.path.splitext(filePath)[1] == ".mat"

if __name__ == "__main__":
    MaterialFixer().run()

Alex