GLSL教程 第5章:光照和材质

news2024/9/28 15:20:15

目录

5.1 光照模型基础

5.2 Phong光照模型

5.3 Blinn-Phong光照模型

5.4 Cook-Torrance光照模型

5.5 Lambert光照模型

5.6 材质属性的深入讲解

小结


       光照和材质是计算机图形学中至关重要的元素,它们共同决定了渲染图像的视觉效果。光照模型用于模拟光源与物体表面之间的光交互,而材质则定义了物体表面对这些光线的响应。深入理解光照模型和材质属性对于创建逼真的3D图形至关重要。本章将介绍多种光照模型,包括Phong光照模型、Blinn-Phong光照模型、Cook-Torrance光照模型和Lambert光照模型,并对材质进行详细讲解。

5.1 光照模型基础

       光照模型用于计算场景中物体的光照效果,考虑光源的类型、物体表面的材质属性以及光源与物体之间的相对位置。以下是几种常见的光照模型:

  1. 环境光(Ambient Light)

    • 定义:环境光是均匀照射在场景中所有表面的光线,模拟环境中的背景光。它不依赖于光源的位置,通常用于为所有表面提供一个基本的光照水平。

    • 计算:环境光的强度是恒定的,通常由一个固定的环境光强度系数和光源颜色相乘得到。例如:

      vec3 ambient = ambientStrength * lightColor;
      
  2. 漫反射光(Diffuse Light)

    • 定义:漫反射光模拟光源照射到粗糙表面上的光线,光的强度取决于光线与表面法线之间的夹角。漫反射光的强度与光源到表面的角度和距离有关。

    • 计算:漫反射光的强度可以通过光线与表面法线的点积来计算,即:

      vec3 norm = normalize(Normal);
      vec3 lightDir = normalize(lightPos - FragPos);
      float diff = max(dot(norm, lightDir), 0.0);
      vec3 diffuse = diff * lightColor;
      
  3. 镜面反射光(Specular Light)

    • 定义:镜面反射光模拟光线在光滑表面上的高光反射。镜面反射光的强度取决于视角和光源之间的角度。

    • 计算:镜面反射光的强度可以通过视角与反射方向的点积来计算,通常使用一个光泽度因子来调整高光的强度。例如:

      float specularStrength = 0.5;
      vec3 viewDir = normalize(viewPos - FragPos);
      vec3 reflectDir = reflect(-lightDir, norm);
      float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
      vec3 specular = specularStrength * spec * lightColor;
      
光照模型示意图
  • 环境光:展示环境光的均匀分布对物体表面的照射。
  • 漫反射光:展示光源照射到粗糙表面时的光线散射效果。
  • 镜面反射光:展示光源在光滑表面上的高光效果和视角对高光的影响。
5.2 Phong光照模型

       Phong光照模型是计算机图形学中一种经典的光照模型,它结合了环境光、漫反射光和镜面反射光,提供了一个全面的光照解决方案。Phong模型的公式如下:

 

其中:

  • I 是最终的光照强度。
  • I_{_{a}}是环境光强度。
  • I_{b} 是漫反射光强度。
  • I{_{s}}是镜面反射光强度。
  • K{_{a}}是环境反射系数。
  • K{_{d}}​ 是漫反射反射系数。
  • K{_{s}}​ 是镜面反射系数。
  • norm 是表面法线。
  • lightDir是光源方向。
  • viewDir是视角方向。
  • reflectDir 是反射方向。
  • shininess 是材质的光泽度。
    Phong光照模型示意图

示例:Phong光照模型的GLSL代码

  • 顶点着色器代码
#version 330 core

layout(location = 0) in vec3 aPos; // 顶点位置
layout(location = 1) in vec3 aNormal; // 顶点法线

out vec3 FragPos; // 传递到片段着色器的片段位置
out vec3 Normal; // 传递到片段着色器的法线

uniform mat4 model; // 模型矩阵
uniform mat4 view;  // 视图矩阵
uniform mat4 projection; // 投影矩阵

void main() {
    FragPos = vec3(model * vec4(aPos, 1.0)); // 计算片段位置
    Normal = mat3(transpose(inverse(model))) * aNormal; // 计算变换后的法线
    gl_Position = projection * view * vec4(FragPos, 1.0); // 计算最终位置
}
  • 片段着色器代码
#version 330 core

in vec3 FragPos; // 从顶点着色器接收的片段位置
in vec3 Normal; // 从顶点着色器接收的法线

out vec4 FragColor; // 片段的最终颜色

uniform vec3 lightPos; // 光源位置
uniform vec3 viewPos; // 观察者位置
uniform vec3 lightColor; // 光源颜色
uniform vec3 objectColor; // 物体颜色

void main() {
    // 环境光
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;
    
    // 漫反射光
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;
    
    // 镜面反射光
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor;
    
    // 合成最终颜色
    vec3 result = (ambient + diffuse + specular) * objectColor;
    FragColor = vec4(result, 1.0);
}

解释

  • 顶点着色器
    • FragPos:计算片段在世界空间中的位置。
    • Normal:计算片段的法线,考虑模型的变换。
  • 片段着色器
    • ambient:环境光的贡献。
    • diffuse:漫反射光的贡献,计算光线与表面法线的夹角。
    • specular:镜面反射光的贡献,计算视角和反射方向的夹角。
    • FragColor:最终颜色的合成,包括环境光、漫反射光和镜面反射光。
5.3 Blinn-Phong光照模型

       Blinn-Phong光照模型是对Phong模型的改进,主要目的是提高计算效率。Blinn-Phong模型用半角向量(lightDir + viewDir的归一化向量)代替了Phong模型中的反射向量来计算镜面反射光,这可以减少计算复杂度,特别是在处理大量光源时。

公式

 

其中:

  • halfVec 是光线方向和视角方向的半角向量,即:
Blinn-Phong光照模型的效果图

 

示例:Blinn-Phong光照模型的GLSL代码

  • 顶点着色器代码:与Phong模型相同。

  • 片段着色器代码

#version 330 core

in vec3 FragPos; // 从顶点着色器接收的片段位置
in vec3 Normal; // 从顶点着色器接收的法线

out vec4 FragColor; // 片段的最终颜色

uniform vec3 lightPos; // 光源位置
uniform vec3 viewPos; // 观察者位置
uniform vec3 lightColor; // 光源颜色
uniform vec3 objectColor; // 物体颜色

void main() {
    // 环境光
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;
    
    // 漫反射光
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;
    
    // 镜面反射光(Blinn-Phong)
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 halfVec = normalize(lightDir + viewDir);
    float spec = pow(max(dot(norm, halfVec), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor;
    
    // 合成最终颜色
    vec3 result = (ambient + diffuse + specular) * objectColor;
    FragColor = vec4(result, 1.0);
}

解释

  • Blinn-Phong模型中,镜面反射光使用halfVec来代替reflectDir,计算更为高效。
5.4 Cook-Torrance光照模型

       Cook-Torrance光照模型是一种基于物理的光照模型,提供了更为真实的光照效果。它考虑了光线在表面上的微观粗糙度,并引入了菲涅尔反射效应。

公式

其中:

  • F 是菲涅尔反射项,计算反射的强度。
  • G 是几何遮蔽项,考虑表面粗糙度对光照的影响。

示例:Cook-Torrance光照模型的GLSL代码

#version 330 core

in vec3 FragPos; // 从顶点着色器接收的片段位置
in vec3 Normal; // 从顶点着色器接收的法线

out vec4 FragColor; // 片段的最终颜色

uniform vec3 lightPos; // 光源位置
uniform vec3 viewPos; // 观察者位置
uniform vec3 lightColor; // 光源颜色
uniform vec3 objectColor; // 物体颜色

// 菲涅尔反射项
float Fresnel(float cosTheta) {
    float f0 = 0.04; // 玻璃的菲涅尔反射
    return f0 + (1.0 - f0) * pow(1.0 - cosTheta, 5.0);
}

// 几何遮蔽项
float Geometry(float NdotH, float roughness) {
    float k = pow(roughness + 1.0, 2.0) / 8.0;
    return NdotH / (NdotH * (1.0 - k) + k);
}

void main() {
    // 环境光
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;
    
    // 漫反射光
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;
    
    // 镜面反射光(Cook-Torrance)
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 halfVec = normalize(lightDir + viewDir);
    float NdotH = max(dot(norm, halfVec), 0.0);
    float F = Fresnel(dot(viewDir, halfVec));
    float G = Geometry(NdotH, 0.5);
    vec3 specular = F * G * lightColor;
    
    // 合成最终颜色
    vec3 result = (ambient + diffuse + specular) * objectColor;
    FragColor = vec4(result, 1.0);
}

解释

  • Cook-Torrance模型更为复杂,考虑了菲涅尔反射效应和几何遮蔽,适用于需要高度真实感的渲染。
5.5 Lambert光照模型

       Lambert光照模型是一种简单的漫反射光照模型,基于Lambert余弦定律。它假设光线均匀地散射在表面上,使得每个点的光照强度与光线和表面法线的夹角余弦成正比。

公式

示例:Lambert光照模型的GLSL代码

#version 330 core

in vec3 FragPos; // 从顶点着色器接收的片段位置
in vec3 Normal; // 从顶点着色器接收的法线

out vec4 FragColor; // 片段的最终颜色

uniform vec3 lightPos; // 光源位置
uniform vec3 lightColor; // 光源颜色
uniform vec3 objectColor; // 物体颜色

void main() {
    // 漫反射光(Lambert)
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;
    
    // 合成最终颜色
    vec3 result = diffuse * objectColor;
    FragColor = vec4(result, 1.0);
}

解释

  • Lambert模型非常简单,只考虑漫反射光,适合需要快速计算的应用。
5.6 材质属性的深入讲解

       材质属性定义了物体表面的光照响应特性,包括环境反射、漫反射和镜面反射。以下是材质属性的详细介绍:

  1. 环境反射(Ambient Reflectance)

    • 定义:环境反射决定了材质对环境光的响应能力。通常较低的环境反射系数会使物体看起来较为暗淡。
    • 计算:环境反射的计算包括环境光强度和材质的环境反射颜色。
  2. 漫反射(Diffuse Reflectance)

    • 定义:漫反射决定了材质对漫射光的响应能力。粗糙表面的漫反射效果通常比光滑表面更为明显。
    • 计算:漫反射光的强度基于光源方向和表面法线之间的夹角。光源和表面法线的点积用于计算漫反射光的贡献。
  3. 镜面反射(Specular Reflectance)

    • 定义:镜面反射决定了材质对镜面光的响应能力。光滑的表面会产生更强的镜面反射效果。
    • 计算:镜面反射的强度基于视角和反射方向之间的夹角。光泽度控制高光的集中程度和强度。
  4. 光泽度(Shininess)

    • 定义:光泽度控制镜面反射的高光强度。高光泽度会产生更加集中和锐利的高光效果。
    • 计算:光泽度的计算通常通过指数函数来调整高光的强度,影响镜面反射的最终效果。

示例:材质属性的GLSL代码

#version 330 core

in vec3 FragPos; // 从顶点着色器接收的片段位置
in vec3 Normal; // 从顶点着色器接收的法线

out vec4 FragColor; // 片段的最终颜色

uniform vec3 lightPos; // 光源位置
uniform vec3 viewPos; // 观察者位置
uniform vec3 lightColor; // 光源颜色
uniform vec3 materialAmbient; // 材质环境反射
uniform vec3 materialDiffuse; // 材质漫反射
uniform vec3 materialSpecular; // 材质镜面反射
uniform float materialShininess; // 材质光泽度

void main() {
    // 环境光
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * materialAmbient * lightColor;
    
    // 漫反射光
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * materialDiffuse * lightColor;
    
    // 镜面反射光
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), materialShininess);
    vec3 specular = specularStrength * spec * materialSpecular * lightColor;
    
    // 合成最终颜色
    vec3 result = ambient + diffuse + specular;
    FragColor = vec4(result, 1.0);
}

解释

  • 材质属性:包括环境反射、漫反射、镜面反射和光泽度,影响物体在不同光照条件下的视觉效果。
  • 环境反射:决定物体在暗环境中的基础亮度。
  • 漫反射:影响物体在光源照射下的亮度分布。
  • 镜面反射:影响高光的强度和集中度。
  • 光泽度:控制镜面反射的锐利程度。

小结

       本章介绍了光照和材质的基本概念及其在GLSL中的实现,包括环境光、漫反射光和镜面反射光的计算方法。通过实现各种光照模型,我们可以创建更加逼真的3D场景。掌握光照和材质的编程技巧有助于提升渲染效果的真实感和视觉效果,为复杂场景的开发奠定了基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1948990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Scrapy 爬取旅游景点相关数据( 二 )

1 安装selenium 借助 selenium 可以使用浏览器来进行爬取数据,可以解决上一节遗留的翻页问题,首先介绍一下如何集成到scrapy环境中。 由于我使用的是macbook,因此以下都是使用macbook安装的过程 ( 网络上很容易找到windows安装…

git实践汇总【配置+日常使用+问题解决】

**最初配置步骤:** git config --global user.name "yournemae" git config --global user.email "yourmail" git config -l ssh-keygen -t rsa -C “xxx.xxxx.EXTcccc.com” git config --global ssh.variant ssh $ git clone git仓库路径 git…

【我的养猪日记】区块链游戏

剧情介绍 年少无知留给了故乡,谦卑有礼送给了远方,有工作的地方没家,有家的地方没工作,他乡留不下灵魂,故乡安不了肉身,从此便有了漂泊。在外漂泊数年的你每天过着,挤不完的公交地铁、交不完的房…

上传项目到GitHub

上传项目到GitHub 前期工作:创建GitHub仓库 1.使用git命令初始化文件夹 git init2.将文件夹里面所有的文件添加到本地仓库,如果想添加单个文件,将.换成文件名就好。 git add .3.给文件备注,双引号里面是文件备注的内容 git c…

架构师篇-14、大型汽车企业之OTD案例分析

本节内容摘要: 1、 通过实际案例从项目背景、战略、业务分析、技术解决方案【应用、数据、技术架构设计】 2、理清问题、识别关键业务或技术、寻求合适的方案 本章节课程交付: 业务理解和分析业务4A架构分析设计案例总结和问题讨论 本节要点&#xff…

VMware 16虚拟机 Linux 挂载U盘(exFAT)

一、环境配置 本机系统:Windows11专业版 软件为:VMware 16 虚拟机系统(镜像文件)为:乌班图 文中U盘格式为下列: exFAT USB 3.0 二、挂载前的准备 1、 首先查看Vmware 软件中的U盘配置 …

使用Apache SeaTunnel进行二次开发的实践分享

大家好,我是范佳,是Apache SeaTunnel社区的PMC member。今天给大家分享一些基于Apache SeaTunnel二次开发的内容。 这部分内容主要涉及代码层面的知识,如果大家有什么疑问,欢迎来社区找我交流! 引言 大部分数据开发工…

谷粒商城实战笔记-62-商品服务-API-品牌管理-OSS整合测试

文章目录 一,Java中上传文件到阿里云OSS1,整合阿里云OSS2,测试上传文件 二,Java中整合阿里云OSS服务指南引言准备工作1. 注册阿里云账号2. 获取Access Key3. 添加依赖 实现OSS客户端1. 初始化OSSClient2. 创建Bucket3. 上传文件4.…

Redis的五种数据类型与命令

目录 引言 一 Redis的特性 二 Redis的安装 三 Redis的优点 四 Redis的五种数据类型与命令 五 Redis的配置文件 引言 Redis是什么? Remote Dictionary Service(远程字典服务器) Redis 是一个开源的(BSD许可)的,C语言编写的,高性能的数…

Windows电脑如何启动RTSP服务实现本地摄像头数据共享

技术背景 提起Windows共享本地摄像头,好多人想到的是通过ffmepg或vlc串流到服务器,实际上,用轻量级RTSP服务更简单,本文就介绍下,如何用大牛直播SDK的Windows轻量级RTSP服务,采集摄像头,生成本…

记录使用el-form的resetFields时遇到的表单数据回显失败的问题,去除nextTick解决

首先简单介绍一下resetFields的基础作用 element-plus官网el-form介绍 本案例中实现点击每行的编辑按钮时,弹出弹窗和表单 由于设置了表单校验,如图,表单内容不符合设定的校验规则时会有提示 如果仅仅这样就会出现问题,下次打…

分布式搜索引擎ES--Elasticsearch集群

1.Elasticsearch集群的概念 分片机制:每个索引都可以被分片 索引my_doc只有一个主分片;索引shop有三个主分片;索引shop2有5个主分片;(参考前面案例) 每个主分片都包含索引的数据,由于目前是单机,所以副分片是没有的&a…

PyQt ERROR:ModuleNotFoundError: No module named ‘matplotlib‘

Solution:打开cmd输入指令下载malplotlib pip install matplotlib

【Docker】CentOS7环境下的安装

环境展示 安装 配置仓库 sudo yum install -y yum-utils # docker官方key文件下载 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 建议使用阿里云key文件下载 sudo yum-config-manager --add-repo https://mirrors.aliyun.…

KubeSphere介绍及一键安装k8s

KubeSphere介绍 官网地址:https://kubesphere.io/zh/ KubeSphere愿景是打造一个以 Kubernetes 为内核的云原生分布式操作系统,它的架构可以非常方便地使第三方应用与云原生生态组件进行即插即用(plug-and-play)的集成&#xff0…

【Android】数据存储方案——文件存储、SharedPreferences、SQLite数据库用法总结

文章目录 文件存储存储到文件读取文件 SharedPreferences存储存储获取SharedPreferences对象Context 类的 getSharedPreferences() 方法Activity 类的 getPreferences() 方法PreferenceManager 类中的 getDefaultSharedPreferences() 方法 示例 读取记住密码的功能 SQLite数据库…

【解决方案】华普微汽车智能钥匙解决方案

一、方案概述 1.什么是被动式无钥匙进入 "被动式无钥匙进入"(Passive Keyless Entry)是一种用于车辆、建筑物或其他设施的访问控制系统。它利用无线射频技术自动判断用户是否接近,并进行身份识别以执行开锁或落锁动作&#xff0c…

【Unity2D 2022:UI】TextMeshPro组件无法显示中文

在Unity中创建了一个预制体Card,上面挂载了一些Text Mesh Pro组件用来显示卡牌信息。但是在输入文字后,发现无法显示中文: 解决方法如下: 一、导入字体文件(ttf格式)和常用字字集(txt格式&…

leetcode日记(51)不同路径Ⅱ

和上一道题(无障碍物的最短路径)很像,但事实上比上一题多了优化方法 根据上一题改的代码如下,添加了对障碍物的判定,如果有障碍物则将数组值设为0。 class Solution { public:int uniquePathsWithObstacles(vector&l…

理发店收银管理系统 python、sqlite3、pyqt5

给姐姐家店写的一个,功能比较简单,结合gpt 功能包含:次卡和充值卡,可以查剩余次数、以及查找消费记录 后期会把sqlite3转到mysql,换成springboot的一个项目 1.使用技术: Python、sqlite3、PyQt5 2.页面 …