unity像素游戏里面的像素自适应关系和移动抖动闪烁问题分析

补充这篇的http://blog.csdn.net/shenmifangke/article/details/49611567

unity想要做像素游戏最好摄像机用正交视图(不排除可以用透视的)

这样里面就只有size可以调节,默认是5,就是半个屏幕的高度

注意这里的5是unity里单位距离,一个quad不进行缩放的情况下宽度就是1

plane的话不进行缩放时10*10也就是摄像机设置成正交,并且位置归为0位置,那么plane正好在高度上适应

可以看到下图关系


然后说的是像素游戏

游戏一般使用的都是sprite里面有个设置叫pixel per unity 就是unity单位长度里像素的个数,这个后面再说

下面是一般图片导入设置

  1. sprite Mode根据是否是单一元素调节
  2. FIlter Mode,不需要抗锯齿就改成Point
  3. 大部分情况下像素游戏没有远近的话Mip Maps勾也能去掉
  4. 还有下面的Max Size千万不要比你原图小,那样会对像素进行模糊的,大一点可以
  5. format改成True color
  6. 记得修改pixel per unity(见后面分析)

还有就是场景上的问题

游戏的分辨率,这个决定了实际游戏的窗口大小,从而也决定你设计游戏像素应该放大的倍数问题

这里假设用的是5倍像素放大(就是1个像素实际显示是5个像素大小)

想要的游戏窗口是500*400 那么游戏元素大小应该是100*80

那么接下来就是分析


如果用的正交摄像机Size是5,也就是屏幕高度是单位距离10,如果一个单位表示上sprite里默认100像素长度的话,

高度上就有1000个像素,这个都超出了实际窗口大小,显然不是我们要的效果

所以这里sprite上的pixel per unity可以调节为 400/10 = 40,这里意思就是如果要1一个像素对应一个像素的话设置为40

但是我们需要的是5倍大小 所以40/5=8,这样就行了

下面放上一个10*10的测试图片

(可以另存为 因为放大所以模糊了,实际上并不模糊)

因为实际上游戏画面是100*80的所以横排可以铺10个,我们验证一下见下面的图


像素效果现在看起还行

上面这个图是动态演示移动效果,如果觉得这种锯齿效果还ok,那就没问题了

但是如果觉得效果不好,比如像素在移动的时候有抖动效果,这是因为设置成point后,取值截断而没有抗锯齿的原因

如果想去掉这种明显的锯齿效果,那就要重新找种方案了,另外说下这时在摄像机上加上抗锯齿脚本并不能解决问题,因为这种锯齿是被放大的,point采样造成的误差也被放大了,所以不可能用简单的抗锯齿脚本去掉的

视觉效果最大的问题就是会造成物体在缓慢移动的时候有变大变小的效果(应该也是不明显的,在sprite边缘单个像素内发生)


然后如果想要简单解决这种问题就是,像素在完成后直接放大一定倍数再导入


point方式像素移动是产生的抖动,像素拉伸stretch,和变化锯齿的主要原因(这些在其他引擎里也适用)


如果像素不是按照整数来移动,而且采样方式又是point,就会造成像素点在局部的拉伸

所以一个解决思想就是整数化移动(当然这种方式并不适合大量物体,或者某些嵌套子物体)

void LateUpdate () {
transform.position = new Vector3(Mathf.Round(truePos.x),Mathf.Round(truePos.y), z);
}

还有方法当然是让摄像机移动整数个像素距离(这种只适合像素场景不被拉伸)


另外使用sprite的另一种材质,只要新建Sprites/Default shader 并打开 pixel snap,然后直接拖到sprite上即可(不需要放图片,自动的)可以在一定程度上很小的提高一点像素质量,但效果在移动上还是不明显


当然还有一种像素游戏情况是和屏幕像素1:1的这个有个shader可以解决闪烁问题

Shader "Sprites/Pixel Snap/Alpha Blended"
{
	Properties
	{
		_MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Main Color", Color) = (1,1,1,1)
	}

	SubShader
	{
		Tags
		{ 
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent" 
		}

		Cull Off
		Lighting Off
		ZWrite Off
		ZTest Always
		Fog { Mode Off }
		Blend SrcAlpha OneMinusSrcAlpha

		Pass
		{
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest
			#include "UnityCG.cginc"

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;

			struct appdata_t
			{
				float4 vertex   : POSITION;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex        : POSITION;
				float2 texcoord      : TEXCOORD0;
			};

			v2f vert(appdata_t IN)
			{
				v2f OUT;
				OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
				OUT.texcoord = TRANSFORM_TEX(IN.texcoord, _MainTex);

				// Snapping params
				float hpcX = _ScreenParams.x * 0.5;
				float hpcY = _ScreenParams.y * 0.5;
			#ifdef UNITY_HALF_TEXEL_OFFSET
				float hpcOX = -0.5;
				float hpcOY = 0.5;
			#else
				float hpcOX = 0;
				float hpcOY = 0;
			#endif	
				// Snap
				float pos = floor((OUT.vertex.x / OUT.vertex.w) * hpcX + 0.5f) + hpcOX;
				OUT.vertex.x = pos / hpcX * OUT.vertex.w;

				pos = floor((OUT.vertex.y / OUT.vertex.w) * hpcY + 0.5f) + hpcOY;
				OUT.vertex.y = pos / hpcY * OUT.vertex.w;

				return OUT;
			}

			fixed4 frag(v2f IN) : COLOR
			{
				return tex2D( _MainTex, IN.texcoord) * _Color;
			}
		ENDCG
		}
	}

}
下图gif就是使用了上面方法后的结果,左侧三个使用了这种shader,右边三个使用的是默认的


可以看出正常移动效果好了,但是旋转后移动的效果并不完美

谁能得到更好的效果可以进一步交流


参考网站

http://blogs.unity3d.com/2015/06/19/pixel-perfect-2d/

http://forum.unity3d.com/threads/help-fixing-a-major-flaw-in-unity2d.244014/http://forum.unity3d.com/threads/pixel-perfect-2d-in-4-3.210497/
http://www.gamasutra.com/blogs/EduardoCabrera/20150203/235483/Unity_Set_Up__Pixel_Perfect.php
https://www.reddit.com/r/Unity2D/comments/2bsoj1/recommended_best_practices_for_pixel_art_games/

http://tieba.baidu.com/p/4031440265

http://forum.unity3d.com/threads/solved-2d-sprites-flicker-shake-on-camera-movement.270741/

http://forum.unity3d.com/threads/unity-5-2d-and-pixel-perfection.310023/


http://wiki.unity3d.com/index.php?title=SnapToGrid

http://answers.unity3d.com/questions/725621/best-method-for-dealing-with-rough-sprite-edges-du.html



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值