// Check all light maps referenced within the current batch of converted Renderers. // Any references to light maps that have already been inserted into a LightMaps array // will be implemented by reusing the existing LightMaps object. Any leftover previously // unseen (or changed = content hash changed) light maps are combined into a new LightMaps array. public void ProcessLightMapsForConversion() { var lightmaps = LightmapSettings.lightmaps; var uniqueIndices = m_UsedLightmapIndices .Distinct() .OrderBy(x => x) .Where(x => x >= 0 && x != 65534 && x < lightmaps.Length) .ToArray(); var colors = new List <Texture2D>(); var directions = new List <Texture2D>(); var shadowMasks = new List <Texture2D>(); var lightMapIndices = new List <int>(); // Each light map reference is converted into a LightMapKey which identifies the light map // using the content hashes regardless of the index number. Previously encountered light maps // should be found from the cache even if their index number has changed. New or changed // light maps are placed into a new array. for (var i = 0; i < uniqueIndices.Length; i++) { var index = uniqueIndices[i]; var lightmapData = lightmaps[index]; var key = new LightMapKey(lightmapData); if (m_LightMapArrayCache.TryGetValue(key, out var lightMapRef)) { m_LightMapReferences[index] = lightMapRef; ++m_NumLightMapCacheHits; } else { colors.Add(lightmapData.lightmapColor); directions.Add(lightmapData.lightmapDir); shadowMasks.Add(lightmapData.shadowMask); lightMapIndices.Add(index); ++m_NumLightMapCacheMisses; } } if (lightMapIndices.Count > 0) { #if DEBUG_LOG_LIGHT_MAP_CONVERSION Debug.Log($"Creating new DOTS light map array from {lightMapIndices.Count} light maps."); #endif var lightMapArray = LightMaps.ConstructLightMaps(colors, directions, shadowMasks); for (int i = 0; i < lightMapIndices.Count; ++i) { var lightMapRef = new LightMapReference { LightMaps = lightMapArray, LightMapIndex = i, }; m_LightMapReferences[lightMapIndices[i]] = lightMapRef; m_LightMapArrayCache[new LightMapKey(colors[i], directions[i], shadowMasks[i])] = lightMapRef; } } }
protected override void OnUpdate() { var globalToLocalLightmapMap = new Dictionary <int, int>(); #if UNITY_2020_2_OR_NEWER var usedIndicies = new List <int>(); Entities.WithNone <TextMesh>().ForEach((MeshRenderer meshRenderer, MeshFilter meshFilter) => { usedIndicies.Add(meshRenderer.lightmapIndex); }); var setting = LightmapSettings.lightmaps; var uniqueIndices = usedIndicies.Distinct().OrderBy(x => x).Where(x => x >= 0 && x != 65534 && x < setting.Length).ToArray(); var colors = new List <Texture2D>(); var directions = new List <Texture2D>(); var shadowMasks = new List <Texture2D>(); for (var i = 0; i < uniqueIndices.Length; i++) { var index = uniqueIndices[i]; colors.Add(setting[index].lightmapColor); directions.Add(setting[index].lightmapDir); shadowMasks.Add(setting[index].shadowMask); globalToLocalLightmapMap.Add(index, i); } var lightMaps = LightMaps.ConstructLightMaps(colors, directions, shadowMasks); #else var lightMaps = new LightMaps(); #endif var sourceMaterials = new List <Material>(10); var createdMaterials = new Dictionary <MaterialLookupKey, Material>(); Entities.WithNone <TextMesh>().ForEach((MeshRenderer meshRenderer, MeshFilter meshFilter) => { var mesh = meshFilter.sharedMesh; meshRenderer.GetSharedMaterials(sourceMaterials); if (!globalToLocalLightmapMap.TryGetValue(meshRenderer.lightmapIndex, out var lightmapIndex)) { lightmapIndex = meshRenderer.lightmapIndex; } if (mesh != null) { Convert(DstEntityManager, this, AttachToPrimaryEntityForSingleMaterial, meshRenderer, mesh, sourceMaterials, createdMaterials, lightMaps, lightmapIndex, meshRenderer.transform, mesh.bounds.ToAABB()); } }); }
private static Material CreateLightMappedMaterial(Material material, LightMaps lightMaps) { var lightMappedMaterial = new Material(material); lightMappedMaterial.name = $"{lightMappedMaterial.name}_Lightmapped_"; lightMappedMaterial.EnableKeyword("LIGHTMAP_ON"); lightMappedMaterial.SetTexture("unity_Lightmaps", lightMaps.colors); lightMappedMaterial.SetTexture("unity_LightmapsInd", lightMaps.directions); lightMappedMaterial.SetTexture("unity_ShadowMasks", lightMaps.shadowMasks); if (lightMaps.hasDirections) { lightMappedMaterial.name = lightMappedMaterial.name + "_DIRLIGHTMAP"; lightMappedMaterial.EnableKeyword("DIRLIGHTMAP_COMBINED"); } if (lightMaps.hasShadowMask) { lightMappedMaterial.name = lightMappedMaterial.name + "_SHADOW_MASK"; } return(lightMappedMaterial); }
public static void Convert( EntityManager dstEntityManager, GameObjectConversionSystem conversionSystem, bool attachToPrimaryEntityForSingleMaterial, Renderer meshRenderer, Mesh mesh, List <Material> materials, Dictionary <MaterialLookupKey, Material> createdMaterials, LightMaps lightMaps, int lightmapIndex, Transform root, AABB localBounds) { var materialCount = materials.Count; // Don't add RenderMesh (and other required components) unless both mesh and material are assigned. if (mesh == null || materialCount == 0) { Debug.LogWarning( "MeshRenderer is not converted because either the assigned mesh is null or no materials are assigned.", meshRenderer); return; } //@TODO: Transform system should handle RenderMeshFlippedWindingTag automatically. This should not be the responsibility of the conversion system. float4x4 localToWorld = root.localToWorldMatrix; var flipWinding = math.determinant(localToWorld) < 0.0; if (materialCount == 1 && attachToPrimaryEntityForSingleMaterial) { var meshEntity = conversionSystem.GetPrimaryEntity(meshRenderer); AddComponentsToEntity( meshEntity, dstEntityManager, conversionSystem, meshRenderer, mesh, materials, createdMaterials, flipWinding, 0, lightMaps, lightmapIndex, localBounds); } else { var rootEntity = conversionSystem.GetPrimaryEntity(root); for (var m = 0; m != materialCount; m++) { var meshEntity = conversionSystem.CreateAdditionalEntity(meshRenderer); dstEntityManager.AddComponentData(meshEntity, new LocalToWorld { Value = localToWorld }); if (!dstEntityManager.HasComponent <Static>(meshEntity)) { dstEntityManager.AddComponentData(meshEntity, new Parent { Value = rootEntity }); dstEntityManager.AddComponentData(meshEntity, new LocalToParent { Value = float4x4.identity }); } AddComponentsToEntity( meshEntity, dstEntityManager, conversionSystem, meshRenderer, mesh, materials, createdMaterials, flipWinding, m, lightMaps, lightmapIndex, localBounds); } } }
private static void AddComponentsToEntity( Entity entity, EntityManager dstEntityManager, GameObjectConversionSystem conversionSystem, Renderer meshRenderer, Mesh mesh, List <Material> materials, Dictionary <MaterialLookupKey, Material> createdMaterials, bool flipWinding, int id, LightMaps lightMaps, int lightmapIndex, AABB localBounds) { var needMotionVectorPass = (meshRenderer.motionVectorGenerationMode == MotionVectorGenerationMode.Object) || (meshRenderer.motionVectorGenerationMode == MotionVectorGenerationMode.ForceNoMotion); var renderMesh = new RenderMesh { mesh = mesh, castShadows = meshRenderer.shadowCastingMode, receiveShadows = meshRenderer.receiveShadows, layer = meshRenderer.gameObject.layer, subMesh = id, needMotionVectorPass = needMotionVectorPass }; var staticLightingMode = StaticLightingMode.None; if (meshRenderer.lightmapIndex >= 65534 || meshRenderer.lightmapIndex < 0) { staticLightingMode = StaticLightingMode.LightProbes; } else if (meshRenderer.lightmapIndex >= 0) { staticLightingMode = StaticLightingMode.Lightmapped; } dstEntityManager.AddComponentData(entity, new PerInstanceCullingTag()); dstEntityManager.AddComponentData(entity, new RenderBounds { Value = localBounds }); var material = materials[id]; if (staticLightingMode == StaticLightingMode.Lightmapped && lightMaps.isValid) { conversionSystem.DeclareAssetDependency(meshRenderer.gameObject, material); var localFlags = LightMappingFlags.Lightmapped; if (lightMaps.hasDirections) { localFlags |= LightMappingFlags.Directional; } if (lightMaps.hasShadowMask) { localFlags |= LightMappingFlags.ShadowMask; } var key = new MaterialLookupKey { BaseMaterial = materials[id], lightmaps = lightMaps, Flags = localFlags }; var lookUp = createdMaterials ?? new Dictionary <MaterialLookupKey, Material>(); if (lookUp.TryGetValue(key, out Material result)) { material = result; } else { material = new Material(materials[id]); material.name = $"{material.name}_Lightmapped_"; material.EnableKeyword("LIGHTMAP_ON"); material.SetTexture("unity_Lightmaps", lightMaps.colors); material.SetTexture("unity_LightmapsInd", lightMaps.directions); material.SetTexture("unity_ShadowMasks", lightMaps.shadowMasks); if (lightMaps.hasDirections) { material.name = material.name + "_DIRLIGHTMAP"; material.EnableKeyword("DIRLIGHTMAP_COMBINED"); } if (lightMaps.hasShadowMask) { material.name = material.name + "_SHADOW_MASK"; } lookUp[key] = material; } dstEntityManager.AddComponentData(entity, new BuiltinMaterialPropertyUnity_LightmapST() { Value = meshRenderer.lightmapScaleOffset }); dstEntityManager.AddComponentData(entity, new BuiltinMaterialPropertyUnity_LightmapIndex() { Value = lightmapIndex }); dstEntityManager.AddSharedComponentData(entity, lightMaps); } else if (staticLightingMode == StaticLightingMode.LightProbes) { if (meshRenderer.lightProbeUsage == LightProbeUsage.CustomProvided) { dstEntityManager.AddComponent <CustomProbeTag>(entity); } else if (meshRenderer.lightProbeUsage == LightProbeUsage.BlendProbes && LightmapSettings.lightProbes != null && LightmapSettings.lightProbes.count > 0) { dstEntityManager.AddComponent <BlendProbeTag>(entity); } else { dstEntityManager.AddComponent <AmbientProbeTag>(entity); } } renderMesh.material = material; dstEntityManager.AddSharedComponentData(entity, renderMesh); if (flipWinding) { dstEntityManager.AddComponent(entity, ComponentType.ReadWrite <RenderMeshFlippedWindingTag>()); } conversionSystem.ConfigureEditorRenderData(entity, meshRenderer.gameObject, true); #if ENABLE_HYBRID_RENDERER_V2 dstEntityManager.AddComponent(entity, ComponentType.ReadOnly <WorldToLocal_Tag>()); #if HDRP_9_0_0_OR_NEWER // HDRP previous frame matrices (for motion vectors) if (needMotionVectorPass) { dstEntityManager.AddComponent(entity, ComponentType.ReadWrite <BuiltinMaterialPropertyUnity_MatrixPreviousM>()); dstEntityManager.AddComponent(entity, ComponentType.ReadWrite <BuiltinMaterialPropertyUnity_MatrixPreviousMI_Tag>()); } dstEntityManager.AddComponentData(entity, CreateMotionVectorsParams(ref renderMesh, ref meshRenderer)); #endif dstEntityManager.AddComponentData(entity, new BuiltinMaterialPropertyUnity_RenderingLayer { Value = new uint4(meshRenderer.renderingLayerMask, 0, 0, 0) }); dstEntityManager.AddComponentData(entity, new BuiltinMaterialPropertyUnity_WorldTransformParams { Value = flipWinding ? new float4(0, 0, 0, -1) : new float4(0, 0, 0, 1) }); #if URP_9_0_0_OR_NEWER // Default initialized light data for URP dstEntityManager.AddComponentData(entity, new BuiltinMaterialPropertyUnity_LightData { Value = new float4(0, 0, 1, 0) }); #endif #endif }