微网站开发 在线商城,凡科网页登录,营销型网站改版,俄罗斯外贸公司名录概述
本篇简单汇总Godot中的颜色的构造和使用#xff0c;内容包括了#xff1a;
RGB、RGBA#xff0c;HSV以及HTML16进制颜色值、颜色常量等形式构造颜色颜色的运算以及取反、插值用类型化数组、紧缩数组或PNG图片形式存储多个颜色
构造颜色
因为颜色是一种视觉元素内容包括了
RGB、RGBAHSV以及HTML16进制颜色值、颜色常量等形式构造颜色颜色的运算以及取反、插值用类型化数组、紧缩数组或PNG图片形式存储多个颜色
构造颜色
因为颜色是一种视觉元素所以用print打印颜色值到输出窗口是比较抽象的做法。
这里我采用了HFlowContainerColorRect的形式并编写一个函数show_color来动态生成ColorRect添加到HFlowContainer来显示我们构造的颜色。
其中
HFlowContainer是水平流式布局容器添加为其一级子节点的控件将按照类似HTML文档的流式布局形式也就是逐行从右向左排列占满一行自动换行。ColorRect也是一个专用于显示单个颜色的矩形控件
测试场景 颜色显示函数
# 用ColorRect显示颜色
func show_color(color:Color):var rect ColorRect.new()rect.color colorrect.custom_minimum_size Vector2(100,100)print(color) # 打印颜色值add_child(rect)使用Color类型的构造函数构造颜色
在GDScript中颜色有专门的数据类型Color。Color和int、float以及String一样属于GDScript内置的数据类型之一专用于构造和存储颜色数据并提供方法进行颜色的处理。Color类型提供了多种构造函数我们可以用构造函数形式创建Color类型的变量。
# 使用构造函数构造颜色
var c1 Color() # 默认黑色
# RGB或RGBA形式
var c2 Color(1.0,0.0,0.0) # Color(r,g,b)
var c3 Color(0.0,1.0,0.0,1.0) # Color(r,g,b,a)用show_color函数显示的效果 可以看到和Vector2或Vector3类似空的构造函数都会返回所有分量都为0的值。而Color()也返回R、G、B分量都是0但不透明度为1的颜色也就是黑色。
也就是说
Vector2()Vector2(0,0)Vector3()Vector3(0,0,0)Color()Color(0,0,0)Color(0,0,0,1)
另外你可以使用RGBA或RGB形式构造颜色
一个Color由R、G、B、A四个通道组成分别代表红色Red、绿色Green、蓝色Blue和不透明度Alpha。每个通道值都采用0.0到1.0之间的小数你也可以将其理解为百分比0%100%。在构造Color类型的时候你可以使用RGB和RGBA两种基本形式RGB形式可以看做是固定A为1.0的RGBA。
使用全局函数Color8
除了Color类型及其构造函数GDScript还提供了一个全局函数Color8
Color8(r8: int, g8: int, b8: int, a8: int 255)8的意思就是8位2^8256也就是R、G、B、A通道值的范围是从0到 255其中A的默认值为255也就是完全不透明。
其实Color8返回的也是Color类型。所以两者本质上没有什么区别。实际使用中Color类型的小数形式或者说百分比形式更直观一点。Color8更偏向原始的计算机定义。
var c1 Color8(255,0,0) # 红色
var c2 Color8(255,0,0,127) # 红色不透明度约0.5使用16进制字符串或颜色名称形式
# 字符串16进制或颜色名(不区分大小写)
var c6 Color(#0000ff) # #RRGGBB
var c7 Color(#0000ffcc) # #RRGGBBAA
var c8 Color(#cc0) # #RGB
var c9 Color(#cc0c) # #RGBA
var c10 Color(cc0c) # RGBA# 颜色名字符串形式
var c11 Color(red) # 颜色名字符串
var c12 Color(red,0.5) # 颜色名字符串 Alpha值# from_string方法
var c20 Color.from_string(blue,Color.BLUE) # (颜色名默认值)
var c21 Color.from_string(#ccc,Color.BLUE) # (颜色名默认值)16进制整数形式
# 16进制整数形式
var c24 Color.hex(0xff0000ff) # 0xRRGGBBAA,0x为前缀表示为16进制
var c25 Color.hex(0x00ff00ff) # 0xRRGGBBAA,0x为前缀表示为16进制16进制html颜色字符串形式
# 16进制html颜色字符串形式
var c26 Color.html(#ccc) # #RGB
var c27 Color.html(#ff0000) # #RRGGBB
var c28 Color.html(#ff0000ee) # #RRGGBBAA
var c29 Color.html(ff0000ee) # RRGGBBAA使用颜色常量
Color类型内部定义了很多颜色常量你可以很方便的用颜色的常量名。 你可以在《包含GODOT所有名称颜色的JSON》中获得所有颜色常量的英文名和中文名及其颜色值的信息。
# 颜色常量
var c1 Color.YELLOW # Color内置常量
var c2 Color(Color.YELLOW_GREEN,1.0) # Color内置常量使用HSV形式构造
除了以上的RGB形式16进制颜色值形式颜色常量或颜色名形式还可以使用(h,s,v)或(h,s,v,a)形式构造颜色。
var c1 Color.from_hsv(1,1,1,1)
var c2 Color.from_hsv(0,1,1,1)show_color(c1) # (1, 0, 0, 1)
show_color(c2) # (1, 0, 0, 1)关于HSV颜色模式的具体内容见下文《获取HSV分量》部分。
获取比当前颜色更暗或更亮的颜色
使用Color的lightened()方法可以创建比当前颜色更亮的颜色使用Color的darkened()方法则可以创建比当前颜色更暗的颜色
var c1 Color.RED # 显示颜色
show_color(c1.lightened(0.8))
show_color(c1.lightened(0.6))
show_color(c1.lightened(0.4))
show_color(c1.lightened(0.2))
show_color(c1) # 原始颜色
show_color(c1.darkened(0.2))
show_color(c1.darkened(0.4))
show_color(c1.darkened(0.6))
show_color(c1.darkened(0.8))获取颜色的分量
你可以通过以下形式获取一个Color的分量
r,g,b,a获取其小数形式的分量r8,g8,b8,a8获取其8位形式的分量下标[0],[1],[2],[3]形式获取r,g,b,a分量h,s,v获取HSV模式的分量
var c1 Color(red) # 显示颜色
show_color(c1) # (1, 0, 0, 1)# 小数形式
print(c1.r) # 1
print(c1.g) # 0
print(c1.b) # 0
print(c1.a) # 1# 8位形式
print(c1.r8) # 255
print(c1.g8) # 0
print(c1.b8) # 0
print(c1.a8) # 255# 下标形式
print(c1[0]) # 1
print(c1[1]) # 0
print(c1[2]) # 0
print(c1[3]) # 1获取HSV分量
HSV颜色模型
HSV是另一种构造或表示颜色的模型你可以称其为色相-饱和度-明度模型即 其数学形式的表示一种是圆柱体一种是圆锥体。
H色相Hue是围绕中心轴的角度取值为0~360度GDScript中将其映射到0.0~1.0范围S饱和度Saturation是距中心轴的距离取值为0~100GDScript中将其映射到0.0~1.0范围V明度Value是中心轴的高度取值为0~100GDScript中将其映射到0.0~1.0范围
HSV模型又称HSB其中B为Brightness。
Godot中的HSV ColorPicker和ColorPickerButton使用的是下图左的取色形式 检视器面板的颜色类属性包括导出变量采用的时下图右的取色形式 可以看到两者只是将H、S、V三个参数进行了不同的组合 前者将色相H单独拎出来饱和度S和明度V进行组合 后者将明度V单独出来将色相和饱和度进行组合
在其他一些软件还可以看到“色环”形式的HSV取色器设计
其中色相H采用360度的色环形式饱和度S和明度V组合成一个正三角形且三角形顶部的顶点指向色相对应锥形模型的切面饱和度S和明度V也可以组合成正方形对应圆柱体模型的一个切面
360度色相映射0到1的方法
度数/360即可。 黄色在RGB/CMY色环中为60度60/3601/60.16666666…
var c1 Color.YELLOWprint(c1.h) # 色相 0.16666667163372
print(c1.s) # 饱和度 1
print(c1.v) # 亮度 1可以看到数值非常相近。
用HSV形式构造颜色
可以用Color类型的from_hsv()方法以(h,s,v,a)形式构造颜色。
var c1 Color.from_hsv(1,1,1,1)
var c2 Color.from_hsv(0,1,1,1)show_color(c1) # (1, 0, 0, 1)
show_color(c2) # (1, 0, 0, 1)因为0°和360°都是红色所以用00/360或1360/360都是可以的。 生成简易HSV360色相
for i in range(360.0):show_color(Color.from_hsv(i/360.0,1,1,1))颜色的比较
两个Color类型的颜色值可以使用或!进行比较判断是否相等。
var c1 Color(1.0,0,0)print(c1 Color.RED) # true
print(c1 ! Color.RED) # false判断两个颜色是否近似相等
如果你按F1搜索is_equal_approx可以看到很多内置类型都自带了一个is_equal_approx方法这些类型一般都是由几个分量组成。
而在GlobalScope中也存在一个is_equal_approx方法用于比较两个浮点数是否相近。
其他内置类型is_equal_approx方法都是在其各个分量上调用GlobalScope的is_equal_approx方法。 根据内置文档的说法is_equal_approx的精度与比较的数字本身的大小有关数字越小精度要求越高数字越大精度要求越低。 以下是我简单进行的几组测试
print(is_equal_approx(0.9,1.0)) # flase
print(is_equal_approx(0.99,1.0)) # flase
print(is_equal_approx(0.999,1.0)) # flase
print(is_equal_approx(0.9999,1.0)) # flase
print(is_equal_approx(0.99999,1.0)) # trueprint(is_equal_approx(9,10)) # flase
print(is_equal_approx(9.9,10)) # flase
print(is_equal_approx(9.99,10)) # flase
print(is_equal_approx(9.999,10)) # flase
print(is_equal_approx(9.9999,10)) # flase
print(is_equal_approx(9.99999,10)) # trueprint(is_equal_approx(9999,10000)) # flase
print(is_equal_approx(9999.9,10000)) # flase
print(is_equal_approx(9999.99,10000)) # true
print(is_equal_approx(9999.999,10000)) # trueprint(is_equal_approx(999999999,1000000000)) # true因此在使用Color类型的is_equal_approx()判定两个颜色是否近似时其判定为true的条件是非常严格的就是每个分量的差值都要0.00001才行。
var c1 Color(0,1,0,1)
var c2 Color(0,0.9,0,1)
var c3 Color(0,0.99,0,1)
var c4 Color(0,0.999,0,1)
var c5 Color(0,0.9999,0,1)
var c6 Color(0,0.99999,0,1)
var c7 Color(0,0.999999,0,1)show_color(c1)
show_color(c2)
show_color(c3)
show_color(c4)
show_color(c5)
show_color(c6)
show_color(c7)
print(c1.is_equal_approx(c2)) # false
print(c1.is_equal_approx(c3)) # false
print(c1.is_equal_approx(c4)) # false
print(c1.is_equal_approx(c5)) # false
print(c1.is_equal_approx(c6)) # false
print(c1.is_equal_approx(c7)) # true这种近乎变态的近似判断几乎没有实用意义因此不如自己编写一个函数来判断两个颜色的近似。
# 判断两个颜色是否相似精度precision可以自定义默认0.1
func is_similar_color(color1:Color,color2:Color,precision:float 0.1) - bool:var bol:boolvar color_d color1-color2 # 获得颜色的差值var color_d_arr [] # 存储转化为绝对值和特定精度的分量# 将分量转换为特定精度的小数的绝对值for i in range(4):var d_val snapped(absf(color_d[i]),precision) # 转换为与precision小数位数一致的浮点数color_d_arr.append(d_val)# 比较每个分量的绝对值是否都达到精度值的要求if color_d_arr[0] precision and \color_d_arr[1] precision and \color_d_arr[2] precision and \color_d_arr[3] precision:bol true# 或者所有有分量的差值之和小于3倍精度elif color_d_arr[0] color_d_arr[1] color_d_arr[2] color_d_arr[3] precision * 3:bol trueelse:bol falsereturn bolvar c1 Color(0,1,0,1)
var c2 Color(0,0.9,0,1)
var c3 Color(0.1,0,0,1)
var c4 Color(0.1,0.9,0,1)
var c5 Color(0.2,0.9,0,1)
var c6 Color(0.1,0.9,0.1,0.9)show_color(c1)
show_color(c2)
show_color(c3)
show_color(c4)
show_color(c5)
show_color(c6)
print(is_similar_color(c1,c2)) # true
print(is_similar_color(c1,c3)) # false
print(is_similar_color(c1,c4)) # true
print(is_similar_color(c1,c5)) # true
print(is_similar_color(c1,c6)) # true颜色的运算
颜色运算这部分可以完全类比颜色是一个Vector4虽然GDScript中没有这种数据类型但运算形式和运算性质几乎和Vector2、Vector3如出一辙。
颜色相加
var c1 Color.AQUAMARINE
var c2 Color.BLUE_VIOLET# 显示颜色
show_color(c1) # (0.498, 1, 0.8314, 1)
show_color(c2) # (0.5412, 0.1686, 0.8863, 1)
show_color(c1c2) # (1.0392, 1.1686, 1.7176, 2)可以看到一个Color值类似与一个四分量向量其加法就是各个分量值相加这里两个颜色相加的值为(1.0392, 1.1686, 1.7176, 2)超出了Color所定义的颜色值的上限(1.0,1.0,1.0,1.0)也就是白色所以最终它是以白色显示。
颜色相减
与颜色相加类似两个颜色之间也可以进行相减运算。同样是RBGA四个通道的分量相减。
var c1 Color.AQUAMARINE
var c2 Color.BLUE_VIOLET# 显示颜色
show_color(c1) # (0.498, 1, 0.8314, 1)
show_color(c2) # (0.5412, 0.1686, 0.8863, 1)
show_color(c1-c2) # (-0.0431, 0.8314, -0.0549, 0)这里因为相减后Alpha通道值为0所以颜色变为完全透明。
颜色相乘
var c1 Color.AQUAMARINE
var c2 Color.BLUE_VIOLET# 显示颜色
show_color(c1) # (0.498, 1, 0.8314, 1)
show_color(c2) # (0.5412, 0.1686, 0.8863, 1)
show_color(c1*c2) # (0.2695, 0.1686, 0.7368, 1)CanvasItem的modulate属性就是采用了颜色的乘法。其中比较特殊的就是
白色为(1.0,1.0,1.0,1.0)任何数乘以1都保持不变所以任何颜色乘以白色还是这个颜色本身。黑色为(0.0,0.0,0.0,0.0)任何数乘以0都会变成0所以任何颜色乘以黑色都会变成黑色。 颜色相除
var c1 Color.AQUAMARINE
var c2 Color.BLUE_VIOLET# 显示颜色
show_color(c1) # (0.498, 1, 0.8314, 1)
show_color(c2) # (0.5412, 0.1686, 0.8863, 1)
show_color(c1/c2) # (0.9203, 5.9302, 0.9381, 1)颜色乘以整数或浮点数
var c1 Color(0.1,0.1,0.1)show_color(c1)
show_color(c1 * 0.5) # (0.05, 0.05, 0.05, 0.5)
show_color(c1 * 1.2) # (0.12, 0.12, 0.12, 1.2)
show_color(c1 * 2) # (0.2, 0.2, 0.2, 2)
show_color(c1 * 0) # (0, 0, 0, 0)除以一个整数或浮点数类似。
颜色的混合
var yellow Color.YELLOW
var green Color.GREEN # 显示颜色
show_color(yellow) # (1, 1, 0, 1)
show_color(green) # (0, 1, 0, 1)
show_color(yellow.blend(green)) # (0, 1, 0, 1)var yellow Color(Color.YELLOW,0.5)
var green Color.GREEN # 显示颜色
show_color(yellow) # (1, 1, 0, 0.5)
show_color(green) # (0, 1, 0, 1)
show_color(yellow.blend(green)) # (0, 1, 0, 1)可以看到如果混合的第2个颜色alpha是1也就是不带透明度会用后一个颜色覆盖之前的颜色。
var yellow Color(Color.YELLOW,0.5)
var green Color(Color.GREEN,0.5)# 显示颜色
show_color(yellow)
show_color(green)
show_color(yellow.blend(green))只有当第2个颜色alpha小于1也就是带透明度才可以看到混合的效果。
获取反色
var green Color.GREEN # 显示颜色
show_color(green) # (0, 1, 0, 1)
show_color(green.inverted()) # (1, 0, 1, 1)inverted()返回反色 (1-r,1-g,1-b,a)。
获取颜色的灰度和亮度
godot4.2已经删除了Color的gray()方法但我们根据其灰度值计算原理(r g b) / 3。可以自己构造一个函数进行代替
# 返回颜色的灰度值
func get_gray(color:Color) - float:return (color.r color.g color.b)/3.0get_luminance()返回该颜色的亮度位于[0.0, 1.0]的范围内。可以用来确定颜色是亮色还是暗色。一般认为亮度小于0.5的颜色是暗色。
var green Color.GREEN # 显示颜色
show_color(green) # (0, 1, 0, 1)
print(green.get_luminance()) # 0.71520000696182
print(get_gray(green)) # 0.33333333333333颜色插值
var green Color.GREEN
var red Color.RED# 从0%到100%cha插值
for i in range(11):show_color(green.lerp(red,i * 0.1)) # 显示颜色查看输出的数据可以看到插值的整个过程
(0, 1, 0, 1)
(0.1, 0.9, 0, 1)
(0.2, 0.8, 0, 1)
(0.3, 0.7, 0, 1)
(0.4, 0.6, 0, 1)
(0.5, 0.5, 0, 1)
(0.6, 0.4, 0, 1)
(0.7, 0.3, 0, 1)
(0.8, 0.2, 0, 1)
(0.9, 0.1, 0, 1)
(1, 0, 0, 1)3.5的函数linear_interpolate4.x改名为lerp。
不同颜色表示形式之间的转化
关于RGB模式8位,16位,32位和64位色
RGB色彩就是常说的光学三原色R代表Red红色G代表Green绿色B代表Blue蓝色。自然界中肉眼所能看到的任何色彩都可以由这三种色彩混合叠加而成因此也称为加色模式。现代的电子显示器包括电视、电脑、手机和平板等大都是采用了RGB颜色标准在显示器上是通过电子枪打在屏幕的红、绿、蓝三色发光极上来产生色彩的电脑一般都能显示32位颜色约有一百万种以上的颜色。在led 领域 利用三合一点阵全彩技术 即在一个发光单元里由RGB三色晶片组成全彩像素。 随着这一技术的不断成熟led显示技术会给人们带来更加丰富真实的色彩感受。8位深2的8次方意味着有256种灰度或彩色组合16位深2的16次方能表现65536种可能的颜色组合24位深能够表现约1670万种不同的颜色。32位图像所含的信息多所以表现的图像更加细腻逼真而16位图像和8位图像由于所含的图像信息较少所以表现的图像画质不如32位的细腻。
—— photoshop RGB模式8位,16位,32位有什么不同?_百度知道 (baidu.com)
RGBA转ABGR、ARGB等
Color类型提供了几个颜色表示形式转化的的函数提供RGBA转ABGR、ARGB等格式。抱歉我对ABGR、ARGB格式的使用了解较少。这里贴出内置文档源码
var color Color(1, 0.5, 0.2)
print(color.to_abgr32()) # 输出 4281565439
print(color.to_abgr64()) # 输出 -225178692812801
print(color.to_argb32()) # 输出 4294934323
print(color.to_argb64()) # 输出 -2147470541
print(color.to_rgba32()) # 输出 4286526463
print(color.to_rgba64()) # 输出 -140736629309441RGBA转HTML16进制颜色字符串
var color Color(1, 1, 1, 0.5)
var s1 color.to_html() # 返回 7fffffff
var s2 color.to_html(false) # 返回 ffffff判断某个变量是否为Color类型
var color Color(1, 1, 1, 0.5)print(color is Color) # true
print(typeof(color) TYPE_COLOR) # true批量存储颜色
在Godot4.X中你可以用类型化数组Array[Color]形式或紧缩数组PackedColorArray来专门用于存储多个颜色。
var colors:Array[Color]for i in range(360.0):colors.append(Color.from_hsv(i/360.0,1,1,1))或者
var colors:PackedColorArrayfor i in range(360.0):colors.append(Color.from_hsv(i/360.0,1,1,1))声明存储多个颜色的导出变量
通过将导出变量类型设定为Array[Color]或PackedColorArray就可以在检视器面板设定多个颜色。
extends HFlowContainerexport var colors:PackedColorArray声明存储多个颜色的自定义资源
可以自定义Resource来存储多个颜色。
# 调色板 - 存储多个颜色
tool
class_name ColorPalette extends Resourceexport var colors:PackedColorArray你可以在检视器面板新建和编辑ColorPalette 或者用代码方式创建、编辑并保存
var p1 ColorPalette.new()
p1.colors.append(Color.RED)
p1.colors.append(Color.GREEN)
p1.colors.append(Color.YELLOW)
p1.colors.append(Color.BLUE)
ResourceSaver.save(p1,res://colors_p1.tres)用PNG图存储调色板
利用Image类型我们可以直接将颜色值存储到一张png或jpg等形式的图片上。
var img Image.create(5,1,false,Image.FORMAT_RGBA8)
img.set_pixel(0,0,Color.RED)
img.set_pixel(1,0,Color.GREEN)
img.set_pixel(2,0,Color.YELLOW)
img.set_pixel(3,0,Color.BLUE)
img.set_pixel(4,0,Color.GOLD)
img.save_png(colos1.png)输出的图片如下 我们可以重新加载这张图片然后通过get_pixel来读取其中的颜色信息。
参考资料
维基百科 - HSL和HSV色彩空间百度百科 - 三原色