这个文章的代码和素材来源自UnityStore的项目 Endless Runner - Sample Game
实现的效果就是下图一样。整体使平坦的场景呈球面。并且靠近摄像机的位置越平,越远越下坠
使用Shader来实现鱼眼扭曲,通过shader来改变模型的显示位置,而对模型的实际位置posisiton、rotation、碰撞体等东西不会造成偏移。只是单纯的视觉位置进行偏移。选中具体 效果如下图:
直接实现效果的话,需要导入上面的一个项目的Unity包。保留shader文件
还有控制世界扭曲的脚本文件
在摄像机上挂上控制脚本,并且可以通过调整参数来修改扭曲幅度,正数朝下负数朝上
然后把对应需要扭曲的模型都是用打包进来的shader就可以实现扭曲
启用了这个扭曲之后可能会早Scene和PrefabEditor下也会造成扭曲,调整Prefab和场景时候最好先把控制扭曲的脚本关掉,保持未扭曲状态调整
两个shader的核心代码:
Unlit/CurvedUnlit 为扭曲模型上的Unlitshader,需要进行鱼眼扭曲的对象都要使用这个shader
(如果场景扭曲了,有部分对象没有进行扭曲,会造成在远处的时候浮起物体的问题)
CurvedCode.cginc 为实现扭曲的shader核心代码
Shader "Unlit/CurvedUnlit"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "CurvedCode.cginc"
ENDCG
}
}
}
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 color : TEXCOORD2;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _CurveStrength;
v2f vert(appdata v)
{
v2f o;
float _Horizon = 100.0f;
float _FadeDist = 50.0f;
o.vertex = UnityObjectToClipPos(v.vertex);
float dist = UNITY_Z_0_FAR_FROM_CLIPSPACE(o.vertex.z);
o.vertex.y -= _CurveStrength * dist * dist * _ProjectionParams.x;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color;
UNITY_TRANSFER_FOG(o, o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv) * i.color;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
“CurvedCode.cginc”
所做的工作大致是:
1.计算模型店到摄像机平面的距离
2.根据是摄像机距离进行下坠
3.把uv和对应的贴图点输出到下坠点后的点上