开篇
核算机图形学(Computer Graphics)是一种运用数学算法将二维或三维图形转换为核算机显示器的栅格方式的科学
本文为学习图形学进程中,运用iOS
渠道开发言语模仿图画烘托和变化的笔记
系列往期
图形学笔记-烘托
图形学笔记-改换
物体显色
天然光是由多种不同波长的光组成的,经过凸透镜等工具折射反射后,会呈现出不同波长的光,表现为不同的色彩,例如彩虹构成的七种色彩便是天然光折射呈七种不同波长的光线进入肉眼后看到的。因为不同物质会吸收不同波长的光,反射其不能吸收的光,反射的可见光就被会被作为该物体的色彩。打个比方,运用RGB
色彩系统,天然光能够认为是白色,其表明为
lightColor = RGB(1, 1, 1)
一个看起来是赤色的物体,天然光在入射到物体上时,发生了光线的吸收和反射,将这一进程的用代码能够描绘成
@implementation RedItem
- (RGBColor)absorbLight:(RGBColor)lightColor {
RGBColor itemColor = lightColor;
itemColor.green = 0;
itemColor.blue = 0;
return itemColor;
}
@end
描绘物体吸收天然光的进程并不直观,更好的方式是去核算物体反射的部分,用代码描绘就能够表明为
@implementation RedItem
- (instancetype)init {
if (self = [super init]) {
self.itemColor = RGBColor(1, 0, 0);
}
return self;
}
- (RGBColor)absorbLight:(RGBColor)lightColor {
return self.itemColor * lightColor;
}
@end
光照含义
在不考虑天然光的情况下,日常中运用的光线是随间隔衰减的,比如手电筒、手机闪光灯等,光照的含义之一在于协助人类预算间隔,间隔更远的物体必定色彩更不显着;反之如果没有合适的光照,会有过错的视觉作用
以上一篇《改换》做间隔,如下图,垂直方向上为沿着x
轴每次向上旋转30
,水平方向上为沿着y
轴每次向左旋转30
。在不考虑透视的情况下,图画和向下旋转、向右旋转相同视点也是相同的,乃至还能够被看做只是x
轴和y
轴上的缩放。因此如果能模仿
光线核算
本文谈及的点光源
和球光源
是根据模仿光照核算的描绘,并不指代其原含义(ps:命名请勿较真)
点光源
点光源是一种光线强度只和入射视点有关,当入射光线与物体面垂直(x
与y
轴坐标持平时)时,光线强度最高
由图能够看出点光源的核算非常简单,即求点光源到入射点夹角的余弦cos
即可,在给定了点光源坐标点lightPosition
和入射点坐标pixelPosition
的情况下,入射光强度核算为
RGBColor calculateColor(RGBColor color, Position lightPosition, Position pixelPosition) {
Position referencePosition = MakePosition(lightPosition.x, lightPosition.y, pixelPosition.z);
float referenceDistance = PositionDistance(referencePosition, lightPosition);
float pixelDistance = PositionDistance(pixelPosition, lightPosition);
return color * (referenceDistance / pixelDistance);
}
经过添加点光源,就能显着感受到旋转感
球光源
将光源看做是一个球体,光线不断的向外分散,光线从光源中心动身后,在不同时刻构成了以光源为中心的一个个球体,球体的外表积S=4r
看做是构成球体的光线强度的总和
以光线到光源中心的间隔生成半径为R
的球体,恣意分散两个时刻点t1
和t2
,别离构成的光线球体的强度和S1
和S2
是持平的。根据这个理论,核算像素点的光照强度时,能够换算成核算像素点到光源的间隔构成的R
的光球外表单个点的能量。为了便于核算,咱们需要引入一些变量
- 规范光强间隔
Intensity
:表明球体外表单个点光线强度为1
时的R
值,光球强度总和为4I
根据规范值,能够得到恣意像素点受到的光照强度核算
@implementation SDLLightSource
- (void)setIntensity:(CGFloat)intensity {
_intensity = intensity;
self.totalPower = 4 * M_PI * intensity * intensity;
}
- (CGFloat)lightIntensityAtPosition:(Position)position {
float distance = PositionDistance(self.position, poisition);
return self.totalPower / (4 * M_PI * distance * distance);
}
@end
经过核算公式能够看出球光源单点的光线强度随间隔平方衰减,比点光源核算量也要大,但换来了更实在的光照作用
光照色彩
有时分光源不一定规范的RGB(1, 1, 1)
的白色,但不管光源色彩是否为白色,都不影响作用
半通明照射
上面选用的例子最顶层的图画都对错通明的,现在试着把大黄脸改成60%
的通明度
看起来还能够,但实际上是不对的,上面两个图画别离和光源做了独自的光照核算后再进行像素混合核算,这个进程忽略了一个问题,如下图所示,光线穿过半通明的大黄脸后,必定会被吸收掉一部分,那么穿过大黄脸的光线色彩是什么?
读书的时分有个小游戏,给一张半通明的赤色纸片,和一张黄色的纸张,翻开手电筒让光线穿过赤色纸片照射到黄色纸片上,终究会在黄色纸片上出现橙色
由此能够假定一些规则
- 光线穿过半通明物体时,物体的通明度为
alpha
,穿透的光线比例为1-alpha
- 穿透色必定为物体不可吸收的色彩(物体反射色)
假定A
像素点是半通明像素点,B
是在A
像素点后方的像素点,能够得到
B = A * lightColor * (1 - A.alpha)
作用