︎︎︎ Games of Deletion



Tags :
︎ Educational AR Game
︎ Book
︎ M.Arch Thesis  


Status :
Presented

Role :
Developer, Designer, CGI, Writer

Buy the book


︎SCI-Arc

︎ Collaboration with Runze Zhang


︎ Los Angeles, California

︎ 2018 09

︎ Project Breakdown

. “Games of Deletion” is an AR project speculating on the use of Augmented Reality, specifically related to design, architecture and urbanism

. the mobile application allows two players located in different locations to communicate with each other through a portal opened up using Image Tracking AR on large scale murals

. the game consists in pushing and pulling visual urban informations from one location to the other, generating a collage of information and letting the two location collapse in a unique physical-digital environment

. this project opened up a lot of diverse possible minor application taking advantage of geo-location SDKs as Mapbox

. Games of Deletion can be considered a project still in development and that explores the most updated available AR templates

. Games of Deletion has been praised as Best Graduate Thesis in 2018 at SCI-Arc


︎ Games of Deletion : Rise of an Interface


. this project starts with the writing of a semi-fictional story that try listing all the possible application of AR in the field of architecture and their implications. 

. The book narrates the story of Kay, a design student that lives in a world where the “League of Games of Deletions” is the main entity defining society and advancment in technology

. strongly inspired by stories as “Battle Royale” and “Ready Player One”, “Games of Deletion” approaches AR from an educational perspective, being a reference for students starting to appreciate AR from application intersecting the design field

. the book narrating the whole story is available in the impermament collection of A+D Musueum in Los Angeles

Read it
︎

. Demonstrative Video featuring CGI and Real Time demonstration.

. 00.00 CGI : Concept Video First Person View

. 02.26 CGI : Concept Video Trailer

. 04.51 AR Real Time Demo

. 07.24 CGI : Video Diagram

. more real time materal at IG thesis account @gamesofdeletion







︎ Shared Code Sample :
Boolean Shaders


. the main feature of the AR demo is determined by the application of shaders using AR Foundation’s AR templates

. the shaders simulate a boolean operation between solids and with added transparency create the effect showcased in the previous diagram

. two solid shapes intersecting open up a “portal” where the players can see each other and conceptually transfering information through the portal

. This has been a process of finding more resources, putting them together and exploring shaders, especially the stencil buffer shader that makes the “portal effect” possible

. significant sources and thanks 

Unity        : Writing Shaders 
YouTube : quill18creates
YouTube : PushyPixels
YouTube : Unity Shader Crash Course
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
Shader "Custom/CUTOBJ" {
	// to be assigned to the CUT OBJECT 
	// basic properties of the material in the inspector 
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
	        _BumpMap("Bumpmap", 2D) = "bump" {}
		_Glossiness ("Smoothness", Range(0,1)) = 0.5
		_Metallic ("Metallic", Range(0,1)) = 0.0
	    _StencilMask("Stencil Mask", Range(0, 255)) = 128
	}
        // a subshader alters the shader for a number of purposes 
	SubShader {
		// tags are basically key-value pairs. Inside a SubShader tags are used to determine rendering order and other parameters of a subshader.
		// https://docs.unity3d.com/Manual/SL-SubShaderTags.html
		// “renderType” tag set that can be used when rendering with replaced shaders
		// https://docs.unity3d.com/Manual/SL-ShaderReplacement.html
		Tags { "RenderType"="Opaque" }
		// level of detail (LOD) for shaders - 200 = Diffuse 
		LOD 200
		// https://docs.unity3d.com/Manual/SL-CullAndDepth.html
		// all faces are drawn so there is no culling 
		Cull Off
                // https://docs.unity3d.com/Manual/SL-Stencil.html
		// the stencil defined as 8 bit integer per pixel is a value that define the masking of the pixel
		Stencil
		{
			// The value to be compared against (if Comp is anything else than always) and/or the value to be written to the buffer (if either Pass, Fail or ZFail is set to replace). 0–255 integer.
			Ref[_StencilMask]
			// The function used to compare the reference value to the current contents of the buffer. Default: always.
			// **Comp, Pass, Fail and ZFail will be applied to the front-facing geometry, unless Cull Front is specified, in which case it’s back-facing geometry
			// **You can also explicitly specify the two-sided stencil state by defining CompFront, PassFront
			CompBack Always
			// What to do with the contents of the buffer if the stencil test (and the depth test) passes. Default: keep.
			// Replace = Write the reference value into the buffer.
			PassBack Replace
			// 
			CompFront Always
			// Zero = Write 0 into the buffer
			PassFront Zero
			// AN EASIER WAY to think about this is having an external reference to compare 
			// and passing something only if the external reference is what we are looking for 
			// or not looking for 
		}
		// this is where actually the shader is written 
		// physically based Standard lighting model, and enable shadows on all light types
		CGPROGRAM 
	        // https://docs.unity3d.com/Manual/SL-ShaderPrograms.html
	        // compilation directives can be given as #pragma statements
		#pragma surface surf Standard fullforwardshadows
		// nicer looking lighting
		#pragma target 3.0
                // https://shadowmint.gitbooks.io/unity-material-shaders/content/support/input_structure.html
		// a basic form of surface shader is Input and Structure 
                // https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/texturing.php
		// sampler 2D signifies a 2D Texture 
		sampler2D _MainTex;
		sampler2D _Thickness;
		sampler2D _BumpMap;
		// listing the variables in a struct 
		struct Input {
			float2 uv_MainTex;
			float2 uv_BumpMap;
			float4 screenPos;
			float  faceDir: VFACE;
		};
		// https://docs.unity3d.com/Manual/SL-DataTypesAndPrecision.html
		// Half precision is useful for short vectors, directions, object space positions, high dynamic range colors.
		// Several variants of floating point types are present: float, half and fixed
		half _Glossiness;
		half _Metallic;
		// fixed4 (low precision RGBA color)
		fixed4 _Color;
		// execute the shader program
		// https://stackoverflow.com/questions/50429120/what-does-the-shader-function-surf-do
		// that takes any UVs or data you need as input, and fills in output structure SurfaceOutput. 
		// SurfaceOutput basically describes properties of the surface [HLSL]
		void surf (Input IN, inout SurfaceOutputStandard o) {
			// Albedo comes from a texture tinted by color
			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
			// create a depth data float 
			float4 depthData = tex2Dproj(_Thickness,
				UNITY_PROJ_COORD(IN.screenPos));
			// https://docs.unity3d.com/Manual/SL-BuiltinMacros.html
			// UNITY_PROJ_COORD(a)	Given a 4-component vector, this returns a Texture coordinate suitable for projected Texture reads. 
			// On most platforms this returns the given value directly.
			// decode the rg and ba [rgba] to front and back depth
			float frontDepth = DecodeFloatRG(depthData.xy);
			float backDepth = DecodeFloatRG(depthData.zw);
			// fragment depth
			// calculate the 01 depth _ view.z = -porj.w
			float partZ = IN.screenPos.w*_ProjectionParams.w;
			// discard fragment in between front and back
			clip((partZ - frontDepth -1.0f / (65536 * 2))*(partZ - backDepth + 1.0f / (65536 * 2)));
			//
			o.Albedo = c.rgb;
			o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
			// Metallic and smoothness come from slider variables
			// set the back surface normal to forward direction
			// if (IN.faceDir < 0) o.Normal = half3(0.0f, 0.0f, 1.0f);
			o.Normal = lerp(o.Normal, half3(0, 0, 1), step(IN.faceDir, 0));
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
Shader "Custom/CUT" {
	// to be assigned to the CUTTING OBJECT  
	// basic properties of the material in the inspector 
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
		_Emission ("Emission",Color) = (0,0,0,1)
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
	        _BumpMap("Bumpmap", 2D) = "bump" {}
		_Glossiness ("Smoothness", Range(0,1)) = 0.5
		_Metallic ("Metallic", Range(0,1)) = 0.0
	        _StencilMask("StencilMask",Range(0,255))=128
	}
	SubShader {
		//https://docs.unity3d.com/Manual/SL-SubShaderTags.html
		//This will make the object be rendered after all opaque objects, but before transparent objects, 
		// as render queue index will be 2001 (geometry plus one). This is useful in situations where you 
		// want some objects be always drawn between other sets of objects. For example, in most cases transparent 
		// water should be drawn after opaque objects but before transparent objects.
		Tags { "RenderType"="Opaque" "Queue" = "Geometry+10" }
		LOD 200
		Cull Front //only render back faces
		Stencil{
			Ref[_StencilMask]
			// https://docs.unity3d.com/Manual/SL-Stencil.html
			// Only render pixels whose reference value equals the value in the buffer.
			Comp Equal
		}
		// this is where actually the shader is written 
		// physically based Standard lighting model, and enable shadows on all light types
		CGPROGRAM
		#pragma surface surf Standard fullforwardshadows
		// nicer looking lighting
		#pragma target 3.0

		sampler2D _MainTex;
		sampler2D _Thickness;
		sampler2D _BumpMap;

		struct Input {
			float2 uv_MainTex;
			float2 uv_BumpMap;
			float4 screenPos;
		};

		half _Glossiness;
		half _Metallic;
		fixed4 _Color;
		fixed4 _Emission;
                // 
		void surf (Input IN, inout SurfaceOutputStandard o) {
			// Albedo comes from a texture tinted by color
			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
			float4 depthData = tex2Dproj(_Thickness,
				UNITY_PROJ_COORD(IN.screenPos));
			// decode the rg and ba [rgba] to front and back depth
			// float frontDepth = DecodeFloatRG(depthData.xy);
			float backDepth = DecodeFloatRG(depthData.zw);
			// fragment depth
			// calculate the 01 depth
			float partZ = IN.screenPos.w*_ProjectionParams.w;
			// discard fragment 
			clip(partZ - backDepth + 1.0f/(65536*2));
			o.Albedo = c.rgb;
			o.Normal = -UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
			// Metallic and smoothness come from slider variables
			o.Metallic = _Metallic;
			o.Emission = _Emission*_Emission.a;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}