900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Unity Shader 实现简单的压扁效果

Unity Shader 实现简单的压扁效果

时间:2019-07-23 06:02:51

相关推荐

Unity Shader 实现简单的压扁效果

有点累啊,一个CoverMap搞了一周多,还是太嫩了,还有好多东西等着我去学呢,今天就写个简单的东西吧——一个把模型压扁的效果,参考博客Unity Shader - 一些玩具Shader。话不多说,先上效果图:

我这版本有一个条件是需要知道模型的模型空间下的最高点和最低点的位置信息(这个还是简单,写个脚本一算就出来了,其实其他模型我也没算过——云“简单”),我这里用的是默认的Sphere就不用算了()。

思路也很简单,就是用 Range(0, 1)的_Control去控制模型的压程度,1就全压扁。每一个顶点根据_Control的值以及顶点Y坐标其在最高Y坐标与最低Y坐标的范围的比例进行不同程度的偏移,偏移范围为0~1,从而达到一个压扁效果。

以下是代码:

Shader "MyShader/Squash"{Properties{_MainTex ("Texture", 2D) = "white" {}_TopY("Model Top Y", Float) = 0 //The top Y of the GameObject in world coord_BottomY("Model Bottom Y", Float) = 0 _Control("Control Squash", Range(0, 1)) = 0 //control the level of squash}SubShader{Tags {"RenderType"="Opaque" }Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float _TopY;float _BottomY;float _Control;float GetNormalizedDist(float posY){float range = _TopY - _BottomY;float border = _TopY;float dist = abs(posY - border);float normalizedDist = saturate(dist / range);return normalizedDist;}v2f vert (appdata v){v2f o;o.uv = TRANSFORM_TEX(v.uv, _MainTex);float3 localNegativeY=float3(0, -1, 0);float normalizedDist = GetNormalizedDist(v.vertex.y);float val = max(0, _Control - normalizedDist);v.vertex.xyz += localNegativeY * val;o.vertex = UnityObjectToClipPos(v.vertex);return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv);return col;}ENDCG}}}

我这边对原文的顶点着色器代码进行了小小的优化(就改了两三行),这是原文的顶点着色器代码

v2f vert (appdata v){v2f o;o.uv = TRANSFORM_TEX(v.uv, _MainTex);//这部分代码float worldPosY = mul(unity_ObjectToWorld, v.vertex).y;float3 localNegativeY = mul(unity_WorldToObject, float4(0, -1, 0, 1)).xyz;float normalizedDist = GetNormalizedDist(worldPosY);//float val = max(0, _Control - normalizedDist);v.vertex.xyz += localNegativeY * val;o.vertex = UnityObjectToClipPos(v.vertex);return o;}

就是一点小毛病,他这里用的世界坐标进行计算,这就导致一系列问题——他的模型只能放在原点才能出来正确的效果,并且不能进行缩放以及旋转(当然,某些轴可以),如果不在原点你会发现模型使劲往一个点缩而不是压成一个平面,这就是用世界坐标导致的一系列问题。我改成了用模型左边,现在你怎么弄他都能得到正确的结果,当然旋转会改变他压向的方向。

好了,大概就这么多了,感谢你的阅读,如有错误,欢迎指正。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。