OPENGL光源(shader部分)整体实现思想

OPENGL光源(shader部分)整体实现思想_第1张图片

先附图一张,所有矩阵变换的坐标系变换结果。

所有光源代码思想:

// 每种光经过一种处理。这里举最复杂的聚光灯的例子,光源的处理主要是在fragment中,举了fragment shader的例子。但由于所有位置都是基于世界坐标的,所以顶点坐标要经过处理变换为世界坐标。(我也不知道为什么纹理不需要变成世界坐标系。。因为是自学,也没有老师问。。。。)。法向量因为是向量,所以只需要经过法线矩阵转换反缩放就好

材质结构体{ // 以下都是uniform型的,传参以接收

环境光 // 由纹理图片设置 sampler2D

漫反射光

镜面反射光

发光值 // 设置镜面反射光的光值大小

}

Uniform 材质 材质;

 

光源结构体{

视线向量 // 摄像头的方向向量

光源位置

环境光光强度 // 也就是弱化了多少的颜色

漫反射光光强度

镜面反射光光强度

光源衰减三参数 // 衰减公式三参数(float型),光源才有

内圆锥范围

外圆锥范围 // 聚光灯才有

}

Uniform 光源 光源

 

接收法向量

接收世界向量

接收纹理坐标

 

Main{

单个光源方法(); // 计算系数,然后由系数和该材质相乘得到最终渲染

// 所有颜色相加得到最终的fragment的值。

}

 

聚光灯光源方法(光源,法向量,顶点世界位置,视线向量){

// 计算光源衰减值

距离 = length(光源位置 - 顶点位置)

float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));   // 公式计算

 

// 计算聚光灯值

由视线向量和光线向量点乘得到余弦值

float epsilon = light.cutOff - light.outerCutOff;

float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);     // 公式计算

 

// 计算入射光

光源位置 - 顶点坐标(标准化)

 

// 计算环境光

纹理和环境光强结合

 

// 计算漫反射光

由入射光和法向量点乘得到。然后和漫反射光强结合,再与纹理结合

 

// 计算镜面反射光

由入射光反射得到,然后和视线向量点乘。然后和镜面反射光强结合,再和纹理结合。

 

// 处理

将三种光和衰减值和聚光灯光锥结合,即漫反射 = 漫反射*衰减值*光锥值; // 得到聚光灯的颜色

}

你可能感兴趣的:(OpenGL学习整理)