» cn.Tutorial Effects - Manipulating Colors
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

cn.Tutorial Effects - Manipulating Colors

English | Italian | Spanish | Japanese

TOC: Of Effects and Shaders
Back: Pixelshader Preparations
Next: Texture Coordinates


我们现在专心研究的是像素着色的函数:

  1. float4 PS(vs2ps In): COLOR
  2. {
  3.     return 1;
  4. }

想一想,在你的场景中,网格所占据的屏幕空间中的每个像素都去执行这个函数。

float4 = 一个像素中的颜色

这个函数有一个float4作为返回的类型。PS 是这个函数的名称,这个名称可以任意制定,它只需要与本代码文件最底部technique程序块中制定的名称对应即可。

The float4 the function has to return is a vector with 4 components making up the color of one pixel. The 4 components are in this particular order:这个float4函数必须返回含有四个元素的向量作为一个像素上的颜色。这4个元素按照下面指定的顺序排列:

  • 绿
  • 透明通道

因此如果不是返回1,你返回一个float4如下:

return float4(1, 0, 0, 1);

你的quad将会完全变为红色,每一个元素值的范围是在0到1之间(不是0到255)。

Instead of returning the float4 directly as above you can also define a variable of type float4 first, do something with it and then return the variable, as such:如果不像上面的例子一样直接返回float4,你也可以定义一个float4类型的变量,做一些运算然后在返回变量,例如:

float4 col;
col = float4(1, 0, 0, 1);
col /= 2;     //short syntax for: col = col / 2
return col;

这个得到的结果是一个暗红色因为这个变量col在除以2之后包含的数值如下:

 (0.5, 0, 0, 0.5)

在float4上的数学运算(例如:除以2)同时应用于向量中的所有元素。

访问每个单独的颜色通道

你能够控制每一个独立的元素。

float4 col = float4(1, 0, 0, 1);
col.g = col.r / 2;
return col;

这段代码得到下面的结果:

 (1, 0.5, 0, 1)

使用称之为swizzling的方法,你可以获取向量中每个单独的元素。最基本的swizzles是.r, .g, .b 和 .a这四个颜色的元素,但是你可以以随意的方式组合他们例如:

 col = col.bgra;

这会对你变量的颜色元素和结果从新排序:

 (0, 0.5, 1, 1)

对于swizzling所有的组合都是被允许的,甚至像这样:
.rrgg
.rb
.abba
...你明白的吗。

现实一张材质

FileTexture (EX9.Texture)节点的 Filename引脚选着一张你喜欢的图。

为了在像素着色中输入一张材质返回它某个像素的颜色需要一行代码:

return tex2D(Samp, In.TexCd);
 这里我们直接返回tex2D(4位浮点数)函数的结果。这个函数使用一个取样器作为它的第一个参数,一个材质坐标作为它的第二个输入参数。

在编辑器中,对任意的单词上双击会标记出文本中这个单词出现的所有地方,因此通过双击取样器的变量Samp你可以看到它在文件最开始的部分被定义。一个取样器是一个构造函数,它把一个材质和一些取样状态结合。我们暂时先忽略这个部分,同样过会在来关注材质坐标。

现在我们玩一下材质的颜色通道:

float4 col = tex2D(Samp, In.TexCd);
return col.bgra;

这里我们首先对图像的颜色进行取样并制定到命名为col的变量中。不是简单的返回col我们把当前像素颜色的红色通道和蓝色通道调换之后在返回它。

float4 col = tex2D(Samp, In.TexCd);
return col.b;  //short syntax for: return float4(col.b, col.b, col.b, col.b)

或者我们也可以只看图像中的蓝色元素把它应用到4个颜色通道上。

反转材质颜色

为了反转一张材质的颜色,我们只需要反转红色/绿色/蓝色元素而透明通道不变,例如:

float4 col = tex2D(Samp, In.TexCd);
col.rgb = 1 - col.rgb;
return col;

调节材质的对比度

图像的对比度提高可以通过提高所有高于0.5颜色值同时降低所有低于0.5的颜色值。为了这样做,首先我们把值得范围减少0.5这样我们就能对两个方向做对称的扩大(以0为中心)通过和对比度参数一个简单的乘法。然后重新把值的范围提高到0到1之间。

float4 col = tex2D(Samp, In.TexCd);
col.rgb -= 0.5;
col.rgb *= Contrast;
col.rgb += 0.5;
return col;

保存这段代码会出现错误提示:

 未申明'Contrast'标识符

因为我们还没有定义它。因此只要在你像素着色代码顶部写入:

 float Contrast = 1;

定义一个名叫Contrast变量然后设置其初始值为1。保存。注意这个结果会在你的effect节点上自动的生成一个名叫Contrast的引脚。改变引脚的值,就可以改变图像的对比度了。

转换成灰度图

正如 the internet 告诉我们有一个简单的表现公式把一个颜色转化为相应的灰度值,同时不损害3个颜色通都的亮度,这个想法是把30%的红色值、59%的绿色值和11%蓝色值相加。这个可以用两种方法实现:

float4 col = tex2D(Samp, In.TexCd);
col.rgb = col.r * 0.3 + col.g * 0.59 + col.b * 0.11;
return col;

跟好的方法是在两个向量之间使用 dot product :

const float3 lumCoeff = {0.3, 0.59, 0.11};
col.rgb = dot(col.rgb, lumCoeff);

这个和上面的代码所做的是一样的事情。

从新使用函数中的代码

如果在我们的代码中我们需要不只一次把一个像素转化为对应的灰度值。不需要重新写这个代码两编,而是我们可以抽出灰度转换的代码把它变成一个单独的函数在我们想用的时候调用。因此我建立一个新的函数命名为ConvertToGray输入一个4位浮点数为参数,并返回一个四位浮点数:

float4 ConvertToGray(float4 col)
{
    const float4 lumcoeff = {0.3, 0.59, 0.11, 0};
    return dot(col, lumcoeff);
}

我们把这个函数用到像素着色的主函数中例如:

float4 col = tex2D(Samp, In.TexCd);
return ConvertToGray(col);

耶,现在系紧你的安全带。


Next: Texture Coordinates
Back: Pixelshader Preparations
TOC: Of Effects and Shaders

anonymous user login

Shoutbox

~3d ago

skyliner: the vcard page is assembled by personal settings + user page

~3d ago

lasal: thank you guys but this is to edit the user data, i don't find how to edit the vcard

~3d ago

CeeYaa: @lasal - haha nice - I think it's funny - you should keep it ;) to change - HOME-SETTINGS - PERSONAL SETTINGS

~3d ago

skyliner: @lasal: here?

~3d ago

lasal: who knows how to edit the vcard?

~3d ago

joreg: get started with #vl with this first part of a series of "vl for vvvv users" tutorial: https://discourse.vvvv.org/t/vl-for-vvvv-users-key-differences-1-5/15919 #vvvv

~3d ago

joreg: speak japanese? this looks like a great resource for #vvvv tipsntricks: https://qiita.com/advent-calendar/2017/vvvv