UnityShader入门日记-翻页shader

 观前提示,写的比较啰嗦,能查到的信息都贴了一遍,主要是复习一下

效果如图

原理:

通过贝塞尔曲线世界空间位置生成一张RGBAHalf的asset文件儿,

在shader顶点着色器中采样颜色图片,获得偏移信息,再乘模型大小,

可以得到固定角度翻转的翻页效果.

相对矩阵计算的简单,但比GUI翻转的效果单一

 x的偏移值为0时(初始状态),面片的形态与曲线一致,下文中把坐标转换到模型空间中,所以曲线的位移不影响面片的形态

 

 详解:

1,需要绘制一条贝塞尔曲线,大概这个形状,因为我这个是需要从右往左翻,所以x-,y+,z-(这里是相对于坐标轴来理解的,实际上还有uv翻转的影响,比如我这个就不是x-,因为我的uv有翻转,具体细节需要自己去测试)

 三阶贝塞尔曲线(三次贝塞尔方程 参考资料【Unity3d游戏开发】游戏中的贝塞尔曲线以及其在Unity中的实现 - 马三小伙儿 - 博客园)

我用的是一个插件,类似ps的钢笔工具,每两个点之间是一个三阶贝塞尔曲线

 2,通过代码导出点的偏移位置

保存格式,RGBAHalf格式,Asset(我存的png,只取了0-1区间,大坑),

Texture2D tex  = new Texture2D(sampleValue, 1, TextureFormat.RGBAHalf, false, false);

曲线需要取样数来输出图片,我这个是取样64次在for循环中除64就可.

由于我们的位置是在世界空间中取到的,需要把它放进模型空间中,做自身的偏移,否则可能导致翻页翻着翻着书走远了

 转模型空间(不能应用全部情况)

  //采样数
  public int m_splineSamlpeValue = 64;
  //起始位置,t=0时
  Vector3 srcPos = spline.GetPoint(0);
  for (int i = 0; i < sampleValue; i++)
        {
            float sv = i / (float)sampleValue;
            //每一个采样位置归一化处理,
            Vector3 p  = (spline.GetPoint(sv) - srcPos) / length;
            Vector3 ps = new Vector3(i / (float)sampleValue, 0, 0);
            //模型空间偏移值
            Vector3 offset = p - ps;
            //根据位置写出一张图片儿
            tex.SetPixel(i, 0, new Color(offset.x, offset.y, offset.z, 1.0f));
        }

 public Vector3 GetPoint(float t)
{
 //贝塞尔曲线计算
}

 当处于任意时间t上,p与ps的偏移值如图

 3,shader绘制

        _MainTex ("Texture", 2D) = "white" {}
        //采样的颜色图
        _SrcTex("SrcTex",2D) = "white"{}
             
        //收缩程度
        _Shrink("shrink",Range(-2,1))=0.3

       //我这里翻转了uv,固定y轴,移动x,0.26是x的放大值控制倾斜程度
       float2 offsetUV = 1-v.uv-float2(v.uv.y, 0)*0.26;
       offsetUV.x += _Shrink;
       //采样颜色图片
       float3 offset = tex2Dlod(_SrcTex,float4(offsetUV.x, 0, 0, 0)).rgb;
       //200是模型参数 
       v.vertex.x +=  offset.x  * 200;
       v.vertex.y+=  offset.y*_YY  * 100;
       v.vertex.z+=offset.z/3*100;

 4,当预制体显示给材质球设置参数(自动播放)

 if (this.gameObject.activeInHierarchy == true)
 {
      pos = this.gameObject.GetComponent<Renderer>().material.GetFloat ("_Shrink");
      if (pos>-1.31)
      {   
      float finalPos = pos - Time.deltaTime * speed;
      this.gameObject.GetComponent<Renderer>().material.SetFloat("_Shrink",finalPos);
      }
      else{}


  }

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值