浏览代码

Fixing labeling on per-material MaterialPropertyBlocks (#73)

* Fixing labeling when renderers have per-material MaterialPropertyBlocks. Also supporting refreshing labeling manually after making changes to renderers or the Labeling component.

* updating changelog
/main
GitHub 4 年前
当前提交
bca49aeb
共有 10 个文件被更改,包括 199 次插入11 次删除
  1. 36
      TestProjects/PerceptionURP/Assets/Scenes/SampleScene.unity
  2. 2
      TestProjects/PerceptionURP/ProjectSettings/QualitySettings.asset
  3. 4
      com.unity.perception/CHANGELOG.md
  4. 19
      com.unity.perception/Runtime/GroundTruth/GroundTruthLabelSetupSystem.cs
  5. 11
      com.unity.perception/Runtime/GroundTruth/Labeling/Labeling.cs
  6. 70
      com.unity.perception/Tests/Runtime/GroundTruthTests/SegmentationGroundTruthTests.cs
  7. 18
      com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs
  8. 8
      TestProjects/PerceptionURP/Assets/Scenes/SampleScene.meta
  9. 31
      TestProjects/PerceptionURP/Assets/TestMpbPerMaterial.cs
  10. 11
      TestProjects/PerceptionURP/Assets/TestMpbPerMaterial.cs.meta

36
TestProjects/PerceptionURP/Assets/Scenes/SampleScene.unity


- component: {fileID: 411238278}
- component: {fileID: 411238277}
- component: {fileID: 411238282}
- component: {fileID: 411238283}
m_Layer: 0
m_Name: Crate
m_TagString: Untagged

m_Name:
m_EditorClassIdentifier:
yDegreesPerSecond: 180
--- !u!114 &411238283
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 411238276}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 695e410829600ff40bcdd76fa0818f6a, type: 3}
m_Name:
m_EditorClassIdentifier:
materialPropertyTarget: 1
color: {r: 0.745283, g: 0.40428087, b: 0.40428087, a: 0}
--- !u!1 &464025704
GameObject:
m_ObjectHideFlags: 0

- component: {fileID: 464025706}
- component: {fileID: 464025705}
- component: {fileID: 464025710}
- component: {fileID: 464025711}
m_Layer: 0
m_Name: Cube
m_TagString: Untagged

m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0

m_Name:
m_EditorClassIdentifier:
yDegreesPerSecond: 180
--- !u!114 &464025711
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 464025704}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 695e410829600ff40bcdd76fa0818f6a, type: 3}
m_Name:
m_EditorClassIdentifier:
materialPropertyTarget: 1
color: {r: 0.34109113, g: 0.42664438, b: 0.6886792, a: 0}
--- !u!1 &705507993
GameObject:
m_ObjectHideFlags: 0

- id: 1
- id: 2
- id: 3
showVisualizations: 0
showVisualizations: 1
references:
version: 1
00000000:

m_Script: {fileID: 11500000, guid: 673a227032a8e4940b9828c5b6f852ab, type: 3}
m_Name:
m_EditorClassIdentifier:
yDegreesPerSecond: 180
yDegreesPerSecond: 180

2
TestProjects/PerceptionURP/ProjectSettings/QualitySettings.asset


skinWeights: 2
textureQuality: 0
anisotropicTextures: 1
antiAliasing: 0
antiAliasing: 2
softParticles: 0
softVegetation: 1
realtimeReflectionProbes: 1

4
com.unity.perception/CHANGELOG.md


Added support for 2020.1
Added Labeling.RefreshLabeling(), which can be used to update ground truth generators after the list of labels or the renderers is changed
Added support for renderers with MaterialPropertyBlocks assigned to individual materials
### Changed
Changed the way realtime visualizers rendered to avoid rendering conflicts

19
com.unity.perception/Runtime/GroundTruth/GroundTruthLabelSetupSystem.cs


pass.SetupMaterialProperties(mpb, renderer, labeling, instanceId);
renderer.SetPropertyBlock(mpb);
var materialCount = renderer.materials.Length;
for (int i = 0; i < materialCount; i++)
{
renderer.GetPropertyBlock(mpb, i);
//Only apply to individual materials if there is already a MaterialPropertyBlock on it
if (!mpb.isEmpty)
{
foreach (var pass in m_ActiveGenerators)
pass.SetupMaterialProperties(mpb, renderer, labeling, instanceId);
renderer.SetPropertyBlock(mpb, i);
}
}
}
for (var i = 0; i < gameObject.transform.childCount; i++)

public bool Deactivate(IGroundTruthGenerator generator)
{
return m_ActiveGenerators.Remove(generator);
}
internal void RefreshLabeling(Entity labelingEntity)
{
EntityManager.RemoveComponent<GroundTruthInfo>(labelingEntity);
}
}
}

11
com.unity.perception/Runtime/GroundTruth/Labeling/Labeling.cs


public class Labeling : MonoBehaviour
{
/// <summary>
/// The label names to associate with the GameObject. Modifications to this list after the Update() step of the frame the object is created in are
/// The label names to associate with the GameObject. Modifications to this list after the Update() step of the frame the object is created in are
/// not guaranteed to be reflected by labelers.
/// </summary>
[FormerlySerializedAs("classes")]

{
if (World.DefaultGameObjectInjectionWorld != null)
World.DefaultGameObjectInjectionWorld.EntityManager.DestroyEntity(m_Entity);
}
/// <summary>
/// Refresh ground truth generation for the labeling of the attached GameObject. This is necessary when the
/// list of labels changes or when renderers or materials change on objects in the hierarchy.
/// </summary>
public void RefreshLabeling()
{
World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<GroundTruthLabelSetupSystem>().RefreshLabeling(m_Entity);
}
}
}

70
com.unity.perception/Tests/Runtime/GroundTruthTests/SegmentationGroundTruthTests.cs


using System.Linq;
using NUnit.Framework;
using Unity.Collections;
using Unity.Simulation;
using UnityEngine;
using UnityEngine.Perception.GroundTruth;
using UnityEngine.Rendering;

AddTestObjectForCleanup(TestHelper.CreateLabeledPlane());
yield return null;
//NativeArray<Color32> readbackArray = new NativeArray<Color32>(targetTextureOverride.width * targetTextureOverride.height, Allocator.Temp);
var request = AsyncGPUReadback.Request(targetTextureOverride, callback: r =>
TestHelper.ReadRenderTextureRawData<Color32>(targetTextureOverride, data =>
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, targetTextureOverride.width * targetTextureOverride.height), r.GetData<Color32>());
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, targetTextureOverride.width * targetTextureOverride.height), data);
AsyncGPUReadback.WaitAllRequests();
//request.WaitForCompletion();
Assert.IsTrue(request.done);
Assert.IsFalse(request.hasError);
}
[UnityTest]
public IEnumerator SemanticSegmentationPass_WithMultiMaterial_ProducesCorrectValues([Values(true, false)] bool showVisualizations)
{
int timesSegmentationImageReceived = 0;
var expectedPixelValue = k_SemanticPixelValue;
void OnSegmentationImageReceived(NativeArray<Color32> data)
{
timesSegmentationImageReceived++;
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, data.Length), data);
}
var cameraObject = SetupCameraSemanticSegmentation(a => OnSegmentationImageReceived(a.data), false);
var plane = TestHelper.CreateLabeledPlane();
var meshRenderer = plane.GetComponent<MeshRenderer>();
var baseMaterial = meshRenderer.material;
meshRenderer.materials = new[] { baseMaterial, baseMaterial };
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
mpb.SetFloat("float", 1f);
for (int i = 0; i < 2; i++)
{
meshRenderer.SetPropertyBlock(mpb, i);
}
AddTestObjectForCleanup(plane);
yield return null;
//destroy the object to force all pending segmented image readbacks to finish and events to be fired.
DestroyTestObject(cameraObject);
Assert.AreEqual(1, timesSegmentationImageReceived);
}
[UnityTest]
public IEnumerator SemanticSegmentationPass_WithChangingLabeling_ProducesCorrectValues([Values(true, false)] bool showVisualizations)
{
int timesSegmentationImageReceived = 0;
var expectedPixelValue = k_SemanticPixelValue;
void OnSegmentationImageReceived(NativeArray<Color32> data)
{
if (timesSegmentationImageReceived == 1)
{
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, data.Length), data);
}
timesSegmentationImageReceived++;
}
var cameraObject = SetupCameraSemanticSegmentation(a => OnSegmentationImageReceived(a.data), false);
var plane = TestHelper.CreateLabeledPlane(label: "non-matching");
AddTestObjectForCleanup(plane);
yield return null;
var labeling = plane.GetComponent<Labeling>();
labeling.labels = new List<string> { "label" };
labeling.RefreshLabeling();
yield return null;
//destroy the object to force all pending segmented image readbacks to finish and events to be fired.
DestroyTestObject(cameraObject);
Assert.AreEqual(2, timesSegmentationImageReceived);
}
[UnityTest]

18
com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs


using System;
using System.Diagnostics;
using Unity.Collections;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Perception.GroundTruth;
namespace GroundTruthTests

var labeling = planeObject.AddComponent<Labeling>();
labeling.labels.Add(label);
return planeObject;
}
public static void ReadRenderTextureRawData<T>(RenderTexture renderTexture, Action<NativeArray<T>> callback) where T : struct
{
RenderTexture.active = renderTexture;
var cpuTexture = new Texture2D(renderTexture.width, renderTexture.height, renderTexture.graphicsFormat, TextureCreationFlags.None);
cpuTexture.ReadPixels(new Rect(
Vector2.zero,
new Vector2(renderTexture.width, renderTexture.height)),
0, 0);
RenderTexture.active = null;
var data = cpuTexture.GetRawTextureData<T>();
callback(data);
}
#if UNITY_EDITOR

8
TestProjects/PerceptionURP/Assets/Scenes/SampleScene.meta


fileFormatVersion: 2
guid: c63d11a708fe3f047a545d7e457f6e81
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

31
TestProjects/PerceptionURP/Assets/TestMpbPerMaterial.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum MaterialPropertyTarget
{
Renderer,
Material
}
[ExecuteInEditMode]
public class TestMpbPerMaterial : MonoBehaviour
{
public MaterialPropertyTarget materialPropertyTarget = MaterialPropertyTarget.Material;
public Color color;
// Update is called once per frame
void Start()
{
var meshRenderer = GetComponent<MeshRenderer>();
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
mpb.SetColor("_BaseColor", color);
if (materialPropertyTarget == MaterialPropertyTarget.Renderer)
meshRenderer.SetPropertyBlock(mpb);
else
{
for (int i = 0; i < meshRenderer.sharedMaterials.Length; i++)
{
meshRenderer.SetPropertyBlock(mpb, i);
}
}
}
}

11
TestProjects/PerceptionURP/Assets/TestMpbPerMaterial.cs.meta


fileFormatVersion: 2
guid: 695e410829600ff40bcdd76fa0818f6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存