【Cocos Creator】最新 3D shader UV 动画实现

此前曾在 Cocos 社区分享过 3D 捕鱼达人中鱼背上波光 UV 动画的实现,今天就给大家讲解一下,这种技术细节如何用最新 Cocos Creator 2.1.2 版本的Shader 来实现。

f70863d597939a0a317d35d8c26b2cdb.png

c09dbf1ee31f8b394222e61a66575d66.png

1、什么是 UV 动画?

就是将两个纹理合成以后,不断改变一个纹理的 UV 坐标,让这个纹理的贴图位置不断改变而形成 UV 动画。比如火焰,河流,都可以采用这样的技术来实现。

2、Cocos Creator Shader 为什么要重点学习?

毫无疑问,未来的微信小游戏会越来越大,越来越精美,shader 开发也是未来的一个核心,因为它能定制精美的画面,和完成精美的特效。

3、Cocos Creator Shader 要使用哪个版本?

Cocos Creator Shader 要使用 2.1.x 版本,目前使用最新的 2.1.2 这个版本会比较好一些。Cocos Creator 2.0 以下版本都不支持材质+Shader。

4、Cocos Creator 材质和 Shader

Shader 是一种給 GPU 执行的代码,GPU 的渲染流水线,为了方便开发人员定制效果,开放出接口給程序员编写代码来控制,这种程序叫作 Shader。Shader开发语言,Cocos 采用的是 GLSL 编程语言,开发人员可以在下图顶点 Shader 和着色 Shader 来插入代码。

1fbd5b9fc10b8ae92b6cfcf7ada5d304.png

材质是一种配置文件,选择好一个 Shader(算法),并給这个 Shader 提供必要的参数,材质被关联到 Sprite, MeshRenderer 等组件里面,当游戏引擎绘制物体的时候,先读取材质,根据材质,給 GPU 配置 Shader 和 Shader 要的参数, 这样管道流水线就可以完成的绘制出来这个物体。

d67abb767b7171a0e48ebb089bb1cd87.png

53da77d5baa0dc949214bd96217c20a7.png

5、Cocos Creator 3D Shader 的模板结构详解

%{ 
  techniques: [
    {
      passes: [
        { 
          vert: vs  // 顶点shader代码模块
          frag: fs  // 着色shader代码模块
          cullMode: none
          depthTest: true
          depthWrite: true
          blend: true
        }
      ]
      layer: 0
    }
  ]
  
  properties: { // 材质上的属性变量,可以在材质属性编辑器上看到变量作可视化编辑
    diffuseTexture: {
      type: sampler2D
      value: null
    }
  }
%} 


%% vs { // 顶点shader
precision highp float;
attribute vec3 a_position; // 从渲染管道获取的顶点坐标
attribute mediump vec2 a_uv0; // 从渲染管道获取的纹理坐标;
attribute lowp vec4 a_color; // 从渲染管道获取的顶点颜色




uniform mat4 cc_matWorld;  //引擎绘制物体时设置当前物体模型到世界的变换矩阵
uniform mat4 cc_matViewProj; // 引擎绘制物体时设置世界坐标到投影坐标系的变换


varying lowp vec4 v_color; // 顶点shader传递給着色shader的顶点颜色
varying mediump vec2 v_uv0; // 顶点shader传递給着色shader的顶点纹理坐标




void main () {
  vec4 position = vec4(a_position, 1);
  v_uv0 = a_uv0;
  v_color = a_color; 
  // 将模型坐标变换到透视投影坐标,返回給渲染管道;
  gl_Position = cc_matViewProj * cc_matWorld * position; 
}
}


%% fs { // 着色shader
precision highp float;
uniform sampler2D diffuseTexture; // 用户指定的模型贴图
varying lowp vec4 v_color; // 顶点shader传递过来的颜色
varying mediump vec2 v_uv0; // 顶点shader传递过来的纹理坐标


void main () {
  // 根据纹理坐标获取颜色
  vec4 col = texture2D(diffuseTexture, v_uv0);
  gl_FragColor = col; // 将着色返回給渲染管道
}
}

6、uv 动画 shader 的实现

%{ 
  techniques: [
    {
      passes: [
        { 
          vert: vs  
          frag: fs
          cullMode: none
          depthTest: true
          depthWrite: true
          blend: true
        }
      ]
      layer: 0
    }
  ]
  
  properties: {
    diffuseTexture: {
      type: sampler2D
      value: null
    }
  // sub_tex, 存放第二个纹理
  sub_tex: {
    type: sampler2D
      value: null
  }
  // 程序设置給shader当前运行时间;
  run_time: {
    type: number
    value: 0
  }
  }
%} 


%% vs { 
precision highp float;
attribute vec3 a_position; 
attribute mediump vec2 a_uv0; 
attribute lowp vec4 a_color;




uniform mat4 cc_matWorld; 
uniform mat4 cc_matViewProj;


varying lowp vec4 v_color; 
varying mediump vec2 v_uv0;




void main () {
  vec4 position = vec4(a_position, 1);
  v_uv0 = a_uv0;
  v_color = a_color; 
  gl_Position = cc_matViewProj * cc_matWorld * position;
}
}


%% fs {
precision highp float;
uniform sampler2D diffuseTexture;
uniform sampler2D sub_tex;
uniform float run_time;


varying lowp vec4 v_color;
varying mediump vec2 v_uv0;


void main () {
  // 根据时间来生成坐标偏移,时间不断变化,坐标也就变化,形成了uv动画
  vec2 offset = vec2(run_time, run_time);
  // 第二章贴图的颜色采样
  vec4 light = texture2D(sub_tex, v_uv0 + offset);
  vec4 col = texture2D(diffuseTexture, v_uv0);
  gl_FragColor = col + light;
}
}

7、程序如何控制Shader代码

cc.Class({
    extends: cc.Component,


    properties: {
        
    },


    // LIFE-CYCLE CALLBACKS:


    // onLoad () {},


    start () {
        this.now_time = 0;
        // 获取MeshRenderer组件,去找到材质对象;
        this.mr = this.getComponent(cc.MeshRenderer);
    },


    update (dt) {
        this.now_time += dt;
        
        // 获取材质对象;
        let material = this.mr.sharedMaterials[0];
        // 通过材质来修改shader里面的变量值run_time,
        // shader里面的run_time跟着改变了;
        material.setProperty('run_time', this.now_time);
        // 将材质更新到MeshRenderer的材质对象上
        this.mr.setMaterial(0, material);
    },
});

今天的分享都到这里结束了,谢谢大家!UV shader 动画的视频详细讲解,和项目工程,可以加作者 Blake 的 QQ 一起学习,QQ:937624748。

C姐:需要注意的是,Cocos Creator 2.1 阶段的材质系统仍然是处于实验阶段,将来正式推出后还会有一轮调整,到时这些 Effect 的语法和 API 需要重新适配才行。

创意小游戏橙皮书发布

用 Cocos Creator 快速制作打地鼠游戏

1周开发,7留35%,小游戏《成语消消对战》团队专访

Cocos Service 全面解析

我的小游戏开发之路|腾讯TGideas周桂华

创意小游戏《荒野日记》Cocos专访:游戏如何讲故事?

5G 云游戏亮相 Chinajoy,大作一键秒玩

Cocos Creator 接入微信小游戏引擎插件指引

【报名通道】全球游戏开发者大会即将来袭

Cocos海外开发者专访:遗憾的是没早点开始做游戏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值