Creator3D:shader6_程序员也会心动

前言

程序员也是人,当然也会心动的。而且想想明天就周六,能不心动嘛。那么程序员的心动到底是啥样的,看图

效果展示


其实和其他人没啥区别

正文

1.概述

前边一直在说片元着色器,片元着色器中的顶点,法线等等一系列可以用in导入的参数到底是从哪里来的呢,看过顶点着色器的可能会知道,他是在顶点着色器中out导出的。下面借助这个心动的效果,简单说一下顶点着色器

2.实现

Effect代码:

CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: general-vs:vert # builtin header
      frag: unlit-fs:frag
      properties: &props
        mainTexture:    { value: white }
        mainColor:      { value: [1, 1, 1, 1], editor: { type: color } }
  - name: transparent
    passes:
    - vert: unlit-vs:vert # builtin header
      frag: unlit-fs:frag 
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendSrcAlpha: src_alpha
          blendDstAlpha: one_minus_src_alpha
      rasterizerState:
        cullMode: none
      properties: *props
}%

CCProgram unlit-vs %{
  precision highp float;
  #include <input-standard>
  #include <cc-global>
  #include <cc-local-batch>

  in vec3 a_color;
  in vec2 a_texCoord;
  #if HAS_SECOND_UV
    in vec2 a_texCoord1;
  #endif

  out vec3 v_position;
  out vec3 v_normal;
  out vec3 v_tangent;
  out vec3 v_bitangent;
  out vec2 v_uv;
  out vec2 v_uv1;
  out vec3 v_color;

  vec4 vert () {
    StandardVertInput In;
    CCVertInput(In);
    mat4 matWorld, matWorldIT;
    CCGetWorldMatrixFull(matWorld, matWorldIT);
    v_position = (matWorld * In.position).xyz;
    v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);
    v_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);
    v_bitangent = cross(v_normal, v_tangent) * In.tangent.w; // note the cross order
  
    v_uv = a_texCoord;
    #if HAS_SECOND_UV
      v_uv1 = a_texCoord1;
    #endif
    v_color = a_color;
    v_position += v_normal*abs(sin(cc_time.x*10.0))/5.0*-1.0;
    return cc_matProj * (cc_matView)*vec4(v_position,1.0);
  }
}%

CCProgram unlit-fs %{
  precision highp float;
  #include <output>

  in vec2 v_uv;
  uniform sampler2D mainTexture;
  
  uniform Constant {
    vec4 mainColor;
  };
  in vec3 v_position;
  in vec3 v_normal;
  vec4 frag () {
    vec4 col=texture(mainTexture, v_uv);
    return CCFragOutput(mainColor*col);
  }
}%

2.1 代码说明

    1. 声明顶点着色器入口函数
      之前咱们一直用的是引擎默认自带的顶点着色器,现在开始咱们就开始自己按照自己的需求编辑顶点着色器
  vert: unlit-vs:vert # builtin header
  frag: unlit-fs:frag 
  • 2.顶点着色器实现

CCProgram unlit-vs %{
  precision highp float;
  #include <input-standard>
  #include <cc-global>
  #include <cc-local-batch>

  in vec3 a_color;
  in vec2 a_texCoord;
  #if HAS_SECOND_UV
    in vec2 a_texCoord1;
  #endif

  //out 声明可以在外部(片元着色器)引入的参数
  out vec3 v_position;
  out vec3 v_normal;
  out vec3 v_tangent;
  out vec3 v_bitangent;
  out vec2 v_uv;
  out vec2 v_uv1;
  out vec3 v_color;

  vec4 vert () {
    //声明StandardVertInput类型的参数 并且对其就行赋值
    //通过看官方代码,可以法线StandardVertInput包含了三个参数
    //struct StandardVertInput {
    //  highp vec4 position;   顶点
    //  vec3 normal;       法线
    //  vec4 tangent;      切线
    //}
    StandardVertInput In;
    CCVertInput(In);
    //下面六行代码,是多获得的顶点,法线,切线的坐标进行了转化
    //需要注意的In里边的这三个属性所拿到的坐标是相对于模型本身的,
    //想要将模型渲染到屏幕上,需要经过三部转化
    //自身坐标(转)世界坐标(转)视图坐标

    mat4 matWorld, matWorldIT;
    CCGetWorldMatrixFull(matWorld, matWorldIT);
    v_position = (matWorld * In.position).xyz;
    v_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);
    v_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);
    v_bitangent = cross(v_normal, v_tangent) * In.tangent.w; // note the cross order
    
    
    v_uv = a_texCoord;
    #if HAS_SECOND_UV
      v_uv1 = a_texCoord1;
    #endif
    v_color = a_color;
    
    //这一行代码对模型的大小变化进行控制
    //在原顶点坐标的基础上使其延法线方向延伸
    v_position += v_normal*abs(sin(cc_time.x*10.0))/5.0*-1.0;
    
    return cc_matProj * (cc_matView)*vec4(v_position,1.0);
  }
}%

3.地址

要下班了,激动的心已经开始颤抖起来了

都不讲一下原理嘛,大侠

哈哈,其实原理就一行代码v_position += v_normalabs(sin(cc_time.x10.0))/5.0*-1.0;
心形模型在网上下载的:joy:

2D也可以做吧 哈哈

嗯嗯,可以的

眼位~~~~