今天我們以一個(gè)2.1版最新creator材質(zhì)+熔巖Shader為例子,詳細(xì)的注解最新的cocos creator Shader結(jié)構(gòu), 希望幫助新手搞定cocos creaetor Shader。
先看一下完成的渲染流程圖,多看幾遍,我們寫的Shader代碼就是實(shí)現(xiàn)紅色環(huán)節(jié)的:

看完了么?啥也不說(shuō)了,直接上注解:
dissolve.effect (creator Shader文件), 我將文件按不同顏色分成了三個(gè)部分,
方便大家理解。
%{ // 描述開(kāi)始
// shader 細(xì)節(jié)描述開(kāi)始
techniques: [
{
// 存放渲染管道描述的數(shù)組集合
passes: [?
// pass ---> 完整的渲染流水線;
{?
vert: vs // 頂點(diǎn)Shader在 vs模塊(下面定義);
frag: fs // 著色shader 在fs模塊(下面定義)
cullMode: none
blend: true
}
]
layer: 0
}
] // 細(xì)節(jié)描述結(jié)束
// 材質(zhì)球上的面板屬性
properties: {
texture: {
type: sampler2D // 類型
value: null // 默認(rèn)值
}
nosie_tex: {
? type: sampler2D
? value: null
}
time: {
? type: number
? value: 0
}
}
%} // shader 描述結(jié)束
// 頂點(diǎn)Shader模塊開(kāi)始
%% vs {?
// 定義float的精度為高精度
precision highp float;?
// 引擎根據(jù)節(jié)點(diǎn)位置等生成的模型到透視的變換矩陣;
uniform mat4 cc_matViewProj;
// 頂點(diǎn)Shader 從渲染管道里面獲取哪些數(shù)據(jù),使用attribute來(lái)修飾;
attribute vec3 a_position; // 頂點(diǎn)坐標(biāo)
attribute lowp vec4 a_color; // 顏色;
attribute mediump vec2 a_uv0; // 紋理坐標(biāo);
// 傳遞給著色Shader; varying 來(lái)修飾;
// 頂點(diǎn)Shader 和著色Shader都要定義一次;
varying mediump vec2 v_uv0;?
varying lowp vec4 v_color;
void main () {
// 定義了一個(gè)矩陣類型變量;
mat4 mvp;?
// 模型坐標(biāo)到透視的變換矩陣, 由游戲引擎設(shè)置好。
mvp = cc_matViewProj;
// 把頂點(diǎn)紋理坐標(biāo),傳遞給著色Shader;
v_uv0 = a_uv0;
// 把頂點(diǎn)的顏色傳遞給著色Shader;
v_color = a_color;?
// 將我們模型頂點(diǎn)的坐標(biāo)變換以后, 返回給渲染通道;
gl_Position = mvp * vec4(a_position, 1);?
}
} // end 頂點(diǎn)Shader模塊結(jié)束
%% fs {?
// 定義了我們的float的精度;
precision highp float;
// CPU給我們指定的紋理對(duì)象; Sprite組件內(nèi)部代碼會(huì)設(shè)置進(jìn)來(lái);
uniform sampler2D texture;?
// 熔巖閥值[0, 1];
uniform float time;?
// 熔巖形狀的紋理;
uniform sampler2D nosie_tex;
// vert定義了,著色也要定義,而且是同名的;
varying mediump vec2 v_uv0;?
varying lowp vec4 v_color;
void main () {
vec4 color = v_color;
// texture2D: GLSL紋理采樣函數(shù), 返回一個(gè)顏色值;
float value = texture2D(nosie_tex, v_uv0).r;
// 如果顏色的r分量小于閥值,將這個(gè)著色操作丟棄;
// discard將著色操作丟棄, 實(shí)現(xiàn)空洞
if (value < time) {?
discard;?
}
color *= texture2D(texture, v_uv0); // 從原紋理里面采樣一個(gè)顏色,疊加;
// 將0.05范圍內(nèi)的邊緣設(shè)置成一個(gè)顏色;
if (value < time + 0.05) {?
// 熔巖的邊緣設(shè)置一個(gè)邊緣過(guò)度顏色
color = vec4(0.9, 0.6, 0.3, color.a);
}
// 將顏色返回給渲染管道, gl_FragColor 固定的;
gl_FragColor = color;?
}
} // 著色shader 結(jié)束
程序里面如何控制Shader里面的參數(shù)?
Step1: 獲取材質(zhì)
Step2: 使用材質(zhì)對(duì)象cc. Material的接口setProperty來(lái)修改Shader uniform變量
Step3: 更新材質(zhì)對(duì)象
上注解:
熔巖特效代碼控制dissolve_ctrl.js
cc.Class({
extends: cc.Component,
properties: {
},
onLoad() {
// 材質(zhì)對(duì)象在Sprite組件實(shí)例上,所以要獲取;
this.sp = this.getComponent(cc.Sprite);
this.theold_value = 0; // 熔巖的閥值的變化范圍[0, 1]
this.dis_speed = 1 / 5; // 熔巖5秒結(jié)束, 計(jì)算出熔巖的速度;
this.set_dissolve_threold(0);
},
start () {
},
set_dissolve_threold(value) {
// 從精靈中clone出精靈的材質(zhì)對(duì)象;
// (注意是clone, 另外一個(gè)材質(zhì)對(duì)象)
let material = this.sp.sharedMaterials[0];
// 設(shè)置材質(zhì)對(duì)象的屬性變量即 uniform 變量名字;
material.setProperty('time', this.theold_value);
// 將材質(zhì)對(duì)象設(shè)置為Sprite的材質(zhì)對(duì)象;
this.sp.setMaterial(0, material);
},
update (dt) {
// 每次update 修改閥值
// 將閥值設(shè)置到shader, 參生動(dòng)態(tài)的熔巖效果;
this.theold_value += (this.dis_speed * dt);
this.set_dissolve_threold(this.theold_value);
},
});
需要完整的熔巖特效項(xiàng)目源碼+視頻講解課程的同學(xué),可以點(diǎn)擊鏈接加群點(diǎn)擊鏈接加入群聊【cocos/unity交流群】