本帖最后由 chyx 于 2016-10-28 20:21 编辑 
@tsd1 @719220502 @⊙v⊙ @乙烯_中国 @719823597 @pacerrecap @pca006132
章节
第一节 着色器导论
在你开始前,你需要对着色器有个概念。着色器是一段在显示器显示前修改3d的对象的代码。着色器有两种,分别是顶点着色器和片元着色器。顶点着色器修改3d对象的几何尺寸,而片元着色器修改画到屏幕的像素。在原版minecraft中,着色器访问不了3d尺寸,所以你完全不用理会顶点着色器。
这是一个最简单的片元着色器:复制代码这两行复制代码是着色器的输入。"DiffuseSampler"是minecraft游戏的图案,而texCoord是我们正在编辑的像素的位置。为了获得该像素的颜色,你需要使用"texture2D"函数。他需要一个图片和一个坐标,并且他返回该图片在该坐标处的位置。
"gl_FragColor"是着色器的输出。它的值就是将要显示的颜色。
第二节 计算机如何理解颜色
现在,为了让你知道如何编辑颜色,你需要懂得计算机是如何理解颜色的。
每个屏幕上的像素由三色光组成。分别是红光、绿光和蓝光。
在着色器里,1代表完全点亮,0表示完全熄灭,0.5表示半亮半灭。
三个颜色总是按照红绿蓝的顺序排列的。(这就是RGB这个词的来源)
(1,1,1) 代表白色
(0,0,0) 代表黑色
(1,0,0) 代表红色
(0,1,0) 代表绿色
(0,0.5,0) 代表深绿色
在你继续前请确保你熟练掌握RGB。
第三节 向量
向量是一组数,glsl中的颜色是用向量表示的。对向量做乘法就是把他的各个分量分别乘起来。
例如:
(1,2,3) x (1,2,3) = (1,4,9)
你也可以用一个数来乘向量。这就是用向量的各个分量分别乘以这个数。
(1,2,3) x 4 = (4,8,12)
第四节 glsl数据类型和声明变量
glsl有许多数据类型,包括向量。
向量可以是各种不同的大小,这是创建他们的方法:
vec2(1.0,1.0)
vec3(1.0,1.0,1.0)
vec4(1.0,1.0,1.0,1.0)
通常使用vec4来表示颜色
每个分量都在0和1之间
这些数依次代表红绿蓝和透明度。
透明度是颜色透明的程度。若他是0,颜色是不可见的。若他是0.5,他是半透明的。等等。
注意:永远要在你用的所有的数后面加上小数位。glsl对待整数和浮点数是不一样的。把它们混在一起会引起BUG。
这是你在glsl中声明一个变量的方法(如果你不知道啥是变量,Google它)。
复制代码
你可以用的type包括向量:"vec2","vec3","vec4"
还有数:"float","int" (除非你知道你在干什么,不要用int)
例如:
复制代码
注意:每个操作后面都要有一个分号:";"
第五节 glsl格式
让我们回到我们最初的例子
复制代码
我们将像素点的颜色存储到变量中。
复制代码
glsl拥有这些运算
加: +
减: -
乘: *
除: /
我们用*将这颜色乘以一个系数
复制代码
如果我们只想将图中红色分量放大呢?
复制代码
你可以像这样获得 color 的各个分量
color.r
color.g
color.b
color.a
下面是你在黑白着色器中使用它的方法:
复制代码
译注 原文如此 中间的vec4 average那里似乎是float average
(notice how you can use parentheses)
你也可使用xyzw获得向量的分量
如果一个向量代表坐标 你就可以这样获得x坐标
vector.x;
你也可以用这个输出多个量 比如说 这个着色器对换红色和蓝色通道
复制代码
glsl也可以使用条件语句
复制代码
还有循环 (大括号中所有语句会执行5次)
复制代码
第六节 函数
你能够让一些代码重复使用(通常称为函数或子程序)
复制代码
接下来 你就可以任意使用它了 像这样
复制代码
这里有一些有用的程序
复制代码译注 原文如此  中间的amp那里似乎是逻辑与&&
复制代码
第七节 例子
一个简单的爆炸着色器
复制代码
原版着色器可以放在资源包里
这里有一个你能够魔改的范例着色器材质
http://pack.maloweb.com/willpackshaders.zip
未完待续。。。
我在mcforum上逛的时候看见了一个貌似不错的教程 感到有趣 于是决定尽我所能翻译它 如有任何错误请指出 谢谢
希望不会已经有人翻译过了
有glsl问题不要问我
这只是一个基础教程 会光影的大神请绕路
原文minecraftforum.net/forums/resource-pack-discussion/1255965
@tsd1 @719220502 @⊙v⊙ @乙烯_中国 @719823597 @pacerrecap @pca006132
章节
- 着色器导论
- 计算机如何理解颜色
- 向量
- glsl数据类型和声明变量
- glsl格式
- 函数
- 例子
- minecraft着色器文件系统
 
第一节 着色器导论
在你开始前,你需要对着色器有个概念。着色器是一段在显示器显示前修改3d的对象的代码。着色器有两种,分别是顶点着色器和片元着色器。顶点着色器修改3d对象的几何尺寸,而片元着色器修改画到屏幕的像素。在原版minecraft中,着色器访问不了3d尺寸,所以你完全不用理会顶点着色器。
这是一个最简单的片元着色器:
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
- void main() {
 
- gl_FragColor = texture2D(DiffuseSampler, texCoord);
 
- }
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
"gl_FragColor"是着色器的输出。它的值就是将要显示的颜色。
第二节 计算机如何理解颜色
现在,为了让你知道如何编辑颜色,你需要懂得计算机是如何理解颜色的。
每个屏幕上的像素由三色光组成。分别是红光、绿光和蓝光。
在着色器里,1代表完全点亮,0表示完全熄灭,0.5表示半亮半灭。
三个颜色总是按照红绿蓝的顺序排列的。(这就是RGB这个词的来源)
(1,1,1) 代表白色
(0,0,0) 代表黑色
(1,0,0) 代表红色
(0,1,0) 代表绿色
(0,0.5,0) 代表深绿色
在你继续前请确保你熟练掌握RGB。
第三节 向量
向量是一组数,glsl中的颜色是用向量表示的。对向量做乘法就是把他的各个分量分别乘起来。
例如:
(1,2,3) x (1,2,3) = (1,4,9)
你也可以用一个数来乘向量。这就是用向量的各个分量分别乘以这个数。
(1,2,3) x 4 = (4,8,12)
第四节 glsl数据类型和声明变量
glsl有许多数据类型,包括向量。
向量可以是各种不同的大小,这是创建他们的方法:
vec2(1.0,1.0)
vec3(1.0,1.0,1.0)
vec4(1.0,1.0,1.0,1.0)
通常使用vec4来表示颜色
每个分量都在0和1之间
这些数依次代表红绿蓝和透明度。
透明度是颜色透明的程度。若他是0,颜色是不可见的。若他是0.5,他是半透明的。等等。
注意:永远要在你用的所有的数后面加上小数位。glsl对待整数和浮点数是不一样的。把它们混在一起会引起BUG。
这是你在glsl中声明一个变量的方法(如果你不知道啥是变量,Google它)。
- [type] [name] = [value];
你可以用的type包括向量:"vec2","vec3","vec4"
还有数:"float","int" (除非你知道你在干什么,不要用int)
例如:
- vec4 myColor = vec4(1.0,1.0,1.0,1.0);
 
- float myNumber = 3.0;
注意:每个操作后面都要有一个分号:";"
第五节 glsl格式
让我们回到我们最初的例子
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
- void main() {
 
- gl_FragColor = texture2D(DiffuseSampler, texCoord);
 
- }
我们将像素点的颜色存储到变量中。
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
- void main() {
 
- vec4 color = texture2D(DiffuseSampler, texCoord);
 
- gl_FragColor = color;
 
- }
glsl拥有这些运算
加: +
减: -
乘: *
除: /
我们用*将这颜色乘以一个系数
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
- void main() {
 
- vec4 color = texture2D(DiffuseSampler, texCoord);
 
- gl_FragColor = color*1.5;
 
- }
如果我们只想将图中红色分量放大呢?
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
- void main() {
 
- vec4 color = texture2D(DiffuseSampler, texCoord);
 
- gl_FragColor = color*vec4(1.5,1.0,1.0,1.0);
 
- }
你可以像这样获得 color 的各个分量
color.r
color.g
color.b
color.a
下面是你在黑白着色器中使用它的方法:
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
- void main() {
 
- vec4 color = texture2D(DiffuseSampler, texCoord);
 
- vec4 average = (color.r+color.g+color.b)/3.0;
 
- gl_FragColor = vec4(average,average,average,1.0);
 
- }
译注 原文如此 中间的vec4 average那里似乎是float average
(notice how you can use parentheses)
你也可使用xyzw获得向量的分量
如果一个向量代表坐标 你就可以这样获得x坐标
vector.x;
你也可以用这个输出多个量 比如说 这个着色器对换红色和蓝色通道
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
- void main() {
 
- vec4 color = texture2D(DiffuseSampler, texCoord);
 
- gl_FragColor = color.bgra;
 
- }
glsl也可以使用条件语句
- if(color<3){
 
 
- }else{
 
 
- }
还有循环 (大括号中所有语句会执行5次)
- float i;
 
- for (i = 0; i < 5.0; i++){
 
 
- }
第六节 函数
你能够让一些代码重复使用(通常称为函数或子程序)
- vec4 brighten( vec4 input )
 
- {
 
-         vec4 output  =  input*1.5;
 
-         return output;
 
- }
接下来 你就可以任意使用它了 像这样
- vec4 newColor = brighten(color);
这里有一些有用的程序
- vec4 RGBtoHSL( vec4 col )
 
- {
 
-         float red   = col.r;
 
-         float green = col.g;
 
-         float blue  = col.b;
 
-         float minc  = min(min( col.r, col.g),col.B) ;
 
-         float maxc  = max(max( col.r, col.g),col.B);
 
-         float delta = maxc - minc;
 
-         float lum = (minc + maxc) * 0.5;
 
-         float sat = 0.0;
 
-         float hue = 0.0;
 
-         if (lum > 0.0 &amp;&amp; lum < 1.0) {
 
-                 float mul = (lum < 0.5)  ?  (lum)  :  (1.0-lum);
 
-                 sat = delta / (mul * 2.0);
 
-         }
 
-         vec3 masks = vec3(
 
-                 (maxc == red   &amp;&amp; maxc != green) ? 1.0 : 0.0,
 
-                 (maxc == green &amp;&amp; maxc != blue)  ? 1.0 : 0.0,
 
-                 (maxc == blue  &amp;&amp; maxc != red)   ? 1.0 : 0.0
 
-         );
 
-         vec3 adds = vec3(
 
-                           ((green - blue ) / delta),
 
-                 2.0 + ((blue  - red  ) / delta),
 
-                 4.0 + ((red   - green) / delta)
 
-         );
 
-         float deltaGtz = (delta > 0.0) ? 1.0 : 0.0;
 
-         hue += dot( adds, masks );
 
-         hue *= deltaGtz;
 
-         hue /= 6.0;
 
-         if (hue < 0.0)
 
-                 hue += 1.0;
 
-         return vec4( hue, sat, lum, col.a );
 
- }
- vec4 HSLtoRGB( vec4 col )
 
- {
 
-     const float onethird = 1.0 / 3.0;
 
-     const float twothird = 2.0 / 3.0;
 
-     const float rcpsixth = 6.0;
 
 
-     float hue = col.x;
 
-     float sat = col.y;
 
-     float lum = col.z;
 
 
-     vec3 xt = vec3(
 
-         rcpsixth * (hue - twothird),
 
-         0.0,
 
-         rcpsixth * (1.0 - hue)
 
-     );
 
 
-     if (hue < twothird) {
 
-         xt.r = 0.0;
 
-         xt.g = rcpsixth * (twothird - hue);
 
-         xt.b = rcpsixth * (hue      - onethird);
 
-     } 
 
 
-     if (hue < onethird) {
 
-         xt.r = rcpsixth * (onethird - hue);
 
-         xt.g = rcpsixth * hue;
 
-         xt.b = 0.0;
 
-     }
 
 
-     xt = min( xt, 1.0 );
 
 
-     float sat2   =  2.0 * sat;
 
-     float satinv =  1.0 - sat;
 
-     float luminv =  1.0 - lum;
 
-     float lum2m1 = (2.0 * lum) - 1.0;
 
-     vec3  ct     = (sat2 * xt) + satinv;
 
 
-     vec3 rgb;
 
-     if (lum >= 0.5)
 
-          rgb = (luminv * ct) + lum2m1;
 
-     else rgb =  lum    * ct;
 
 
-     return vec4( rgb, col.a );
 
- }
第七节 例子
一个简单的爆炸着色器
- uniform sampler2D DiffuseSampler;
 
- varying vec2 texCoord;
 
 
 
- //width of steps (higher numbers make quality worse)
 
- const float blurWidth=0.001;
 
 
- //number of steps (higher numbers cause more lag)
 
- const float blurSteps=8.0;
 
 
- //bloom brightness
 
- const float amount=1.0;
 
 
- void main() {
 
-     vec4 color=texture2D(DiffuseSampler, texCoord);
 
-     float brightness=(color.r+color.g+color.b)/3.0;
 
 
-     vec4 sum = vec4(0);
 
-     float j;
 
-     float i;
 
-     const float foo = 10.0/(   ((blurSteps*2.0)+1.0)*((blurSteps*2.0)+1.0)   );
 
 
 
-     for( i= -blurSteps ;i < blurSteps; i++){
 
-         for (j = -blurSteps; j < blurSteps; j++){
 
-             sum += texture2D(DiffuseSampler, texCoord + vec2(j, i)*blurWidth);
 
-         }
 
-     }
 
 
-     sum*=foo;
 
-     vec4 modifier = sum*sum*(0.015-(brightness*0.01));
 
-     vec4 outputColor = modifier*amount + color;
 
 
-     gl_FragColor = outputColor;
 
- }
原版着色器可以放在资源包里
这里有一个你能够魔改的范例着色器材质
http://pack.maloweb.com/willpackshaders.zip
未完待续。。。
水个贴....................
开头文字点不进去啊?
然后你在写什么……为什么要叫我来看
然后你在写什么……为什么要叫我来看
 本帖最后由 chyx 于 2016-9-28 02:07 编辑 
@tsd1 @719220502 @pca006132 @andylizi @yushijinhun @hhttll @chyx @siiftun1857 @Zero_Exact
又翻译了一大段 啊~
这个帖子可否搬至材质板块?
而且文中这一段我有一个问题
uniform sampler2D DiffuseSampler;
varying vec2 texCoord;
void main() {
vec4 color = texture2D(DiffuseSampler, texCoord);
vec4 average = (color.r+color.g+color.b)/3.0;
gl_FragColor = vec4(average,average,average,1.0);
}
这里为何用vec4?
@tsd1 @719220502 @pca006132 @andylizi @yushijinhun @hhttll @chyx @siiftun1857 @Zero_Exact
又翻译了一大段 啊~
这个帖子可否搬至材质板块?
而且文中这一段我有一个问题
uniform sampler2D DiffuseSampler;
varying vec2 texCoord;
void main() {
vec4 color = texture2D(DiffuseSampler, texCoord);
vec4 average = (color.r+color.g+color.b)/3.0;
gl_FragColor = vec4(average,average,average,1.0);
}
这里为何用vec4?
 本帖最后由 ustc_zzzz 于 2016-9-28 19:35 编辑 
这句话好像是错的= =因为对向量做内积是把它的各个分量分别乘起来并加在一起= =
楼主已经改掉了
此外我感觉
这块就是写错了= =
========
shader这种东西。。。扔进编程开发版是不是更合适= =
对向量做内积就是把他的各个分量分别乘起来。
楼主已经改掉了
此外我感觉
vec4 average = (color.r+color.g+color.b)/3.0;
这块就是写错了= =
========
shader这种东西。。。扔进编程开发版是不是更合适= =
这个有什么用处吗
。。。。。。。。
。。。。。。。。
居然有这种骚操作,我一直都不知道
这个有什么用处吗