Cocos 3.x Shader入門

本文參考
Creator3D: shader10_解析【Creator3D shader】的正確姿勢(shì)(匯總1)

一五芝、Creator3D:基礎(chǔ)1_一起學(xué)shader_紅色小球

源碼見https://gitee.com/carlosyzy/Creator3D_Mesh_Basics項(xiàng)目中的Tes1示例

1.用法

新建一個(gè)material冤狡,選擇示例中的Effect


image.png

image.png

這里面Technique只有一個(gè),別的選項(xiàng)先不管志群。創(chuàng)建一個(gè)3D物體,把上面的material替換上去渡处,就能看到變成紅色施无。


image.png
2.test1.effect文件內(nèi)容
CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: general-vs:vert # builtin header
      frag: unlit-fs:frag
}%

CCProgram unlit-fs %{
  precision highp float;
  vec4 frag () {
    vec4 color=vec4(1.0,0.0,0.0,1.0);
    return color;
  }
}%

這里如果在VS CODE中打開容劳,會(huì)自動(dòng)提示安裝一下插件


image.png

name對(duì)應(yīng)的就是每一個(gè)technique名字,這里只填了一個(gè)闸度,對(duì)應(yīng)在IDE中也只有一個(gè)竭贩。

每個(gè)technique只有一個(gè)pass。有一些效果莺禁,我們需要多次渲染同一個(gè)物體才能實(shí)現(xiàn)留量,這個(gè)時(shí)候就需要多pass,大部分情況下哟冬,只需要一個(gè)pass就能搞定了楼熄。

在effect格式中的代碼中我們能看見這樣三行代碼,文檔中是這樣寫的:每個(gè) Pass 只有兩個(gè)必填參數(shù):vert 和 frag 聲明了當(dāng)前 pass 使用的 shader, 格式為 片段名:入口函數(shù)名 這個(gè)名字可以是本文件中聲明的 shader 片段名, 也可以是引擎提供的標(biāo)準(zhǔn)頭文件浩峡。其中:

  • vert 表示的是頂點(diǎn)著色器的入口函數(shù)
  • frag 表示的片元著色器的入口

在示例一中可岂,只是讓物體顯示紅色,所以只要寫片元著色器

CCProgram unlit-fs %{
  precision highp float;
  vec4 frag () {
    vec4 color=vec4(1.0,0.0,0.0,1.0);
    return color;
  }
}%

這里我改了一下effect內(nèi)容的方法名红符,如下:

      frag: unlit-fs111:frag
}%

CCProgram unlit-fs11 %{
image.png

報(bào)錯(cuò)了青柄,方法名改成一樣的,就可以了预侯。

1.precision highp float;

float類型在 shaders 中非常重要致开,
所以精度非常重要。更低的精度會(huì)有更快的渲染速度萎馅,但是會(huì)以質(zhì)量為代價(jià)双戳。
你可以選擇每一個(gè)浮點(diǎn)值的精度。
在第一行(precision highp float;)我們就是設(shè)定了所有的浮點(diǎn)值都是高精度糜芳。
但我們也可以選擇把這個(gè)值設(shè)為“低”(precision lowp float;)或者“中”(precision mediump float;)飒货。

2.vec4 frag () 函數(shù)入口

大概寫一下shader中的數(shù)據(jù)類型:float, vec2, vec3, vec4, mat2, mat3, mat4, sampler2D and samplerCube,至于具體的區(qū)別峭竣,我都列出來塘辅,大家可以百度查一下。

3.vec4 color=vec4(1.0,0.0,0.0,1.0);

定義一個(gè)顏色皆撩,其中vec4中的x,y,z,w分別代表顏色的r,g,b,a;我用的是紅色扣墩,大家可以任意設(shè)置(0-1直接的浮點(diǎn)數(shù))

二、Creator3D:基礎(chǔ)2_一起學(xué)shader_變色小球

源碼見https://gitee.com/carlosyzy/Creator3D_Mesh_Basics項(xiàng)目中的Tes2示例

CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: general-vs:vert # builtin header
      frag: unlit-fs:frag
}%

CCProgram unlit-fs %{
  precision highp float;
  #include <cc-global>
  #include <output>
  vec4 frag () {
    vec4 oldColor=vec4(abs(sin(cc_time.x)),0.2,0.2,1.0);
    return CCFragOutput(oldColor);
  }
}%
1.cc_time

官方文檔常用 shader 內(nèi)置 Uniform

image.png

2.Fragment Ouput

在之前的文章和今天這個(gè)文章的我對(duì)顏色的返回都是直接return:

return oldColor;

當(dāng)然這樣是不標(biāo)準(zhǔn)的扛吞,來看看官方的文檔Effect syntax
為對(duì)接引擎渲染管線呻惕,Creator 提供了 CCFragOutput 工具函數(shù),對(duì)所有無光照 shader滥比,都可以直接在 fs 返回時(shí)類似這樣寫:

#include <output>
vec4 frag () {
  vec4 o = vec4(0.0);
  // ... do the computation
  return CCFragOutput(o);
}

這樣中間的顏色計(jì)算就不必區(qū)分當(dāng)前渲染管線是否為 HDR 流程等亚脆。
如需包含光照計(jì)算,可結(jié)合標(biāo)準(zhǔn)著色函數(shù) CCStandardShading 一起構(gòu)成 surface shader 流程:

#include <shading-standard>
#include <output-standard>
void surf (out StandardSurface s) {
  // fill in your data here
}
vec4 frag () {
  StandardSurface s; surf(s);
  vec4 color = CCStandardShading(s);
  return CCFragOutput(color);
}

在此框架下可方便地實(shí)現(xiàn)自己的 surface 輸入盲泛,或其他 shading 算法濒持。

注意:CCFragOutput 函數(shù)一般還是不需要自己實(shí)現(xiàn)键耕,它只起到與渲染管線對(duì)接的作用,且對(duì)于這種含有光照計(jì)算的輸出弥喉,因?yàn)橛?jì)算結(jié)果已經(jīng)在 HDR 范圍郁竟,所以應(yīng)該包含 output-standard 而非 output 頭文件。

3.內(nèi)置函數(shù)

上邊用到了sin函數(shù)由境,這里順帶給大家提供一下shader的內(nèi)置函數(shù)

  • radians(degree) : 角度變弧度;
  • degrees(radian) : 弧度變角度蓖议;
  • sin(angle), cos(angle), tan(angle)
  • asin(x): arc sine, 返回弧度 [-PI/2, PI/2];
  • acos(x): arc cosine,返回弧度 [0, PI];
  • atan(y, x): arc tangent, 返回弧度 [-PI, PI];
  • atan(y/x): arc tangent, 返回弧度 [-PI/2, PI/2];
  • pow(x, y): x的y次方虏杰;
  • exp(x): 指數(shù), log(x):
  • exp2(x): 2的x次方, log2(x):
  • sqrt(x): x的根號(hào)勒虾;inversesqrt(x): x根號(hào)的倒數(shù)
  • abs(x): 絕對(duì)值
  • sign(x): 符號(hào), 1, 0 或 -1
  • floor(x): 底部取整
  • ceil(x): 頂部取整
  • fract(x): 取小數(shù)部分
  • mod(x, y): 取模纺阔, x - y*floor(x/y)
  • min(x, y): 取最小值
  • max(x, y): 取最大值
  • clamp(x, min, max): min(max(x, min), max);
  • mix(x, y, a): x, y的線性混疊, x(1-a) + y*a;
  • step(edge, x): 如 x
  • smoothstep(edge0, edge1, x): threshod smooth transition時(shí)使用修然。edge0<=edge0時(shí)為0.0笛钝, x>=edge1時(shí)為1.0
  • length(x): 向量長度
  • distance(p0, p1): 兩點(diǎn)距離, length(p0-p1);
  • dot(x, y): 點(diǎn)積愕宋,各分量分別相乘 后 相加
  • cross(x, y): 差積玻靡,x[1]y[2]-y[1]x[2], x[2]y[0] - y[2]x[0], x[0]y[1] - y[0]x[1]
  • normalize(x): 歸一化, length(x)=1;
  • faceforward(N, I, Nref): 如 dot(Nref, I)< 0則N, 否則 -N
  • reflect(I, N): I的反射方向中贝, I -2dot(N, I)N, N必須先歸一化
  • refract(I, N, eta): 折射囤捻,k=1.0-etaeta(1.0 - dot(N, I) * dot(N, I)); 如k<0.0 則0.0,否則 etaI - (etadot(N, I)+sqrt(k))*N
  • matrixCompMult(matX, matY): 矩陣相乘, 每個(gè)分量 自行相乘邻寿, 即 r[i][j] = x[i][j]*y[i][j];矩陣線性相乘蝎土,直接用 *
  • lessThan(vecX, vecY): 向量 每個(gè)分量比較 x < y
  • lessThanEqual(vecX, vecY): 向量 每個(gè)分量比較 x<=y
  • greaterThan(vecX, vecY): 向量 每個(gè)分量比較 x>y
  • greaterThanEqual(vecX, vecY): 向量 每個(gè)分量比較 x>=y
  • equal(vecX, vecY): 向量 每個(gè)分量比較 x==y
  • notEqual(vecX, vexY): 向量 每個(gè)分量比較 x!=y
  • any(bvecX): 只要有一個(gè)分量是true, 則true
  • all(bvecX): 所有分量是true绣否, 則true
  • not(bvecX): 所有分量取反
  • texture2D(sampler2D, coord): texture lookup
  • texture2D(sampler2D, coord, bias): LOD bias, mip-mapped texture
  • texture2DProj(sampler2D, coord):
  • texture2DProj(sampler2D, coord, bias):
  • texture2DLod(sampler2D, coord, lod):
  • texture2DProjLod(sampler2D, coord, lod):
  • textureCube(samplerCube, coord):
  • textureCube(samplerCube, coord, bias):
  • textureCubeLod(samplerCube, coord, lod):
三誊涯、Creator3D:基礎(chǔ)3_一起學(xué)shader_波浪小球

源碼見https://gitee.com/carlosyzy/Creator3D_Mesh_Basics項(xiàng)目中的Tes3示例

波浪小球

CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: general-vs:vert # builtin header
      frag: unlit-fs:frag
}%
//第一個(gè)shader 正常渲染
CCProgram unlit-fs %{
  precision highp float;
  #include <cc-global>
  #include <output>
  #include <cc-local-batch>
  in vec3 v_position;
  
  vec4 frag () {
    vec4 color = vec4(0.0,0.6,1.0,1.0); 
    //頂點(diǎn)坐標(biāo),法線坐標(biāo)都是基于世界坐標(biāo)系的
    if(v_position.y+sin((v_position.x+cc_time.x)*7.0)/40.0> 0.0){
        color = vec4(1.0,1.1,1.0,0.0);
    }
    return CCFragOutput(color);
  }
}%
1.in vec3 v_position

首先大家可以先了解一下in和out的蒜撮,in表示傳入暴构,out表示傳出。

在這里是將模型頂點(diǎn)的世界坐標(biāo)傳了進(jìn)來淀弹,從哪里傳進(jìn)來的呢丹壕,答案是頂點(diǎn)著色器(vert: general-vs:vert),在這里咱們沒有自定義頂點(diǎn)著色器薇溃,用的是引擎自帶的默認(rèn)的菌赖。

給大家看一下默認(rèn)頂點(diǎn)著色器的代碼:

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;

  return cc_matProj * (cc_matView * matWorld) * In.position;
}

因?yàn)楝F(xiàn)在沒有說到頂點(diǎn)著色器,所以就不做詳細(xì)的說明沐序,大家只要知道片元著色器中的in和頂點(diǎn)著色器中的out是對(duì)應(yīng)的琉用。

//初始化顏色  藍(lán)色
vec4 color = vec4(0.0,0.6,1.0,1.0); 
//頂點(diǎn)的y軸坐標(biāo)+正弦值(頂點(diǎn)的x坐標(biāo)+shader運(yùn)行時(shí)間)
//shader運(yùn)行時(shí)間保證同一坐標(biāo)正弦值是變化的堕绩,
//7.0是一個(gè)波浪波動(dòng)速度縮放值,可以手動(dòng)調(diào)整
//40 是波浪高度的縮放值邑时,因?yàn)榍虻拇笮関ec3(1.0,1.0,1.0,),sin介于-1到1直接奴紧,
if(v_position.y+sin((v_position.x+cc_time.x)*7.0)/40.0> 0.0){
    color = vec4(1.0,1.1,1.0,0.0);
    return CCFragOutput(color);
}

把上述代碼的color改成vec4(1.0,0.0,0.0,0.0),可以看到上半部分的白色變成紅色晶丘。
如果把+cc_time.x去除黍氮,波浪就不變化了

四、Creator3D:基礎(chǔ)4_一起學(xué)shader_沒有盡頭的路

沒找到源碼浅浮,效果如下


沒有盡頭的路

實(shí)際效果就是利用shader實(shí)現(xiàn)一個(gè)透明度變化的效果沫浆,變化規(guī)則是根據(jù)攝像機(jī)的距離,透明度從1到0的一個(gè)變化過程

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: general-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
      properties: *props
}%

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

  in vec2 v_uv;
  in vec3 v_position;
  uniform sampler2D mainTexture;

  uniform Constant {
    vec4 mainColor;
  };

  vec4 frag () {
    float dis=distance(cc_cameraPos.xyz,v_position);
    //隨著距離增大滚秩,透明度變小
    float apha=1.0-(dis-5.0)/50.0;;
    vec3 color=mainColor.xyz;
    return CCFragOutput(vec4(color,apha) * texture(mainTexture, v_uv));
  }
}%

核心代碼如下

 //cc_cameraPos  creator內(nèi)部提供的专执,相機(jī)的位置,注意需要導(dǎo)入#include <cc-global>
  //逐個(gè)頂點(diǎn)判斷與攝像機(jī)的距離
  float dis=distance(cc_cameraPos.xyz,v_position);
  //隨著距離增大郁油,透明度變小
  //5.0  表示從距離攝像機(jī)5.0后開始透明度變化
  //50.0表示透明度從1-0的距離為50
  //兩個(gè)參數(shù)大家都可以修改
  float apha=1.0-(dis-5.0)/50.0;;
  vec3 color=mainColor.xyz;
  return CCFragOutput(vec4(color,apha) * texture(mainTexture, v_uv));
五本股、其它示例

Creator3D_shader5_代碼如何控制effect中的屬性

Creator3D:shader6_程序員也是會(huì)心動(dòng)的

Creator3D:shader7_盡然還有雙pass這波操作

Creator3D:shader8_這種shader怎樣配標(biāo)題

Creator3D:shader9_這樣的內(nèi)發(fā)光你喜歡不

六、

Cocos Shader入門基礎(chǔ)四:Uniform與材質(zhì)參數(shù)控制

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末桐腌,一起剝皮案震驚了整個(gè)濱河市拄显,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哩掺,老刑警劉巖凿叠,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異嚼吞,居然都是意外死亡盒件,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門舱禽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炒刁,“玉大人,你說我怎么就攤上這事誊稚∠枋迹” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵里伯,是天一觀的道長城瞎。 經(jīng)常有香客問我,道長疾瓮,這世上最難降的妖魔是什么脖镀? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮狼电,結(jié)果婚禮上蜒灰,老公的妹妹穿的比我還像新娘弦蹂。我一直安慰自己,他們只是感情好强窖,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布凸椿。 她就那樣靜靜地躺著,像睡著了一般翅溺。 火紅的嫁衣襯著肌膚如雪脑漫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天未巫,我揣著相機(jī)與錄音窿撬,去河邊找鬼。 笑死叙凡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的密末。 我是一名探鬼主播握爷,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼严里!你這毒婦竟也來了新啼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤刹碾,失蹤者是張志新(化名)和其女友劉穎燥撞,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迷帜,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡物舒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了戏锹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冠胯。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖锦针,靈堂內(nèi)的尸體忽然破棺而出荠察,到底是詐尸還是另有隱情,我是刑警寧澤奈搜,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布悉盆,位于F島的核電站,受9級(jí)特大地震影響馋吗,放射性物質(zhì)發(fā)生泄漏焕盟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一耗美、第九天 我趴在偏房一處隱蔽的房頂上張望京髓。 院中可真熱鬧航缀,春花似錦、人聲如沸堰怨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽备图。三九已至灿巧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揽涮,已是汗流浹背抠藕。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒋困,地道東北人盾似。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像雪标,于是被迫代替她去往敵國和親零院。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 動(dòng)機(jī)自己使用Unity3D也有一段時(shí)間了村刨,但是很多時(shí)候是流于表面告抄,更多地是把這個(gè)引擎簡(jiǎn)單地用作腳本控制,而對(duì)更深入...
    JumboWu閱讀 2,115評(píng)論 0 24
  • 首先threejs基于webgl的嵌牺,而webgl又是OpenGL ES 的打洼。Shader其實(shí)就是一段執(zhí)行在GPU上...
    Doter閱讀 6,707評(píng)論 0 6
  • Egret的shader支持glsl語言進(jìn)行編寫,原因應(yīng)該在于webgl是基于opengl的基礎(chǔ)上進(jìn)行開發(fā)的逆粹,所以...
    一步離閱讀 2,065評(píng)論 0 1
  • Cocos 的3D捕魚達(dá)人里面有魚背上的波光(圖一)募疮,今天就給大家講解一下,這種技術(shù)細(xì)節(jié)的實(shí)現(xiàn)---》UV動(dòng)畫枯饿。 ...
    游戲開發(fā)大表哥閱讀 4,884評(píng)論 0 0
  • 轉(zhuǎn)載注明出處:點(diǎn)擊打開鏈接 Shader(著色器)是一段能夠針對(duì)3D對(duì)象進(jìn)行操作酝锅、并被GPU所執(zhí)行的程序。Shad...
    游戲開發(fā)小Y閱讀 3,382評(píng)論 0 4