├── .gitignore
├── LICENSE
├── LICENSE.meta
├── PixelCamDrawer.cs
├── PixelCamDrawer.cs.meta
├── PixelCamFallback.shader
├── PixelCamFallback.shader.meta
├── PixelCamera.cs
├── PixelCamera.cs.meta
├── README.md
└── README.md.meta
/.gitignore:
--------------------------------------------------------------------------------
1 | /[Ll]ibrary/
2 | /[Tt]emp/
3 | /[Oo]bj/
4 | /[Bb]uild/
5 | /[Bb]uilds/
6 | /Assets/AssetStoreTools*
7 |
8 | # Autogenerated VS/MD solution and project files
9 | ExportedObj/
10 | *.csproj
11 | *.unityproj
12 | *.sln
13 | *.suo
14 | *.tmp
15 | *.user
16 | *.userprefs
17 | *.pidb
18 | *.booproj
19 | *.svd
20 |
21 |
22 | # Unity3D generated meta files
23 | *.pidb.meta
24 |
25 | # Unity3D Generated File On Crash Reports
26 | sysinfo.txt
27 |
28 | # Builds
29 | *.apk
30 | *.unitypackage
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Jeiel Aranal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSE.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 79f9d5cb70ce03f4986e605d1583609e
3 | timeCreated: 1488381179
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/PixelCamDrawer.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace SubjectNerd.Utilities
4 | {
5 | [ExecuteInEditMode]
6 | [AddComponentMenu("")]
7 | public class PixelCamDrawer : MonoBehaviour
8 | {
9 | /*
10 | This class sits on a hidden camera that draws nothing, the pixel camera output
11 | is being redirected to a render texture, so we need a camera context to draw into
12 | */
13 | public PixelCamera SourceCamera { get; set; }
14 |
15 | private void OnPostRender()
16 | {
17 | if (SourceCamera == null) return;
18 | DrawQuad();
19 | SourceCamera.CheckCamera();
20 | }
21 |
22 | public void DrawQuad()
23 | {
24 | if (SourceCamera == null || SourceCamera.CameraMaterial == null)
25 | return;
26 |
27 | Vector2 min = SourceCamera.QuadMin;
28 | Vector2 max = SourceCamera.QuadMax;
29 |
30 | float zOffset = -0.1f;
31 |
32 | Material renderMat = SourceCamera.CameraMaterial;
33 | GL.PushMatrix();
34 | GL.LoadOrtho();
35 | for (int i = 0; i < renderMat.passCount; i++)
36 | {
37 | renderMat.SetPass(i);
38 |
39 | GL.Begin(GL.QUADS);
40 |
41 | GL.TexCoord2(0.0f, 0.0f);
42 | GL.Vertex3(min.x, min.y, zOffset);
43 | GL.TexCoord2(0.0f, 1.0f);
44 | GL.Vertex3(min.x, max.y, zOffset);
45 | GL.TexCoord2(1.0f, 1.0f);
46 | GL.Vertex3(max.x, max.y, zOffset);
47 | GL.TexCoord2(1.0f, 0.0f);
48 | GL.Vertex3(max.x, min.y, zOffset);
49 |
50 | GL.End();
51 | }
52 | GL.PopMatrix();
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/PixelCamDrawer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a7cc3004c6416db4980b6c46de6bd972
3 | timeCreated: 1488381179
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/PixelCamFallback.shader:
--------------------------------------------------------------------------------
1 | Shader "Hidden/SubjectNerd/PixelCamFallback"
2 | {
3 | // Simple unlit shader with fog removed
4 | Properties
5 | {
6 | _MainTex ("Texture", 2D) = "white" {}
7 | }
8 | SubShader
9 | {
10 | Tags { "RenderType"="Opaque" }
11 | LOD 100
12 |
13 | Pass
14 | {
15 | CGPROGRAM
16 | #pragma vertex vert
17 | #pragma fragment frag
18 |
19 | #include "UnityCG.cginc"
20 |
21 | struct appdata
22 | {
23 | float4 vertex : POSITION;
24 | float2 uv : TEXCOORD0;
25 | };
26 |
27 | struct v2f
28 | {
29 | float2 uv : TEXCOORD0;
30 | float4 vertex : SV_POSITION;
31 | };
32 |
33 | sampler2D _MainTex;
34 | float4 _MainTex_ST;
35 |
36 | v2f vert (appdata v)
37 | {
38 | v2f o;
39 | o.vertex = UnityObjectToClipPos(v.vertex);
40 | o.uv = TRANSFORM_TEX(v.uv, _MainTex);
41 | return o;
42 | }
43 |
44 | fixed4 frag (v2f i) : SV_Target
45 | {
46 | // sample the texture
47 | fixed4 col = tex2D(_MainTex, i.uv);
48 | return col;
49 | }
50 | ENDCG
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/PixelCamFallback.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 549026f9040c7234f9c316d29194b4eb
3 | timeCreated: 1488381182
4 | licenseType: Free
5 | ShaderImporter:
6 | defaultTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/PixelCamera.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 |
4 | namespace SubjectNerd.Utilities
5 | {
6 | [ExecuteInEditMode]
7 | [RequireComponent(typeof(Camera))]
8 | public class PixelCamera : MonoBehaviour
9 | {
10 | [Serializable]
11 | protected class AdvancedSettings
12 | {
13 | [Tooltip("Material to draw output render with")]
14 | public Material cameraMaterial;
15 | [Tooltip("Stretches output display, for non square pixels")]
16 | public Vector2 aspectStretch = Vector2.one;
17 | [Tooltip("Scales down camera render size")]
18 | public float downSample = 1;
19 | [Tooltip("Z distance to draw as pixel perfect for perspective camera.")]
20 | public float perspectiveZ = 10;
21 | }
22 |
23 | protected struct CamSettings
24 | {
25 | public int[] screenSize;
26 | public Vector2 aspect;
27 | public float zoomLevel;
28 | public float pixelsPerUnit;
29 | public float zDistance;
30 | public float downsample;
31 | public float fieldOfView;
32 | public float farPlane;
33 | public bool isOrtho;
34 |
35 | public CamSettings(PixelCamera pixelCam, Camera cam)
36 | {
37 | screenSize = new[] {Screen.width, Screen.height};
38 | this.aspect = pixelCam.AspectStretch;
39 | this.zoomLevel = pixelCam.ZoomLevel;
40 | this.pixelsPerUnit = pixelCam.pixelsPerUnit;
41 | this.zDistance = pixelCam.PerspectiveZ;
42 | this.downsample = pixelCam.DownSample;
43 | this.fieldOfView = cam.fieldOfView;
44 | this.isOrtho = cam.orthographic;
45 | this.farPlane = cam.farClipPlane;
46 | }
47 |
48 | public bool Equals(CamSettings other)
49 | {
50 | bool equalScreen = other.screenSize[0] == screenSize[0] &&
51 | other.screenSize[1] == screenSize[1];
52 | bool equalAspect = other.aspect == aspect;
53 |
54 | bool isEqual = other.isOrtho == isOrtho &&
55 | equalScreen &&
56 | equalAspect &&
57 | Mathf.Approximately(other.zoomLevel, zoomLevel) &&
58 | Mathf.Approximately(other.pixelsPerUnit, pixelsPerUnit) &&
59 | Mathf.Approximately(other.downsample, downsample);
60 |
61 | if (isEqual && isOrtho == false)
62 | {
63 | isEqual &= Mathf.Approximately(other.zDistance, zDistance) &&
64 | Mathf.Approximately(other.fieldOfView, fieldOfView) &&
65 | Mathf.Approximately(other.farPlane, farPlane);
66 | }
67 |
68 | return isEqual;
69 | }
70 | }
71 |
72 | [SerializeField] protected Camera cam;
73 | [SerializeField] protected float pixelsPerUnit = 100;
74 | [SerializeField] protected float zoomLevel = 1f;
75 | [Space]
76 | [SerializeField] protected AdvancedSettings advancedSettings;
77 |
78 | protected RenderTexture renderTexture;
79 |
80 | protected GameObject falseCamGO;
81 | protected Camera falseCam;
82 | protected PixelCamDrawer camDraw;
83 |
84 | protected Shader fallbackShader;
85 | protected Material fallbackMaterial;
86 |
87 | protected CamSettings lastSettings;
88 |
89 | protected Vector2 quadOffset;
90 | public Vector2 QuadMin { get; protected set; }
91 | public Vector2 QuadMax { get; protected set; }
92 |
93 | ///
94 | /// Material to draw output render with
95 | ///
96 | public Material CameraMaterial
97 | {
98 | get
99 | {
100 | Material useMaterial = fallbackMaterial;
101 | if (advancedSettings != null && advancedSettings.cameraMaterial != null)
102 | useMaterial = advancedSettings.cameraMaterial;
103 | return useMaterial;
104 | }
105 | set
106 | {
107 | if (advancedSettings.cameraMaterial != null)
108 | advancedSettings.cameraMaterial.SetTexture("_MainTex", null);
109 |
110 | advancedSettings.cameraMaterial = value;
111 | if (advancedSettings.cameraMaterial == null) return;
112 |
113 | if (renderTexture != null)
114 | advancedSettings.cameraMaterial.SetTexture("_MainTex", renderTexture);
115 | }
116 | }
117 |
118 | public float ZoomLevel
119 | {
120 | get { return zoomLevel; }
121 | set { zoomLevel = value; }
122 | }
123 |
124 | public float PixelsPerUnit
125 | {
126 | get { return pixelsPerUnit; }
127 | set { pixelsPerUnit = value; }
128 | }
129 |
130 | ///
131 | /// For perspective cameras. Z distance between near and far plane to scale as pixel perfect.
132 | ///
133 | public float PerspectiveZ
134 | {
135 | get
136 | {
137 | if (advancedSettings == null)
138 | return cam.farClipPlane*0.5f;
139 | advancedSettings.perspectiveZ = Mathf.Clamp(advancedSettings.perspectiveZ, cam.nearClipPlane, cam.farClipPlane);
140 | return advancedSettings.perspectiveZ;
141 | }
142 | set
143 | {
144 | if (advancedSettings == null)
145 | return;
146 | advancedSettings.perspectiveZ = Mathf.Clamp(value, cam.nearClipPlane, cam.farClipPlane); ;
147 | }
148 | }
149 |
150 | ///
151 | /// Stretches output display, for non square pixels
152 | ///
153 | public Vector2 AspectStretch
154 | {
155 | get
156 | {
157 | if (advancedSettings == null)
158 | return Vector2.one;
159 | return advancedSettings.aspectStretch;
160 | }
161 | set
162 | {
163 | if (advancedSettings == null)
164 | return;
165 | advancedSettings.aspectStretch = value;
166 | }
167 | }
168 |
169 | ///
170 | /// Scales down camera render size. Clamped at minimum value of 1.
171 | ///
172 | public float DownSample
173 | {
174 | get
175 | {
176 | if (advancedSettings == null)
177 | return 1f;
178 | advancedSettings.downSample = Mathf.Max(1f, advancedSettings.downSample);
179 | return advancedSettings.downSample;
180 | }
181 | set
182 | {
183 | if (advancedSettings == null)
184 | return;
185 | advancedSettings.downSample = Mathf.Max(1f, value);
186 | }
187 | }
188 |
189 | ///
190 | /// The render texture camera is being drawn into
191 | ///
192 | public RenderTexture RenderTexture { get { return renderTexture; } }
193 |
194 | ///
195 | /// Pixel size of the camera
196 | ///
197 | public int[] CameraSize
198 | {
199 | get
200 | {
201 | if (renderTexture == null)
202 | return new[] {0, 0};
203 |
204 | return new[] {renderTexture.width, renderTexture.height};
205 | }
206 | }
207 |
208 | private void Reset()
209 | {
210 | cam = GetComponent();
211 | float cameraPixelHeight = Mathf.FloorToInt(cam.aspect*2*pixelsPerUnit);
212 | zoomLevel = Screen.height/cameraPixelHeight;
213 | }
214 |
215 | private void Start()
216 | {
217 | // Disable if we don't support image effects
218 | if (!SystemInfo.supportsImageEffects)
219 | enabled = false;
220 |
221 | if (cam == null)
222 | cam = GetComponent();
223 | if (cam == null)
224 | enabled = false;
225 |
226 | OnDisable(); // Force cleanup
227 | if (enabled)
228 | OnEnable();
229 | }
230 |
231 | protected virtual void OnEnable()
232 | {
233 | lastSettings = new CamSettings(this, cam)
234 | {
235 | screenSize = new []{0, 0}
236 | };
237 | ForceRefresh();
238 |
239 | falseCamGO = new GameObject("False Camera") {hideFlags = HideFlags.HideAndDontSave};
240 | falseCam = falseCamGO.AddComponent();
241 | falseCam.cullingMask = LayerMask.GetMask();
242 |
243 | camDraw = falseCamGO.AddComponent();
244 | camDraw.SourceCamera = this;
245 |
246 | fallbackShader = Shader.Find("Hidden/SubjectNerd/PixelCamFallback");
247 | if (fallbackShader != null)
248 | {
249 | fallbackMaterial = new Material(fallbackShader)
250 | {
251 | hideFlags = HideFlags.DontSave
252 | };
253 | }
254 | else
255 | {
256 | Debug.Log("Couldn't find fall back shader, material not created");
257 | enabled = false;
258 | }
259 | }
260 |
261 | protected virtual void OnDisable()
262 | {
263 | if (fallbackMaterial != null)
264 | DestroyImmediate(fallbackMaterial);
265 | fallbackShader = null;
266 | cam.targetTexture = null;
267 | cam.ResetAspect();
268 | if (renderTexture != null)
269 | DestroyImmediate(renderTexture);
270 | if (falseCamGO != null)
271 | DestroyImmediate(falseCamGO);
272 | falseCam = null;
273 | }
274 |
275 | private void SetupCamera(CamSettings settings)
276 | {
277 | var aspect = settings.aspect;
278 |
279 | zoomLevel = Mathf.Max(0.05f, Mathf.Abs(zoomLevel))*Math.Sign(zoomLevel);
280 | // "Physical" pixel render size
281 | Vector2 screenRenderSize = GetScreenRenderSize();
282 | // Pixel render size
283 | int[] pixelRenderSize = GetRenderTextureSize(screenRenderSize, settings.aspect);
284 |
285 | float targetAspect = (float)pixelRenderSize[0] / (float)pixelRenderSize[1];
286 | cam.aspect = targetAspect;
287 |
288 | if (cam.orthographic)
289 | {
290 | // Orthographic camera needs to use screen size when calculating quad offset
291 | screenRenderSize = new Vector2(Screen.width, Screen.height);
292 |
293 | // Set the camera's size, according to pixel size
294 | float targetHeight = pixelRenderSize[1];
295 | // Use pixel density to convert to world units
296 | targetHeight /= pixelsPerUnit;
297 | targetHeight /= 2f;
298 | // Change orthographic size so camera is sized to world unit
299 | cam.orthographicSize = targetHeight;
300 | }
301 |
302 | // Find the settings to be used for drawing the GL quad
303 | CalculateQuad(screenRenderSize, pixelRenderSize);
304 |
305 | // Important to release current render texture
306 | cam.targetTexture = null;
307 | fallbackMaterial.SetTexture("_MainTex", null);
308 | if (advancedSettings != null && advancedSettings.cameraMaterial != null)
309 | advancedSettings.cameraMaterial.SetTexture("_MainTex", null);
310 | if (renderTexture != null)
311 | renderTexture.Release();
312 |
313 | // Create new render texture
314 | Vector2 renderSize = new Vector2(pixelRenderSize[0], pixelRenderSize[1]) / settings.downsample;
315 | int[] actualRenderSize = GetRenderTextureSize(renderSize, Vector2.one);
316 | renderTexture = new RenderTexture(actualRenderSize[0], actualRenderSize[1], 0)
317 | {
318 | useMipMap = true,
319 | filterMode = FilterMode.Point,
320 | wrapMode = TextureWrapMode.Clamp
321 | };
322 | // Make main camera render into it
323 | cam.targetTexture = renderTexture;
324 |
325 | // Set render texture as _MainTex on materials
326 | fallbackMaterial.SetTexture("_MainTex", renderTexture);
327 | if (advancedSettings != null)
328 | CameraMaterial = advancedSettings.cameraMaterial;
329 |
330 | lastSettings = settings;
331 |
332 | cam.Render();
333 | camDraw.DrawQuad();
334 | }
335 |
336 | private float GetPerspectiveHeight(float z)
337 | {
338 | var frustumHeight = 2.0f * z * Mathf.Tan(cam.fieldOfView * 0.5f * Mathf.Deg2Rad);
339 | return frustumHeight;
340 | }
341 |
342 | protected Vector2 GetScreenRenderSize()
343 | {
344 | // For orthographic camera, physical render size is based on screen pixels
345 | Vector2 screenRenderSize = new Vector2(Screen.width, Screen.height);
346 | screenRenderSize /= zoomLevel;
347 |
348 | // For perspective camera, physical render is based on world unit height
349 | // in terms of fustrum distance, converted to pixels
350 | if (cam.orthographic == false)
351 | {
352 | cam.aspect = (float) Screen.width / Screen.height;
353 |
354 | float scale = Mathf.InverseLerp(cam.nearClipPlane, cam.farClipPlane, PerspectiveZ);
355 | float maxHeight = GetPerspectiveHeight(cam.farClipPlane);
356 | float minHeight = GetPerspectiveHeight(cam.nearClipPlane);
357 |
358 | float height = Mathf.Lerp(minHeight, maxHeight, scale);
359 | float width = height*cam.aspect;
360 |
361 | screenRenderSize.x = width;
362 | screenRenderSize.y = height;
363 | screenRenderSize *= pixelsPerUnit;
364 | }
365 |
366 | return screenRenderSize;
367 | }
368 |
369 | ///
370 | /// The integer width and height of the texture to render to
371 | ///
372 | ///
373 | protected int[] GetRenderTextureSize(Vector2 size, Vector2 aspect)
374 | {
375 | int width = Mathf.FloorToInt(Mathf.Abs(size.x / aspect.x));
376 | int height = Mathf.FloorToInt(Mathf.Abs(size.y / aspect.y));
377 |
378 | // Size is not integer, add padding
379 | if (Math.Abs(size.x - width) > float.Epsilon)
380 | width += 2;
381 | if (Mathf.Abs(size.y - height) > float.Epsilon)
382 | height += 2;
383 | // Make sure this isn't an odd number
384 | if (width%2 > 0)
385 | width += 1;
386 | if (height%2 > 0)
387 | height += 1;
388 |
389 | // Just in case
390 | width = Mathf.Clamp(width, 2, 4096);
391 | height = Mathf.Clamp(height, 2, 4096);
392 |
393 | return new[] {width, height};
394 | }
395 |
396 | private void CalculateQuad(Vector2 screenRenderSize, int[] pixelRenderSize)
397 | {
398 | Vector2 pixelSize = new Vector2(pixelRenderSize[0], pixelRenderSize[1]) * zoomLevel;
399 | quadOffset = pixelSize - screenRenderSize;
400 | quadOffset /= 2;
401 | quadOffset.x /= Screen.width;
402 | quadOffset.y /= Screen.height;
403 |
404 | Vector2 min = Vector2.zero - quadOffset;
405 | Vector2 max = Vector2.one + quadOffset;
406 | if (advancedSettings == null)
407 | {
408 | QuadMin = min;
409 | QuadMax = max;
410 | return;
411 | }
412 |
413 | Vector2 aspectStretch = advancedSettings.aspectStretch;
414 | if (aspectStretch.x < float.Epsilon || aspectStretch.y < float.Epsilon)
415 | return;
416 |
417 | Vector2 center = (min + max) / 2;
418 | min -= center;
419 | max -= center;
420 |
421 | min.x *= aspectStretch.x;
422 | max.x *= aspectStretch.x;
423 |
424 | min.y *= aspectStretch.y;
425 | max.y *= aspectStretch.y;
426 |
427 | min += center;
428 | max += center;
429 |
430 | QuadMin = min;
431 | QuadMax = max;
432 | }
433 |
434 | public void ForceRefresh()
435 | {
436 | lastSettings.screenSize = new [] {0, 0};
437 | }
438 |
439 | public bool CheckCamera()
440 | {
441 | var currentSettings = new CamSettings(this, cam);
442 | bool didChange = currentSettings.Equals(lastSettings) == false;
443 | if (didChange)
444 | SetupCamera(currentSettings);
445 | return didChange;
446 | }
447 | }
448 | }
--------------------------------------------------------------------------------
/PixelCamera.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1480e3aaaeec2f144a53c656b42fa9d4
3 | timeCreated: 1488381179
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Unity Pixel Camera
2 |
3 | A resolution independent pixel perfect camera for Unity.
4 |
5 | This package simplifies making a Unity camera render to exact pixel units, for use with pixel art or similar art styles where blockiness is part of the aesthetic.
6 |
7 | ## Features ##
8 |
9 | * Simple setup
10 | * Experimental perspective camera support
11 |
12 | *Standard unity camera*
13 |
14 | 
15 |
16 | *Pixel perfect camera*
17 |
18 | 
19 |
20 | ## Installation ##
21 |
22 | Clone the repository or download the UnityPackage of the [latest release](https://github.com/ChemiKhazi/UnityPixelCamera/releases/latest). The `PixelCamera` directory can be moved to your location of choice in your unity project.
23 |
24 | ## Basic Usage ##
25 |
26 | 1. Attach the `Pixel Camera` script to an existing camera.
27 | 2. Set `Pixels Per Unit` to an appropriate value, usually matching the settings used for your assets.
28 | 3. Set the `Zoom Level` for the camera.
29 |
30 | ## Advanced Settings ##
31 |
32 | * __Camera Material__ - A material applied to the camera output, allows shaders to modify the image. The camera output is set as the `_MainTex` of the material.
33 | * __Aspect Stretch__ - Apply a stretch to the output, allows the display to be non square pixels.
34 | * __Down Sample__ - Scales down the render resolution, making the output blockier.
35 | * __Perspective Z__ - Only for perspective cameras. The Z distance between the near and far clip planes, that is rendered as pixel perfect.
36 |
37 | ## Caveats ##
38 |
39 | * If a camera or sprite is out of alignment with the pixel grid, unwanted artifacts may occur.
40 | * Pixel Camera will not automatically zoom in or out according to the window/viewport size.
41 | * Camera `Viewport Rect` settings are not taken into account.
42 |
43 | ## Perspective Camera Notes ##
44 | * A zoom level below 1 will leave a border on the edge of the screen.
45 | * Perspective camera is unoptimized. A high `Field of View` setting will generate unreasonably large RenderTextures. Use with caution.
46 |
47 | ## Technical Details ##
48 |
49 | Pixel camera takes the size of the screen and finds the render size required to cover the screen in a pixel perfect manner, at the given settings.
50 |
51 | A `RenderTexture` of the calculated render size is created, and if needed the camera settings are modified so the render fits the calculated size.
52 |
53 | The camera output is sent to the `RenderTexture`.
54 |
55 | A dummy camera that renders nothing is created, and the `OnPostRender()` function is used to draw the output of the attached camera onto the screen using GL commands.
56 |
57 | ## API ##
58 |
59 | ### Properties ###
60 |
61 | __ZoomLevel__ : float
62 |
63 | The pixel zoom scale used by the camera.
64 |
65 | __PixelsPerUnit__ : float
66 |
67 | The pixels per unit value used by the camera.
68 |
69 | __CameraMaterial__ : Material
70 |
71 | The Material used to render the camera output, setting to `null` will use the default material. Pixel Camera sets the camera output as the `_MainTex` texture of the given material.
72 |
73 | __AspectStretch__ : Vector2
74 |
75 | An additional stretch applied to the camera, allows camera to render as non square pixels.
76 |
77 | __DownSample__ : float
78 |
79 | Scales down the render resolution, makes the output blockier. Minimum value is clamped at 1.
80 |
81 | __PerspectiveZ__ : float
82 |
83 | With a perspective camera, the distance between the camera near and far planes that is rendered as pixel perfect. Value is clamped between the near and far plane values.
84 |
85 | __RenderTexture__ : RenderTexture, read only
86 |
87 | Access the RenderTexture used as the camera output.
88 |
89 | __CameraSize__ : int[], read only
90 |
91 | Actual pixel size of the camera, as an integer array.
92 |
93 | ### Methods ###
94 |
95 | __ForceRefresh()__ : void
96 |
97 | Force the camera to recalculate rendering sizes.
98 |
99 | __CheckCamera()__ : bool
100 |
101 | Checks camera settings. If different from the last camera settings used, camera will be setup again. Returns `true` when settings have changed.
102 |
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 97d97f703fdb57f428e07cf5469942dc
3 | timeCreated: 1488381179
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------