最新creator 材质与shader详解

Cocos creator 2.1以后引入了3D渲染的底层,所以引入了Shader和材质系统,比如精灵,下面有一个材质, 材质又选了一个Shader;

1: 什么是Shader和材质?
Shader是一种给显卡GPU执行的程序, 是一种绘制算法,显卡的渲染流水线加载Shader代码后,就能够在绘制的时候执行Shader的代码。Cocos 有自己的一个Shader的结构,Shader的开发语言cocos使用的是GLSL编程语言。
材质是一种配置文件,选好一个Shader,并指定好这个Shader所需要的参数;

2: cocos 物体是如何绘制的?
以Sprite组件为例,它有一个材质,这个时候绘制图片的时候,就使用这个材质,通过材质渲染管道准备好算法,和参数,这样,渲染管道就绘制出来。

2: 完整的Shader渲染流程(pass)

3: cocos Shader的结构
1: 描述部分
顶点shader在哪里,着色shader在哪里?材质上的参数定义哪些,这个是描述部分。

2: 顶点Shader部分:

3: 着色Shader部分:

4: GLSL常用的概念:
GLSL变量精度级别: highp, mediump, lowp (高, 中, 低)
attribute: 渲染管道传过来的数据, 只能在顶点Shader中使用;
varying: vectex Shader, frag Shader 的传递变量
uniform: 外部程序可以来设置的变量;

如果需要完更详细的视频教程的同学,可以加群领取哦 群号:776828784

5赞

赞 大佬牛皮

战略性插眼

请问大佬,要是想用多次pass,如何让第一次pass的结果传递到第二次pass呢?我现在在做的shader只有第二次pass的结果。

再加一个pass, 到passes数组里面

主要是参考了这个教程的高斯模糊的Fragment着色器的部分,然后发现需要两次pass,于是就把效果写成了这样:

// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.  

// Note: Current format version is experiment, the format may be changed.
// The future format may not be compatible, you may need to update the script manually.

// 注意:当前版本的格式是实验性的,之后还会进行修改。
// 后续版本的格式不保证兼容当前格式,可能需要手动升级到最新版本。,
%{
  techniques: [
    {
      passes: [
        {
          vert: vsH
          frag: fsH
          cullMode: none
          blend: true
        },
        {
          vert: vsV
          frag: fsV
          cullMode: none
          blend: true
        }
      ]
      layer: 0
    }
  ]
  properties: {
    iResolution: {
      type: vec3
      value: null
    }
    iTime: {
      type: number
      value: 0
    }
    texture: {
      type: sampler2D
      value: null
    }
    alphaThreshold: {
      type: number
      value: 0.5
    }
  }
%}

%% vsH {

precision highp float;

uniform mat4 cc_matViewProj;

attribute vec3 a_position;
attribute lowp vec4 a_color;

#if USE_TEXTURE
  attribute mediump vec2 a_uv0;
  varying mediump vec2 v_uv0;
#endif

varying lowp vec4 v_color;

void main () {
  mat4 mvp;
  mvp = cc_matViewProj;

  #if USE_TEXTURE
    v_uv0 = a_uv0;
  #endif

  v_color = a_color;

  gl_Position = mvp * vec4(a_position, 1);
}

}

%% vsV {

precision highp float;

uniform mat4 cc_matViewProj;

attribute vec3 a_position;
attribute lowp vec4 a_color;

#if USE_TEXTURE
  attribute mediump vec2 a_uv0;
  varying mediump vec2 v_uv0;
#endif

varying lowp vec4 v_color;

void main () {
  mat4 mvp;
  mvp = cc_matViewProj;

  #if USE_TEXTURE
    v_uv0 = a_uv0;
  #endif

  v_color = a_color;

  gl_Position = mvp * vec4(a_position, 1);
}

}


%% fsH {

precision highp float;

// default uniforms
uniform vec3  iResolution;  // viewport resolution (in pixels)
uniform float iTime;        // shader playback time (in seconds)

// custom uniforms
uniform float intensity;

#if USE_TEXTURE
  uniform sampler2D texture;
  varying mediump vec2 v_uv0;
#endif

#include 

varying highp vec4 v_color;

vec4 blurVar() {
	//this will be our RGBA sum
  vec2 dir = vec2(1.0, 0.0);
	vec4 sum = vec4(0.0);
  float radius = 5.0;
	
	//our original texcoord for this fragment
	vec2 tc = v_uv0;
	
	//the amount to blur, i.e. how far off center to sample from 
	//1.0 -> blur by one pixel
	//2.0 -> blur by two pixels, etc.
	float blur = radius/iResolution.x; 
    
	//the direction of our blur
	//(1.0, 0.0) -> x-axis blur
	//(0.0, 1.0) -> y-axis blur
	float hstep = dir.x;
	float vstep = dir.y;
    
	//apply blurring, using a 9-tap filter with predefined gaussian weights
    
	sum += texture2D(texture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
	sum += texture2D(texture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
	sum += texture2D(texture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
	sum += texture2D(texture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
	
	sum += texture2D(texture, vec2(tc.x, tc.y)) * 0.2270270270;
	
	sum += texture2D(texture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
	sum += texture2D(texture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
	sum += texture2D(texture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
	sum += texture2D(texture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;

	//discard alpha for our simple demo, multiply by vertex color and return
	return v_color * vec4(sum.rgb, 1.0);
}

void main () {
  ALPHA_TEST(color);
  gl_FragColor = blurVar();
}

}

%% fsV {

precision highp float;

// default uniforms
uniform vec3  iResolution;  // viewport resolution (in pixels)
uniform float iTime;        // shader playback time (in seconds)

// custom uniforms
uniform float intensity;

#if USE_TEXTURE
  uniform sampler2D texture;
  varying mediump vec2 v_uv0;
#endif

#include 

varying highp vec4 v_color;

vec4 blurVar() {
	//this will be our RGBA sum
  vec2 dir = vec2(0.0, 1.0);
	vec4 sum = vec4(0.0);
  float radius = 1.0;
	
	//our original texcoord for this fragment
	vec2 tc = v_uv0;
	
	//the amount to blur, i.e. how far off center to sample from 
	//1.0 -> blur by one pixel
	//2.0 -> blur by two pixels, etc.
	float blur = radius/iResolution.y; 
    
	//the direction of our blur
	//(1.0, 0.0) -> x-axis blur
	//(0.0, 1.0) -> y-axis blur
	float hstep = dir.x;
	float vstep = dir.y;
    
	//apply blurring, using a 9-tap filter with predefined gaussian weights
    
	sum += texture2D(texture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
	sum += texture2D(texture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
	sum += texture2D(texture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
	sum += texture2D(texture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
	
	sum += texture2D(texture, vec2(tc.x, tc.y)) * 0.2270270270;
	
	sum += texture2D(texture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
	sum += texture2D(texture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
	sum += texture2D(texture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
	sum += texture2D(texture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;

	//discard alpha for our simple demo, multiply by vertex color and return
	return v_color * vec4(sum.rgb, 1.0);
}

void main () {
  ALPHA_TEST(color);
  gl_FragColor = blurVar();
}

}

是不是哪里逻辑上有点问题

大佬牛皮 插眼

插眼

博毅创为的课程

定坐标

这个看起来有点牛逼啊!!

mark

mark

mark

mark

mark!

一张图片,只有4个顶点的
顶点着色器中新加的自定义的 attribute vec2
如何传值呢?

学习了,感谢楼主分享

感谢分享

插眼