Skip to content

Commit 7bb8571

Browse files
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
1 parent 0b71f0d commit 7bb8571

File tree

10 files changed

+199
-11
lines changed

10 files changed

+199
-11
lines changed

TestProjects/PerceptionURP/Assets/Scenes/SampleScene.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

TestProjects/PerceptionURP/Assets/Scenes/SampleScene.unity

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ GameObject:
135135
- component: {fileID: 411238278}
136136
- component: {fileID: 411238277}
137137
- component: {fileID: 411238282}
138+
- component: {fileID: 411238283}
138139
m_Layer: 0
139140
m_Name: Crate
140141
m_TagString: Untagged
@@ -243,6 +244,20 @@ MonoBehaviour:
243244
m_Name:
244245
m_EditorClassIdentifier:
245246
yDegreesPerSecond: 180
247+
--- !u!114 &411238283
248+
MonoBehaviour:
249+
m_ObjectHideFlags: 0
250+
m_CorrespondingSourceObject: {fileID: 0}
251+
m_PrefabInstance: {fileID: 0}
252+
m_PrefabAsset: {fileID: 0}
253+
m_GameObject: {fileID: 411238276}
254+
m_Enabled: 1
255+
m_EditorHideFlags: 0
256+
m_Script: {fileID: 11500000, guid: 695e410829600ff40bcdd76fa0818f6a, type: 3}
257+
m_Name:
258+
m_EditorClassIdentifier:
259+
materialPropertyTarget: 1
260+
color: {r: 0.745283, g: 0.40428087, b: 0.40428087, a: 0}
246261
--- !u!1 &464025704
247262
GameObject:
248263
m_ObjectHideFlags: 0
@@ -257,6 +272,7 @@ GameObject:
257272
- component: {fileID: 464025706}
258273
- component: {fileID: 464025705}
259274
- component: {fileID: 464025710}
275+
- component: {fileID: 464025711}
260276
m_Layer: 0
261277
m_Name: Cube
262278
m_TagString: Untagged
@@ -310,6 +326,8 @@ MeshRenderer:
310326
m_RendererPriority: 0
311327
m_Materials:
312328
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
329+
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
330+
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
313331
m_StaticBatchInfo:
314332
firstSubMesh: 0
315333
subMeshCount: 0
@@ -365,6 +383,20 @@ MonoBehaviour:
365383
m_Name:
366384
m_EditorClassIdentifier:
367385
yDegreesPerSecond: 180
386+
--- !u!114 &464025711
387+
MonoBehaviour:
388+
m_ObjectHideFlags: 0
389+
m_CorrespondingSourceObject: {fileID: 0}
390+
m_PrefabInstance: {fileID: 0}
391+
m_PrefabAsset: {fileID: 0}
392+
m_GameObject: {fileID: 464025704}
393+
m_Enabled: 1
394+
m_EditorHideFlags: 0
395+
m_Script: {fileID: 11500000, guid: 695e410829600ff40bcdd76fa0818f6a, type: 3}
396+
m_Name:
397+
m_EditorClassIdentifier:
398+
materialPropertyTarget: 1
399+
color: {r: 0.34109113, g: 0.42664438, b: 0.6886792, a: 0}
368400
--- !u!1 &705507993
369401
GameObject:
370402
m_ObjectHideFlags: 0
@@ -595,7 +627,7 @@ MonoBehaviour:
595627
- id: 1
596628
- id: 2
597629
- id: 3
598-
showVisualizations: 0
630+
showVisualizations: 1
599631
references:
600632
version: 1
601633
00000000:
@@ -762,4 +794,4 @@ MonoBehaviour:
762794
m_Script: {fileID: 11500000, guid: 673a227032a8e4940b9828c5b6f852ab, type: 3}
763795
m_Name:
764796
m_EditorClassIdentifier:
765-
yDegreesPerSecond: 180
797+
yDegreesPerSecond: 180
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
5+
public enum MaterialPropertyTarget
6+
{
7+
Renderer,
8+
Material
9+
}
10+
[ExecuteInEditMode]
11+
public class TestMpbPerMaterial : MonoBehaviour
12+
{
13+
public MaterialPropertyTarget materialPropertyTarget = MaterialPropertyTarget.Material;
14+
public Color color;
15+
// Update is called once per frame
16+
void Start()
17+
{
18+
var meshRenderer = GetComponent<MeshRenderer>();
19+
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
20+
mpb.SetColor("_BaseColor", color);
21+
if (materialPropertyTarget == MaterialPropertyTarget.Renderer)
22+
meshRenderer.SetPropertyBlock(mpb);
23+
else
24+
{
25+
for (int i = 0; i < meshRenderer.sharedMaterials.Length; i++)
26+
{
27+
meshRenderer.SetPropertyBlock(mpb, i);
28+
}
29+
}
30+
}
31+
}

TestProjects/PerceptionURP/Assets/TestMpbPerMaterial.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

TestProjects/PerceptionURP/ProjectSettings/QualitySettings.asset

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ QualitySettings:
9595
skinWeights: 2
9696
textureQuality: 0
9797
anisotropicTextures: 1
98-
antiAliasing: 0
98+
antiAliasing: 2
9999
softParticles: 0
100100
softVegetation: 1
101101
realtimeReflectionProbes: 1

com.unity.perception/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ Added new randomization tools
1212

1313
Added support for 2020.1
1414

15+
Added Labeling.RefreshLabeling(), which can be used to update ground truth generators after the list of labels or the renderers is changed
16+
17+
Added support for renderers with MaterialPropertyBlocks assigned to individual materials
18+
1519
### Changed
1620

1721
Changed the way realtime visualizers rendered to avoid rendering conflicts

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ void InitGameObjectRecursive(GameObject gameObject, MaterialPropertyBlock mpb, L
7070
pass.SetupMaterialProperties(mpb, renderer, labeling, instanceId);
7171

7272
renderer.SetPropertyBlock(mpb);
73+
74+
var materialCount = renderer.materials.Length;
75+
for (int i = 0; i < materialCount; i++)
76+
{
77+
renderer.GetPropertyBlock(mpb, i);
78+
//Only apply to individual materials if there is already a MaterialPropertyBlock on it
79+
if (!mpb.isEmpty)
80+
{
81+
foreach (var pass in m_ActiveGenerators)
82+
pass.SetupMaterialProperties(mpb, renderer, labeling, instanceId);
83+
84+
renderer.SetPropertyBlock(mpb, i);
85+
}
86+
}
7387
}
7488

7589
for (var i = 0; i < gameObject.transform.childCount; i++)
@@ -106,5 +120,10 @@ public bool Deactivate(IGroundTruthGenerator generator)
106120
{
107121
return m_ActiveGenerators.Remove(generator);
108122
}
123+
124+
internal void RefreshLabeling(Entity labelingEntity)
125+
{
126+
EntityManager.RemoveComponent<GroundTruthInfo>(labelingEntity);
127+
}
109128
}
110129
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace UnityEngine.Perception.GroundTruth
1212
public class Labeling : MonoBehaviour
1313
{
1414
/// <summary>
15-
/// 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
15+
/// 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
1616
/// not guaranteed to be reflected by labelers.
1717
/// </summary>
1818
[FormerlySerializedAs("classes")]
@@ -37,5 +37,14 @@ void OnDestroy()
3737
if (World.DefaultGameObjectInjectionWorld != null)
3838
World.DefaultGameObjectInjectionWorld.EntityManager.DestroyEntity(m_Entity);
3939
}
40+
41+
/// <summary>
42+
/// Refresh ground truth generation for the labeling of the attached GameObject. This is necessary when the
43+
/// list of labels changes or when renderers or materials change on objects in the hierarchy.
44+
/// </summary>
45+
public void RefreshLabeling()
46+
{
47+
World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<GroundTruthLabelSetupSystem>().RefreshLabeling(m_Entity);
48+
}
4049
}
4150
}

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

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using NUnit.Framework;
77
using Unity.Collections;
8+
using Unity.Simulation;
89
using UnityEngine;
910
using UnityEngine.Perception.GroundTruth;
1011
using UnityEngine.Rendering;
@@ -290,15 +291,70 @@ public IEnumerator SemanticSegmentationPass_WithTextureOverride_RendersToOverrid
290291
AddTestObjectForCleanup(TestHelper.CreateLabeledPlane());
291292

292293
yield return null;
293-
//NativeArray<Color32> readbackArray = new NativeArray<Color32>(targetTextureOverride.width * targetTextureOverride.height, Allocator.Temp);
294-
var request = AsyncGPUReadback.Request(targetTextureOverride, callback: r =>
294+
TestHelper.ReadRenderTextureRawData<Color32>(targetTextureOverride, data =>
295295
{
296-
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, targetTextureOverride.width * targetTextureOverride.height), r.GetData<Color32>());
296+
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, targetTextureOverride.width * targetTextureOverride.height), data);
297297
});
298-
AsyncGPUReadback.WaitAllRequests();
299-
//request.WaitForCompletion();
300-
Assert.IsTrue(request.done);
301-
Assert.IsFalse(request.hasError);
298+
}
299+
300+
301+
[UnityTest]
302+
public IEnumerator SemanticSegmentationPass_WithMultiMaterial_ProducesCorrectValues([Values(true, false)] bool showVisualizations)
303+
{
304+
int timesSegmentationImageReceived = 0;
305+
var expectedPixelValue = k_SemanticPixelValue;
306+
void OnSegmentationImageReceived(NativeArray<Color32> data)
307+
{
308+
timesSegmentationImageReceived++;
309+
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, data.Length), data);
310+
}
311+
312+
var cameraObject = SetupCameraSemanticSegmentation(a => OnSegmentationImageReceived(a.data), false);
313+
314+
var plane = TestHelper.CreateLabeledPlane();
315+
var meshRenderer = plane.GetComponent<MeshRenderer>();
316+
var baseMaterial = meshRenderer.material;
317+
meshRenderer.materials = new[] { baseMaterial, baseMaterial };
318+
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
319+
mpb.SetFloat("float", 1f);
320+
for (int i = 0; i < 2; i++)
321+
{
322+
meshRenderer.SetPropertyBlock(mpb, i);
323+
}
324+
AddTestObjectForCleanup(plane);
325+
yield return null;
326+
//destroy the object to force all pending segmented image readbacks to finish and events to be fired.
327+
DestroyTestObject(cameraObject);
328+
Assert.AreEqual(1, timesSegmentationImageReceived);
329+
}
330+
331+
332+
[UnityTest]
333+
public IEnumerator SemanticSegmentationPass_WithChangingLabeling_ProducesCorrectValues([Values(true, false)] bool showVisualizations)
334+
{
335+
int timesSegmentationImageReceived = 0;
336+
var expectedPixelValue = k_SemanticPixelValue;
337+
void OnSegmentationImageReceived(NativeArray<Color32> data)
338+
{
339+
if (timesSegmentationImageReceived == 1)
340+
{
341+
CollectionAssert.AreEqual(Enumerable.Repeat(expectedPixelValue, data.Length), data);
342+
}
343+
timesSegmentationImageReceived++;
344+
}
345+
346+
var cameraObject = SetupCameraSemanticSegmentation(a => OnSegmentationImageReceived(a.data), false);
347+
348+
var plane = TestHelper.CreateLabeledPlane(label: "non-matching");
349+
AddTestObjectForCleanup(plane);
350+
yield return null;
351+
var labeling = plane.GetComponent<Labeling>();
352+
labeling.labels = new List<string> { "label" };
353+
labeling.RefreshLabeling();
354+
yield return null;
355+
//destroy the object to force all pending segmented image readbacks to finish and events to be fired.
356+
DestroyTestObject(cameraObject);
357+
Assert.AreEqual(2, timesSegmentationImageReceived);
302358
}
303359

304360
[UnityTest]

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Text.RegularExpressions;
4+
using Unity.Collections;
35
using UnityEngine;
6+
using UnityEngine.Experimental.Rendering;
47
using UnityEngine.Perception.GroundTruth;
58

69
namespace GroundTruthTests
@@ -18,6 +21,21 @@ public static GameObject CreateLabeledPlane(float scale = 10, string label = "la
1821
return planeObject;
1922
}
2023

24+
public static void ReadRenderTextureRawData<T>(RenderTexture renderTexture, Action<NativeArray<T>> callback) where T : struct
25+
{
26+
RenderTexture.active = renderTexture;
27+
28+
var cpuTexture = new Texture2D(renderTexture.width, renderTexture.height, renderTexture.graphicsFormat, TextureCreationFlags.None);
29+
30+
cpuTexture.ReadPixels(new Rect(
31+
Vector2.zero,
32+
new Vector2(renderTexture.width, renderTexture.height)),
33+
0, 0);
34+
RenderTexture.active = null;
35+
var data = cpuTexture.GetRawTextureData<T>();
36+
callback(data);
37+
}
38+
2139
#if UNITY_EDITOR
2240
public static void LoadAndStartRenderDocCapture(out UnityEditor.EditorWindow gameView)
2341
{

0 commit comments

Comments
 (0)