├── .gitattributes ├── Assets ├── Dither3D │ ├── Dither3D_1x1.png │ ├── Dither3D_2x2.png │ ├── Dither3D_4x4.png │ ├── Dither3D_8x8.png │ ├── Dither3D_1x1_Ramp.png │ ├── Dither3D_2x2_Ramp.png │ ├── Dither3D_4x4_Ramp.png │ ├── Dither3D_8x8_Ramp.png │ ├── FullscreenEffect │ │ ├── Upscale.shader.meta │ │ ├── Monochrome.shader.meta │ │ ├── Monochrome.cs.meta │ │ ├── Upscale.cs.meta │ │ ├── Monochrome.cs │ │ ├── Monochrome.shader │ │ ├── Upscale.shader │ │ └── Upscale.cs │ ├── Editor.meta │ ├── FullscreenEffect.meta │ ├── Dither3D_1x1.asset.meta │ ├── Dither3D_2x2.asset.meta │ ├── Dither3D_4x4.asset.meta │ ├── Dither3D_8x8.asset.meta │ ├── Dither3DInclude.cginc.meta │ ├── Particle Alpha Blend.shader.meta │ ├── Dither3DGlobalProperties.cs.meta │ ├── Editor │ │ ├── Dither3DTextureMaker.cs.meta │ │ ├── OverridePropertyDrawer.cs.meta │ │ ├── DitherPatternPropertyDrawer.cs.meta │ │ ├── OverridePropertyDrawer.cs │ │ ├── DitherPatternPropertyDrawer.cs │ │ └── Dither3DTextureMaker.cs │ ├── Dither3DParticleAdd.shader.meta │ ├── Dither3DCutout.shader.meta │ ├── Dither3DOpaque.shader.meta │ ├── Dither3DSkybox.shader.meta │ ├── Dither3D_1x1.asset │ ├── Dither3D_1x1.png.meta │ ├── Dither3D_2x2.png.meta │ ├── Dither3D_4x4.png.meta │ ├── Dither3D_1x1_Ramp.png.meta │ ├── Dither3D_2x2_Ramp.png.meta │ ├── Dither3D_4x4_Ramp.png.meta │ ├── Dither3D_8x8_Ramp.png.meta │ ├── Dither3D_8x8.png.meta │ ├── Dither3DOpaque.shader │ ├── Dither3DCutout.shader │ ├── Particle Alpha Blend.shader │ ├── Dither3DParticleAdd.shader │ ├── Dither3DGlobalProperties.cs │ ├── Dither3DSkybox.shader │ ├── Dither3D_2x2.asset │ └── Dither3DInclude.cginc ├── Materials │ ├── TilesAlbedo.png │ ├── TilesNormal.png │ ├── Dither3D.mat.meta │ ├── Dither3DTiles.mat.meta │ ├── Dither3D_LargeDots.mat.meta │ ├── TilesAlbedo.png.meta │ ├── TilesNormal.png.meta │ ├── Dither3D.mat │ ├── Dither3D_LargeDots.mat │ └── Dither3DTiles.mat ├── Scenes │ ├── TestGradient │ │ ├── Gradient.png │ │ ├── TestGradient.unity.meta │ │ ├── TestGradientRaw.mat.meta │ │ ├── TestGradientDither.mat.meta │ │ ├── TestGradientRaw.mat │ │ ├── TestGradientDither.mat │ │ ├── Gradient.png.meta │ │ └── TestGradient.unity │ ├── Zoom.unity.meta │ ├── PerspectiveRow.unity.meta │ ├── RotatingLight.unity.meta │ ├── RotatingScene.unity.meta │ ├── RotatingSceneLowRes.unity.meta │ ├── TestGradient.meta │ └── Zoom.unity ├── Scenes.meta ├── Scripts.meta ├── Dither3D.meta ├── Materials.meta └── Scripts │ ├── ConstantExpScale.cs │ ├── ConstantMovement.cs │ ├── ConstantExpScale.cs.meta │ ├── ConstantMovement.cs.meta │ ├── ConstantRotation.cs.meta │ └── ConstantRotation.cs ├── ProjectSettings ├── ProjectVersion.txt ├── ClusterInputManager.asset ├── PresetManager.asset ├── EditorBuildSettings.asset ├── XRSettings.asset ├── TimeManager.asset ├── VFXManager.asset ├── AudioManager.asset ├── TagManager.asset ├── UnityConnectSettings.asset ├── PackageManagerSettings.asset ├── EditorSettings.asset ├── DynamicsManager.asset ├── NavMeshAreas.asset ├── Physics2DSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset └── QualitySettings.asset ├── Packages ├── manifest.json └── packages-lock.json ├── .gitignore ├── README.md └── LICENSE.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_1x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_1x1.png -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_2x2.png -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_4x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_4x4.png -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_8x8.png -------------------------------------------------------------------------------- /Assets/Materials/TilesAlbedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Materials/TilesAlbedo.png -------------------------------------------------------------------------------- /Assets/Materials/TilesNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Materials/TilesNormal.png -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2019.4.36f1 2 | m_EditorVersionWithRevision: 2019.4.36f1 (660c164b2fc5) 3 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_1x1_Ramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_1x1_Ramp.png -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_2x2_Ramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_2x2_Ramp.png -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_4x4_Ramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_4x4_Ramp.png -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_8x8_Ramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Dither3D/Dither3D_8x8_Ramp.png -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/Gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/runevision/Dither3D/HEAD/Assets/Scenes/TestGradient/Gradient.png -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Upscale.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4da39e2b66444bcebcc2e9c11cbb54b 3 | ShaderImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Monochrome.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d63ac8e9aa3a143ae830f3acc6e0a7a5 3 | ShaderImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /Assets/Scenes/Zoom.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf36fd3113b244afeb145f311989756e 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_DefaultPresets: {} 8 | -------------------------------------------------------------------------------- /Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 842227e10eba944b89aa7ae3c6b36f64 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/PerspectiveRow.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae8b14e7956dd43738b40e1f2bdf6de4 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scenes/RotatingLight.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38943719e90724576823735524e4d39f 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scenes/RotatingScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46b69c284164244a78b4b4bfb0d80c30 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f836645ab97f244e297ff5ba5b57c8cc 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Dither3D.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b25dff505bbcf4075b2ed516f0a59f80 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 24ddd2e81a1b74d1b84abadd8e24b2c8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/RotatingSceneLowRes.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b7a7feb4d3b4b49dc9c6475bf59f3276 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Dither3D/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98e1fc1df813546d7909f5dcf4c31cb6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/TestGradient.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db052a482af5146f38404fc29b5d7b9a 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: [] 8 | m_configObjects: {} 9 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99ec3166843624a4989ad7c32567c4fa 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57a056707932f48fd999b5bb2a5a18e4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Dither3D.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27dfb3c546ce5450c80a05f92e4b4fd5 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_1x1.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 878b6eb063b8e454fa77b6c500c76c7d 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11700000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_2x2.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0129ac74a9f624535ad0c631fdb4aa11 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11700000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_4x4.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adcf445c5001b42a5ba7ad33a98ccdea 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11700000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_8x8.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f8c14933cd8df41c29224daa7bcca430 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11700000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Dither3DTiles.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ab77b42de82240eca9055407fb790f2 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Dither3D_LargeDots.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53bde496bb3f94d9b81bce37e0f00b99 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/TestGradientRaw.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f3d621e03f24d4a669d79217d79463a5 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/TestGradientDither.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 941acd07f30aa49ae92eb7bd12f89d80 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/ConstantExpScale.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ConstantExpScale : MonoBehaviour { 4 | 5 | public float scaleExp = 1.2f; 6 | 7 | void Update() { 8 | transform.localScale = Vector3.one * Mathf.Pow(scaleExp, Time.time); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DInclude.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 456a6df74427c4ea0946aae1d1bd81ab 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scripts/ConstantMovement.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ConstantMovement : MonoBehaviour { 4 | 5 | public Vector3 velocity = new Vector3(1, 0, 0); 6 | 7 | void Update() { 8 | transform.Translate(velocity * Time.deltaTime, Space.World); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Assets/Dither3D/Particle Alpha Blend.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53f23dc15fa4e4fac8131e368a4b8c1b 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scripts/ConstantExpScale.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dfdea1d043522496897e2cde7bfbccb4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/ConstantMovement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee2c2148318cc40c39e1fa8441926c3f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/ConstantRotation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b045519b7a33948bc9168acec4ccf0f2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DGlobalProperties.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e125df9991507453eaf633f12ee503f7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Dither3D/Editor/Dither3DTextureMaker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5f2285bf922e4e2491f9bca160fc747 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Dither3D/Editor/OverridePropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d92c62016467047e4932d429c6449f77 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Dither3D/Editor/DitherPatternPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b977af414b615384ba4d21457527393e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/ConstantRotation.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class ConstantRotation : MonoBehaviour { 4 | 5 | public float speed = 22.5f; 6 | public float phase = 0; 7 | public int axis = 1; 8 | 9 | void Update() { 10 | Vector3 rot = Vector3.zero; 11 | rot[axis] = Time.time * speed + phase; 12 | transform.localRotation = Quaternion.Euler(rot); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_StripUpdateShader: {fileID: 0} 10 | m_RenderPipeSettingsPath: 11 | m_FixedTimeStep: 0.016666668 12 | m_MaxDeltaTime: 0.05 13 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DParticleAdd.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df63585fc566f4d049db83ea1993e138 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: 6 | - _MainTex: {instanceID: 0} 7 | - _DitherTex: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 8 | nonModifiableTextures: [] 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Monochrome.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 82e40db38270a4297aa522b0a441f5bd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - monochromeShader: {fileID: 4800000, guid: d63ac8e9aa3a143ae830f3acc6e0a7a5, type: 3} 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DCutout.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b7b71f3d4a51486d945cea394aeae1d 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: 6 | - _MainTex: {instanceID: 0} 7 | - _BumpMap: {instanceID: 0} 8 | - _EmissionMap: {instanceID: 0} 9 | - _DitherTex: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 10 | nonModifiableTextures: [] 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DOpaque.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b406c17af5df4375b715b8770f556fe 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: 6 | - _MainTex: {instanceID: 0} 7 | - _BumpMap: {instanceID: 0} 8 | - _EmissionMap: {instanceID: 0} 9 | - _DitherTex: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 10 | nonModifiableTextures: [] 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Upscale.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 342cf6596452e4a29a5e7a924690e897 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: 7 | - upscaleShader: {fileID: 4800000, guid: f4da39e2b66444bcebcc2e9c11cbb54b, type: 3} 8 | - tex: {instanceID: 0} 9 | - renderCam: {instanceID: 0} 10 | - screenCam: {instanceID: 0} 11 | executionOrder: 0 12 | icon: {instanceID: 0} 13 | userData: 14 | assetBundleName: 15 | assetBundleVariant: 16 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Volume: 1 8 | Rolloff Scale: 1 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_SampleRate: 0 12 | m_DSPBufferSize: 1024 13 | m_VirtualVoiceCount: 512 14 | m_RealVoiceCount: 32 15 | m_SpatializerPlugin: 16 | m_AmbisonicDecoderPlugin: 17 | m_DisableAudio: 0 18 | m_VirtualizeEffects: 1 19 | m_RequestedDSPBufferSize: 1024 20 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DSkybox.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51e5156a714e7425e913815e4ee7b4e3 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: 6 | - _FrontTex: {instanceID: 0} 7 | - _BackTex: {instanceID: 0} 8 | - _LeftTex: {instanceID: 0} 9 | - _RightTex: {instanceID: 0} 10 | - _UpTex: {instanceID: 0} 11 | - _DownTex: {instanceID: 0} 12 | - _DitherTex: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 13 | nonModifiableTextures: [] 14 | userData: 15 | assetBundleName: 16 | assetBundleVariant: 17 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 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 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/TestGradientRaw.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: TestGradientRaw 11 | m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _MainTex: 23 | m_Texture: {fileID: 2800000, guid: c6247dd9f381d48ab8a02fb10c8c68cd, type: 3} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | m_Floats: [] 27 | m_Colors: [] 28 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /ProjectSettings/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_ScopedRegistriesSettingsExpanded: 1 16 | oneTimeWarningShown: 0 17 | m_Registries: 18 | - m_Id: main 19 | m_Name: 20 | m_Url: https://packages.unity.com 21 | m_Scopes: [] 22 | m_IsDefault: 1 23 | m_UserSelectedRegistryName: 24 | m_UserAddingNewScopedRegistry: 0 25 | m_RegistryInfoDraft: 26 | m_ErrorMessage: 27 | m_Original: 28 | m_Id: 29 | m_Name: 30 | m_Url: 31 | m_Scopes: [] 32 | m_IsDefault: 0 33 | m_Modified: 0 34 | m_Name: 35 | m_Url: 36 | m_Scopes: 37 | - 38 | m_SelectedScopeIndex: 0 39 | -------------------------------------------------------------------------------- /Assets/Dither3D/Editor/OverridePropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | using UnityEngine; 10 | using UnityEditor; 11 | 12 | [CustomPropertyDrawer(typeof(OverridePropertyAttribute))] 13 | public class OverridePropertyDrawer : PropertyDrawer 14 | { 15 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 16 | { 17 | SerializedProperty overrideProp = 18 | property.serializedObject.FindProperty(property.propertyPath + "Override"); 19 | Rect posToggle = position; 20 | posToggle.width = 16; 21 | EditorGUI.PropertyField(posToggle, overrideProp, GUIContent.none); 22 | 23 | using (new EditorGUI.DisabledScope(!overrideProp.boolValue)) 24 | { 25 | position.xMin += 16; 26 | EditorGUIUtility.labelWidth -= 16; 27 | EditorGUI.PropertyField(position, property, label); 28 | EditorGUIUtility.labelWidth = 0; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 0 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | m_AsyncShaderCompilation: 1 26 | m_EnterPlayModeOptionsEnabled: 0 27 | m_EnterPlayModeOptions: 3 28 | m_ShowLightmapResolutionOverlay: 1 29 | m_UseLegacyProbeSampleCount: 0 30 | m_AssetPipelineMode: 1 31 | m_CacheServerMode: 0 32 | m_CacheServerEndpoint: 33 | m_CacheServerNamespacePrefix: default 34 | m_CacheServerEnableDownload: 1 35 | m_CacheServerEnableUpload: 1 36 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 11 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | m_FrictionType: 0 32 | m_EnableEnhancedDeterminism: 0 33 | m_EnableUnifiedHeightmaps: 1 34 | m_DefaultMaxAngluarSpeed: 7 35 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_1x1.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!117 &11700000 4 | Texture3D: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: Dither3D_1x1 10 | m_ImageContentsHash: 11 | serializedVersion: 2 12 | Hash: 00000000000000000000000000000000 13 | m_ForcedFallbackFormat: 4 14 | m_DownscaleFallback: 0 15 | serializedVersion: 3 16 | m_ColorSpace: 0 17 | m_Format: 5 18 | m_Width: 16 19 | m_Height: 16 20 | m_Depth: 1 21 | m_MipCount: 1 22 | m_DataSize: 256 23 | m_TextureSettings: 24 | serializedVersion: 2 25 | m_FilterMode: 1 26 | m_Aniso: 1 27 | m_MipBias: 0 28 | m_WrapU: 0 29 | m_WrapV: 0 30 | m_WrapW: 0 31 | m_IsReadable: 1 32 | image data: 256 33 | _typelessdata: f3e5d5c4b4a392828292a3b4c4d5e5f3e5dccec0b0a090808090a0b0c0cedce5d5cec4b7a99a8b7b7b8b9aa9b7c4ced5c4c0b7ada0928475758492a0adb7c0c4b4b0a9a095897b6d6d7b8995a0a9b0b4a3a09a92897e716464717e89929aa0a392908b847b71665a5a66717b848b909282807b756d645a4e4e5a646d757b808282807b756d645a4e4e5a646d757b808292908b847b71665a5a66717b848b9092a3a09a92897e716464717e89929aa0a3b4b0a9a095897b6d6d7b8995a0a9b0b4c4c0b7ada0928475758492a0adb7c0c4d5cec4b7a99a8b7b7b8b9aa9b7c4ced5e5dccec0b0a090808090a0b0c0cedce5f3e5d5c4b4a392828292a3b4c4d5e5f3 34 | m_StreamData: 35 | offset: 0 36 | size: 0 37 | path: 38 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.ide.visualstudio": "2.0.22", 4 | "com.unity.ugui": "1.0.0", 5 | "com.unity.modules.ai": "1.0.0", 6 | "com.unity.modules.androidjni": "1.0.0", 7 | "com.unity.modules.animation": "1.0.0", 8 | "com.unity.modules.assetbundle": "1.0.0", 9 | "com.unity.modules.audio": "1.0.0", 10 | "com.unity.modules.cloth": "1.0.0", 11 | "com.unity.modules.director": "1.0.0", 12 | "com.unity.modules.imageconversion": "1.0.0", 13 | "com.unity.modules.imgui": "1.0.0", 14 | "com.unity.modules.jsonserialize": "1.0.0", 15 | "com.unity.modules.particlesystem": "1.0.0", 16 | "com.unity.modules.physics": "1.0.0", 17 | "com.unity.modules.physics2d": "1.0.0", 18 | "com.unity.modules.screencapture": "1.0.0", 19 | "com.unity.modules.terrain": "1.0.0", 20 | "com.unity.modules.terrainphysics": "1.0.0", 21 | "com.unity.modules.tilemap": "1.0.0", 22 | "com.unity.modules.ui": "1.0.0", 23 | "com.unity.modules.uielements": "1.0.0", 24 | "com.unity.modules.umbra": "1.0.0", 25 | "com.unity.modules.unityanalytics": "1.0.0", 26 | "com.unity.modules.unitywebrequest": "1.0.0", 27 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 28 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 29 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 30 | "com.unity.modules.unitywebrequestwww": "1.0.0", 31 | "com.unity.modules.vehicles": "1.0.0", 32 | "com.unity.modules.video": "1.0.0", 33 | "com.unity.modules.vr": "1.0.0", 34 | "com.unity.modules.wind": "1.0.0", 35 | "com.unity.modules.xr": "1.0.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Monochrome.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | using UnityEngine; 10 | 11 | [ExecuteAlways] 12 | [RequireComponent(typeof(Camera))] 13 | public class Monochrome : MonoBehaviour 14 | { 15 | public bool monochrome; 16 | public Color darkColor = Color.black; 17 | public Color lightColor = Color.white; 18 | 19 | public Shader monochromeShader; 20 | Material monochromeMaterial; 21 | 22 | void OnDisable() 23 | { 24 | if (monochromeMaterial) 25 | DestroyImmediate(monochromeMaterial); 26 | monochromeMaterial = null; 27 | } 28 | 29 | public void OnRenderImage(RenderTexture source, RenderTexture destination) 30 | { 31 | if (!monochromeMaterial) 32 | monochromeMaterial = new Material (monochromeShader); 33 | 34 | // Set material properties. 35 | EnableKeyword("MONOCHROME_1BIT", monochrome); 36 | monochromeMaterial.SetColor("_DarkColor", darkColor); 37 | monochromeMaterial.SetColor("_LightColor", lightColor); 38 | monochromeMaterial.SetPass (0); 39 | 40 | // Apply effect. 41 | Graphics.Blit(source, destination, monochromeMaterial); 42 | } 43 | 44 | void EnableKeyword(string keyword, bool enable) 45 | { 46 | if (enable) 47 | Shader.EnableKeyword(keyword); 48 | else 49 | Shader.DisableKeyword(keyword); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Monochrome.shader: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | Shader "Hidden/Monochrome" 10 | { 11 | Properties 12 | { 13 | _MainTex ("Base", 2D) = "" {} 14 | } 15 | 16 | CGINCLUDE 17 | 18 | #pragma multi_compile __ MONOCHROME_1BIT 19 | 20 | #include "UnityCG.cginc" 21 | 22 | struct v2f 23 | { 24 | half4 pos : SV_POSITION; 25 | half2 uv : TEXCOORD0; 26 | }; 27 | 28 | sampler2D _MainTex; 29 | half4 _DarkColor; 30 | half4 _LightColor; 31 | 32 | v2f vert (appdata_img v) 33 | { 34 | v2f o; 35 | o.pos = UnityObjectToClipPos(v.vertex); 36 | o.uv.xy = v.texcoord.xy; 37 | return o; 38 | } 39 | 40 | half4 fragMonochrome (v2f i) : SV_Target 41 | { 42 | half4 color = saturate(tex2D(_MainTex, i.uv.xy)); 43 | #ifdef MONOCHROME_1BIT 44 | color.rgb = color.rgb > 0.5 ? 1.0 : 0.0; 45 | #endif 46 | color.rgb = lerp(_DarkColor, _LightColor, color.rgb); 47 | return color; 48 | } 49 | 50 | ENDCG 51 | 52 | Subshader 53 | { 54 | // pass 0 55 | Pass 56 | { 57 | ZTest Always Cull Off ZWrite Off 58 | 59 | CGPROGRAM 60 | #pragma vertex vert 61 | #pragma fragment fragMonochrome 62 | ENDCG 63 | } 64 | } 65 | 66 | Fallback off 67 | } 68 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Mercurial version control. 2 | /.hg 3 | .hgignore 4 | 5 | # Ignore visual studio code files. 6 | /.vscode 7 | .vsconfig 8 | 9 | # Ignore folders for own use. 10 | /Design 11 | /Progress 12 | 13 | # The remainder comes from GitHub's standard Unity project gitignore template. 14 | 15 | # This .gitignore file should be placed at the root of your Unity project directory 16 | # 17 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore 18 | # 19 | /[Ll]ibrary/ 20 | /[Tt]emp/ 21 | /[Oo]bj/ 22 | /[Bb]uild/ 23 | /[Bb]uilds/ 24 | /[Ll]ogs/ 25 | /[Uu]ser[Ss]ettings/ 26 | 27 | # MemoryCaptures can get excessive in size. 28 | # They also could contain extremely sensitive data 29 | /[Mm]emoryCaptures/ 30 | 31 | # Recordings can get excessive in size 32 | /[Rr]ecordings/ 33 | 34 | # Uncomment this line if you wish to ignore the asset store tools plugin 35 | # /[Aa]ssets/AssetStoreTools* 36 | 37 | # Autogenerated Jetbrains Rider plugin 38 | /[Aa]ssets/Plugins/Editor/JetBrains* 39 | 40 | # JetBrains Rider cache directory 41 | .idea 42 | 43 | # Visual Studio cache directory 44 | .vs/ 45 | 46 | # Gradle cache directory 47 | .gradle/ 48 | 49 | # Autogenerated VS/MD/Consulo solution and project files 50 | ExportedObj/ 51 | .consulo/ 52 | *.csproj 53 | *.unityproj 54 | *.sln 55 | *.suo 56 | *.tmp 57 | *.user 58 | *.userprefs 59 | *.pidb 60 | *.booproj 61 | *.svd 62 | *.pdb 63 | *.mdb 64 | *.opendb 65 | *.VC.db 66 | 67 | # Unity3D generated meta files 68 | *.pidb.meta 69 | *.pdb.meta 70 | *.mdb.meta 71 | 72 | # Unity3D generated file on crash reports 73 | sysinfo.txt 74 | 75 | # Builds 76 | *.apk 77 | *.aab 78 | *.unitypackage 79 | *.app 80 | 81 | # Crashlytics generated file 82 | crashlytics-build.properties 83 | 84 | # Packed Addressables 85 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* 86 | 87 | # Temporary auto-generated Android Assets 88 | /[Aa]ssets/[Ss]treamingAssets/aa.meta 89 | /[Aa]ssets/[Ss]treamingAssets/aa/* 90 | -------------------------------------------------------------------------------- /Assets/Materials/TilesAlbedo.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 14d02e7d769e147d49d1fd83418f5fa6 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 4 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | sRGBTexture: 1 10 | linearTexture: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: 0.25 19 | normalMapFilter: 0 20 | isReadable: 1 21 | grayScaleToAlpha: 0 22 | generateCubemap: 6 23 | cubemapConvolution: 0 24 | seamlessCubemap: 0 25 | textureFormat: 12 26 | maxTextureSize: 1024 27 | textureSettings: 28 | filterMode: 2 29 | aniso: -1 30 | mipBias: -1 31 | wrapMode: -1 32 | nPOTScale: 1 33 | lightmap: 0 34 | compressionQuality: 50 35 | spriteMode: 0 36 | spriteExtrude: 1 37 | spriteMeshType: 1 38 | alignment: 0 39 | spritePivot: {x: 0.5, y: 0.5} 40 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 41 | spritePixelsToUnits: 100 42 | alphaUsage: 1 43 | alphaIsTransparency: 0 44 | spriteTessellationDetail: -1 45 | textureType: 0 46 | textureShape: 1 47 | maxTextureSizeSet: 0 48 | compressionQualitySet: 0 49 | textureFormatSet: 0 50 | platformSettings: 51 | - buildTarget: DefaultTexturePlatform 52 | maxTextureSize: 1024 53 | textureFormat: -1 54 | textureCompression: 1 55 | compressionQuality: 50 56 | crunchedCompression: 0 57 | allowsAlphaSplitting: 0 58 | overridden: 0 59 | - buildTarget: Standalone 60 | maxTextureSize: 1024 61 | textureFormat: -1 62 | textureCompression: 1 63 | compressionQuality: 50 64 | crunchedCompression: 0 65 | allowsAlphaSplitting: 0 66 | overridden: 0 67 | spriteSheet: 68 | serializedVersion: 2 69 | sprites: [] 70 | outline: [] 71 | spritePackingTag: 72 | userData: 73 | assetBundleName: 74 | assetBundleVariant: 75 | -------------------------------------------------------------------------------- /Assets/Materials/TilesNormal.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 16619831a675e44c98e5c453e4f27d2b 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 4 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | sRGBTexture: 0 10 | linearTexture: 1 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 1 18 | heightScale: 0.25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 6 23 | cubemapConvolution: 0 24 | seamlessCubemap: 0 25 | textureFormat: -1 26 | maxTextureSize: 1024 27 | textureSettings: 28 | filterMode: 2 29 | aniso: -1 30 | mipBias: -1 31 | wrapMode: -1 32 | nPOTScale: 1 33 | lightmap: 0 34 | compressionQuality: 50 35 | spriteMode: 0 36 | spriteExtrude: 1 37 | spriteMeshType: 1 38 | alignment: 0 39 | spritePivot: {x: 0.5, y: 0.5} 40 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 41 | spritePixelsToUnits: 100 42 | alphaUsage: 1 43 | alphaIsTransparency: 0 44 | spriteTessellationDetail: -1 45 | textureType: 1 46 | textureShape: 1 47 | maxTextureSizeSet: 0 48 | compressionQualitySet: 0 49 | textureFormatSet: 0 50 | platformSettings: 51 | - buildTarget: DefaultTexturePlatform 52 | maxTextureSize: 1024 53 | textureFormat: -1 54 | textureCompression: 1 55 | compressionQuality: 50 56 | crunchedCompression: 0 57 | allowsAlphaSplitting: 0 58 | overridden: 0 59 | - buildTarget: Standalone 60 | maxTextureSize: 1024 61 | textureFormat: -1 62 | textureCompression: 1 63 | compressionQuality: 50 64 | crunchedCompression: 0 65 | allowsAlphaSplitting: 0 66 | overridden: 0 67 | spriteSheet: 68 | serializedVersion: 2 69 | sprites: [] 70 | outline: [] 71 | spritePackingTag: 72 | userData: 73 | assetBundleName: 74 | assetBundleVariant: 75 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 1 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Upscale.shader: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | Shader "Hidden/Upscale" 10 | { 11 | Properties 12 | { 13 | _MainTex("Texture", 2D) = "white" {} 14 | } 15 | SubShader 16 | { 17 | Cull Off 18 | Lighting Off 19 | ZWrite Off 20 | 21 | Pass 22 | { 23 | CGPROGRAM 24 | #pragma vertex vert 25 | #pragma fragment frag 26 | #include "UnityCG.cginc" 27 | 28 | struct v2f 29 | { 30 | float4 vertex : SV_POSITION; 31 | float2 uv : TEXCOORD0; 32 | }; 33 | 34 | sampler2D _MainTex; 35 | float4 _MainTex_TexelSize; 36 | float4 _MainTex_ST; 37 | 38 | v2f vert(appdata_img v) 39 | { 40 | v2f o; 41 | o.vertex = UnityObjectToClipPos(v.vertex); 42 | o.uv = v.texcoord; 43 | return o; 44 | } 45 | 46 | fixed4 frag(v2f IN) : SV_Target 47 | { 48 | // Shift by half a pixel so UV is (0, 0) half a texel from the screen corner. 49 | IN.uv -= _MainTex_TexelSize.xy * 0.5; 50 | 51 | // Get texel coordinates that are integers at the center of each texel. 52 | float2 uv_pixels = IN.uv * _MainTex_TexelSize.zw; 53 | 54 | // Get vector with coordinates that are 0 at texel corners 55 | // and flip from 0.5 to -0.5 at texel centers. 56 | float2 texel_border_gradient = frac(uv_pixels) - 0.5; 57 | 58 | float2 texel_size = fwidth(uv_pixels); 59 | float2 texel_border_gradient_1px = saturate(texel_border_gradient / texel_size); 60 | float2 sample_offset = (texel_border_gradient_1px - texel_border_gradient); 61 | 62 | float2 clampedUV = IN.uv + sample_offset * _MainTex_TexelSize.xy; 63 | return tex2Dlod(_MainTex, float4(clampedUV, 0, 0)); 64 | } 65 | 66 | ENDCG 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_1x1.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ba5c6f346dee4db9a316bfdfe30d6fd 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 1 36 | mipBias: 0 37 | wrapU: 0 38 | wrapV: 0 39 | wrapW: 0 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 1 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_2x2.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a6cae3ada3c94a23b1c3ecfd74340a0 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 1 36 | mipBias: 0 37 | wrapU: 0 38 | wrapV: 0 39 | wrapW: 0 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 1 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_4x4.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9438b71f52ac142d89b5811a675a8129 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 1 36 | mipBias: 0 37 | wrapU: 0 38 | wrapV: 0 39 | wrapW: 0 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 1 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_1x1_Ramp.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f3bb5b5efa5b5f243961cb5278517cbf 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 0 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 0 36 | mipBias: 0 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: 63 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 1 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_2x2_Ramp.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da0cae81968470742904ed586986dd58 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 0 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 0 36 | mipBias: 0 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: 63 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 1 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_4x4_Ramp.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 285a1b4a02cc814418077bbda04d6262 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 0 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 0 36 | mipBias: 0 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: 63 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 1 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_8x8_Ramp.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 419773c4530aa874ca10a245f0675350 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 0 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 0 36 | mipBias: 0 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: 63 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 1 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | bones: [] 80 | spriteID: 81 | internalID: 0 82 | vertices: [] 83 | indices: 84 | edges: [] 85 | weights: [] 86 | secondaryTextures: [] 87 | spritePackingTag: 88 | pSDRemoveMatte: 0 89 | pSDShowRemoveMatteOption: 0 90 | userData: 91 | assetBundleName: 92 | assetBundleVariant: 93 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_CustomRenderPipeline: {fileID: 0} 42 | m_TransparencySortMode: 0 43 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 44 | m_DefaultRenderingPath: 1 45 | m_DefaultMobileRenderingPath: 1 46 | m_TierSettings: [] 47 | m_LightmapStripping: 0 48 | m_FogStripping: 0 49 | m_InstancingStripping: 0 50 | m_LightmapKeepPlain: 1 51 | m_LightmapKeepDirCombined: 1 52 | m_LightmapKeepDynamicPlain: 1 53 | m_LightmapKeepDynamicDirCombined: 1 54 | m_LightmapKeepShadowMask: 1 55 | m_LightmapKeepSubtractive: 1 56 | m_FogKeepLinear: 1 57 | m_FogKeepExp: 1 58 | m_FogKeepExp2: 1 59 | m_AlbedoSwatchInfos: [] 60 | m_LightsUseLinearIntensity: 0 61 | m_LightsUseColorTemperature: 0 62 | m_LogWhenShaderIsCompiled: 0 63 | m_AllowEnlightenSupportForUpgradedProject: 0 64 | -------------------------------------------------------------------------------- /Assets/Dither3D/FullscreenEffect/Upscale.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | using UnityEngine; 10 | 11 | [ExecuteAlways] 12 | [RequireComponent(typeof(Camera))] 13 | public class Upscale : MonoBehaviour 14 | { 15 | public int origVerticalRes = 450; 16 | public Shader upscaleShader; 17 | public Camera renderCam; 18 | 19 | Camera screenCam; 20 | RenderTexture rtRender; 21 | Material upscaleMaterial; 22 | int origVerticalResLast; 23 | 24 | void OnEnable() 25 | { 26 | if (!renderCam || !upscaleShader) 27 | { 28 | enabled = false; 29 | return; 30 | } 31 | screenCam = GetComponent(); 32 | screenCam.clearFlags = CameraClearFlags.Nothing; 33 | screenCam.cullingMask = 0; 34 | upscaleMaterial = new Material (upscaleShader); 35 | UpdateRenderTextureIfNeeded(); 36 | } 37 | 38 | void OnDisable() 39 | { 40 | if (upscaleMaterial) 41 | DestroyImmediate(upscaleMaterial); 42 | upscaleMaterial = null; 43 | if (renderCam) 44 | renderCam.targetTexture = null; 45 | if (rtRender) 46 | DestroyImmediate(rtRender); 47 | rtRender = null; 48 | origVerticalResLast = 0; 49 | } 50 | 51 | void OnValidate() 52 | { 53 | UpdateRenderTextureIfNeeded(); 54 | } 55 | 56 | void OnDidApplyAnimationProperties() 57 | { 58 | UpdateRenderTextureIfNeeded(); 59 | } 60 | 61 | void UpdateRenderTextureIfNeeded() 62 | { 63 | if (enabled && screenCam && origVerticalRes != origVerticalResLast) 64 | { 65 | renderCam.targetTexture = null; 66 | if (rtRender) 67 | DestroyImmediate(rtRender); 68 | rtRender = new RenderTexture( 69 | Mathf.RoundToInt(screenCam.pixelWidth * (float)origVerticalRes / screenCam.pixelHeight), 70 | origVerticalRes, 71 | 32); 72 | rtRender.hideFlags = HideFlags.DontSave; 73 | renderCam.targetTexture = rtRender; 74 | origVerticalResLast = origVerticalRes; 75 | } 76 | } 77 | 78 | public void OnRenderImage (RenderTexture source, RenderTexture destination) 79 | { 80 | Graphics.Blit(rtRender, destination, upscaleMaterial); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Assets/Dither3D/Editor/DitherPatternPropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | // ReSharper disable once UnusedType.Global - make Rider not complain that class is unused 5 | public class DitherPatternPropertyDrawer : MaterialPropertyDrawer 6 | { 7 | static readonly GUIContent[] s_PopupNames = {new GUIContent("1x1"), new GUIContent("2x2"), new GUIContent("4x4"), new GUIContent("8x8")}; 8 | static readonly int[] s_PopupValues = {0, 1, 2, 3}; 9 | public override void OnGUI (Rect position, MaterialProperty prop, string label, MaterialEditor editor) 10 | { 11 | int value = (int)prop.floatValue; 12 | EditorGUI.BeginChangeCheck(); 13 | EditorGUI.showMixedValue = prop.hasMixedValue; 14 | value = EditorGUI.IntPopup(position, new GUIContent(label), value, s_PopupNames, s_PopupValues); 15 | EditorGUI.showMixedValue = false; 16 | if (EditorGUI.EndChangeCheck()) 17 | { 18 | prop.floatValue = value; 19 | Texture ditherTex = null; 20 | Texture ditherRampTex = null; 21 | switch (value) 22 | { 23 | case 0: 24 | ditherTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_1x1.asset"); 25 | ditherRampTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_1x1_Ramp.png"); 26 | break; 27 | case 1: 28 | ditherTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_2x2.asset"); 29 | ditherRampTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_2x2_Ramp.png"); 30 | break; 31 | case 2: 32 | ditherTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_4x4.asset"); 33 | ditherRampTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_4x4_Ramp.png"); 34 | break; 35 | case 3: 36 | ditherTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_8x8.asset"); 37 | ditherRampTex = AssetDatabase.LoadAssetAtPath($"{Dither3DTextureMaker.kTexturesPath}/Dither3D_8x8_Ramp.png"); 38 | break; 39 | } 40 | 41 | if (ditherTex != null) 42 | { 43 | foreach (Material mat in editor.targets) 44 | mat.SetTexture("_DitherTex", ditherTex); 45 | } 46 | if (ditherRampTex != null) 47 | { 48 | foreach (Material mat in editor.targets) 49 | mat.SetTexture("_DitherRampTex", ditherRampTex); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Assets/Materials/Dither3D.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Dither3D 11 | m_Shader: {fileID: 4800000, guid: 0b406c17af5df4375b715b8770f556fe, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _DitherRampTex: 39 | m_Texture: {fileID: 2800000, guid: 419773c4530aa874ca10a245f0675350, type: 3} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _DitherTex: 43 | m_Texture: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _EmissionMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _MainTex: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _MetallicGlossMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _OcclusionMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | - _ParallaxMap: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | m_Floats: 67 | - _A: 0.35 68 | - _B: 0.46 69 | - _BumpScale: 1 70 | - _Contrast: 1 71 | - _Cutoff: 0.5 72 | - _DetailNormalMapScale: 1 73 | - _DitherMode: 3 74 | - _DstBlend: 0 75 | - _GlossMapScale: 1 76 | - _Glossiness: 0.5 77 | - _GlossyReflections: 1 78 | - _InputExposure: 1 79 | - _InputOffset: 0 80 | - _Metallic: 0 81 | - _Mode: 0 82 | - _OcclusionStrength: 1 83 | - _Parallax: 0.02 84 | - _Scale: 7 85 | - _SizeVariability: 0 86 | - _SmoothnessTextureChannel: 0 87 | - _Softness: 1 88 | - _SpecularHighlights: 1 89 | - _SrcBlend: 1 90 | - _StretchSmoothness: 1 91 | - _UVSec: 0 92 | - _ZResolution: 64 93 | - _ZWrite: 1 94 | m_Colors: 95 | - _Color: {r: 1, g: 1, b: 1, a: 1} 96 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 97 | -------------------------------------------------------------------------------- /Assets/Materials/Dither3D_LargeDots.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Dither3D_LargeDots 11 | m_Shader: {fileID: 4800000, guid: 0b406c17af5df4375b715b8770f556fe, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _DitherRampTex: 39 | m_Texture: {fileID: 2800000, guid: 419773c4530aa874ca10a245f0675350, type: 3} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _DitherTex: 43 | m_Texture: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _EmissionMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _MainTex: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _MetallicGlossMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _OcclusionMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | - _ParallaxMap: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | m_Floats: 67 | - _A: 0.35 68 | - _B: 0.46 69 | - _BumpScale: 1 70 | - _Contrast: 1 71 | - _Cutoff: 0.5 72 | - _DetailNormalMapScale: 1 73 | - _DitherMode: 3 74 | - _DstBlend: 0 75 | - _GlossMapScale: 1 76 | - _Glossiness: 0.5 77 | - _GlossyReflections: 1 78 | - _InputExposure: 1 79 | - _InputOffset: 0 80 | - _Metallic: 0 81 | - _Mode: 0 82 | - _OcclusionStrength: 1 83 | - _Parallax: 0.02 84 | - _Scale: 9 85 | - _SizeVariability: 0 86 | - _SmoothnessTextureChannel: 0 87 | - _Softness: 1 88 | - _SpecularHighlights: 1 89 | - _SrcBlend: 1 90 | - _StretchSmoothness: 1 91 | - _UVSec: 0 92 | - _ZResolution: 64 93 | - _ZWrite: 1 94 | m_Colors: 95 | - _Color: {r: 1, g: 1, b: 1, a: 1} 96 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 97 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/TestGradientDither.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: TestGradientDither 11 | m_Shader: {fileID: 4800000, guid: 0b406c17af5df4375b715b8770f556fe, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _DitherRampTex: 39 | m_Texture: {fileID: 2800000, guid: 419773c4530aa874ca10a245f0675350, type: 3} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _DitherTex: 43 | m_Texture: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _EmissionMap: 47 | m_Texture: {fileID: 2800000, guid: c6247dd9f381d48ab8a02fb10c8c68cd, type: 3} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _MainTex: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _MetallicGlossMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _OcclusionMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | - _ParallaxMap: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | m_Floats: 67 | - _A: 0.35 68 | - _B: 0.46 69 | - _BumpScale: 1 70 | - _Contrast: 1 71 | - _Cutoff: 0.5 72 | - _DetailNormalMapScale: 1 73 | - _DitherMode: 3 74 | - _DstBlend: 0 75 | - _GlossMapScale: 1 76 | - _Glossiness: 0.5 77 | - _GlossyReflections: 1 78 | - _InputExposure: 1 79 | - _InputOffset: 0 80 | - _Metallic: 0 81 | - _Mode: 0 82 | - _OcclusionStrength: 1 83 | - _Parallax: 0.02 84 | - _Scale: 7 85 | - _SizeVariability: 0 86 | - _SmoothnessTextureChannel: 0 87 | - _Softness: 1 88 | - _SpecularHighlights: 1 89 | - _SrcBlend: 1 90 | - _StretchSmoothness: 1 91 | - _UVSec: 0 92 | - _ZResolution: 64 93 | - _ZWrite: 1 94 | m_Colors: 95 | - _Color: {r: 0, g: 0, b: 0, a: 1} 96 | - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} 97 | -------------------------------------------------------------------------------- /Assets/Materials/Dither3DTiles.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Dither3DTiles 11 | m_Shader: {fileID: 4800000, guid: 0b406c17af5df4375b715b8770f556fe, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 2800000, guid: 16619831a675e44c98e5c453e4f27d2b, type: 3} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _DitherRampTex: 39 | m_Texture: {fileID: 2800000, guid: 419773c4530aa874ca10a245f0675350, type: 3} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _DitherTex: 43 | m_Texture: {fileID: 11700000, guid: f8c14933cd8df41c29224daa7bcca430, type: 2} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _EmissionMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _MainTex: 51 | m_Texture: {fileID: 2800000, guid: 14d02e7d769e147d49d1fd83418f5fa6, type: 3} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _MetallicGlossMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _OcclusionMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | - _ParallaxMap: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | m_Floats: 67 | - _A: 0.35 68 | - _B: 0.46 69 | - _BumpScale: 1 70 | - _Contrast: 1 71 | - _Cutoff: 0.5 72 | - _DetailNormalMapScale: 1 73 | - _DitherMode: 3 74 | - _DstBlend: 0 75 | - _GlossMapScale: 1 76 | - _Glossiness: 0.5 77 | - _GlossyReflections: 1 78 | - _InputExposure: 1 79 | - _InputOffset: 0 80 | - _Metallic: 0 81 | - _Mode: 0 82 | - _OcclusionStrength: 1 83 | - _Parallax: 0.02 84 | - _Scale: 6.5 85 | - _SizeVariability: 0.1 86 | - _SmoothnessTextureChannel: 0 87 | - _Softness: 1 88 | - _SpecularHighlights: 1 89 | - _SrcBlend: 1 90 | - _StretchSmoothness: 1 91 | - _UVSec: 0 92 | - _ZResolution: 64 93 | - _ZWrite: 1 94 | m_Colors: 95 | - _Color: {r: 1, g: 1, b: 1, a: 1} 96 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 97 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_8x8.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 818a4f3c477c44de995b42b27502350a 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 1 36 | mipBias: 0 37 | wrapU: 0 38 | wrapV: 0 39 | wrapW: 0 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 8192 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 1 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | - serializedVersion: 3 75 | buildTarget: Standalone 76 | maxTextureSize: 8192 77 | resizeAlgorithm: 0 78 | textureFormat: -1 79 | textureCompression: 1 80 | compressionQuality: 50 81 | crunchedCompression: 0 82 | allowsAlphaSplitting: 0 83 | overridden: 0 84 | androidETC2FallbackOverride: 0 85 | forceMaximumCompressionQuality_BC6H_BC7: 0 86 | - serializedVersion: 3 87 | buildTarget: Android 88 | maxTextureSize: 8192 89 | resizeAlgorithm: 0 90 | textureFormat: -1 91 | textureCompression: 1 92 | compressionQuality: 50 93 | crunchedCompression: 0 94 | allowsAlphaSplitting: 0 95 | overridden: 0 96 | androidETC2FallbackOverride: 0 97 | forceMaximumCompressionQuality_BC6H_BC7: 0 98 | spriteSheet: 99 | serializedVersion: 2 100 | sprites: [] 101 | outline: [] 102 | physicsShape: [] 103 | bones: [] 104 | spriteID: 105 | internalID: 0 106 | vertices: [] 107 | indices: 108 | edges: [] 109 | weights: [] 110 | secondaryTextures: [] 111 | spritePackingTag: 112 | pSDRemoveMatte: 0 113 | pSDShowRemoveMatteOption: 0 114 | userData: 115 | assetBundleName: 116 | assetBundleVariant: 117 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/Gradient.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6247dd9f381d48ab8a02fb10c8c68cd 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 1 35 | aniso: 1 36 | mipBias: 0 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | applyGammaDecoding: 0 61 | platformSettings: 62 | - serializedVersion: 3 63 | buildTarget: DefaultTexturePlatform 64 | maxTextureSize: 2048 65 | resizeAlgorithm: 0 66 | textureFormat: -1 67 | textureCompression: 0 68 | compressionQuality: 50 69 | crunchedCompression: 0 70 | allowsAlphaSplitting: 0 71 | overridden: 0 72 | androidETC2FallbackOverride: 0 73 | forceMaximumCompressionQuality_BC6H_BC7: 0 74 | - serializedVersion: 3 75 | buildTarget: Standalone 76 | maxTextureSize: 2048 77 | resizeAlgorithm: 0 78 | textureFormat: -1 79 | textureCompression: 0 80 | compressionQuality: 50 81 | crunchedCompression: 0 82 | allowsAlphaSplitting: 0 83 | overridden: 0 84 | androidETC2FallbackOverride: 0 85 | forceMaximumCompressionQuality_BC6H_BC7: 0 86 | - serializedVersion: 3 87 | buildTarget: Android 88 | maxTextureSize: 2048 89 | resizeAlgorithm: 0 90 | textureFormat: -1 91 | textureCompression: 0 92 | compressionQuality: 50 93 | crunchedCompression: 0 94 | allowsAlphaSplitting: 0 95 | overridden: 0 96 | androidETC2FallbackOverride: 0 97 | forceMaximumCompressionQuality_BC6H_BC7: 0 98 | spriteSheet: 99 | serializedVersion: 2 100 | sprites: [] 101 | outline: [] 102 | physicsShape: [] 103 | bones: [] 104 | spriteID: 105 | internalID: 0 106 | vertices: [] 107 | indices: 108 | edges: [] 109 | weights: [] 110 | secondaryTextures: [] 111 | spritePackingTag: 112 | pSDRemoveMatte: 0 113 | pSDShowRemoveMatteOption: 0 114 | userData: 115 | assetBundleName: 116 | assetBundleVariant: 117 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DOpaque.shader: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | Shader "Dither 3D/Opaque" 10 | { 11 | Properties 12 | { 13 | _Color ("Color", Color) = (1,1,1,1) 14 | _MainTex ("Albedo", 2D) = "white" {} 15 | _BumpMap ("Normal Map", 2D) = "bump" {} 16 | _EmissionMap ("Emission", 2D) = "white" {} 17 | _EmissionColor ("Emission Color", Color) = (0,0,0,0) 18 | _Glossiness ("Smoothness", Range(0,1)) = 0.5 19 | _Metallic ("Metallic", Range(0,1)) = 0.0 20 | 21 | [Header(Dither Input Brightness)] 22 | _InputExposure ("Exposure", Range(0,5)) = 1 23 | _InputOffset ("Offset", Range(-1,1)) = 0 24 | 25 | [Header(Dither Settings)] 26 | [DitherPatternProperty] _DitherMode ("Pattern", Int) = 3 27 | [HideInInspector] _DitherTex ("Dither 3D Texture", 3D) = "" {} 28 | [HideInInspector] _DitherRampTex ("Dither Ramp Texture", 2D) = "white" {} 29 | _Scale ("Dot Scale", Range(2,10)) = 5.0 30 | _SizeVariability ("Dot Size Variability", Range(0,1)) = 0 31 | _Contrast ("Dot Contrast", Range(0,2)) = 1 32 | _StretchSmoothness ("Stretch Smoothness", Range(0,2)) = 1 33 | } 34 | SubShader 35 | { 36 | Tags { "RenderType"="Opaque" } 37 | LOD 200 38 | 39 | CGPROGRAM 40 | // Physically based Standard lighting model, and enable shadows on all light types 41 | #pragma surface surf Standard fullforwardshadows vertex:vert finalcolor:mycolor 42 | 43 | #pragma target 3.5 44 | #pragma multi_compile_fog 45 | #pragma multi_compile __ DITHERCOL_GRAYSCALE DITHERCOL_RGB DITHERCOL_CMYK 46 | #pragma multi_compile __ INVERSE_DOTS 47 | #pragma multi_compile __ RADIAL_COMPENSATION 48 | #pragma multi_compile __ QUANTIZE_LAYERS 49 | #pragma multi_compile __ DEBUG_FRACTAL 50 | 51 | #include "Dither3DInclude.cginc" 52 | 53 | sampler2D _MainTex; 54 | sampler2D _BumpMap; 55 | sampler2D _EmissionMap; 56 | 57 | struct Input 58 | { 59 | float2 uv_MainTex; 60 | float2 uv_BumpMap; 61 | float2 uv_EmissionMap; 62 | float2 uv_DitherTex; 63 | float4 screenPos; 64 | UNITY_FOG_COORDS(4) 65 | }; 66 | 67 | half _Glossiness; 68 | half _Metallic; 69 | fixed4 _Color; 70 | fixed4 _EmissionColor; 71 | 72 | void vert(inout appdata_full v, out Input o) { 73 | UNITY_INITIALIZE_OUTPUT(Input, o); 74 | float4 clipPos = UnityObjectToClipPos(v.vertex); 75 | UNITY_TRANSFER_FOG(o, clipPos); 76 | } 77 | 78 | void surf (Input IN, inout SurfaceOutputStandard o) 79 | { 80 | fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; 81 | o.Albedo = c.rgb; 82 | o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); 83 | o.Emission = tex2D (_EmissionMap, IN.uv_EmissionMap) * _EmissionColor; 84 | 85 | o.Metallic = _Metallic; 86 | o.Smoothness = _Glossiness; 87 | o.Alpha = c.a; 88 | } 89 | 90 | void mycolor (Input IN, SurfaceOutputStandard o, inout fixed4 color) 91 | { 92 | UNITY_APPLY_FOG(IN.fogCoord, color); 93 | color = GetDither3DColor(IN.uv_DitherTex, IN.screenPos, color); 94 | } 95 | ENDCG 96 | } 97 | FallBack "Diffuse" 98 | } 99 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DCutout.shader: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | Shader "Dither 3D/Cutout" 10 | { 11 | Properties 12 | { 13 | _Color ("Color", Color) = (1,1,1,1) 14 | _MainTex ("Albedo", 2D) = "white" {} 15 | _Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5 16 | _BumpMap ("Normal Map", 2D) = "bump" {} 17 | _EmissionMap ("Emission", 2D) = "white" {} 18 | _EmissionColor ("Emission Color", Color) = (0,0,0,0) 19 | _Glossiness ("Smoothness", Range(0,1)) = 0.5 20 | _Metallic ("Metallic", Range(0,1)) = 0.0 21 | 22 | [Header(Dither Input Brightness)] 23 | _InputExposure ("Exposure", Range(0,5)) = 1 24 | _InputOffset ("Offset", Range(-1,1)) = 0 25 | 26 | [Header(Dither Settings)] 27 | [DitherPatternProperty] _DitherMode ("Pattern", Int) = 3 28 | [HideInInspector] _DitherTex ("Dither 3D Texture", 3D) = "" {} 29 | [HideInInspector] _DitherRampTex ("Dither Ramp Texture", 2D) = "white" {} 30 | _Scale ("Dot Scale", Range(2,10)) = 5.0 31 | _SizeVariability ("Dot Size Variability", Range(0,1)) = 0 32 | _Contrast ("Dot Contrast", Range(0,2)) = 1 33 | _StretchSmoothness ("Stretch Smoothness", Range(0,2)) = 1 34 | } 35 | SubShader 36 | { 37 | Tags { "RenderType"="Opaque" } 38 | LOD 200 39 | 40 | CGPROGRAM 41 | // Physically based Standard lighting model, and enable shadows on all light types 42 | #pragma surface surf Standard fullforwardshadows vertex:vert alphatest:_Cutoff finalcolor:mycolor 43 | 44 | #pragma target 3.5 45 | #pragma multi_compile_fog 46 | #pragma multi_compile __ DITHERCOL_GRAYSCALE DITHERCOL_RGB DITHERCOL_CMYK 47 | #pragma multi_compile __ INVERSE_DOTS 48 | #pragma multi_compile __ RADIAL_COMPENSATION 49 | #pragma multi_compile __ QUANTIZE_LAYERS 50 | #pragma multi_compile __ DEBUG_FRACTAL 51 | 52 | #include "Dither3DInclude.cginc" 53 | 54 | sampler2D _MainTex; 55 | sampler2D _BumpMap; 56 | sampler2D _EmissionMap; 57 | 58 | struct Input 59 | { 60 | float2 uv_MainTex; 61 | float2 uv_BumpMap; 62 | float2 uv_EmissionMap; 63 | float2 uv_DitherTex; 64 | float4 screenPos; 65 | UNITY_FOG_COORDS(4) 66 | }; 67 | 68 | half _Glossiness; 69 | half _Metallic; 70 | fixed4 _Color; 71 | fixed4 _EmissionColor; 72 | 73 | void vert(inout appdata_full v, out Input o) { 74 | UNITY_INITIALIZE_OUTPUT(Input, o); 75 | float4 clipPos = UnityObjectToClipPos(v.vertex); 76 | UNITY_TRANSFER_FOG(o, clipPos); 77 | } 78 | 79 | void surf (Input IN, inout SurfaceOutputStandard o) 80 | { 81 | fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; 82 | o.Albedo = c.rgb; 83 | o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); 84 | o.Emission = tex2D (_EmissionMap, IN.uv_EmissionMap) * _EmissionColor; 85 | 86 | o.Metallic = _Metallic; 87 | o.Smoothness = _Glossiness; 88 | o.Alpha = c.a; 89 | } 90 | 91 | void mycolor (Input IN, SurfaceOutputStandard o, inout fixed4 color) 92 | { 93 | UNITY_APPLY_FOG(IN.fogCoord, color); 94 | color = GetDither3DColor(IN.uv_DitherTex, IN.screenPos, color); 95 | } 96 | ENDCG 97 | } 98 | FallBack "Diffuse" 99 | } 100 | -------------------------------------------------------------------------------- /Assets/Dither3D/Particle Alpha Blend.shader: -------------------------------------------------------------------------------- 1 | // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 | 3 | Shader "Dither 3D/Particles (Alpha Blended)" { 4 | Properties { 5 | _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5) 6 | _MainTex ("Particle Texture", 2D) = "white" {} 7 | _InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0 8 | 9 | [Header(Dither Input Brightness)] 10 | _InputExposure ("Exposure", Range(0,5)) = 1 11 | _InputOffset ("Offset", Range(-1,1)) = 0 12 | 13 | [Header(Dither Settings)] 14 | _DitherTex ("Dither 3D Texture", 3D) = "white" {} 15 | _Scale ("Dot Scale", Range(2,10)) = 5.0 16 | _SizeVariability ("Dot Size Variability", Range(0,1)) = 0 17 | _Contrast ("Dot Contrast", Range(0,2)) = 1 18 | _StretchSmoothness ("Stretch Smoothness", Range(0,2)) = 1 19 | } 20 | 21 | Category { 22 | Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } 23 | Blend SrcAlpha OneMinusSrcAlpha 24 | ColorMask RGB 25 | Cull Off Lighting Off ZWrite Off 26 | 27 | SubShader { 28 | Pass { 29 | 30 | CGPROGRAM 31 | #pragma vertex vert 32 | #pragma fragment frag 33 | #pragma target 2.0 34 | #pragma multi_compile_particles 35 | #pragma multi_compile_fog 36 | #pragma multi_compile __ DITHERCOL_GRAYSCALE DITHERCOL_RGB DITHERCOL_CMYK 37 | #pragma multi_compile __ INVERSE_DOTS 38 | #pragma multi_compile __ RADIAL_COMPENSATION 39 | #pragma multi_compile __ QUANTIZE_LAYERS 40 | #pragma multi_compile __ DEBUG_FRACTAL 41 | 42 | #include "UnityCG.cginc" 43 | #include "Dither3DInclude.cginc" 44 | 45 | sampler2D _MainTex; 46 | fixed4 _TintColor; 47 | 48 | struct appdata_t { 49 | float4 vertex : POSITION; 50 | fixed4 color : COLOR; 51 | float2 texcoord : TEXCOORD0; 52 | UNITY_VERTEX_INPUT_INSTANCE_ID 53 | }; 54 | 55 | struct v2f { 56 | float4 vertex : SV_POSITION; 57 | fixed4 color : COLOR; 58 | float2 texcoord : TEXCOORD0; 59 | UNITY_FOG_COORDS(1) 60 | float4 screenPos : TEXCOORD3; 61 | #ifdef SOFTPARTICLES_ON 62 | float4 projPos : TEXCOORD2; 63 | #endif 64 | UNITY_VERTEX_OUTPUT_STEREO 65 | }; 66 | 67 | float4 _MainTex_ST; 68 | 69 | v2f vert (appdata_t v) 70 | { 71 | v2f o; 72 | UNITY_SETUP_INSTANCE_ID(v); 73 | UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 74 | o.vertex = UnityObjectToClipPos(v.vertex); 75 | #ifdef SOFTPARTICLES_ON 76 | o.projPos = ComputeScreenPos (o.vertex); 77 | COMPUTE_EYEDEPTH(o.projPos.z); 78 | #endif 79 | o.color = v.color * _TintColor; 80 | o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); 81 | UNITY_TRANSFER_FOG(o,o.vertex); 82 | o.screenPos = ComputeScreenPos(o.vertex); 83 | return o; 84 | } 85 | 86 | UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); 87 | float _InvFade; 88 | 89 | fixed4 frag (v2f i) : SV_Target 90 | { 91 | UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); 92 | 93 | #ifdef SOFTPARTICLES_ON 94 | float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); 95 | float partZ = i.projPos.z; 96 | float fade = saturate (_InvFade * (sceneZ-partZ)); 97 | i.color.a *= fade; 98 | #endif 99 | 100 | fixed4 col = 2.0f * i.color * tex2D(_MainTex, i.texcoord); 101 | col.a = saturate(col.a); // alpha should not have double-brightness applied to it, but we can't fix that legacy behavior without breaking everyone's effects, so instead clamp the output to get sensible HDR behavior (case 967476) 102 | 103 | UNITY_APPLY_FOG(i.fogCoord, col); 104 | col.rgb = GetDither3DColor(i.texcoord, i.screenPos, col).rgb; 105 | col.a = GetDither3D(RotateUV(i.texcoord, float2(0.707, 0.707)), i.screenPos, col.a).x; 106 | return col; 107 | } 108 | ENDCG 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DParticleAdd.shader: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | Shader "Dither 3D/Particles (Additive)" 10 | { 11 | Properties 12 | { 13 | [HDR]_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5) 14 | _MainTex ("Particle Texture", 2D) = "white" {} 15 | _InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0 16 | 17 | [Header(Dither Input Brightness)] 18 | _InputExposure ("Exposure", Range(0,5)) = 1 19 | _InputOffset ("Offset", Range(-1,1)) = 0 20 | 21 | [Header(Dither Settings)] 22 | [DitherPatternProperty] _DitherMode ("Pattern", Int) = 3 23 | [HideInInspector] _DitherTex ("Dither 3D Texture", 3D) = "" {} 24 | [HideInInspector] _DitherRampTex ("Dither Ramp Texture", 2D) = "white" {} 25 | _Scale ("Dot Scale", Range(2,10)) = 5.0 26 | _SizeVariability ("Dot Size Variability", Range(0,1)) = 0 27 | _Contrast ("Dot Contrast", Range(0,2)) = 1 28 | _StretchSmoothness ("Stretch Smoothness", Range(0,2)) = 1 29 | } 30 | Category 31 | { 32 | Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } 33 | Blend SrcAlpha One 34 | ColorMask RGB 35 | Cull Off Lighting Off ZWrite Off 36 | 37 | SubShader 38 | { 39 | Pass 40 | { 41 | CGPROGRAM 42 | #pragma vertex vert 43 | #pragma fragment frag 44 | #pragma target 2.0 45 | #pragma multi_compile_particles 46 | #pragma multi_compile_fog 47 | #pragma multi_compile __ INVERSE_DOTS 48 | #pragma multi_compile __ RADIAL_COMPENSATION 49 | #pragma multi_compile __ QUANTIZE_LAYERS 50 | #pragma multi_compile __ DEBUG_FRACTAL 51 | 52 | #include "UnityCG.cginc" 53 | #include "Dither3DInclude.cginc" 54 | 55 | sampler2D _MainTex; 56 | fixed4 _TintColor; 57 | 58 | struct appdata_t 59 | { 60 | float4 vertex : POSITION; 61 | fixed4 color : COLOR; 62 | float2 texcoord : TEXCOORD0; 63 | UNITY_VERTEX_INPUT_INSTANCE_ID 64 | }; 65 | 66 | struct v2f 67 | { 68 | float4 vertex : SV_POSITION; 69 | fixed4 color : COLOR; 70 | float2 texcoord : TEXCOORD0; 71 | UNITY_FOG_COORDS(1) 72 | float4 screenPos : TEXCOORD3; 73 | #ifdef SOFTPARTICLES_ON 74 | float4 projPos : TEXCOORD2; 75 | #endif 76 | UNITY_VERTEX_OUTPUT_STEREO 77 | }; 78 | 79 | float4 _MainTex_ST; 80 | 81 | v2f vert (appdata_t v) 82 | { 83 | v2f o; 84 | UNITY_SETUP_INSTANCE_ID(v); 85 | UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 86 | o.vertex = UnityObjectToClipPos(v.vertex); 87 | #ifdef SOFTPARTICLES_ON 88 | o.projPos = ComputeScreenPos (o.vertex); 89 | COMPUTE_EYEDEPTH(o.projPos.z); 90 | #endif 91 | o.color = v.color; 92 | o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); 93 | o.screenPos = ComputeScreenPos(o.vertex); 94 | UNITY_TRANSFER_FOG(o,o.vertex); 95 | return o; 96 | } 97 | 98 | UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); 99 | float _InvFade; 100 | 101 | fixed4 frag (v2f i) : SV_Target 102 | { 103 | UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); 104 | 105 | #ifdef SOFTPARTICLES_ON 106 | float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); 107 | float partZ = i.projPos.z; 108 | float fade = saturate (_InvFade * (sceneZ-partZ)); 109 | i.color.a *= fade; 110 | #endif 111 | 112 | fixed4 col = 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord); 113 | col.a = saturate(col.a); // alpha should not have double-brightness applied to it, but we can't fix that legacy behavior without breaking everyone's effects, so instead clamp the output to get sensible HDR behavior (case 967476) 114 | 115 | UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); // fog towards black due to our blend mode 116 | 117 | col = fixed4(col.rgb * col.a, 1); 118 | col.rgb = GetDither3D(i.texcoord, i.screenPos, GetGrayscale(col)).x; 119 | 120 | return col; 121 | } 122 | ENDCG 123 | } 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DGlobalProperties.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | using System.Collections.Generic; 10 | using UnityEngine; 11 | 12 | public class OverridePropertyAttribute : PropertyAttribute { } 13 | 14 | [ExecuteAlways] 15 | public class Dither3DGlobalProperties : MonoBehaviour 16 | { 17 | static List ditherMaterials = new List(); 18 | 19 | public enum DitherColorMode { Grayscale, RGB, CMYK } 20 | 21 | [Header("Global Options")] 22 | public DitherColorMode colorMode; 23 | 24 | public bool inverseDots; 25 | public bool radialCompensation; 26 | public bool quantizeLayers; 27 | public bool debugFractal; 28 | 29 | [Header("Global Overrides")] 30 | public bool setOnEnable = true; 31 | public bool saveInMaterials; 32 | 33 | [Space] 34 | 35 | [OverrideProperty] public float inputExposure = 1; 36 | [HideInInspector] public bool inputExposureOverride; 37 | 38 | [OverrideProperty] public float inputOffset = 0; 39 | [HideInInspector] public bool inputOffsetOverride; 40 | 41 | [Space] 42 | 43 | [OverrideProperty] public float dotScale = 5; 44 | [HideInInspector] public bool dotScaleOverride; 45 | 46 | [OverrideProperty] public float dotSizeVariability = 0; 47 | [HideInInspector] public bool dotSizeVariabilityOverride; 48 | 49 | [OverrideProperty] public float dotContrast = 1; 50 | [HideInInspector] public bool dotContrastOverride; 51 | 52 | [OverrideProperty] public float stretchSmoothness = 1; 53 | [HideInInspector] public bool stretchSmoothnessOverride; 54 | 55 | [Header("Dots Scaling Behavior")] 56 | public bool scaleWithScreen = true; 57 | public int referenceRes = 1080; 58 | 59 | void OnEnable() 60 | { 61 | CollectMaterials(); 62 | UpdateGlobalOptions(); 63 | if (setOnEnable) 64 | UpdateGlobalOverrides(); 65 | } 66 | 67 | void OnDisable() 68 | { 69 | } 70 | 71 | void OnValidate() 72 | { 73 | if (ditherMaterials != null && ditherMaterials.Count > 0 && ditherMaterials[0] == null) 74 | CollectMaterials(); 75 | 76 | UpdateGlobalOptions(); 77 | UpdateGlobalOverrides(); 78 | } 79 | 80 | void OnDidApplyAnimationProperties() 81 | { 82 | UpdateGlobalOptions(); 83 | UpdateGlobalOverrides(); 84 | } 85 | 86 | void CollectMaterials() 87 | { 88 | ditherMaterials.Clear(); 89 | Material[] materials = Resources.FindObjectsOfTypeAll(); 90 | foreach (var mat in materials) 91 | { 92 | if (mat.HasProperty("_DitherTex")) 93 | { 94 | ditherMaterials.Add(mat); 95 | } 96 | } 97 | } 98 | 99 | void UpdateGlobalOptions() 100 | { 101 | EnableKeyword("DITHERCOL_GRAYSCALE", colorMode == DitherColorMode.Grayscale); 102 | EnableKeyword("DITHERCOL_RGB", colorMode == DitherColorMode.RGB); 103 | EnableKeyword("DITHERCOL_CMYK", colorMode == DitherColorMode.CMYK); 104 | EnableKeyword("INVERSE_DOTS", inverseDots); 105 | EnableKeyword("RADIAL_COMPENSATION", radialCompensation); 106 | EnableKeyword("QUANTIZE_LAYERS", quantizeLayers); 107 | EnableKeyword("DEBUG_FRACTAL", debugFractal); 108 | } 109 | 110 | void UpdateGlobalOverrides() 111 | { 112 | bool changed = false; 113 | if (inputExposureOverride) 114 | SetShaderOverride("_InputExposure", inputExposure, ref changed); 115 | if (inputOffsetOverride) 116 | SetShaderOverride("_InputOffset", inputOffset, ref changed); 117 | if (dotScaleOverride) 118 | { 119 | float shaderDotScale = dotScale; 120 | if (scaleWithScreen) 121 | { 122 | float multiplier = Screen.height / referenceRes; 123 | if (multiplier > 0f) 124 | { 125 | float logDelta = Mathf.Log(multiplier, 2f); 126 | shaderDotScale += logDelta; 127 | } 128 | } 129 | SetShaderOverride("_Scale", shaderDotScale, ref changed); 130 | } 131 | if (dotSizeVariabilityOverride) 132 | SetShaderOverride("_SizeVariability", dotSizeVariability, ref changed); 133 | if (dotContrastOverride) 134 | SetShaderOverride("_Contrast", dotContrast, ref changed); 135 | if (stretchSmoothnessOverride) 136 | SetShaderOverride("_StretchSmoothness", stretchSmoothness, ref changed); 137 | 138 | #if UNITY_EDITOR 139 | if (changed && saveInMaterials) 140 | { 141 | foreach (var mat in ditherMaterials) 142 | { 143 | UnityEditor.EditorUtility.SetDirty(mat); 144 | } 145 | } 146 | #endif 147 | } 148 | 149 | void EnableKeyword(string keyword, bool enable) 150 | { 151 | if (enable) 152 | Shader.EnableKeyword(keyword); 153 | else 154 | Shader.DisableKeyword(keyword); 155 | } 156 | 157 | void SetShaderOverride(string property, float value, ref bool changed) 158 | { 159 | foreach (var mat in ditherMaterials) 160 | { 161 | if (mat.GetFloat(property) != value) 162 | { 163 | mat.SetFloat(property, value); 164 | changed = true; 165 | } 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DSkybox.shader: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | Shader "Dither 3D/Skybox (6 Sided)" 10 | { 11 | Properties 12 | { 13 | _Tint ("Tint Color", Color) = (.5, .5, .5, .5) 14 | [Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0 15 | _Rotation ("Rotation", Range(0, 360)) = 0 16 | [NoScaleOffset] _FrontTex ("Front [+Z] (HDR)", 2D) = "grey" {} 17 | [NoScaleOffset] _BackTex ("Back [-Z] (HDR)", 2D) = "grey" {} 18 | [NoScaleOffset] _LeftTex ("Left [+X] (HDR)", 2D) = "grey" {} 19 | [NoScaleOffset] _RightTex ("Right [-X] (HDR)", 2D) = "grey" {} 20 | [NoScaleOffset] _UpTex ("Up [+Y] (HDR)", 2D) = "grey" {} 21 | [NoScaleOffset] _DownTex ("Down [-Y] (HDR)", 2D) = "grey" {} 22 | 23 | [Header(Dither Input Brightness)] 24 | _InputExposure ("Exposure", Range(0,5)) = 1 25 | _InputOffset ("Offset", Range(-1,1)) = 0 26 | 27 | [Header(Dither Settings)] 28 | [DitherPatternProperty] _DitherMode ("Pattern", Int) = 3 29 | [HideInInspector] _DitherTex ("Dither 3D Texture", 3D) = "" {} 30 | [HideInInspector] _DitherRampTex ("Dither Ramp Texture", 2D) = "white" {} 31 | _Scale ("Dot Scale", Range(2,10)) = 5.0 32 | _SizeVariability ("Dot Size Variability", Range(0,1)) = 0 33 | _Contrast ("Dot Contrast", Range(0,2)) = 1 34 | _StretchSmoothness ("Stretch Smoothness", Range(0,2)) = 1 35 | } 36 | 37 | SubShader 38 | { 39 | Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" } 40 | Cull Off ZWrite Off 41 | 42 | CGINCLUDE 43 | #pragma multi_compile __ DITHERCOL_GRAYSCALE DITHERCOL_RGB DITHERCOL_CMYK 44 | #pragma multi_compile __ INVERSE_DOTS 45 | #pragma multi_compile __ RADIAL_COMPENSATION 46 | #pragma multi_compile __ QUANTIZE_LAYERS 47 | #pragma multi_compile __ DEBUG_FRACTAL 48 | 49 | #include "UnityCG.cginc" 50 | #include "Dither3DInclude.cginc" 51 | 52 | half4 _Tint; 53 | half _Exposure; 54 | float _Rotation; 55 | 56 | float3 RotateAroundYInDegrees (float3 vertex, float degrees) 57 | { 58 | float alpha = degrees * UNITY_PI / 180.0; 59 | float sina, cosa; 60 | sincos(alpha, sina, cosa); 61 | float2x2 m = float2x2(cosa, -sina, sina, cosa); 62 | return float3(mul(m, vertex.xz), vertex.y).xzy; 63 | } 64 | 65 | struct appdata_t 66 | { 67 | float4 vertex : POSITION; 68 | float2 texcoord : TEXCOORD0; 69 | UNITY_VERTEX_INPUT_INSTANCE_ID 70 | }; 71 | struct v2f 72 | { 73 | float4 vertex : SV_POSITION; 74 | float2 texcoord : TEXCOORD0; 75 | float3 worldPos : TEXCOORD1; 76 | float4 screenPos : TEXCOORD2; 77 | UNITY_VERTEX_OUTPUT_STEREO 78 | }; 79 | v2f vert (appdata_t v) 80 | { 81 | v2f o; 82 | UNITY_SETUP_INSTANCE_ID(v); 83 | UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 84 | float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation); 85 | o.worldPos = rotated; 86 | o.vertex = UnityObjectToClipPos(rotated); 87 | o.texcoord = v.texcoord; 88 | o.screenPos = ComputeScreenPos(o.vertex); 89 | return o; 90 | } 91 | half4 skybox_frag (v2f i, sampler2D smp, half4 smpDecode) 92 | { 93 | half4 tex = tex2D (smp, i.texcoord); 94 | half3 c = DecodeHDR (tex, smpDecode); 95 | c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb; 96 | c *= _Exposure; 97 | half4 color = half4(c, 1); 98 | 99 | float3 dir = normalize(i.worldPos); 100 | // U coordinate going from -2 to 2 horizontally around the sphere. 101 | float u = atan2(-dir.z, dir.x) * 2 / UNITY_PI + 1; 102 | float u2 = atan2(dir.z, -dir.x) * 2 / UNITY_PI + 1; 103 | // V coordinate going from -1 to 1 from bottom to top. 104 | float v = acos(-dir.y) * 2 / UNITY_PI - 1; 105 | 106 | // Approximated integral of 1 / cos(v * pi/2) 107 | // The idea is that as the U coordinates become compressed towards 108 | // the poles of a sphere, we make the V coordinates equally compressed 109 | // so the scaling at any given point is still uniform. 110 | // This scaling becomes very small at the poles, but the fractal 111 | // dithering handles that just fine. 112 | float a = v * 0.5 * UNITY_PI; 113 | v = 0.731746 * log(tan(a) + 1.0 / cos(a)); 114 | 115 | color = GetDither3DColorAltUV(float2(u, v), float2(u2, v), i.screenPos, color); 116 | return color; 117 | } 118 | ENDCG 119 | 120 | Pass 121 | { 122 | CGPROGRAM 123 | #pragma vertex vert 124 | #pragma fragment frag 125 | #pragma target 2.0 126 | sampler2D _FrontTex; 127 | half4 _FrontTex_HDR; 128 | half4 frag (v2f i) : SV_Target { return skybox_frag(i,_FrontTex, _FrontTex_HDR); } 129 | ENDCG 130 | } 131 | Pass 132 | { 133 | CGPROGRAM 134 | #pragma vertex vert 135 | #pragma fragment frag 136 | #pragma target 2.0 137 | sampler2D _BackTex; 138 | half4 _BackTex_HDR; 139 | half4 frag (v2f i) : SV_Target { return skybox_frag(i,_BackTex, _BackTex_HDR); } 140 | ENDCG 141 | } 142 | Pass 143 | { 144 | CGPROGRAM 145 | #pragma vertex vert 146 | #pragma fragment frag 147 | #pragma target 2.0 148 | sampler2D _LeftTex; 149 | half4 _LeftTex_HDR; 150 | half4 frag (v2f i) : SV_Target { return skybox_frag(i,_LeftTex, _LeftTex_HDR); } 151 | ENDCG 152 | } 153 | Pass 154 | { 155 | CGPROGRAM 156 | #pragma vertex vert 157 | #pragma fragment frag 158 | #pragma target 2.0 159 | sampler2D _RightTex; 160 | half4 _RightTex_HDR; 161 | half4 frag (v2f i) : SV_Target { return skybox_frag(i,_RightTex, _RightTex_HDR); } 162 | ENDCG 163 | } 164 | Pass 165 | { 166 | CGPROGRAM 167 | #pragma vertex vert 168 | #pragma fragment frag 169 | #pragma target 2.0 170 | sampler2D _UpTex; 171 | half4 _UpTex_HDR; 172 | half4 frag (v2f i) : SV_Target { return skybox_frag(i,_UpTex, _UpTex_HDR); } 173 | ENDCG 174 | } 175 | Pass 176 | { 177 | CGPROGRAM 178 | #pragma vertex vert 179 | #pragma fragment frag 180 | #pragma target 2.0 181 | sampler2D _DownTex; 182 | half4 _DownTex_HDR; 183 | half4 frag (v2f i) : SV_Target { return skybox_frag(i,_DownTex, _DownTex_HDR); } 184 | ENDCG 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 4 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 16 41 | asyncUploadPersistentBuffer: 1 42 | resolutionScalingFixedDPIFactor: 1 43 | excludedTargetPlatforms: [] 44 | - serializedVersion: 2 45 | name: Low 46 | pixelLightCount: 0 47 | shadows: 0 48 | shadowResolution: 0 49 | shadowProjection: 1 50 | shadowCascades: 1 51 | shadowDistance: 20 52 | shadowNearPlaneOffset: 3 53 | shadowCascade2Split: 0.33333334 54 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 55 | shadowmaskMode: 0 56 | blendWeights: 2 57 | textureQuality: 0 58 | anisotropicTextures: 0 59 | antiAliasing: 0 60 | softParticles: 0 61 | softVegetation: 0 62 | realtimeReflectionProbes: 0 63 | billboardsFaceCameraPosition: 0 64 | vSyncCount: 0 65 | lodBias: 0.4 66 | maximumLODLevel: 0 67 | streamingMipmapsActive: 0 68 | streamingMipmapsAddAllCameras: 1 69 | streamingMipmapsMemoryBudget: 512 70 | streamingMipmapsRenderersPerFrame: 512 71 | streamingMipmapsMaxLevelReduction: 2 72 | streamingMipmapsMaxFileIORequests: 1024 73 | particleRaycastBudget: 16 74 | asyncUploadTimeSlice: 2 75 | asyncUploadBufferSize: 16 76 | asyncUploadPersistentBuffer: 1 77 | resolutionScalingFixedDPIFactor: 1 78 | excludedTargetPlatforms: [] 79 | - serializedVersion: 2 80 | name: Medium 81 | pixelLightCount: 1 82 | shadows: 1 83 | shadowResolution: 0 84 | shadowProjection: 1 85 | shadowCascades: 1 86 | shadowDistance: 20 87 | shadowNearPlaneOffset: 3 88 | shadowCascade2Split: 0.33333334 89 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 90 | shadowmaskMode: 0 91 | blendWeights: 2 92 | textureQuality: 0 93 | anisotropicTextures: 1 94 | antiAliasing: 0 95 | softParticles: 0 96 | softVegetation: 0 97 | realtimeReflectionProbes: 0 98 | billboardsFaceCameraPosition: 0 99 | vSyncCount: 1 100 | lodBias: 0.7 101 | maximumLODLevel: 0 102 | streamingMipmapsActive: 0 103 | streamingMipmapsAddAllCameras: 1 104 | streamingMipmapsMemoryBudget: 512 105 | streamingMipmapsRenderersPerFrame: 512 106 | streamingMipmapsMaxLevelReduction: 2 107 | streamingMipmapsMaxFileIORequests: 1024 108 | particleRaycastBudget: 64 109 | asyncUploadTimeSlice: 2 110 | asyncUploadBufferSize: 16 111 | asyncUploadPersistentBuffer: 1 112 | resolutionScalingFixedDPIFactor: 1 113 | excludedTargetPlatforms: [] 114 | - serializedVersion: 2 115 | name: High 116 | pixelLightCount: 2 117 | shadows: 2 118 | shadowResolution: 1 119 | shadowProjection: 1 120 | shadowCascades: 2 121 | shadowDistance: 40 122 | shadowNearPlaneOffset: 3 123 | shadowCascade2Split: 0.33333334 124 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 125 | shadowmaskMode: 1 126 | blendWeights: 2 127 | textureQuality: 0 128 | anisotropicTextures: 1 129 | antiAliasing: 0 130 | softParticles: 0 131 | softVegetation: 1 132 | realtimeReflectionProbes: 1 133 | billboardsFaceCameraPosition: 1 134 | vSyncCount: 1 135 | lodBias: 1 136 | maximumLODLevel: 0 137 | streamingMipmapsActive: 0 138 | streamingMipmapsAddAllCameras: 1 139 | streamingMipmapsMemoryBudget: 512 140 | streamingMipmapsRenderersPerFrame: 512 141 | streamingMipmapsMaxLevelReduction: 2 142 | streamingMipmapsMaxFileIORequests: 1024 143 | particleRaycastBudget: 256 144 | asyncUploadTimeSlice: 2 145 | asyncUploadBufferSize: 16 146 | asyncUploadPersistentBuffer: 1 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Very High 151 | pixelLightCount: 3 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 2 156 | shadowDistance: 70 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 1.5 171 | maximumLODLevel: 0 172 | streamingMipmapsActive: 0 173 | streamingMipmapsAddAllCameras: 1 174 | streamingMipmapsMemoryBudget: 512 175 | streamingMipmapsRenderersPerFrame: 512 176 | streamingMipmapsMaxLevelReduction: 2 177 | streamingMipmapsMaxFileIORequests: 1024 178 | particleRaycastBudget: 1024 179 | asyncUploadTimeSlice: 2 180 | asyncUploadBufferSize: 16 181 | asyncUploadPersistentBuffer: 1 182 | resolutionScalingFixedDPIFactor: 1 183 | excludedTargetPlatforms: [] 184 | - serializedVersion: 2 185 | name: Ultra 186 | pixelLightCount: 4 187 | shadows: 2 188 | shadowResolution: 2 189 | shadowProjection: 1 190 | shadowCascades: 4 191 | shadowDistance: 150 192 | shadowNearPlaneOffset: 3 193 | shadowCascade2Split: 0.33333334 194 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 195 | shadowmaskMode: 1 196 | blendWeights: 4 197 | textureQuality: 0 198 | anisotropicTextures: 2 199 | antiAliasing: 2 200 | softParticles: 1 201 | softVegetation: 1 202 | realtimeReflectionProbes: 1 203 | billboardsFaceCameraPosition: 1 204 | vSyncCount: 1 205 | lodBias: 2 206 | maximumLODLevel: 0 207 | streamingMipmapsActive: 0 208 | streamingMipmapsAddAllCameras: 1 209 | streamingMipmapsMemoryBudget: 512 210 | streamingMipmapsRenderersPerFrame: 512 211 | streamingMipmapsMaxLevelReduction: 2 212 | streamingMipmapsMaxFileIORequests: 1024 213 | particleRaycastBudget: 4096 214 | asyncUploadTimeSlice: 2 215 | asyncUploadBufferSize: 16 216 | asyncUploadPersistentBuffer: 1 217 | resolutionScalingFixedDPIFactor: 1 218 | excludedTargetPlatforms: [] 219 | m_PerPlatformDefaultQuality: 220 | Android: 2 221 | Lumin: 5 222 | Nintendo 3DS: 5 223 | Nintendo Switch: 5 224 | PS4: 5 225 | PSP2: 2 226 | Stadia: 5 227 | Standalone: 5 228 | WebGL: 3 229 | Windows Store Apps: 5 230 | XboxOne: 5 231 | iPhone: 2 232 | tvOS: 2 233 | -------------------------------------------------------------------------------- /Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.ext.nunit": { 4 | "version": "1.0.6", 5 | "depth": 2, 6 | "source": "registry", 7 | "dependencies": {}, 8 | "url": "https://packages.unity.com" 9 | }, 10 | "com.unity.ide.visualstudio": { 11 | "version": "2.0.22", 12 | "depth": 0, 13 | "source": "registry", 14 | "dependencies": { 15 | "com.unity.test-framework": "1.1.9" 16 | }, 17 | "url": "https://packages.unity.com" 18 | }, 19 | "com.unity.test-framework": { 20 | "version": "1.1.30", 21 | "depth": 1, 22 | "source": "registry", 23 | "dependencies": { 24 | "com.unity.ext.nunit": "1.0.6", 25 | "com.unity.modules.imgui": "1.0.0", 26 | "com.unity.modules.jsonserialize": "1.0.0" 27 | }, 28 | "url": "https://packages.unity.com" 29 | }, 30 | "com.unity.ugui": { 31 | "version": "1.0.0", 32 | "depth": 0, 33 | "source": "builtin", 34 | "dependencies": { 35 | "com.unity.modules.ui": "1.0.0", 36 | "com.unity.modules.imgui": "1.0.0" 37 | } 38 | }, 39 | "com.unity.modules.ai": { 40 | "version": "1.0.0", 41 | "depth": 0, 42 | "source": "builtin", 43 | "dependencies": {} 44 | }, 45 | "com.unity.modules.androidjni": { 46 | "version": "1.0.0", 47 | "depth": 0, 48 | "source": "builtin", 49 | "dependencies": {} 50 | }, 51 | "com.unity.modules.animation": { 52 | "version": "1.0.0", 53 | "depth": 0, 54 | "source": "builtin", 55 | "dependencies": {} 56 | }, 57 | "com.unity.modules.assetbundle": { 58 | "version": "1.0.0", 59 | "depth": 0, 60 | "source": "builtin", 61 | "dependencies": {} 62 | }, 63 | "com.unity.modules.audio": { 64 | "version": "1.0.0", 65 | "depth": 0, 66 | "source": "builtin", 67 | "dependencies": {} 68 | }, 69 | "com.unity.modules.cloth": { 70 | "version": "1.0.0", 71 | "depth": 0, 72 | "source": "builtin", 73 | "dependencies": { 74 | "com.unity.modules.physics": "1.0.0" 75 | } 76 | }, 77 | "com.unity.modules.director": { 78 | "version": "1.0.0", 79 | "depth": 0, 80 | "source": "builtin", 81 | "dependencies": { 82 | "com.unity.modules.audio": "1.0.0", 83 | "com.unity.modules.animation": "1.0.0" 84 | } 85 | }, 86 | "com.unity.modules.imageconversion": { 87 | "version": "1.0.0", 88 | "depth": 0, 89 | "source": "builtin", 90 | "dependencies": {} 91 | }, 92 | "com.unity.modules.imgui": { 93 | "version": "1.0.0", 94 | "depth": 0, 95 | "source": "builtin", 96 | "dependencies": {} 97 | }, 98 | "com.unity.modules.jsonserialize": { 99 | "version": "1.0.0", 100 | "depth": 0, 101 | "source": "builtin", 102 | "dependencies": {} 103 | }, 104 | "com.unity.modules.particlesystem": { 105 | "version": "1.0.0", 106 | "depth": 0, 107 | "source": "builtin", 108 | "dependencies": {} 109 | }, 110 | "com.unity.modules.physics": { 111 | "version": "1.0.0", 112 | "depth": 0, 113 | "source": "builtin", 114 | "dependencies": {} 115 | }, 116 | "com.unity.modules.physics2d": { 117 | "version": "1.0.0", 118 | "depth": 0, 119 | "source": "builtin", 120 | "dependencies": {} 121 | }, 122 | "com.unity.modules.screencapture": { 123 | "version": "1.0.0", 124 | "depth": 0, 125 | "source": "builtin", 126 | "dependencies": { 127 | "com.unity.modules.imageconversion": "1.0.0" 128 | } 129 | }, 130 | "com.unity.modules.subsystems": { 131 | "version": "1.0.0", 132 | "depth": 1, 133 | "source": "builtin", 134 | "dependencies": { 135 | "com.unity.modules.jsonserialize": "1.0.0" 136 | } 137 | }, 138 | "com.unity.modules.terrain": { 139 | "version": "1.0.0", 140 | "depth": 0, 141 | "source": "builtin", 142 | "dependencies": {} 143 | }, 144 | "com.unity.modules.terrainphysics": { 145 | "version": "1.0.0", 146 | "depth": 0, 147 | "source": "builtin", 148 | "dependencies": { 149 | "com.unity.modules.physics": "1.0.0", 150 | "com.unity.modules.terrain": "1.0.0" 151 | } 152 | }, 153 | "com.unity.modules.tilemap": { 154 | "version": "1.0.0", 155 | "depth": 0, 156 | "source": "builtin", 157 | "dependencies": { 158 | "com.unity.modules.physics2d": "1.0.0" 159 | } 160 | }, 161 | "com.unity.modules.ui": { 162 | "version": "1.0.0", 163 | "depth": 0, 164 | "source": "builtin", 165 | "dependencies": {} 166 | }, 167 | "com.unity.modules.uielements": { 168 | "version": "1.0.0", 169 | "depth": 0, 170 | "source": "builtin", 171 | "dependencies": { 172 | "com.unity.modules.imgui": "1.0.0", 173 | "com.unity.modules.jsonserialize": "1.0.0" 174 | } 175 | }, 176 | "com.unity.modules.umbra": { 177 | "version": "1.0.0", 178 | "depth": 0, 179 | "source": "builtin", 180 | "dependencies": {} 181 | }, 182 | "com.unity.modules.unityanalytics": { 183 | "version": "1.0.0", 184 | "depth": 0, 185 | "source": "builtin", 186 | "dependencies": { 187 | "com.unity.modules.unitywebrequest": "1.0.0", 188 | "com.unity.modules.jsonserialize": "1.0.0" 189 | } 190 | }, 191 | "com.unity.modules.unitywebrequest": { 192 | "version": "1.0.0", 193 | "depth": 0, 194 | "source": "builtin", 195 | "dependencies": {} 196 | }, 197 | "com.unity.modules.unitywebrequestassetbundle": { 198 | "version": "1.0.0", 199 | "depth": 0, 200 | "source": "builtin", 201 | "dependencies": { 202 | "com.unity.modules.assetbundle": "1.0.0", 203 | "com.unity.modules.unitywebrequest": "1.0.0" 204 | } 205 | }, 206 | "com.unity.modules.unitywebrequestaudio": { 207 | "version": "1.0.0", 208 | "depth": 0, 209 | "source": "builtin", 210 | "dependencies": { 211 | "com.unity.modules.unitywebrequest": "1.0.0", 212 | "com.unity.modules.audio": "1.0.0" 213 | } 214 | }, 215 | "com.unity.modules.unitywebrequesttexture": { 216 | "version": "1.0.0", 217 | "depth": 0, 218 | "source": "builtin", 219 | "dependencies": { 220 | "com.unity.modules.unitywebrequest": "1.0.0", 221 | "com.unity.modules.imageconversion": "1.0.0" 222 | } 223 | }, 224 | "com.unity.modules.unitywebrequestwww": { 225 | "version": "1.0.0", 226 | "depth": 0, 227 | "source": "builtin", 228 | "dependencies": { 229 | "com.unity.modules.unitywebrequest": "1.0.0", 230 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 231 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 232 | "com.unity.modules.audio": "1.0.0", 233 | "com.unity.modules.assetbundle": "1.0.0", 234 | "com.unity.modules.imageconversion": "1.0.0" 235 | } 236 | }, 237 | "com.unity.modules.vehicles": { 238 | "version": "1.0.0", 239 | "depth": 0, 240 | "source": "builtin", 241 | "dependencies": { 242 | "com.unity.modules.physics": "1.0.0" 243 | } 244 | }, 245 | "com.unity.modules.video": { 246 | "version": "1.0.0", 247 | "depth": 0, 248 | "source": "builtin", 249 | "dependencies": { 250 | "com.unity.modules.audio": "1.0.0", 251 | "com.unity.modules.ui": "1.0.0", 252 | "com.unity.modules.unitywebrequest": "1.0.0" 253 | } 254 | }, 255 | "com.unity.modules.vr": { 256 | "version": "1.0.0", 257 | "depth": 0, 258 | "source": "builtin", 259 | "dependencies": { 260 | "com.unity.modules.jsonserialize": "1.0.0", 261 | "com.unity.modules.physics": "1.0.0", 262 | "com.unity.modules.xr": "1.0.0" 263 | } 264 | }, 265 | "com.unity.modules.wind": { 266 | "version": "1.0.0", 267 | "depth": 0, 268 | "source": "builtin", 269 | "dependencies": {} 270 | }, 271 | "com.unity.modules.xr": { 272 | "version": "1.0.0", 273 | "depth": 0, 274 | "source": "builtin", 275 | "dependencies": { 276 | "com.unity.modules.physics": "1.0.0", 277 | "com.unity.modules.jsonserialize": "1.0.0", 278 | "com.unity.modules.subsystems": "1.0.0" 279 | } 280 | } 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Surface-Stable Fractal Dithering 2 | 3 | Surface-Stable Fractal Dithering is a novel form of dithering invented by Rune Skovbo Johansen for use on surfaces in 3D scenes. 4 | 5 | What's unique about it is that the dots in the dither patterns stick to surfaces, and yet the dot sizes and spacing remain approximately constant on the screen, even as surfaces move closer by or further away. This is achieved by dynamically adding or removing dots as needed. 6 | 7 | Here's a video explaining how it works: 8 | 9 | [![Surface-Stable Fractal Dithering video on YouTube](https://img.youtube.com/vi/HPqGaIMVuLs/0.jpg)](https://www.youtube.com/watch?v=HPqGaIMVuLs) 10 | 11 | And here's a feature demo video (with music!) showing color RGB dithering, CMYK halftone, true 1-bit low-res effects, and much more: 12 | 13 | [![Surface-Stable Fractal Dithering Demo video on YouTube](https://img.youtube.com/vi/EzjWBmhO_1E/0.jpg)](https://www.youtube.com/watch?v=EzjWBmhO_1E) 14 | 15 | This repository contains the shader and texture source files, and a Unity example project demonstrating their use. The example project is made with Unity 2019.4 and is also tested in Unity 2022.3 and Unity 6. It's based on the Forward rendering path in the Built-in Render Pipeline. 16 | 17 | The core implementation is located in the folder `Assets/Dither3D`. The remaining files relate to the Unity example project. 18 | 19 | The original version of this repository can be found at: 20 | [https://github.com/runevision/Dither3D](https://github.com/runevision/Dither3D) 21 | 22 | ## Dither Properties 23 | 24 | Each material that uses the dithering has the following dither-specific number properties: 25 | 26 | **Dither Input Brightness** 27 | 28 | - `Exposure` 29 | Exposure to apply to input brightness (default 1). 30 | - `Offset` 31 | Offset to apply to input brightness (default 0). 32 | 33 | **Dither Settings** 34 | 35 | - `Dot Scale` 36 | Value that exponentially scales the dots. 37 | - `Dot Size Variability` 38 | 0 = shading controls dot count "Bayer style" (default); 39 | 1 = shading controls dot sizes "half-tone style". 40 | - `Dot Contrast` 41 | A value of 1 produces perfect anti-aliasing (default 1). 42 | - `Stretch Smoothness` 43 | How much to smooth anisotropic dots (default 1). 44 | 45 | **Global Options** 46 | 47 | Furthermore, the following global toggle properties can be set via the `Dither3DGlobalProperties` component: 48 | 49 | - `Color Mode` 50 | Can be set to Grayscale, RGB or CMYK. Grayscale converts the color to grayscale and runs the dithering once on that. RGB runs the dithering separately for the red, green and blue color channel. CMYK converts the color to CMYK, runs the dithering on each of those with traditional halftone rotations applied, and converts back to RGB. 51 | - `Inverse Dots` 52 | For Grayscale and RGB, disabled produces bright dots on dark background (recommended) while enabled produces dark dots on light background. For CMYK, disabled produces dark dots on light background (like ink) while enabled produces light dots on dark background. Here, disabled works best if the shapes of the individual dots are clearly visible, but it can produce significant banding. For smaller dot sizes, enabled is recommended. 53 | - `Radial Compensation` 54 | When using a perspective camera, dots must be larger towards the edge of the screen in order to be stable under camera rotation. The Radial Compensation feature can be enabled to achieve this. 55 | - `Quantize Layers` 56 | When disabled, dots may grow or shrink in size when they appear or disappear, respectively. Even when enabled, dots may still be partially cut off, but that's a separate and unavoidable effect. 57 | - `Debug Fractal` 58 | Displays an overlay effect showing the pattern size, when enabled. 59 | 60 | The `Dither3DGlobalProperties` component can also be used to override the non-global properties of all dither materials at once. 61 | 62 | ## Files 63 | 64 | A brief overview of the files in the `Assets/Dither3D` folder: 65 | 66 | The central shader include file with the dithering implementation: 67 | 68 | - `Dither3DInclude.cginc` 69 | 70 | Included shader files that use the dithering implementation: 71 | 72 | - `Dither3DOpaque.shader` 73 | - `Dither3DCutout.shader` 74 | - `Dither3DParticleAdd.shader` 75 | - `Dither3DSkybox.shader` 76 | 77 | The dither shaders rely on a 3D texture with dither patterns. These come in several versions with different amounts of dots. In the materials using the dither shaders, you can freely switch between these 3D textures. 78 | 79 | - `Dither3D_1x1.asset` 80 | - `Dither3D_2x2.asset` 81 | - `Dither3D_4x4.asset` 82 | - `Dither3D_8x8.asset` 83 | 84 | Although the 3D textures are available in the repository, a script is also included which can generate them from scratch. You can do this by using the menu items under the grouping `Assets/Create/Dither 3D Texture/...`. 85 | 86 | - `Dither3DTextureMaker.cs` 87 | 88 | The script also generates PNG image files, where the different layers are laid out bottom to top. These PNG files are not used for anything and can be safely deleted, but they are easier to inspect and study than the native 3D textures. Note that later versions of Unity can in principle import 3D textures from such 2D images, but due to an inconsistency between Unity's 3D texture API and their 3D texture importer, the layers will appear in reverse order if this is attempted, and this will cause the fractal dithering effect to not work. 89 | 90 | - `Dither3D_1x1.png` 91 | - `Dither3D_2x2.png` 92 | - `Dither3D_4x4.png` 93 | - `Dither3D_8x8.png` 94 | 95 | ## Discussion of surface-stable trait 96 | 97 | Here is how I define surface-stable: 98 | 99 | - A specific dot "sticks" to the surface whose shading it is part of, both under object movement and camera movement. 100 | - When a pattern is enlarged on the screen, for example due to zooming in on a surface, additional dots may be added to maintain the desired dot density, but no dots may be removed. Likewise, when a pattern shrinks on the screen, dots may be removed, but no dots may be added. 101 | 102 | Conforming to the second constraint is in particular what is new in Surface-Stable Fractal Dithering. Approaches that fade between different scales of a pattern, which is not self-similar in the required way, will typically see dots both appearing and disappearing when zooming in. 103 | 104 | ### Bayer matrices 105 | 106 | My implementation conforms to the second constraint by exploiting a certain "fractal" property of Bayer matrices, as explained in the video above. 107 | 108 | ### Other regular patterns 109 | 110 | Some people have suggested using other regular patterns than Bayer for the dithering, based on triangles, hexes, square root 2 ratio rectangles, or similar. This should be relatively straightforward to implement for someone who so desires. 111 | 112 | ### Blue noise patterns 113 | 114 | Some people have suggested using blue noise for the pattern. But it is not straightforward to construct a blue noise pattern which is self-similar in a way that conforms to the second surface-stable constraint. 115 | 116 | If we use only a single tiled square of blue noise pattern, it would require the dots in each quadrant of the pattern, and each recursive quadrant of the pattern, to perfectly line up with dots in the full pattern, when scaled up to cover the same area as the full pattern. 117 | 118 | Some people have pointed to the paper "Recursive Wang Tiles for Real-Time Blue Noise" by Johannes Kopf et al ([paper](https://johanneskopf.de/publications/blue_noise/paper/Recursive_Wang_Tiles_For_Real-Time_Blue_Noise.pdf) and [video](https://www.youtube.com/watch?v=ykACzjtR6rc)). While the paper describes their technique making use of self-similar blue noise patterns, the practical demonstration in the video shows dots fading both in and out while zooming in, so while I do not fully understand their technique in detail, it does not seem to conform to the second surface-stable constraint. 119 | 120 | I hope others will manage to construct a tiled blue-noise pattern with the required properties. 121 | 122 | ## License 123 | 124 | This Surface-Stable Fractal Dithering implementation is licensed under the [Mozilla Public License, v. 2.0](https://mozilla.org/MPL/2.0/). 125 | 126 | You can read a summary [here](https://choosealicense.com/licenses/mpl-2.0/). In short: If you make changes/improvements to this Surface-Stable Fractal Dithering implementation, you must share those for free with the community. But the rest of the source code for your game or application is not subject to this license, so there's nothing preventing you from creating proprietary and commercial games that use this Surface-Stable Fractal Dithering implementation. 127 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3D_2x2.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!117 &11700000 4 | Texture3D: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: Dither3D_2x2 10 | m_ImageContentsHash: 11 | serializedVersion: 2 12 | Hash: 00000000000000000000000000000000 13 | m_ForcedFallbackFormat: 4 14 | m_DownscaleFallback: 0 15 | serializedVersion: 3 16 | m_ColorSpace: 0 17 | m_Format: 5 18 | m_Width: 32 19 | m_Height: 32 20 | m_Depth: 4 21 | m_MipCount: 1 22 | m_DataSize: 4096 23 | m_TextureSettings: 24 | serializedVersion: 2 25 | m_FilterMode: 1 26 | m_Aniso: 1 27 | m_MipBias: 0 28 | m_WrapU: 0 29 | m_WrapV: 0 30 | m_WrapW: 0 31 | m_IsReadable: 1 32 | image data: 4096 33 | _typelessdata: f9f2eae2d9d1c9c0b8b0a89f978f867e7e868f979fa8b0b8c0c9d1d9e2eaf2f9f2ede7dfd8d0c7bfb7afa79e968e867d7d868e969ea7afb7bfc7d0d8dfe7edf2eae7e2dbd4cdc5bdb5ada59d958d857c7c858d959da5adb5bdc5cdd4dbe2e7eae2dfdbd6d0c9c2bab2aba39b938b837b7b838b939ba3abb2bac2c9d0d6dbdfe2d9d8d4d0cac4bdb6afa8a098908981797981899098a0a8afb6bdc4cad0d4d8d9d1d0cdc9c4beb8b2aba49c958d867e76767e868d959ca4abb2b8bec4c9cdd0d1c9c7c5c2bdb8b2aca69f98918a827b73737b828a91989fa6acb2b8bdc2c5c7c9c0bfbdbab6b2aca7a19a948d867e777070777e868d949aa1a7acb2b6babdbfc0b8b7b5b2afaba6a19b958f88817a736c6c737a81888f959ba1a6abafb2b5b7b8b0afadaba8a49f9a958f89837c766f68686f767c83898f959a9fa4a8abadafb0a8a7a5a3a09c98948f89837d77716a63636a71777d83898f94989ca0a3a5a7a89f9e9d9b9895918d88837d78726b655e5e656b72787d83888d9195989b9d9e9f97969593908d8a86817c77726c6660595960666c72777c81868a8d90939596978f8e8d8b8986827e7a76716b66605a54545a60666b71767a7e8286898b8d8e8f86868583817e7b77736f6a65605a544e4e545a60656a6f73777b7e81838586867e7d7c7b797673706c68635e59544e49494e54595e63686c707376797b7c7d7e7e7d7c7b797673706c68635e59544e49494e54595e63686c707376797b7c7d7e86868583817e7b77736f6a65605a544e4e545a60656a6f73777b7e81838586868f8e8d8b8986827e7a76716b66605a54545a60666b71767a7e8286898b8d8e8f97969593908d8a86817c77726c6660595960666c72777c81868a8d90939596979f9e9d9b9895918d88837d78726b655e5e656b72787d83888d9195989b9d9e9fa8a7a5a3a09c98948f89837d77716a63636a71777d83898f94989ca0a3a5a7a8b0afadaba8a49f9a958f89837c766f68686f767c83898f959a9fa4a8abadafb0b8b7b5b2afaba6a19b958f88817a736c6c737a81888f959ba1a6abafb2b5b7b8c0bfbdbab6b2aca7a19a948d867e777070777e868d949aa1a7acb2b6babdbfc0c9c7c5c2bdb8b2aca69f98918a827b73737b828a91989fa6acb2b8bdc2c5c7c9d1d0cdc9c4beb8b2aba49c958d867e76767e868d959ca4abb2b8bec4c9cdd0d1d9d8d4d0cac4bdb6afa8a098908981797981899098a0a8afb6bdc4cad0d4d8d9e2dfdbd6d0c9c2bab2aba39b938b837b7b838b939ba3abb2bac2c9d0d6dbdfe2eae7e2dbd4cdc5bdb5ada59d958d857c7c858d959da5adb5bdc5cdd4dbe2e7eaf2ede7dfd8d0c7bfb7afa79e968e867d7d868e969ea7afb7bfc7d0d8dfe7edf2f9f2eae2d9d1c9c0b8b0a89f978f867e7e868f979fa8b0b8c0c9d1d9e2eaf2f9f7ece1d5cabeb2a79b8f83786c6054484854606c78838f9ba7b2becad5e1ecf7ece6ddd2c7bcb0a5998e82766b5f535454535f6b76828e99a5b0bcc7d2dde6ece1ddd5ccc2b8ada2978b8074695d5f60605f5d6974808b97a2adb8c2ccd5dde1d5d2ccc5bcb2a89e93887d7266696b6c6c6b6966727d88939ea8b2bcc5ccd2d5cac7c2bcb4aba2988e83796e72747678787674726e79838e98a2abb4bcc2c7cabebcb8b2aba39b92887e73797d8082838382807d79737e88929ba3abb2b8bcbeb2b0ada8a29b938a81787e83888b8e8f8f8e8b88837e78818a939ba2a8adb0b2a7a5a29e98928a827a81888e9397999b9b9997938e88817a828a92989ea2a5a79b9997938e88817a828a92989ea2a5a7a7a5a29e98928a827a81888e9397999b8f8e8b88837e78818a939ba2a8adb0b2b2b0ada8a29b938a81787e83888b8e8f8382807d79737e88929ba3abb2b8bcbebebcb8b2aba39b92887e73797d808283787674726e79838e98a2abb4bcc2c7cacac7c2bcb4aba2988e83796e727476786c6b6966727d88939ea8b2bcc5ccd2d5d5d2ccc5bcb2a89e93887d7266696b6c605f5d6974808b97a2adb8c2ccd5dde1e1ddd5ccc2b8ada2978b8074695d5f6054535f6b76828e99a5b0bcc7d2dde6ecece6ddd2c7bcb0a5998e82766b5f53544854606c78838f9ba7b2becad5e1ecf7f7ece1d5cabeb2a79b8f83786c6054484854606c78838f9ba7b2becad5e1ecf7f7ece1d5cabeb2a79b8f83786c60544854535f6b76828e99a5b0bcc7d2dde6ecece6ddd2c7bcb0a5998e82766b5f5354605f5d6974808b97a2adb8c2ccd5dde1e1ddd5ccc2b8ada2978b8074695d5f606c6b6966727d88939ea8b2bcc5ccd2d5d5d2ccc5bcb2a89e93887d7266696b6c787674726e79838e98a2abb4bcc2c7cacac7c2bcb4aba2988e83796e727476788382807d79737e88929ba3abb2b8bcbebebcb8b2aba39b92887e73797d8082838f8e8b88837e78818a939ba2a8adb0b2b2b0ada8a29b938a81787e83888b8e8f9b9997938e88817a828a92989ea2a5a7a7a5a29e98928a827a81888e9397999ba7a5a29e98928a827a81888e9397999b9b9997938e88817a828a92989ea2a5a7b2b0ada8a29b938a81787e83888b8e8f8f8e8b88837e78818a939ba2a8adb0b2bebcb8b2aba39b92887e73797d8082838382807d79737e88929ba3abb2b8bcbecac7c2bcb4aba2988e83796e72747678787674726e79838e98a2abb4bcc2c7cad5d2ccc5bcb2a89e93887d7266696b6c6c6b6966727d88939ea8b2bcc5ccd2d5e1ddd5ccc2b8ada2978b8074695d5f60605f5d6974808b97a2adb8c2ccd5dde1ece6ddd2c7bcb0a5998e82766b5f535454535f6b76828e99a5b0bcc7d2dde6ecf7ece1d5cabeb2a79b8f83786c6054484854606c78838f9ba7b2becad5e1ecf7f5e8daccbeafa19393a1afbeccdae8f5f5e8daccbeafa19393a1afbeccdae8f5e8e0d5c8bbad9f91919fadbbc8d5e0e8e8e0d5c8bbad9f91919fadbbc8d5e0e8dad5ccc1b5a89b8d8d9ba8b5c1ccd5dadad5ccc1b5a89b8d8d9ba8b5c1ccd5daccc8c1b8ada195888895a1adb8c1c8ccccc8c1b8ada195888895a1adb8c1c8ccbebbb5ada3998d81818d99a3adb5bbbebebbb5ada3998d81818d99a3adb5bbbeafada8a1998f847979848f99a1a8adafafada8a1998f847979848f99a1a8adafa19f9b958d847a70707a848d959b9fa1a19f9b958d847a70707a848d959b9fa193918d888179706666707981888d919393918d888179706666707981888d919384837f7a746d655c66707981888d919393918d88817970665c656d747a7f83847674716d67615965707a848d959b9fa1a19f9b958d847a70655961676d7174766766635f5a54616d79848f99a1a8adafafada8a1998f84796d61545a5f636667595855524d5a6774818d99a3adb5bbbebebbb5ada3998d8174675a4d525558594b4a4744525f6d7a8895a1adb8c1c8ccccc8c1b8ada195887a6d5f5244474a4b3c3b39475563717f8d9ba8b5c1ccd5dadad5ccc1b5a89b8d7f71635547393b3c2e2d3b4a58667483919fadbbc8d5e0e8e8e0d5c8bbad9f91837466584a3b2d2e1f2e3c4b5967768493a1afbeccdae8f5f5e8daccbeafa193847667594b3c2e1f1f2e3c4b5967768493a1afbeccdae8f5f5e8daccbeafa193847667594b3c2e1f2e2d3b4a58667483919fadbbc8d5e0e8e8e0d5c8bbad9f91837466584a3b2d2e3c3b39475563717f8d9ba8b5c1ccd5dadad5ccc1b5a89b8d7f71635547393b3c4b4a4744525f6d7a8895a1adb8c1c8ccccc8c1b8ada195887a6d5f5244474a4b595855524d5a6774818d99a3adb5bbbebebbb5ada3998d8174675a4d525558596766635f5a54616d79848f99a1a8adafafada8a1998f84796d61545a5f6366677674716d67615965707a848d959b9fa1a19f9b958d847a70655961676d71747684837f7a746d655c66707981888d919393918d88817970665c656d747a7f838493918d888179706666707981888d919393918d888179706666707981888d9193a19f9b958d847a70707a848d959b9fa1a19f9b958d847a70707a848d959b9fa1afada8a1998f847979848f99a1a8adafafada8a1998f847979848f99a1a8adafbebbb5ada3998d81818d99a3adb5bbbebebbb5ada3998d81818d99a3adb5bbbeccc8c1b8ada195888895a1adb8c1c8ccccc8c1b8ada195888895a1adb8c1c8ccdad5ccc1b5a89b8d8d9ba8b5c1ccd5dadad5ccc1b5a89b8d8d9ba8b5c1ccd5dae8e0d5c8bbad9f91919fadbbc8d5e0e8e8e0d5c8bbad9f91919fadbbc8d5e0e8f5e8daccbeafa19393a1afbeccdae8f5f5e8daccbeafa19393a1afbeccdae8f5f3e5d5c4b4a392828292a3b4c4d5e5f3f3e5d5c4b4a392828292a3b4c4d5e5f3e5dccec0b0a090808090a0b0c0cedce5e5dccec0b0a090808090a0b0c0cedce5d5cec4b7a99a8b7b7b8b9aa9b7c4ced5d5cec4b7a99a8b7b7b8b9aa9b7c4ced5c4c0b7ada0928475758492a0adb7c0c4c4c0b7ada0928475758492a0adb7c0c4b4b0a9a095897b6d6d7b8995a0a9b0b4b4b0a9a095897b6d6d7b8995a0a9b0b4a3a09a92897e716464717e89929aa0a3a3a09a92897e716464717e89929aa0a392908b847b71665a5a66717b848b909292908b847b71665a5a66717b848b909282807b756d645a4e4e5a646d757b808282807b756d645a4e4e5a646d757b808282807b756d645a4e4e5a646d757b808282807b756d645a4e4e5a646d757b808292908b847b71665a5a66717b848b909292908b847b71665a5a66717b848b9092a3a09a92897e716464717e89929aa0a3a3a09a92897e716464717e89929aa0a3b4b0a9a095897b6d6d7b8995a0a9b0b4b4b0a9a095897b6d6d7b8995a0a9b0b4c4c0b7ada0928475758492a0adb7c0c4c4c0b7ada0928475758492a0adb7c0c4d5cec4b7a99a8b7b7b8b9aa9b7c4ced5d5cec4b7a99a8b7b7b8b9aa9b7c4ced5e5dccec0b0a090808090a0b0c0cedce5e5dccec0b0a090808090a0b0c0cedce5f3e5d5c4b4a392828292a3b4c4d5e5f3f3e5d5c4b4a392828292a3b4c4d5e5f3f3e5d5c4b4a392828292a3b4c4d5e5f3f3e5d5c4b4a392828292a3b4c4d5e5f3e5dccec0b0a090808090a0b0c0cedce5e5dccec0b0a090808090a0b0c0cedce5d5cec4b7a99a8b7b7b8b9aa9b7c4ced5d5cec4b7a99a8b7b7b8b9aa9b7c4ced5c4c0b7ada0928475758492a0adb7c0c4c4c0b7ada0928475758492a0adb7c0c4b4b0a9a095897b6d6d7b8995a0a9b0b4b4b0a9a095897b6d6d7b8995a0a9b0b4a3a09a92897e716464717e89929aa0a3a3a09a92897e716464717e89929aa0a392908b847b71665a5a66717b848b909292908b847b71665a5a66717b848b909282807b756d645a4e4e5a646d757b808282807b756d645a4e4e5a646d757b808282807b756d645a4e4e5a646d757b808282807b756d645a4e4e5a646d757b808292908b847b71665a5a66717b848b909292908b847b71665a5a66717b848b9092a3a09a92897e716464717e89929aa0a3a3a09a92897e716464717e89929aa0a3b4b0a9a095897b6d6d7b8995a0a9b0b4b4b0a9a095897b6d6d7b8995a0a9b0b4c4c0b7ada0928475758492a0adb7c0c4c4c0b7ada0928475758492a0adb7c0c4d5cec4b7a99a8b7b7b8b9aa9b7c4ced5d5cec4b7a99a8b7b7b8b9aa9b7c4ced5e5dccec0b0a090808090a0b0c0cedce5e5dccec0b0a090808090a0b0c0cedce5f3e5d5c4b4a392828292a3b4c4d5e5f3f3e5d5c4b4a392828292a3b4c4d5e5f3 34 | m_StreamData: 35 | offset: 0 36 | size: 0 37 | path: 38 | -------------------------------------------------------------------------------- /Assets/Dither3D/Editor/Dither3DTextureMaker.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | using System.Collections.Generic; 10 | using UnityEditor; 11 | using UnityEngine; 12 | 13 | public class Dither3DTextureMaker : MonoBehaviour 14 | { 15 | internal const string kTexturesPath = "Assets/Dither3D"; 16 | 17 | [MenuItem("Assets/Create/Dither 3D Texture/Bayer 1x1")] 18 | static void CreateDither3DTexture1x1() 19 | { 20 | CreateDither3DTexture(0); 21 | } 22 | 23 | [MenuItem("Assets/Create/Dither 3D Texture/Bayer 2x2")] 24 | static void CreateDither3DTexture2x2() 25 | { 26 | CreateDither3DTexture(1); 27 | } 28 | 29 | [MenuItem("Assets/Create/Dither 3D Texture/Bayer 4x4")] 30 | static void CreateDither3DTexture4x4() 31 | { 32 | CreateDither3DTexture(2); 33 | } 34 | 35 | [MenuItem("Assets/Create/Dither 3D Texture/Bayer 8x8")] 36 | static void CreateDither3DTexture8x8() 37 | { 38 | CreateDither3DTexture(3); 39 | } 40 | 41 | static void CreateDither3DTexture(int recursion) 42 | { 43 | // Create Bayer points. 44 | EditorUtility.DisplayProgressBar("Generating Dither Texture", "Bayer Points", 0.0f); 45 | List bayerPoints = new List(); 46 | bayerPoints.Add(new Vector2(0.00f, 0.00f)); 47 | bayerPoints.Add(new Vector2(0.50f, 0.50f)); 48 | bayerPoints.Add(new Vector2(0.50f, 0.00f)); 49 | bayerPoints.Add(new Vector2(0.00f, 0.50f)); 50 | 51 | for (int r = 0; r < recursion - 1; r++) 52 | { 53 | int count = bayerPoints.Count; 54 | float offset = Mathf.Pow(0.5f, r + 1); 55 | for (int i = 1; i < 4; i++) 56 | { 57 | for (int j = 0; j < count; j++) 58 | { 59 | bayerPoints.Add(bayerPoints[j] + bayerPoints[i] * offset); 60 | } 61 | } 62 | } 63 | 64 | // Determine the texture size. 65 | // If the relationship between layers and size is changed, 66 | // the shader needs to be changed as well. There's no support in shaders 67 | // (in Unity) to get the Z resolution of a 3D texture, so it's inferred 68 | // from the X resolution, based on the logic here. 69 | int dotsPerSide = Mathf.RoundToInt(Mathf.Pow(2, recursion)); 70 | int layers = dotsPerSide * dotsPerSide; 71 | int size = 16 * dotsPerSide; 72 | 73 | // Configure the texture. 74 | Texture3D texture = new Texture3D(size, size, layers, TextureFormat.R8, false); 75 | texture.wrapMode = TextureWrapMode.Repeat; 76 | // Create a 3-dimensional array to store color data 77 | Color[] colors = new Color[size * size * layers]; 78 | 79 | // Keep track of how many pixels are above given brightness levels, 80 | // so we can construct a brightness lookup curve. 81 | int bucketCount = 256; 82 | int[] brightnessBuckets = new int[bucketCount]; 83 | 84 | // Populate the array so that the x, y, and z values of the texture will 85 | // map to red, blue, and green colors 86 | EditorUtility.DisplayProgressBar("Generating Dither Texture", "Brightness Buckets", 0.2f); 87 | float invRes = 1.0f / size; 88 | for (int z = 0; z < layers; z++) 89 | { 90 | int dotCount = z + 1; 91 | float dotArea = 0.5f / dotCount; 92 | float dotRadius = Mathf.Sqrt(dotArea / Mathf.PI); 93 | 94 | int zOffset = z * size * size; 95 | for (int y = 0; y < size; y++) 96 | { 97 | int yOffset = y * size; 98 | for (int x = 0; x < size; x++) 99 | { 100 | Vector2 point = new Vector2((x + 0.5f) * invRes, (y + 0.5f) * invRes); 101 | float dist = Mathf.Infinity; 102 | for (int i = 0; i < dotCount; i++) 103 | { 104 | Vector2 vec = point - bayerPoints[i]; 105 | vec.x = Mathf.Repeat(vec.x + 0.5f, 1) - 0.5f; 106 | vec.y = Mathf.Repeat(vec.y + 0.5f, 1) - 0.5f; 107 | float curDist = vec.magnitude; 108 | dist = Mathf.Min(dist, curDist); 109 | } 110 | // Normalize dist. 111 | dist = dist / (dotRadius * 2.4f); 112 | // Calculate value based on dist. 113 | float val = Mathf.Clamp01(1 - dist); 114 | 115 | colors[x + yOffset + zOffset] = new Color(val, val, val, 1f); 116 | 117 | int bucket = Mathf.Clamp((int)(val * bucketCount), 0, bucketCount - 1); 118 | brightnessBuckets[bucket]++; 119 | } 120 | } 121 | } 122 | 123 | // Calculate brightness ramp. 124 | EditorUtility.DisplayProgressBar("Generating Dither Texture", "Brightness Ramp", 0.4f); 125 | float[] brightnessRamp = new float[brightnessBuckets.Length + 1]; 126 | int sum = 0; 127 | int pixelCount = (size * size * layers); 128 | for (int i = 0; i < brightnessBuckets.Length; i++) 129 | { 130 | sum += brightnessBuckets[brightnessBuckets.Length - 1 - i]; 131 | brightnessRamp[i + 1] = sum / (float)pixelCount; 132 | } 133 | 134 | // Calculate inverse brightness ramp for looking up threshold values 135 | // to achieve a given brightness. 136 | float[] lookupRamp = new float[size]; 137 | float lowerIndexBrightness = 0; 138 | int higherIndex = 1; 139 | float higherIndexBrightness = brightnessRamp[1]; 140 | for (int i = 0; i < size; i++) 141 | { 142 | float desiredBrightness = i / (float)(size - 1); 143 | while (higherIndexBrightness < desiredBrightness) 144 | { 145 | higherIndex++; 146 | higherIndexBrightness = brightnessRamp[higherIndex]; 147 | } 148 | float l = Mathf.InverseLerp( 149 | lowerIndexBrightness, 150 | higherIndexBrightness, 151 | desiredBrightness); 152 | lookupRamp[i] = (higherIndex - 1 + l) / (brightnessRamp.Length - 1); 153 | } 154 | 155 | // Create 3D texture. 156 | EditorUtility.DisplayProgressBar("Generating Dither Texture", "Create Assets", 0.8f); 157 | texture.SetPixels(colors); 158 | texture.Apply(); 159 | string name = "Dither3D_" + dotsPerSide + "x" + dotsPerSide; 160 | AssetDatabase.CreateAsset(texture, $"{kTexturesPath}/{name}/.asset"); 161 | 162 | // Create 2D texture for inspection and debugging. 163 | // (Some versions of Unity can supposedly also create 164 | // a 3D texture from this via the import settings.) 165 | Texture2D tex = new Texture2D(size, size * layers, TextureFormat.ARGB32, false); 166 | tex.wrapMode = TextureWrapMode.Repeat; 167 | tex.SetPixels(colors); 168 | tex.Apply(); 169 | byte[] bytes = tex.EncodeToPNG(); 170 | System.IO.File.WriteAllBytes($"{kTexturesPath}/{name}/.png", bytes); 171 | 172 | // Create ramp texture 173 | CreateRampTexture($"Dither3D_{dotsPerSide}x{dotsPerSide}_Ramp", lookupRamp); 174 | EditorUtility.ClearProgressBar(); 175 | } 176 | 177 | static void CreateRampTexture(string name, float[] lookupRamp) 178 | { 179 | Texture2D tex = new Texture2D(lookupRamp.Length, 1, TextureFormat.R8, false); 180 | Color[] colors = new Color[lookupRamp.Length]; 181 | for (int x = 0; x < lookupRamp.Length; x++) 182 | { 183 | colors[x] = new Color(lookupRamp[x], lookupRamp[x], lookupRamp[x], 1.0f); 184 | } 185 | tex.SetPixels(colors); 186 | 187 | byte[] bytes = tex.EncodeToPNG(); 188 | string path = $"{kTexturesPath}/{name}.png"; 189 | System.IO.File.WriteAllBytes(path, bytes); 190 | AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); 191 | 192 | TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(path); 193 | TextureImporterPlatformSettings settings = new TextureImporterPlatformSettings 194 | { 195 | name = "DefaultTexturePlatform", 196 | overridden = true, 197 | format = TextureImporterFormat.R8 198 | }; 199 | importer.SetPlatformTextureSettings(settings); 200 | importer.textureCompression = TextureImporterCompression.Uncompressed; 201 | importer.sRGBTexture = false; 202 | importer.mipmapEnabled = false; 203 | importer.filterMode = FilterMode.Bilinear; 204 | importer.wrapMode = TextureWrapMode.Clamp; 205 | importer.anisoLevel = 0; 206 | importer.SaveAndReimport(); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /Assets/Scenes/Zoom.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 1 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &446920037 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 446920038} 133 | - component: {fileID: 446920041} 134 | - component: {fileID: 446920040} 135 | - component: {fileID: 446920039} 136 | - component: {fileID: 446920042} 137 | m_Layer: 0 138 | m_Name: Plane 139 | m_TagString: Untagged 140 | m_Icon: {fileID: 0} 141 | m_NavMeshLayer: 0 142 | m_StaticEditorFlags: 0 143 | m_IsActive: 1 144 | --- !u!4 &446920038 145 | Transform: 146 | m_ObjectHideFlags: 0 147 | m_CorrespondingSourceObject: {fileID: 0} 148 | m_PrefabInstance: {fileID: 0} 149 | m_PrefabAsset: {fileID: 0} 150 | m_GameObject: {fileID: 446920037} 151 | m_LocalRotation: {x: -0.7071068, y: -0, z: -0, w: 0.7071068} 152 | m_LocalPosition: {x: 0, y: 0, z: 0} 153 | m_LocalScale: {x: 1, y: 1, z: 1} 154 | m_Children: [] 155 | m_Father: {fileID: 0} 156 | m_RootOrder: 1 157 | m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0} 158 | --- !u!64 &446920039 159 | MeshCollider: 160 | m_ObjectHideFlags: 0 161 | m_CorrespondingSourceObject: {fileID: 0} 162 | m_PrefabInstance: {fileID: 0} 163 | m_PrefabAsset: {fileID: 0} 164 | m_GameObject: {fileID: 446920037} 165 | m_Material: {fileID: 0} 166 | m_IsTrigger: 0 167 | m_Enabled: 1 168 | serializedVersion: 4 169 | m_Convex: 0 170 | m_CookingOptions: 30 171 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} 172 | --- !u!23 &446920040 173 | MeshRenderer: 174 | m_ObjectHideFlags: 0 175 | m_CorrespondingSourceObject: {fileID: 0} 176 | m_PrefabInstance: {fileID: 0} 177 | m_PrefabAsset: {fileID: 0} 178 | m_GameObject: {fileID: 446920037} 179 | m_Enabled: 1 180 | m_CastShadows: 1 181 | m_ReceiveShadows: 1 182 | m_DynamicOccludee: 1 183 | m_MotionVectors: 1 184 | m_LightProbeUsage: 1 185 | m_ReflectionProbeUsage: 1 186 | m_RayTracingMode: 2 187 | m_RenderingLayerMask: 1 188 | m_RendererPriority: 0 189 | m_Materials: 190 | - {fileID: 2100000, guid: 53bde496bb3f94d9b81bce37e0f00b99, type: 2} 191 | m_StaticBatchInfo: 192 | firstSubMesh: 0 193 | subMeshCount: 0 194 | m_StaticBatchRoot: {fileID: 0} 195 | m_ProbeAnchor: {fileID: 0} 196 | m_LightProbeVolumeOverride: {fileID: 0} 197 | m_ScaleInLightmap: 1 198 | m_ReceiveGI: 1 199 | m_PreserveUVs: 0 200 | m_IgnoreNormalsForChartDetection: 0 201 | m_ImportantGI: 0 202 | m_StitchLightmapSeams: 1 203 | m_SelectedEditorRenderState: 3 204 | m_MinimumChartSize: 4 205 | m_AutoUVMaxDistance: 0.5 206 | m_AutoUVMaxAngle: 89 207 | m_LightmapParameters: {fileID: 0} 208 | m_SortingLayerID: 0 209 | m_SortingLayer: 0 210 | m_SortingOrder: 0 211 | --- !u!33 &446920041 212 | MeshFilter: 213 | m_ObjectHideFlags: 0 214 | m_CorrespondingSourceObject: {fileID: 0} 215 | m_PrefabInstance: {fileID: 0} 216 | m_PrefabAsset: {fileID: 0} 217 | m_GameObject: {fileID: 446920037} 218 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} 219 | --- !u!114 &446920042 220 | MonoBehaviour: 221 | m_ObjectHideFlags: 0 222 | m_CorrespondingSourceObject: {fileID: 0} 223 | m_PrefabInstance: {fileID: 0} 224 | m_PrefabAsset: {fileID: 0} 225 | m_GameObject: {fileID: 446920037} 226 | m_Enabled: 1 227 | m_EditorHideFlags: 0 228 | m_Script: {fileID: 11500000, guid: dfdea1d043522496897e2cde7bfbccb4, type: 3} 229 | m_Name: 230 | m_EditorClassIdentifier: 231 | scaleExp: 1.2 232 | --- !u!1 &958598809 233 | GameObject: 234 | m_ObjectHideFlags: 0 235 | m_CorrespondingSourceObject: {fileID: 0} 236 | m_PrefabInstance: {fileID: 0} 237 | m_PrefabAsset: {fileID: 0} 238 | serializedVersion: 6 239 | m_Component: 240 | - component: {fileID: 958598812} 241 | - component: {fileID: 958598811} 242 | - component: {fileID: 958598810} 243 | m_Layer: 0 244 | m_Name: Main Camera 245 | m_TagString: MainCamera 246 | m_Icon: {fileID: 0} 247 | m_NavMeshLayer: 0 248 | m_StaticEditorFlags: 0 249 | m_IsActive: 1 250 | --- !u!81 &958598810 251 | AudioListener: 252 | m_ObjectHideFlags: 0 253 | m_CorrespondingSourceObject: {fileID: 0} 254 | m_PrefabInstance: {fileID: 0} 255 | m_PrefabAsset: {fileID: 0} 256 | m_GameObject: {fileID: 958598809} 257 | m_Enabled: 1 258 | --- !u!20 &958598811 259 | Camera: 260 | m_ObjectHideFlags: 0 261 | m_CorrespondingSourceObject: {fileID: 0} 262 | m_PrefabInstance: {fileID: 0} 263 | m_PrefabAsset: {fileID: 0} 264 | m_GameObject: {fileID: 958598809} 265 | m_Enabled: 1 266 | serializedVersion: 2 267 | m_ClearFlags: 2 268 | m_BackGroundColor: {r: 1, g: 1, b: 1, a: 0} 269 | m_projectionMatrixMode: 1 270 | m_GateFitMode: 2 271 | m_FOVAxisMode: 0 272 | m_SensorSize: {x: 36, y: 24} 273 | m_LensShift: {x: 0, y: 0} 274 | m_FocalLength: 50 275 | m_NormalizedViewPortRect: 276 | serializedVersion: 2 277 | x: 0 278 | y: 0 279 | width: 1 280 | height: 1 281 | near clip plane: 0.3 282 | far clip plane: 1000 283 | field of view: 40 284 | orthographic: 0 285 | orthographic size: 5 286 | m_Depth: -1 287 | m_CullingMask: 288 | serializedVersion: 2 289 | m_Bits: 4294967295 290 | m_RenderingPath: -1 291 | m_TargetTexture: {fileID: 0} 292 | m_TargetDisplay: 0 293 | m_TargetEye: 3 294 | m_HDR: 1 295 | m_AllowMSAA: 1 296 | m_AllowDynamicResolution: 0 297 | m_ForceIntoRT: 0 298 | m_OcclusionCulling: 1 299 | m_StereoConvergence: 10 300 | m_StereoSeparation: 0.022 301 | --- !u!4 &958598812 302 | Transform: 303 | m_ObjectHideFlags: 0 304 | m_CorrespondingSourceObject: {fileID: 0} 305 | m_PrefabInstance: {fileID: 0} 306 | m_PrefabAsset: {fileID: 0} 307 | m_GameObject: {fileID: 958598809} 308 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 309 | m_LocalPosition: {x: 0, y: 0, z: -5} 310 | m_LocalScale: {x: 1, y: 1, z: 1} 311 | m_Children: [] 312 | m_Father: {fileID: 0} 313 | m_RootOrder: 0 314 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 315 | -------------------------------------------------------------------------------- /Assets/Scenes/TestGradient/TestGradient.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 1.0303078, g: 1.0303078, b: 1.0303078, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 1 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &120728892 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 120728894} 133 | - component: {fileID: 120728893} 134 | m_Layer: 0 135 | m_Name: GlobalProperties 136 | m_TagString: Untagged 137 | m_Icon: {fileID: 0} 138 | m_NavMeshLayer: 0 139 | m_StaticEditorFlags: 0 140 | m_IsActive: 1 141 | --- !u!114 &120728893 142 | MonoBehaviour: 143 | m_ObjectHideFlags: 0 144 | m_CorrespondingSourceObject: {fileID: 0} 145 | m_PrefabInstance: {fileID: 0} 146 | m_PrefabAsset: {fileID: 0} 147 | m_GameObject: {fileID: 120728892} 148 | m_Enabled: 1 149 | m_EditorHideFlags: 0 150 | m_Script: {fileID: 11500000, guid: e125df9991507453eaf633f12ee503f7, type: 3} 151 | m_Name: 152 | m_EditorClassIdentifier: 153 | colorMode: 0 154 | inverseDots: 0 155 | radialCompensation: 0 156 | quantizeLayers: 0 157 | debugFractal: 0 158 | setOnEnable: 1 159 | saveInMaterials: 0 160 | inputExposure: 1 161 | inputExposureOverride: 0 162 | inputOffset: 0 163 | inputOffsetOverride: 0 164 | dotScale: 5 165 | dotScaleOverride: 0 166 | dotSizeVariability: 0 167 | dotSizeVariabilityOverride: 0 168 | dotContrast: 1 169 | dotContrastOverride: 0 170 | stretchSmoothness: 1 171 | stretchSmoothnessOverride: 0 172 | scaleWithScreen: 1 173 | referenceRes: 1080 174 | --- !u!4 &120728894 175 | Transform: 176 | m_ObjectHideFlags: 0 177 | m_CorrespondingSourceObject: {fileID: 0} 178 | m_PrefabInstance: {fileID: 0} 179 | m_PrefabAsset: {fileID: 0} 180 | m_GameObject: {fileID: 120728892} 181 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 182 | m_LocalPosition: {x: 0, y: 0, z: 0} 183 | m_LocalScale: {x: 1, y: 1, z: 1} 184 | m_Children: [] 185 | m_Father: {fileID: 0} 186 | m_RootOrder: 0 187 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 188 | --- !u!1 &958598809 189 | GameObject: 190 | m_ObjectHideFlags: 0 191 | m_CorrespondingSourceObject: {fileID: 0} 192 | m_PrefabInstance: {fileID: 0} 193 | m_PrefabAsset: {fileID: 0} 194 | serializedVersion: 6 195 | m_Component: 196 | - component: {fileID: 958598812} 197 | - component: {fileID: 958598811} 198 | - component: {fileID: 958598810} 199 | m_Layer: 0 200 | m_Name: Main Camera 201 | m_TagString: MainCamera 202 | m_Icon: {fileID: 0} 203 | m_NavMeshLayer: 0 204 | m_StaticEditorFlags: 0 205 | m_IsActive: 1 206 | --- !u!81 &958598810 207 | AudioListener: 208 | m_ObjectHideFlags: 0 209 | m_CorrespondingSourceObject: {fileID: 0} 210 | m_PrefabInstance: {fileID: 0} 211 | m_PrefabAsset: {fileID: 0} 212 | m_GameObject: {fileID: 958598809} 213 | m_Enabled: 1 214 | --- !u!20 &958598811 215 | Camera: 216 | m_ObjectHideFlags: 0 217 | m_CorrespondingSourceObject: {fileID: 0} 218 | m_PrefabInstance: {fileID: 0} 219 | m_PrefabAsset: {fileID: 0} 220 | m_GameObject: {fileID: 958598809} 221 | m_Enabled: 1 222 | serializedVersion: 2 223 | m_ClearFlags: 2 224 | m_BackGroundColor: {r: 0.5, g: 0.5, b: 0.5, a: 0} 225 | m_projectionMatrixMode: 1 226 | m_GateFitMode: 2 227 | m_FOVAxisMode: 0 228 | m_SensorSize: {x: 36, y: 24} 229 | m_LensShift: {x: 0, y: 0} 230 | m_FocalLength: 50 231 | m_NormalizedViewPortRect: 232 | serializedVersion: 2 233 | x: 0 234 | y: 0 235 | width: 1 236 | height: 1 237 | near clip plane: 0.3 238 | far clip plane: 1000 239 | field of view: 40 240 | orthographic: 1 241 | orthographic size: 0.3 242 | m_Depth: -1 243 | m_CullingMask: 244 | serializedVersion: 2 245 | m_Bits: 4294967295 246 | m_RenderingPath: -1 247 | m_TargetTexture: {fileID: 0} 248 | m_TargetDisplay: 0 249 | m_TargetEye: 3 250 | m_HDR: 1 251 | m_AllowMSAA: 1 252 | m_AllowDynamicResolution: 0 253 | m_ForceIntoRT: 0 254 | m_OcclusionCulling: 1 255 | m_StereoConvergence: 10 256 | m_StereoSeparation: 0.022 257 | --- !u!4 &958598812 258 | Transform: 259 | m_ObjectHideFlags: 0 260 | m_CorrespondingSourceObject: {fileID: 0} 261 | m_PrefabInstance: {fileID: 0} 262 | m_PrefabAsset: {fileID: 0} 263 | m_GameObject: {fileID: 958598809} 264 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 265 | m_LocalPosition: {x: 0, y: 0, z: -5} 266 | m_LocalScale: {x: 1, y: 1, z: 1} 267 | m_Children: [] 268 | m_Father: {fileID: 0} 269 | m_RootOrder: 1 270 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 271 | --- !u!1 &1712740215 272 | GameObject: 273 | m_ObjectHideFlags: 0 274 | m_CorrespondingSourceObject: {fileID: 0} 275 | m_PrefabInstance: {fileID: 0} 276 | m_PrefabAsset: {fileID: 0} 277 | serializedVersion: 6 278 | m_Component: 279 | - component: {fileID: 1712740216} 280 | - component: {fileID: 1712740218} 281 | - component: {fileID: 1712740217} 282 | m_Layer: 0 283 | m_Name: Dither 284 | m_TagString: Untagged 285 | m_Icon: {fileID: 0} 286 | m_NavMeshLayer: 0 287 | m_StaticEditorFlags: 0 288 | m_IsActive: 1 289 | --- !u!4 &1712740216 290 | Transform: 291 | m_ObjectHideFlags: 0 292 | m_CorrespondingSourceObject: {fileID: 0} 293 | m_PrefabInstance: {fileID: 0} 294 | m_PrefabAsset: {fileID: 0} 295 | m_GameObject: {fileID: 1712740215} 296 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 297 | m_LocalPosition: {x: 0, y: -0.5, z: 0} 298 | m_LocalScale: {x: 1, y: 1, z: 1} 299 | m_Children: [] 300 | m_Father: {fileID: 0} 301 | m_RootOrder: 3 302 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 303 | --- !u!23 &1712740217 304 | MeshRenderer: 305 | m_ObjectHideFlags: 0 306 | m_CorrespondingSourceObject: {fileID: 0} 307 | m_PrefabInstance: {fileID: 0} 308 | m_PrefabAsset: {fileID: 0} 309 | m_GameObject: {fileID: 1712740215} 310 | m_Enabled: 1 311 | m_CastShadows: 1 312 | m_ReceiveShadows: 1 313 | m_DynamicOccludee: 1 314 | m_MotionVectors: 1 315 | m_LightProbeUsage: 1 316 | m_ReflectionProbeUsage: 1 317 | m_RayTracingMode: 2 318 | m_RenderingLayerMask: 1 319 | m_RendererPriority: 0 320 | m_Materials: 321 | - {fileID: 2100000, guid: 941acd07f30aa49ae92eb7bd12f89d80, type: 2} 322 | m_StaticBatchInfo: 323 | firstSubMesh: 0 324 | subMeshCount: 0 325 | m_StaticBatchRoot: {fileID: 0} 326 | m_ProbeAnchor: {fileID: 0} 327 | m_LightProbeVolumeOverride: {fileID: 0} 328 | m_ScaleInLightmap: 1 329 | m_ReceiveGI: 1 330 | m_PreserveUVs: 0 331 | m_IgnoreNormalsForChartDetection: 0 332 | m_ImportantGI: 0 333 | m_StitchLightmapSeams: 1 334 | m_SelectedEditorRenderState: 3 335 | m_MinimumChartSize: 4 336 | m_AutoUVMaxDistance: 0.5 337 | m_AutoUVMaxAngle: 89 338 | m_LightmapParameters: {fileID: 0} 339 | m_SortingLayerID: 0 340 | m_SortingLayer: 0 341 | m_SortingOrder: 0 342 | --- !u!33 &1712740218 343 | MeshFilter: 344 | m_ObjectHideFlags: 0 345 | m_CorrespondingSourceObject: {fileID: 0} 346 | m_PrefabInstance: {fileID: 0} 347 | m_PrefabAsset: {fileID: 0} 348 | m_GameObject: {fileID: 1712740215} 349 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 350 | --- !u!1 &1958452605 351 | GameObject: 352 | m_ObjectHideFlags: 0 353 | m_CorrespondingSourceObject: {fileID: 0} 354 | m_PrefabInstance: {fileID: 0} 355 | m_PrefabAsset: {fileID: 0} 356 | serializedVersion: 6 357 | m_Component: 358 | - component: {fileID: 1958452606} 359 | - component: {fileID: 1958452608} 360 | - component: {fileID: 1958452607} 361 | m_Layer: 0 362 | m_Name: Raw 363 | m_TagString: Untagged 364 | m_Icon: {fileID: 0} 365 | m_NavMeshLayer: 0 366 | m_StaticEditorFlags: 0 367 | m_IsActive: 1 368 | --- !u!4 &1958452606 369 | Transform: 370 | m_ObjectHideFlags: 0 371 | m_CorrespondingSourceObject: {fileID: 0} 372 | m_PrefabInstance: {fileID: 0} 373 | m_PrefabAsset: {fileID: 0} 374 | m_GameObject: {fileID: 1958452605} 375 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 376 | m_LocalPosition: {x: 0, y: 0.5, z: 0} 377 | m_LocalScale: {x: 1, y: 1, z: 1} 378 | m_Children: [] 379 | m_Father: {fileID: 0} 380 | m_RootOrder: 2 381 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 382 | --- !u!23 &1958452607 383 | MeshRenderer: 384 | m_ObjectHideFlags: 0 385 | m_CorrespondingSourceObject: {fileID: 0} 386 | m_PrefabInstance: {fileID: 0} 387 | m_PrefabAsset: {fileID: 0} 388 | m_GameObject: {fileID: 1958452605} 389 | m_Enabled: 1 390 | m_CastShadows: 1 391 | m_ReceiveShadows: 1 392 | m_DynamicOccludee: 1 393 | m_MotionVectors: 1 394 | m_LightProbeUsage: 1 395 | m_ReflectionProbeUsage: 1 396 | m_RayTracingMode: 2 397 | m_RenderingLayerMask: 1 398 | m_RendererPriority: 0 399 | m_Materials: 400 | - {fileID: 2100000, guid: f3d621e03f24d4a669d79217d79463a5, type: 2} 401 | m_StaticBatchInfo: 402 | firstSubMesh: 0 403 | subMeshCount: 0 404 | m_StaticBatchRoot: {fileID: 0} 405 | m_ProbeAnchor: {fileID: 0} 406 | m_LightProbeVolumeOverride: {fileID: 0} 407 | m_ScaleInLightmap: 1 408 | m_ReceiveGI: 1 409 | m_PreserveUVs: 0 410 | m_IgnoreNormalsForChartDetection: 0 411 | m_ImportantGI: 0 412 | m_StitchLightmapSeams: 1 413 | m_SelectedEditorRenderState: 3 414 | m_MinimumChartSize: 4 415 | m_AutoUVMaxDistance: 0.5 416 | m_AutoUVMaxAngle: 89 417 | m_LightmapParameters: {fileID: 0} 418 | m_SortingLayerID: 0 419 | m_SortingLayer: 0 420 | m_SortingOrder: 0 421 | --- !u!33 &1958452608 422 | MeshFilter: 423 | m_ObjectHideFlags: 0 424 | m_CorrespondingSourceObject: {fileID: 0} 425 | m_PrefabInstance: {fileID: 0} 426 | m_PrefabAsset: {fileID: 0} 427 | m_GameObject: {fileID: 1958452605} 428 | m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} 429 | -------------------------------------------------------------------------------- /Assets/Dither3D/Dither3DInclude.cginc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Rune Skovbo Johansen 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | sampler3D _DitherTex; 10 | sampler2D _DitherRampTex; 11 | float4 _DitherTex_TexelSize; 12 | float _Scale; 13 | float _SizeVariability; 14 | float _Contrast; 15 | float _StretchSmoothness; 16 | float _InputExposure; 17 | float _InputOffset; 18 | 19 | // dx is the delta in u and v coordinates along the screen X axis. 20 | // dy is the delta in u and v coordinates along the screen Y axis. 21 | fixed4 GetDither3D_(float2 uv_DitherTex, float4 screenPos, float2 dx, float2 dy, fixed brightness) 22 | { 23 | #if (INVERSE_DOTS) 24 | brightness = 1.0 - brightness; 25 | #endif 26 | 27 | // Get texture X resolution (width) based on Unity builtin data. 28 | // We assume the Y resolution is the same. 29 | float xRes = _DitherTex_TexelSize.z; 30 | float invXres = _DitherTex_TexelSize.x; 31 | 32 | // The relationship between X resolution, dots per side, and total number of 33 | // dots - which is also the Z resolution - is hardcoded in the script that 34 | // creates the 3D texture. Unity has no way to query the Z resolution 35 | // of a 3D texture in a shader. 36 | float dotsPerSide = xRes / 16.0; 37 | float dotsTotal = pow(dotsPerSide, 2); // Could also have been named zRes 38 | float invZres = 1.0 / dotsTotal; 39 | 40 | // Lookup brightness to make dither output have correct output 41 | // brightness at different input brightness values. 42 | float2 lookup = float2((0.5 * invXres + (1 - invXres) * brightness), 0.5); 43 | fixed brightnessCurve = tex2D(_DitherRampTex, lookup).r; 44 | 45 | #if (RADIAL_COMPENSATION) 46 | // Make screenPos have 0,0 in the center of the screen. 47 | float2 screenP = (screenPos.xy / screenPos.w - 0.5) * 2.0; 48 | // Calculate view direction projected onto camera plane. 49 | float2 viewDirProj = float2( 50 | screenP.x / UNITY_MATRIX_P[0][0], 51 | screenP.y / -UNITY_MATRIX_P[1][1]); 52 | // Calculate how much dots should be larger towards the edges of the screen. 53 | // This is meant to keep dots completely stable under camera rotation. 54 | // Currently it doesn't entirely work but is more stable than no compensation. 55 | float radialCompensation = dot(viewDirProj, viewDirProj) + 1; 56 | dx *= radialCompensation; 57 | dy *= radialCompensation; 58 | #endif 59 | 60 | // Get frequency based on singular value decomposition. 61 | // A simpler approach would have been to use fwidth(uv_DitherTex). 62 | // However: 63 | // 1) fwidth is not accurate and produces axis-aligned biases/artefacts. 64 | // 2) We need both the minimum and maximum rate of change. 65 | // These can be along any directions (orthogonal to each other), 66 | // not necessarily aligned with x, y, u or v. 67 | // So we use (a subset of) singular value decomposition to get these. 68 | float2x2 matr = { dx, dy }; 69 | float4 vectorized = float4(dx, dy); 70 | float Q = dot(vectorized, vectorized); 71 | float R = determinant(matr); //ad-bc 72 | float discriminantSqr = max(0, Q*Q-4*R*R); 73 | float discriminant = sqrt(discriminantSqr); 74 | 75 | // "freq" here means rate of change of the UV coordinates on the screen. 76 | // Something smaller on the screen has a larger rate of change of its 77 | // UV coordinates from one pixel to the next. 78 | // 79 | // The freq variable: (max-freq, min-freq) 80 | // 81 | // If a surface has non-uniform scaling, or is seen at an angle, 82 | // or has UVs that are stretched more in one direction than the other, 83 | // the min and max frequency won't be the same. 84 | float2 freq = sqrt(float2(Q + discriminant, Q - discriminant) / 2); 85 | 86 | // We define a spacing variable which linearly correlates with 87 | // the average distance between dots. 88 | // For this dot spacing, we use the smaller frequency, which 89 | // corresponds to the largest amount of stretching. 90 | // This for example means that dots seen at an angle will be 91 | // compressed in one direction rather than enlarged in the other. 92 | float spacing = freq.y; 93 | 94 | // Scale the spacing by the specified input (power of two) scale. 95 | float scaleExp = exp2(_Scale); 96 | spacing *= scaleExp; 97 | 98 | // We keep the spacing the same regardless of whether we're using 99 | // a pattern with more or less dots in it. 100 | spacing *= dotsPerSide * 0.125; 101 | 102 | // We produce higher brightness by having the dots be larger 103 | // compared to the pattern size (based on a contrast threshold 104 | // further down), and lower brightness by having them be smaller. 105 | // 106 | // If we don't want variable dot sizes, we can keep the dot sizes 107 | // approximately constant regardless of brightness by dividing 108 | // the spacing by the brightness. This makes both the dots and 109 | // the spacing between them larger, the lower the brightness is. 110 | // In this case, the two adjustments of dot size cancel out each 111 | // other, leaving only the effect on the spacing between the dots. 112 | // 113 | // Any behavior in between these two is also possible, controlled by 114 | // the _SizeVariability input. 115 | // 116 | // A*pow(B,-1) is the same as A/B, so when _SizeVariability is 0, 117 | // we divide the spacing by the brightness. 118 | // 119 | // A*pow(B,0) is the same as A, so when _SizeVariability is 1, 120 | // we leave the spacing alone. 121 | // 122 | // The "* 2" is there so the mid-size dots keeps constant throughout 123 | // the spectrum, rather than the largest-sized dots. 124 | // The "+ 0.001" is there to avoid dividing by zero. 125 | float brightnessSpacingMultiplier = 126 | pow(brightnessCurve * 2 + 0.001, -(1 - _SizeVariability)); 127 | spacing *= brightnessSpacingMultiplier; 128 | 129 | // Find the power-of-two level that corresponds to the dot spacing. 130 | float spacingLog = log2(spacing); 131 | int patternScaleLevel = floor(spacingLog); // Fractal level. 132 | float f = spacingLog - patternScaleLevel; // Fractional part. 133 | 134 | // Get the UV coordinates in the current fractal level. 135 | float2 uv = uv_DitherTex / exp2(patternScaleLevel); 136 | 137 | // Get the third coordinate for the 3D texture lookup. 138 | // Each layer along the 3rd dimension in the 3D texture has one more dot. 139 | // The first layer we use is the one that has 1/4 of the dots. 140 | // The last layer we use is the one with all the dots. 141 | float subLayer = lerp(0.25 * dotsTotal, dotsTotal, 1 - f); 142 | 143 | // If we don't want to interpolate between different layers, we can 144 | // restrict the sampled values so they correspond exactly to one layer. 145 | #if (QUANTIZE_LAYERS) 146 | float origSubLayer = subLayer; 147 | subLayer = floor(subLayer + 0.5); 148 | 149 | // When we quantize the layers, we can't rely on pattern interpolation 150 | // to keep the dot size constant within each sub-layer, so we have to 151 | // tweak the threshold values to compensate instead. 152 | float thresholdTweak = sqrt(subLayer / origSubLayer); 153 | #endif 154 | 155 | // Texels are half a texel offset from the texture border, so we 156 | // need to subtract half a texel. We also normalize to the 0-1 range. 157 | subLayer = (subLayer - 0.5) * invZres; 158 | 159 | // Sample the 3D texture. 160 | fixed pattern = tex3D(_DitherTex, float3(uv, subLayer)).r; 161 | 162 | // The dots in the pattern are radial gradients. 163 | // We create sharp dots from them by increasing the contrast. 164 | // The desired amount of contrast can be set in the material, 165 | // for example such that there is 1 pixel of blurring around dots, 166 | // which looks equivalent to anti-aliasing. 167 | float contrast = _Contrast * scaleExp * brightnessSpacingMultiplier * 0.1; 168 | 169 | // The spacing is derived from the lowest frequency, but the 170 | // contrast must be based on the highest frequency to avoid aliasing. 171 | // Hence we multiply the contrast by the factor of the smallest 172 | // frequency (freq.y) relative to the highest frequency (freq.x). 173 | // This compensation can be increased or decreased by using exponents 174 | // other than 1, as provided by the _StretchSmoothness input. 175 | contrast *= pow(freq.y / freq.x, _StretchSmoothness); 176 | 177 | // The base brightness value that we scale the contrast around 178 | // should normally be 0.5, but if the pattern is very blurred, 179 | // that would just make the brightness everywhere close to 0.5. 180 | // To avoid this, we lerp towards a base value of the original 181 | // brightness the lower the contrast is. 182 | // The specific formula is arrived at experimentally to maintain 183 | // brightness levels across various contrast and scale values. 184 | fixed baseVal = lerp(0.5, brightness, saturate(1.05 / (1 + contrast))); 185 | 186 | // The brighter output we want, the lower threshold we need to use, 187 | // which makes the resulting dots larger relative to the pattern. 188 | #if (QUANTIZE_LAYERS) 189 | fixed threshold = 1 - brightnessCurve * thresholdTweak; 190 | #else 191 | fixed threshold = 1 - brightnessCurve; 192 | #endif 193 | 194 | // Get the pattern value relative to the threshold, scale it 195 | // according to the contrast, and add the base value. 196 | fixed bw = saturate((pattern - threshold) * contrast + baseVal); 197 | 198 | #if (INVERSE_DOTS) 199 | bw = 1.0 - bw; 200 | #endif 201 | 202 | return fixed4(bw, frac(uv.x), frac(uv.y), subLayer); 203 | } 204 | 205 | fixed GetDither3D(float2 uv_DitherTex, float4 screenPos, fixed brightness) 206 | { 207 | // Get the rates of change of the UV coordinates. 208 | float2 dx = ddx(uv_DitherTex); 209 | float2 dy = ddy(uv_DitherTex); 210 | return GetDither3D_(uv_DitherTex, screenPos, dx, dy, brightness); 211 | } 212 | 213 | fixed GetDither3DAltUV(float2 uv_DitherTex, float2 uv_DitherTexAlt, float4 screenPos, fixed brightness) 214 | { 215 | // Get the rates of change of two sets of UV coordinates and use the smaller ones. 216 | // This can remove seams caused by discontinuities in the UV coordinates, 217 | // as long as the alternative coordinates don't have seams in the same place. 218 | float2 dxA = ddx(uv_DitherTex); 219 | float2 dyA = ddy(uv_DitherTex); 220 | float2 dxB = ddx(uv_DitherTexAlt); 221 | float2 dyB = ddy(uv_DitherTexAlt); 222 | float2 dx = dot(dxA, dxA) < dot(dxB, dxB) ? dxA : dxB; 223 | float2 dy = dot(dyA, dyA) < dot(dyB, dyB) ? dyA : dyB; 224 | return GetDither3D_(uv_DitherTex, screenPos, dx, dy, brightness); 225 | } 226 | 227 | // COLOR HANDLING 228 | 229 | fixed GetGrayscale(fixed4 color) 230 | { 231 | return saturate(0.299 * color.r + 0.587 * color.g + 0.114 * color.b); 232 | } 233 | 234 | fixed3 CMYKtoRGB(fixed4 cmyk) { 235 | fixed c = cmyk.x; 236 | fixed m = cmyk.y; 237 | fixed y = cmyk.z; 238 | fixed k = cmyk.w; 239 | 240 | fixed invK = 1.0 - k; 241 | fixed r = 1.0 - min(1.0, c * invK + k); 242 | fixed g = 1.0 - min(1.0, m * invK + k); 243 | fixed b = 1.0 - min(1.0, y * invK + k); 244 | return saturate(fixed3(r, g, b)); 245 | } 246 | 247 | fixed4 RGBtoCMYK(fixed3 rgb) { 248 | fixed r = rgb.r; 249 | fixed g = rgb.g; 250 | fixed b = rgb.b; 251 | fixed k = min(1.0 - r, min(1.0 - g, 1.0 - b)); 252 | fixed3 cmy = 0.0; 253 | fixed invK = 1.0 - k; 254 | if (invK != 0.0) { 255 | cmy.x = (1.0 - r - k) / invK; 256 | cmy.y = (1.0 - g - k) / invK; 257 | cmy.z = (1.0 - b - k) / invK; 258 | } 259 | return saturate(fixed4(cmy, k)); 260 | } 261 | 262 | float2 RotateUV(float2 uv, float2 xUnitDir) 263 | { 264 | return uv.x * xUnitDir + uv.y * float2(-xUnitDir.y, xUnitDir.x); 265 | } 266 | 267 | fixed4 GetDither3DColor_(float2 uv_DitherTex, float4 screenPos, float2 dx, float2 dy, fixed4 color) 268 | { 269 | // Adjust brightness according to shader exposure and offset properties. 270 | color.rgb = saturate(color.rgb * _InputExposure + _InputOffset); 271 | 272 | #ifdef DITHERCOL_GRAYSCALE 273 | fixed4 dither = GetDither3D_(uv_DitherTex, screenPos, dx, dy, GetGrayscale(color)); 274 | color.rgb = dither.x; 275 | #if (DEBUG_FRACTAL) 276 | fixed3 uvVis = dither.yzw; 277 | color.rgb = lerp(color.rgb, uvVis, 0.7); 278 | #endif 279 | #elif DITHERCOL_RGB 280 | color.r = GetDither3D_(uv_DitherTex, screenPos, dx, dy, color.r).x; 281 | color.g = GetDither3D_(uv_DitherTex, screenPos, dx, dy, color.g).x; 282 | color.b = GetDither3D_(uv_DitherTex, screenPos, dx, dy, color.b).x; 283 | #elif DITHERCOL_CMYK 284 | fixed4 cmyk = RGBtoCMYK(color.rgb); 285 | // Get dither pattern for C, M, Y, K and angles 15, 75, 0, 45. 286 | cmyk.x = GetDither3D_(RotateUV(uv_DitherTex, float2(0.966, 0.259)), screenPos, dx, dy, cmyk.x).x; 287 | cmyk.y = GetDither3D_(RotateUV(uv_DitherTex, float2(0.259, 0.966)), screenPos, dx, dy, cmyk.y).x; 288 | cmyk.z = GetDither3D_(RotateUV(uv_DitherTex, float2(1.000, 0.000)), screenPos, dx, dy, cmyk.z).x; 289 | cmyk.w = GetDither3D_(RotateUV(uv_DitherTex, float2(0.707, 0.707)), screenPos, dx, dy, cmyk.w).x; 290 | color.rgb = CMYKtoRGB(cmyk); 291 | #endif 292 | 293 | return color; 294 | } 295 | 296 | fixed4 GetDither3DColor(float2 uv_DitherTex, float4 screenPos, fixed4 color) 297 | { 298 | // Get the rates of change of the UV coordinates. 299 | float2 dx = ddx(uv_DitherTex); 300 | float2 dy = ddy(uv_DitherTex); 301 | return GetDither3DColor_(uv_DitherTex, screenPos, dx, dy, color); 302 | } 303 | 304 | fixed4 GetDither3DColorAltUV(float2 uv_DitherTex, float2 uv_DitherTexAlt, float4 screenPos, fixed4 color) 305 | { 306 | // Get the rates of change of two sets of UV coordinates and use the smaller ones. 307 | // This can remove seams caused by discontinuities in the UV coordinates, 308 | // as long as the alternative coordinates don't have seams in the same place. 309 | float2 dxA = ddx(uv_DitherTex); 310 | float2 dyA = ddy(uv_DitherTex); 311 | float2 dxB = ddx(uv_DitherTexAlt); 312 | float2 dyB = ddy(uv_DitherTexAlt); 313 | float2 dx = dot(dxA, dxA) < dot(dxB, dxB) ? dxA : dxB; 314 | float2 dy = dot(dyA, dyA) < dot(dyB, dyB) ? dyA : dyB; 315 | return GetDither3DColor_(uv_DitherTex, screenPos, dx, dy, color); 316 | } 317 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | ### 1. Definitions 5 | 6 | **1.1. “Contributor”** 7 | means each individual or legal entity that creates, contributes to 8 | the creation of, or owns Covered Software. 9 | 10 | **1.2. “Contributor Version”** 11 | means the combination of the Contributions of others (if any) used 12 | by a Contributor and that particular Contributor's Contribution. 13 | 14 | **1.3. “Contribution”** 15 | means Covered Software of a particular Contributor. 16 | 17 | **1.4. “Covered Software”** 18 | means Source Code Form to which the initial Contributor has attached 19 | the notice in Exhibit A, the Executable Form of such Source Code 20 | Form, and Modifications of such Source Code Form, in each case 21 | including portions thereof. 22 | 23 | **1.5. “Incompatible With Secondary Licenses”** 24 | means 25 | 26 | * **(a)** that the initial Contributor has attached the notice described 27 | in Exhibit B to the Covered Software; or 28 | * **(b)** that the Covered Software was made available under the terms of 29 | version 1.1 or earlier of the License, but not also under the 30 | terms of a Secondary License. 31 | 32 | **1.6. “Executable Form”** 33 | means any form of the work other than Source Code Form. 34 | 35 | **1.7. “Larger Work”** 36 | means a work that combines Covered Software with other material, in 37 | a separate file or files, that is not Covered Software. 38 | 39 | **1.8. “License”** 40 | means this document. 41 | 42 | **1.9. “Licensable”** 43 | means having the right to grant, to the maximum extent possible, 44 | whether at the time of the initial grant or subsequently, any and 45 | all of the rights conveyed by this License. 46 | 47 | **1.10. “Modifications”** 48 | means any of the following: 49 | 50 | * **(a)** any file in Source Code Form that results from an addition to, 51 | deletion from, or modification of the contents of Covered 52 | Software; or 53 | * **(b)** any new file in Source Code Form that contains any Covered 54 | Software. 55 | 56 | **1.11. “Patent Claims” of a Contributor** 57 | means any patent claim(s), including without limitation, method, 58 | process, and apparatus claims, in any patent Licensable by such 59 | Contributor that would be infringed, but for the grant of the 60 | License, by the making, using, selling, offering for sale, having 61 | made, import, or transfer of either its Contributions or its 62 | Contributor Version. 63 | 64 | **1.12. “Secondary License”** 65 | means either the GNU General Public License, Version 2.0, the GNU 66 | Lesser General Public License, Version 2.1, the GNU Affero General 67 | Public License, Version 3.0, or any later versions of those 68 | licenses. 69 | 70 | **1.13. “Source Code Form”** 71 | means the form of the work preferred for making modifications. 72 | 73 | **1.14. “You” (or “Your”)** 74 | means an individual or a legal entity exercising rights under this 75 | License. For legal entities, “You” includes any entity that 76 | controls, is controlled by, or is under common control with You. For 77 | purposes of this definition, “control” means **(a)** the power, direct 78 | or indirect, to cause the direction or management of such entity, 79 | whether by contract or otherwise, or **(b)** ownership of more than 80 | fifty percent (50%) of the outstanding shares or beneficial 81 | ownership of such entity. 82 | 83 | 84 | ### 2. License Grants and Conditions 85 | 86 | #### 2.1. Grants 87 | 88 | Each Contributor hereby grants You a world-wide, royalty-free, 89 | non-exclusive license: 90 | 91 | * **(a)** under intellectual property rights (other than patent or trademark) 92 | Licensable by such Contributor to use, reproduce, make available, 93 | modify, display, perform, distribute, and otherwise exploit its 94 | Contributions, either on an unmodified basis, with Modifications, or 95 | as part of a Larger Work; and 96 | * **(b)** under Patent Claims of such Contributor to make, use, sell, offer 97 | for sale, have made, import, and otherwise transfer either its 98 | Contributions or its Contributor Version. 99 | 100 | #### 2.2. Effective Date 101 | 102 | The licenses granted in Section 2.1 with respect to any Contribution 103 | become effective for each Contribution on the date the Contributor first 104 | distributes such Contribution. 105 | 106 | #### 2.3. Limitations on Grant Scope 107 | 108 | The licenses granted in this Section 2 are the only rights granted under 109 | this License. No additional rights or licenses will be implied from the 110 | distribution or licensing of Covered Software under this License. 111 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 112 | Contributor: 113 | 114 | * **(a)** for any code that a Contributor has removed from Covered Software; 115 | or 116 | * **(b)** for infringements caused by: **(i)** Your and any other third party's 117 | modifications of Covered Software, or **(ii)** the combination of its 118 | Contributions with other software (except as part of its Contributor 119 | Version); or 120 | * **(c)** under Patent Claims infringed by Covered Software in the absence of 121 | its Contributions. 122 | 123 | This License does not grant any rights in the trademarks, service marks, 124 | or logos of any Contributor (except as may be necessary to comply with 125 | the notice requirements in Section 3.4). 126 | 127 | #### 2.4. Subsequent Licenses 128 | 129 | No Contributor makes additional grants as a result of Your choice to 130 | distribute the Covered Software under a subsequent version of this 131 | License (see Section 10.2) or under the terms of a Secondary License (if 132 | permitted under the terms of Section 3.3). 133 | 134 | #### 2.5. Representation 135 | 136 | Each Contributor represents that the Contributor believes its 137 | Contributions are its original creation(s) or it has sufficient rights 138 | to grant the rights to its Contributions conveyed by this License. 139 | 140 | #### 2.6. Fair Use 141 | 142 | This License is not intended to limit any rights You have under 143 | applicable copyright doctrines of fair use, fair dealing, or other 144 | equivalents. 145 | 146 | #### 2.7. Conditions 147 | 148 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 149 | in Section 2.1. 150 | 151 | 152 | ### 3. Responsibilities 153 | 154 | #### 3.1. Distribution of Source Form 155 | 156 | All distribution of Covered Software in Source Code Form, including any 157 | Modifications that You create or to which You contribute, must be under 158 | the terms of this License. You must inform recipients that the Source 159 | Code Form of the Covered Software is governed by the terms of this 160 | License, and how they can obtain a copy of this License. You may not 161 | attempt to alter or restrict the recipients' rights in the Source Code 162 | Form. 163 | 164 | #### 3.2. Distribution of Executable Form 165 | 166 | If You distribute Covered Software in Executable Form then: 167 | 168 | * **(a)** such Covered Software must also be made available in Source Code 169 | Form, as described in Section 3.1, and You must inform recipients of 170 | the Executable Form how they can obtain a copy of such Source Code 171 | Form by reasonable means in a timely manner, at a charge no more 172 | than the cost of distribution to the recipient; and 173 | 174 | * **(b)** You may distribute such Executable Form under the terms of this 175 | License, or sublicense it under different terms, provided that the 176 | license for the Executable Form does not attempt to limit or alter 177 | the recipients' rights in the Source Code Form under this License. 178 | 179 | #### 3.3. Distribution of a Larger Work 180 | 181 | You may create and distribute a Larger Work under terms of Your choice, 182 | provided that You also comply with the requirements of this License for 183 | the Covered Software. If the Larger Work is a combination of Covered 184 | Software with a work governed by one or more Secondary Licenses, and the 185 | Covered Software is not Incompatible With Secondary Licenses, this 186 | License permits You to additionally distribute such Covered Software 187 | under the terms of such Secondary License(s), so that the recipient of 188 | the Larger Work may, at their option, further distribute the Covered 189 | Software under the terms of either this License or such Secondary 190 | License(s). 191 | 192 | #### 3.4. Notices 193 | 194 | You may not remove or alter the substance of any license notices 195 | (including copyright notices, patent notices, disclaimers of warranty, 196 | or limitations of liability) contained within the Source Code Form of 197 | the Covered Software, except that You may alter any license notices to 198 | the extent required to remedy known factual inaccuracies. 199 | 200 | #### 3.5. Application of Additional Terms 201 | 202 | You may choose to offer, and to charge a fee for, warranty, support, 203 | indemnity or liability obligations to one or more recipients of Covered 204 | Software. However, You may do so only on Your own behalf, and not on 205 | behalf of any Contributor. You must make it absolutely clear that any 206 | such warranty, support, indemnity, or liability obligation is offered by 207 | You alone, and You hereby agree to indemnify every Contributor for any 208 | liability incurred by such Contributor as a result of warranty, support, 209 | indemnity or liability terms You offer. You may include additional 210 | disclaimers of warranty and limitations of liability specific to any 211 | jurisdiction. 212 | 213 | 214 | ### 4. Inability to Comply Due to Statute or Regulation 215 | 216 | If it is impossible for You to comply with any of the terms of this 217 | License with respect to some or all of the Covered Software due to 218 | statute, judicial order, or regulation then You must: **(a)** comply with 219 | the terms of this License to the maximum extent possible; and **(b)** 220 | describe the limitations and the code they affect. Such description must 221 | be placed in a text file included with all distributions of the Covered 222 | Software under this License. Except to the extent prohibited by statute 223 | or regulation, such description must be sufficiently detailed for a 224 | recipient of ordinary skill to be able to understand it. 225 | 226 | 227 | ### 5. Termination 228 | 229 | **5.1.** The rights granted under this License will terminate automatically 230 | if You fail to comply with any of its terms. However, if You become 231 | compliant, then the rights granted under this License from a particular 232 | Contributor are reinstated **(a)** provisionally, unless and until such 233 | Contributor explicitly and finally terminates Your grants, and **(b)** on an 234 | ongoing basis, if such Contributor fails to notify You of the 235 | non-compliance by some reasonable means prior to 60 days after You have 236 | come back into compliance. Moreover, Your grants from a particular 237 | Contributor are reinstated on an ongoing basis if such Contributor 238 | notifies You of the non-compliance by some reasonable means, this is the 239 | first time You have received notice of non-compliance with this License 240 | from such Contributor, and You become compliant prior to 30 days after 241 | Your receipt of the notice. 242 | 243 | **5.2.** If You initiate litigation against any entity by asserting a patent 244 | infringement claim (excluding declaratory judgment actions, 245 | counter-claims, and cross-claims) alleging that a Contributor Version 246 | directly or indirectly infringes any patent, then the rights granted to 247 | You by any and all Contributors for the Covered Software under Section 248 | 2.1 of this License shall terminate. 249 | 250 | **5.3.** In the event of termination under Sections 5.1 or 5.2 above, all 251 | end user license agreements (excluding distributors and resellers) which 252 | have been validly granted by You or Your distributors under this License 253 | prior to termination shall survive termination. 254 | 255 | 256 | ### 6. Disclaimer of Warranty 257 | 258 | > Covered Software is provided under this License on an “as is” 259 | > basis, without warranty of any kind, either expressed, implied, or 260 | > statutory, including, without limitation, warranties that the 261 | > Covered Software is free of defects, merchantable, fit for a 262 | > particular purpose or non-infringing. The entire risk as to the 263 | > quality and performance of the Covered Software is with You. 264 | > Should any Covered Software prove defective in any respect, You 265 | > (not any Contributor) assume the cost of any necessary servicing, 266 | > repair, or correction. This disclaimer of warranty constitutes an 267 | > essential part of this License. No use of any Covered Software is 268 | > authorized under this License except under this disclaimer. 269 | 270 | ### 7. Limitation of Liability 271 | 272 | > Under no circumstances and under no legal theory, whether tort 273 | > (including negligence), contract, or otherwise, shall any 274 | > Contributor, or anyone who distributes Covered Software as 275 | > permitted above, be liable to You for any direct, indirect, 276 | > special, incidental, or consequential damages of any character 277 | > including, without limitation, damages for lost profits, loss of 278 | > goodwill, work stoppage, computer failure or malfunction, or any 279 | > and all other commercial damages or losses, even if such party 280 | > shall have been informed of the possibility of such damages. This 281 | > limitation of liability shall not apply to liability for death or 282 | > personal injury resulting from such party's negligence to the 283 | > extent applicable law prohibits such limitation. Some 284 | > jurisdictions do not allow the exclusion or limitation of 285 | > incidental or consequential damages, so this exclusion and 286 | > limitation may not apply to You. 287 | 288 | 289 | ### 8. Litigation 290 | 291 | Any litigation relating to this License may be brought only in the 292 | courts of a jurisdiction where the defendant maintains its principal 293 | place of business and such litigation shall be governed by laws of that 294 | jurisdiction, without reference to its conflict-of-law provisions. 295 | Nothing in this Section shall prevent a party's ability to bring 296 | cross-claims or counter-claims. 297 | 298 | 299 | ### 9. Miscellaneous 300 | 301 | This License represents the complete agreement concerning the subject 302 | matter hereof. If any provision of this License is held to be 303 | unenforceable, such provision shall be reformed only to the extent 304 | necessary to make it enforceable. Any law or regulation which provides 305 | that the language of a contract shall be construed against the drafter 306 | shall not be used to construe this License against a Contributor. 307 | 308 | 309 | ### 10. Versions of the License 310 | 311 | #### 10.1. New Versions 312 | 313 | Mozilla Foundation is the license steward. Except as provided in Section 314 | 10.3, no one other than the license steward has the right to modify or 315 | publish new versions of this License. Each version will be given a 316 | distinguishing version number. 317 | 318 | #### 10.2. Effect of New Versions 319 | 320 | You may distribute the Covered Software under the terms of the version 321 | of the License under which You originally received the Covered Software, 322 | or under the terms of any subsequent version published by the license 323 | steward. 324 | 325 | #### 10.3. Modified Versions 326 | 327 | If you create software not governed by this License, and you want to 328 | create a new license for such software, you may create and use a 329 | modified version of this License if you rename the license and remove 330 | any references to the name of the license steward (except to note that 331 | such modified license differs from this License). 332 | 333 | #### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses 334 | 335 | If You choose to distribute Source Code Form that is Incompatible With 336 | Secondary Licenses under the terms of this version of the License, the 337 | notice described in Exhibit B of this License must be attached. 338 | 339 | ## Exhibit A - Source Code Form License Notice 340 | 341 | This Source Code Form is subject to the terms of the Mozilla Public 342 | License, v. 2.0. If a copy of the MPL was not distributed with this 343 | file, You can obtain one at https://mozilla.org/MPL/2.0/. 344 | 345 | If it is not possible or desirable to put the notice in a particular 346 | file, then You may include the notice in a location (such as a LICENSE 347 | file in a relevant directory) where a recipient would be likely to look 348 | for such a notice. 349 | 350 | You may add additional accurate notices of copyright ownership. 351 | 352 | ## Exhibit B - “Incompatible With Secondary Licenses” Notice 353 | 354 | This Source Code Form is "Incompatible With Secondary Licenses", as 355 | defined by the Mozilla Public License, v. 2.0. 356 | 357 | 358 | --------------------------------------------------------------------------------