{"id":20749766,"url":"https://github.com/cyberagentgameentertainment/airsticker","last_synced_at":"2025-04-09T10:09:23.512Z","repository":{"id":168847441,"uuid":"553966962","full_name":"CyberAgentGameEntertainment/AirSticker","owner":"CyberAgentGameEntertainment","description":"Air Sticker is a decal system that addresses the limitations of URP decals and has a low impact on performance.","archived":false,"fork":false,"pushed_at":"2024-02-13T08:33:13.000Z","size":306401,"stargazers_count":287,"open_issues_count":1,"forks_count":21,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-02T08:09:39.731Z","etag":null,"topics":["unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CyberAgentGameEntertainment.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-19T03:26:41.000Z","updated_at":"2025-03-25T22:01:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"d105aded-06f0-4e19-9309-c93d6aaeced5","html_url":"https://github.com/CyberAgentGameEntertainment/AirSticker","commit_stats":null,"previous_names":["cyberagentgameentertainment/airsticker"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyberAgentGameEntertainment%2FAirSticker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyberAgentGameEntertainment%2FAirSticker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyberAgentGameEntertainment%2FAirSticker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyberAgentGameEntertainment%2FAirSticker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CyberAgentGameEntertainment","download_url":"https://codeload.github.com/CyberAgentGameEntertainment/AirSticker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248018061,"owners_count":21034048,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["unity"],"created_at":"2024-11-17T08:24:27.465Z","updated_at":"2025-04-09T10:09:23.486Z","avatar_url":"https://github.com/CyberAgentGameEntertainment.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"Documentation/AirSticker_logo_color.png#gh-light-mode-only\" alt=\"AirSticker\"\u003e\n\u003cimg src=\"Documentation/AirSticker_logo_dark.png#gh-dark-mode-only\" alt=\"AirSticker\"\u003e\n\u003c/p\u003e\n\n# Air Sticker\n[![license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE.md)\n[![license](https://img.shields.io/badge/PR-welcome-green.svg)](hogehoge)\n[![license](https://img.shields.io/badge/Unity-2020.3-green.svg)](#Requirements)\n\n**Documents** ([English](README.md), [日本語](README_JA.md)) \u003cbr/\u003e\n**Technical Documents** ([English](README_DEVELOPERS.md), [日本語](README_DEVELOPERS_JA.md)) \u003cbr/\u003e\n\n## Section 1 Summary\nAir Sticker is a decal system that addresses the limitations of URP decals and has a low impact on performance.\u003cbr/\u003e\nAlso, URP decals can only be used with Unity2021 or higher, while Air Sticker supports operation with Unity2020 or higher.\u003cbr/\u003e\n\n\u003cbr/\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"Documentation/fig-014.gif\"\u003e\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cbr/\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"Documentation/fig-015.gif\"\u003e\u003cbr\u003e\n\u003c/p\u003e\n\n## Section 2 Feature\nAir Sticker implements decal processing using the typical mesh generation method used in many games.\u003cbr/\u003e\n\nMesh-generated decals implement decal expression by generating a mesh at runtime with a shape that matches the model to which the decal will be applied and then applying a texture to it.\u003cbr/\u003e\n\nOn the other hand, the decal process implemented in Unity implements projected DBuffer decals and screen space decals.\u003cbr/\u003e\n\nBoth mesh generation and projection decals have advantages/disadvantages.\u003cbr/\u003e\nThe mesh generation and projection methods can also be used together to compensate for many disadvantages. (see section 2.1 and 2.2 for details).\u003cbr/\u003e\n\n### 2.1 Advantages and Disadvantages of URP Decal and Air Sticker\nThe advantages/disadvantages of URP decals and Air Sticker are as follows.\n\n- **URP Decal**\n  - **Advantages**\n    - Fast-applied decal.\n    - Z-fighting doesn't happen.\n  - **Demerit**\n    - Difficult to support full skin animation. ( Can be complemented with Air Sticker. )\n    - Pixel shaders are overloaded.( Can be complemented with Air Sticker. )\n    -  Custom shaders cannot be used as is.( Can be complemented with Air Sticker. )\n- **Air Sticker**\n  -  **Advantages**\n     - Lightweight processing.( However, decal mesh generation is laggy )\n     - Full skin animation is possible.\n     - Custom shaders can be used without modification.\n  - **Demerit**\n    - The process of applying decals takes time. ( Can be complemented with URP decals. )\n    - Z-fighting happen.\n\nThus, the two decals can be used together to complement many of the disadvantages.\u003cbr/\u003e\n\n### 2.2 Combination of URP decal and Air Sticker\nAs we saw in the previous section, the two decal treatments can be used together to complement many disadvantages.\u003cbr/\u003e\u003cbr/\u003e\n\nThe following model case is presented here as a way of combining the two.\n\n|Method|Use Case|\n|---|---|\n|URP Decal| ・ Decal moves in the object space.\u003cbr/\u003e ・ An alternative method until the mesh generation by Air Sticker is finished.|\n|Air Sticker|Decal don't moves in object space.|\n\nThe following movie demonstrates the implementation of this model case.\n\n\u003cbr/\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"80%\" src=\"Documentation/fig-001.gif\" alt=\"Combination of URP decal and Air Sticker\"\u003e\u003cbr\u003e\n\u003cfont color=\"grey\"\u003eCombination of URP decal and Air Sticker\u003c/font\u003e\n\u003c/p\u003e\n\nIn this movie, URP decal is used when the decal moves on the receiver object and to buy time until mesh generation is complete.\u003cbr/\u003e\nOnce the position on the receiver object is determined and mesh generation is finished, the decal by Air Sticker is displayed thereafter.\u003cbr/\u003e\n\nOnce mesh generation is complete, Air Sticker can be used to greatly improve runtime performance(see Section 2.3 for details).\u003cbr/\u003e\n\n### 2.3 URP Decal and Air Sticker rendering performance\nAir Sticker takes several frames to generate the mesh, but once generated, the drawing performance is no different than simple mesh drawing.\u003cbr/\u003e\nOn the other hand, URP decals do not require mesh generation, but a complex drawing process is performed to display the decals.\u003cbr/\u003e\u003cbr/\u003e\nTherefore, the mesh generation method is more advantageous in terms of frame-by-frame rendering performance.\u003cbr/\u003e\u003cbr/\u003e\n\nThe following figure shows the measured rendering performance of URP Decal and Air Sticker.\u003cbr/\u003e\nIn all cases, Air Sticker was superior, with the most significant difference being a performance improvement of 19 ms.\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"80%\" src=\"Documentation/fig-002.png\" alt=\"Performance Measurement Results\"\u003e\u003cbr\u003e\n\u003cfont color=\"grey\"\u003ePerformance Measurement Results\u003c/font\u003e\n\u003c/p\u003e\n\n## Section 3 Install\nTo install the software, follow the steps below.\n\n1. Open the Package Manager from `Window \u003e Package Manager`\n2. `\"+\" button \u003e Add package from git URL`\n3. Enter the following\n   * https://github.com/CyberAgentGameEntertainment/AirSticker.git?path=/Assets/AirSticker\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"60%\" src=\"https://user-images.githubusercontent.com/47441314/143533003-177a51fc-3d11-4784-b9d2-d343cc622841.png\" alt=\"Package Manager\"\u003e\n\u003c/p\u003e\n\nOr, open `Packages/manifest.json` and add the following to the dependencies block.\n\n```json\n{\n    \"dependencies\": {\n        \"jp.co.cyberagent.air-sticker\": \"https://github.com/CyberAgentGameEntertainment/AirSticker.git?path=/Assets/AirSticker\"\n    }\n}\n```\n\nIf you want to set the target version, write as follows.\n\n* https://github.com/CyberAgentGameEntertainment/AirSticker.git?path=/Assets/AirSticker#1.0.0\n\nNote that if you get a message like `No 'git' executable was found. Please install Git on your system and restart Unity`, you will need to set up Git on your machine.\n\nTo update the version, rewrite the version as described above.  \nIf you don't want to specify a version, you can also update the version by editing the hash of this library in the package-lock.json file.\n\n```json\n{\n  \"dependencies\": {\n      \"jp.co.cyberagent.air-sticker\": {\n      \"version\": \"https://github.com/CyberAgentGameEntertainment/AirSticker.git?path=/Assets/AirSticker\",\n      \"depth\": 0,\n      \"source\": \"git\",\n      \"dependencies\": {},\n      \"hash\": \"...\"\n    }\n  }\n}\n```\n\n## Section 4 How to use\nThe following two classes are important for using Air Sticker.\n1. AirStickerSystem\n2. AirStickerProjector \n\n### 4.1 AirStickerSystem\nTo use Air Sticker, you must have one game object attached to this component in your scene.\n\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"50%\" src=\"Documentation/fig-013.png\" alt=\"AirStickerSystem\"\u003e\u003cbr\u003e\n\u003cfont color=\"grey\"\u003eAirStickerSystem\u003c/font\u003e\n\u003c/p\u003e\n\n### 4.2 AirStickerProjector\nThis component is used to project decals. Add this component to the game object that you want to use as a decal projector.\n\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"50%\" src=\"Documentation/fig-004.png\" alt=\"AirStickerProjector inspector\"\u003e\u003cbr\u003e\n\u003cfont color=\"grey\"\u003eAirStickerProjector inspector\u003c/font\u003e\n\u003c/p\u003e\n\nFive parameters can be set for the AirStickerProjector component.\n\n|Parameter name|Description|\n|---|---|\n|Width|Width of the Projector bounding box.This complies with URP's decal projector specifications.\u003cbr/\u003eFor more information, see [Manual for URP Decals](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/renderer-feature-decal.html).|\n|Height|Height of the Projector bounding box.This complies with URP's decal projector specifications.\u003cbr/\u003eFor more information, see [Manual for URP Decals](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/renderer-feature-decal.html).|\n|Depth|Depth of the Projector bounding box.This complies with URP's decal projector specifications.\u003cbr/\u003eFor more information, see [Manual for URP Decals](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/renderer-feature-decal.html).|\n|Receiver Objects| The objects to which the decal texture will be applied.\u003cbr/\u003eAirStickerProjector targets all renderers pasted to children of the configured receiver object (including itself).\u003cbr/\u003e\u003cbr/\u003eTherefore, the receiver object can be specified directly as an object to which a component such as MeshRenderer or SkinMeshRenderer is attached, or it can be an object that contains an object to which a renderer is attached as a child.\u003cbr/\u003eThe more renderers you process, the longer it will take to generate the decal mesh.Therefore, if the object to which the decal texture is to be applied can be restricted, it is more advantageous to specify that object directly as the receiver object.\u003cbr/\u003e\u003cbr/\u003eFor example, if you want to put a sticker on a character's face in a character edit, you can save mesh generation time by specifying the object to which the face renderer is attached rather than specifying the character's root object.|\n|Decal Material| URP decals can only use materials with Shader Graphs/Decal shaders assigned, while Air Sticker can use regular materials.\u003cbr/\u003eThis means that built-in Lit shaders, Unlit shaders, and user-custom, proprietary shaders are also available.|\n|Z Offset In Decal Space|This is the Z offset in the surface space where the decal is applied. By adjusting this value, you can reduce Z-fighting.|\n|Projection Backside|If this checkbox is checked, the decal mesh is projected onto the mesh on the backside.|\n|Launch On Awake|If this checkbox is checked, the decal projection process is started at the same time the instance is created.|\n|On Finished Launch|You can specify a callback to be called at the end of the decal projection.|\n\nThe following video shows how to use AirStickerProjector in a scene.\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"80%\" src=\"Documentation/fig-012.gif\" alt=\"How to use AirStickerProjector\"\u003e\u003cbr\u003e\n\u003cfont color=\"grey\"\u003eHow to use AirStickerProjector\u003c/font\u003e\n\u003c/p\u003e\n\n\n### 4.3 How to generate AirStickerProjector in-game\nAn example of an in-game use of decals is the process of applying bullet holes to a background, such as in a FPS. \u003cbr/\u003e\nSuch a process can be accomplished by determining the collision between the background and the bullet, generating a AirStickerProjector component based on the collision point information, and constructing a decal mesh.\u003cbr/\u003e\u003cbr/\u003e\nAirStickerProjector components can be created by calling the AirStickerProjector.CreateAndLaunch() method.\u003c/br\u003e\nIf true is specified for the launchAwake argument of the CreateAndLaunch() method, the decal mesh construction process is started at the same time the component is created.\u003cbr/\u003e\u003cbr/\u003e\nThe decal mesh construction process takes several frames.Therefore, if you want to monitor the end of the decal mesh construction process, you must monitor the NowState property of AirStickerProjector or use the onFinishedLaunch callback, which is called when the mesh generation process is finished.\u003cbr/\u003e\u003cbr/\u003e\nThe following code is a pseudo code to paste bullet holes on the background using the AirStickerProjector.CreateAndLaunch() method. This code sets up a callback that monitors for termination using the arguments of the CreateAndLaunch() method.\u003cbr/\u003e\n```C#\n// hitPosition    Bullet and background collision point.\n// hitNormal      Normal of the collided surface.\n// receiverObject Receiver object to which decal is applied.\n// decalMaterial  Material with decal texture set\nvoid LaunchProjector( \n  Vector3 hitPosition, Vector3 hitNormal, \n  GameObject receiverObject, Material decalMaterial )\n{\n    var projectorObject = new GameObject(\"Decal Projector\");\n    // Install the projector at the position pushed back in the normal direction.\n    projectorObject.transform.position = hitPosition + hitNormal;\n    // Projector is oriented in the opposite direction of the normal.\n    projectorObject.transform.rotation = Quaternion.LookRotation( hitNormal * -1.0f );\n\n    AirStickerProjector.CreateAndLaunch(\n                    projectorObj,\n                    receiverObject,\n                    decalMaterial,\n                    /*width=*/0.05f,\n                    /*height=*/0.05f,\n                    /*depth=*/0.2f\n                    /*launchOnAwake*/true,\n                    /*onCompletedLaunch*/() =\u003e { Destroy(projectorObj); });\n}\n```\n***\n\u003cp align=\"right\"\u003e\n© Unity Technologies Japan/UC\n\u003c/p\u003e\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyberagentgameentertainment%2Fairsticker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcyberagentgameentertainment%2Fairsticker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyberagentgameentertainment%2Fairsticker/lists"}