光照计算

708 阅读5分钟

光照计算

顶点着色器

业务

  1. 矩阵变换位置
  2. 计算光照公式生成逐顶点颜色
  3. 生成/变换纹理坐标

总结:用于执行自定义计算,实施新的变换,照明或者传统的固定功能所不允许的基于顶点的效果。

示例代码

attribute vec4 position;
attribute vec2 textCoordinate;

uniform mat4 rotateMatrix;

varying lowp vec2 varyTextCoord;

void main() {
    varyTextCoord = textCoordinate;
    vec4 vPos = position;
    vPos = vPos * rotateMatrix;
    gl_Position = vPos;
}

内建特殊变量

gl_VertexID
gl_InstanceID
gl_Position
gl_PointSize
gl_FrontFacing

内建uniform

struct gl_DepthRangeParameters {
    highp float near; //near z
    highp float far; //near far
    highp float diff; //far - near
}

uniform gl_DepthRangeParameters gl_DepthRange;

内建常量

const mediump int gl_MaxVertexAttribs = 16;
const mediump int gl_MaxVertexUniformVectors = 256;
const mediump int gl_MaxVertexOutputVectors = 16;
const mediump int gl_MaxVertexTexturelmageUnits = 16;
const mediump int gl_MaxCombinedTexturelmageUnits = 32;

矩阵变换

MVP(模型->视图->投影)矩阵变换

片元着色器

业务:

  1. 计算颜色
  2. 获取纹理值
  3. 往像素点中填充颜色值[纹理值/颜色值];

总结:它可以用于图片/视频/图形中每个像素的颜色填充,比如给视频添加滤镜,实际上就是将视频中每个图片的像素点颜色填充进行修改

示例代码

varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;

void main() {
    gl_FragColor = texture2D(colorMap, varyTextCoord);
}

内建特殊变量

  • gl_FragCoord
  • gl_FrontFacing
  • gl_PointCoord
  • gl_FragDepth

内建常量

  • const mediump int gl_MaxFragmentInputVectors = 15;
  • const mediump int gl_MaxTextureImageUnits = 16 ;
  • const mediump int gl_MaxFragmentUniformVectors = 224;
  • const mediump int gl_MaxDrawBuffers = 4;

多个纹理单元渲染【服务端】

attribute vec2 v_texCoord;

uniform sampler2D s_baseMap;
uniform sampler2D s_SecondMap;

void main() {
    vec4 baseColor;
    vec4 s_SecondColor;
    baseColor = texture(s_baseMap, v_texCoord) ;
    secondColor = texture(s_SecondMap, v_texCoord) ;
    gl_FragColor = baseColor * secondColor;
]

多个纹理单元渲染【客户端】

/ /客户端代码:将各个纹理对象绑定到纹理单元0和1 ,为采样器设置数值,将采集器绑定到对应的纹理单元
glActiveTexutre ( GL_TEXTUREO ) ;
glBindTeture( GL_TEXTURE_2D , baseMapTexId) ;
glUniformli (baseMapTexId, 0) ;

glActiveTexutre (GL_TEXTURE1) ;
glBindTeture (GL_TEXTURE_2D, secondMapTexId) ;
glUniformli ( secondMapTexId,1);

内建函数

常用内建函数 说明
dot : 点乘
cross : 叉乘
texture2D : 用于对纹理采样
normalize : 对一个向量规格化
clamp : 将一个向量固定在一个最小值和最大值之间
pow () 幂函数(对矢量和标量同样有效,下同)
exp(), log() 指数函数,对数函数
abs () 绝对值
sqrt() 平方根
max(), min() 最值
ceil(),floor () 取大于实参的最小整数,取小于实参的最大整数
sin(), cos(), tan() 三角函数
asin(), acos(), atan() 反三角函数
sinh(), cosh() ,tanh () 双曲正弦,双曲余弦,双曲正切(以及相应的反函数)
length() 向量长度
distance () 两个向量的距离
dot (),cross () 数乘,叉乘
matrixCompMult () 矩阵对应元素分别相乘
transpose(), determinant() , inverse () 矩阵的转置,行列式,逆
lessThan(), greaterThan() , equal () 小于,大于,等于(对实参向量对应位置的每个分量做大小比较,生成布尔向量)

光照基本概念

基础

  1. 环境光
  2. 漫反射
  3. 镜面光照

光照特性

  1. 发射光:由物体自身发光
  2. 环境光:就是在环境中充分散射的光,而且无法分辨它的方向
  3. 漫反射光:光线来自某个方向,但在物体上各个方向反射。
  4. 镜面高光:光线来自一一个特定的方向,然后在物体表面上以一个特定的方向反射出去

各种光.png

材质属性

  1. 泛射材质
  2. 漫反射材质
  3. 镜面反射材质
  4. 发射材质

光照计算

环境光计算

环境光 = 光源的环境颜色 * 物体的材质颜色

环境光的计算(亮度) = 物体的材质颜色 * 光源的环境颜色 * 亮度

发射光的计算

发射颜⾊色 = 物体的反射材质颜⾊色

光照比较

光照比较.png

漫反射光照计算

漫反射关照计算.png

光线照射到物体表面,决定物体表面光照的强度,用下图表示:

光照强度.png

关照强度是光本身强度和光线与物体表面法线夹角cos的乘积

光照有效判断标准.png

漫反射颜色 = 光源的漫反射颜色 * 物体的漫反射材质颜色 * diffuseFactor

diffuseFactor = max(0, dot(N, L))

漫反射因子diffuseFactor是光线顶点法向量点积

漫反射因子图.png

镜面光计算

镜面光计算.png

镜面反射颜色 = 光源的镜面光颜色 * 物体的镜面材质颜色 * specularFactor

specularFactor = power(max(0, dot(N, L)), shininess)

  • H : 视线向量E与光线向量L的半向量
  • dot(N,H): H, N 的点积几何意义,平方线与法线夹角的cos值
  • shiniess : 高光的反光度;

高光的反光度.png

光照计算

光照颜色 = (环境颜色 + 漫反射颜色 + 镜面反射颜色)* 衰减因子

衰减因子.png

衰减因子 = 1.0 /(距离衰减常量 + 线性衰减常量 * 距离 + 二次衰减常量 * 距离的平方)

距离衰减常量,线性衰减常量和二次衰减常量均为常量值

注意:环境光,漫反射光和镜面光的强度都会受距离的增大而衰减,只有发射光和全局环境光的强度不会受影

聚光灯因子

聚光灯夹角cos值 = power(max(0, dot(单位光源位置,单位光线向量)), 聚光灯指数);

  • 单位光线向量是从光源指向顶点的单位向量
  • 聚光灯指数,表示聚光灯的亮度程度
  • 公式解读 : 单位光源位置 * 单位光线向量 点积 的 聚光灯指数次方。

聚光灯的有过渡与无过渡处理

聚光灯的有过渡与无过渡处理.png

增加过渡计算

聚光灯因子= clamp((外环的聚光灯角度cos值 - 当前顶点的聚光灯角度cos值) / (外环的聚光灯角度cos值 - 内环聚光灯的角度的cos值), 0, 1);

增加过渡计算.png

光照计算终极公式

光照颜色 = 发射颜色 + 全局环境颜色 + (环境颜色 + 漫反射颜色 + 镜面反 射颜色) * 聚光灯效果 * 衰减因子