A闪的 BLOG 技术与人文
年前偶然接触Love2D这个2D引擎,研究了一周,后来一直放下。无论从工具支持,还是开发方法上,都显得很别扭。所以一直以来都当它一个玩具。前几天偶然想到,其实Love2D用来做shader的算法试验工具还是非常不错的。因为使用lua语言,也相对简单许多,只需要关心shader的代码即可,其他的都无需关心,因为也不用它来完成游戏开发。
GPU计算中shader非常重要,这里就不再增加篇幅说明,这次来试验一个非常简单的图像算法,将一张彩色图片变为黑白图片。
如果你稍微接触过计算机成像技术,就可以发现,我们所有颜色大量使用RGB模式计算。这里RGB分别表示,红色,绿色,蓝色的颜色分量,一般值为0到255之间。三个颜色互相叠加能够产生16777216种颜色。但是人眼能够识别的颜色仅仅只有其中一部分,但不乏一些神级别的人物能够看出更多的差别。
好了,现在我们来说一下如何将一张彩色图片编程黑白图,或者说灰度图。
首先使用Love2D渲染一张彩色图片(我觉得自己还是很上镜的。。。。。)。最终效果如下:
想实现这个效果,你需要编写下面的Lua代码,并在Love2D种运行。
function love.load()
image = love.graphics.newImage("img.jpg")
end
function love.draw()
love.graphics.draw(image)
end
下面我们稍微加一点点代码,让图像变为灰度图。
function love.load()
image = love.graphics.newImage("img.jpg")
myShader = love.graphics.newShader[[
vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){
vec4 pixel = Texel(texture, texture_coords );
number average = (pixel.r+pixel.b+pixel.g)/3.0;
pixel.r = average;
pixel.g = average;
pixel.b = average;
return pixel;
}
]]
end
function love.draw()
love.graphics.setShader(myShader)
love.graphics.draw(image)
love.graphics.setShader()
end
运行后,效果如下:
事实上,你还可以使用另外的方法让图像的颜色深度发生变化。例如下面这样:
三张图片的颜色深度完全不同,我只修改了shader的一部分,即可改变效果。
三个图,修改的shader代码如下:
pixel.g = pixel.r;
pixel.b = pixel.r;
pixel.r = pixel.g;
pixel.b = pixel.g;
pixel.r = pixel.b;
pixel.g = pixel.b;
从上面的代码不难看出,想然一个颜色从彩色变为灰色,我们需要让RGB三个颜色值相同即可。但值设置为多少并没有强制要求。对于一张图片种所有的颜色信息来说,只要我们按照统一的方式进行变换,则他们直接的色差会保持不变。从而保留了图片种的色差信息,这种信息能够让我们分辨出照片种的不同形状与物体。
通常情况下,我们取值可以设置为RGB三个值的平均值,这个值最为适中,而其他颜色则相对会损失原有图片种的明暗分界线的信息。
简单总结一下灰度图计算公式:
灰度颜色值 =(R+G+B)/3 R = 灰度颜色值 G = 灰度颜色值 B = 灰度颜色值