NDK OpenGLES3.0 开发(九):光照基础

简介: OpenGLES 基础光照模型

作者:字节流动

来源:https://blog.csdn.net/Kennethdroid/article/details/101220947


OpenGLES 基础光照模型

OpenGLES 目前还无法模拟现实世界的复杂光照效果,为了在效果要求和实现难度之间做一个平衡,往往采用一些简化的模型来模拟光照效果。冯氏光照模型(Phong Lighting Model)便是其中常用的一个光照模型,它由三种元素光组成,分别是环境光(Ambient Lighting)、散射光(Diffuse Lighting)及镜面光(Specular Lighting)。

image.png

环境光

环境光表示从四面八方照射到物体上且各个方向都均匀的光,不依赖于光源位置,没有方向性。

要把环境光照添加到场景里,只需用光的颜色乘以一个(数值)很小常量环境因子,再乘以物体的颜色,然后使用它作为片段的颜色:

void main()
{
    float ambientStrength = 0.1f; //常量环境因子
    vec3 ambient = ambientStrength * lightColor; //环境光强度
    vec3 result = ambient * objectColor;
    color = vec4(result, 1.0f);
}

散射光

散射光表示从物体表面向各个方向均匀反射的光。散射光的强度与入射光的强度及入射角密切相关,所以当光源位置发生变化,散射光效果也会发生明显变化。

image.png

散射光最终强度 = 材质反射系数 × 散射光强度 × max(cos(入射角),0)

其中入射角表示:当前片段光源照射方向与法向量之间的夹角。

实现散射光的片段着色器脚本:

out vec3 fragPos;//当前片段坐标
out vec3 normal; //当前片段法向量
uniform vec3 lightPos;//光源位置
void main()
{
    float diffuseStrength = 0.5f; //材质反射系数
  vec3 norm = normalize(normal); // 归一化
  vec3 lightDir = normalize(lightPos - fragPos);//当前片段光源照射方向向量
    float diff = max(dot(norm, lightDir), 0.0);// dot 表示两个向量的点乘
    vec3 diffuse = diffuseStrength * diff * lightColor; //散射光最终强度
    vec3 result = diffuse * objectColor;
    color = vec4(result, 1.0f);
}

镜面光

镜面光是由光滑物体表面反射的方向比较集中的光,镜面光强度不仅依赖于入射光与法向量的夹角,也依赖于观察者的位置。

image.png

镜面光最终强度 = 材质镜面亮度因子 × 镜面光强度 × max(cos(反射光向量与视线方向向量夹角),0)

修正后的模型也可表示为:

镜面光最终强度 = 材质镜面亮度因子 × 镜面光强度 × max(cos(半向量与法向量夹角),0)

其中半向量为镜面反射光向量与视线方向向量(从片段到观察者)的半向量。

实现镜面光的片段着色器脚本:

out vec3 fragPos;//当前片段坐标
out vec3 normal; //当前片段法向量
uniform vec3 lightPos;//光源位置
void main()
{
    float specularStrength = 0.5f;
    vec3 norm = normalize(normal); // 归一化
    vec3 viewDir = normalize(viewPos - FragPos); //视线方向向量 
    vec3 reflectDir = reflect(-lightDir, norm); //镜面反射光向量
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 
    //视线方向向量与镜面反射光向量点乘的32次幂,这个32是高光的发光值(Shininess)。一个物体的发光值越高,反射光的能力越强,散射得越少,高光点越小。
    vec3 specular = specularStrength * spec * lightColor; //镜面光最终强度
    vec3 result = specular * objectColor;
    color = vec4(result, 1.0f);
}

基础光照模型实现

实现基础光照模型的顶点着色器:

#version 300 es
precision mediump float;
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec2 a_texCoord;
layout(location = 2) in vec3 a_normal;
uniform mat4 u_MVPMatrix;
uniform mat4 u_ModelMatrix;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 viewPos;
out vec2 v_texCoord;
out vec3 ambient;
out vec3 diffuse;
out vec3 specular;
void main()
{
gl_Position = u_MVPMatrix * a_position;
vec3 fragPos = vec3(u_ModelMatrix * a_position);
// Ambient
float ambientStrength = 0.1;
ambient = ambientStrength * lightColor;
// Diffuse
float diffuseStrength = 0.5;
vec3 unitNormal = normalize(vec3(u_ModelMatrix * vec4(a_normal, 1.0)));
vec3 lightDir = normalize(lightPos - fragPos);
float diff = max(dot(unitNormal, lightDir), 0.0);
diffuse = diffuseStrength * diff * lightColor;
// Specular
float specularStrength = 0.9;
vec3 viewDir = normalize(viewPos - fragPos);
vec3 reflectDir = reflect(-lightDir, unitNormal);
float spec = pow(max(dot(unitNormal, reflectDir), 0.0), 16.0);
specular = specularStrength * spec * lightColor;
v_texCoord = a_texCoord;
}

对应的片段着色器:

#version 300 es
precision mediump float;
in vec2 v_texCoord;
in vec3 ambient;
in vec3 diffuse;
in vec3 specular;
layout(location = 0) out vec4 outColor;
uniform sampler2D s_TextureMap;
void main()
{
vec4 objectColor = texture(s_TextureMap, v_texCoord);
vec3 finalColor = (ambient + diffuse + specular) * vec3(objectColor);
outColor = vec4(finalColor, 1.0);
}

效果展示

联系与交流

技术交流、获取源码可以扫码添加我的微信:Byte-Flow


「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。

阿里云社区.png

相关文章
|
3月前
|
人工智能 安全 API
最新版通义千问(Qwen3.8-Max)功能介绍
在人工智能大模型技术快速迭代的当下,通义千问推出的Qwen3.8-Max凭借突破性的技术架构与全面升级的能力,成为大模型领域的全新标杆。作为通义千问系列迄今规模最大、能力最强的旗舰模型,Qwen3.8-Max以2.4万亿总参数的体量,结合前沿稀疏混合专家(MoE)架构,在保持高效推理的同时,实现了文本理解、代码生成、多模态交互、长周期任务执行等核心能力的跨越式提升,为个人用户、开发者与企业级应用提供了前所未有的AI能力支撑。
881 1
|
4月前
|
人工智能 供应链 安全
大模型 API 接入的「三座大山」:成本、供应链与合规的工程解法
本文揭示企业接入大模型API面临的三大困境:成本失控(中转平台暗箱扣费)、供应链脆弱(号池封禁致服务中断)、合规升级(跨境数据与身份管理新规)。提出通过API网关可观测计量、Provider抽象路由、RAM+SLS+DataWorks构建身份-传输-审计三层合规体系,实现稳健可控的AI基础设施。
500 0
|
4月前
|
人工智能 运维 容灾
400 电话对接云客服深度技术拆解:中转对接与原生集成架构对比与落地选型最佳实践
在企业客服数字化落地过程中,400热线与云客服系统的打通是构建全渠道语音服务能力的核心环节。目前行业主流包含中转对接、原生集成两种技术实现模式,多数企业在落地时容易出现方案选错、话务卡顿、功能缺失、运维成本偏高、高并发承载不足等问题。 本文基于阿里云云联络中心技术架构,结合行业主流通信服务商的通用落地能力,系统化拆解400电话对接云客服的底层技术、两种对接模式的架构差异、优缺点、适配场景与落地选型标准,搭配实操FAQ与避坑要点,帮助企业技术负责人、运维、开发人员快速完成标准化技术选型与落地部署,内容适配阿里云社区收录、搜索引擎与AI知识库收录规范。
468 0
|
8月前
|
存储 人工智能 搜索推荐
智教相伴,守正前行 ——AI 发展对幼儿教育的利弊探析
人工智能技术正快速渗透幼儿教育领域,以个性化教学、资源普惠、效率提升为幼儿教育注入新动能。同时,过度依赖 AI 也带来情感陪伴缺失、创造力受限、隐私安全等风险。本文辩证分析 AI 对幼儿教育的利好与弊端,提出技术赋能需坚守教育本质、坚持人机协同,让 AI 成为幼儿健康成长的助力而非阻力。
|
9月前
|
存储 人工智能 数据可视化
2026年cms建站系统行业的未来发展趋势及分析
2026年CMS行业正迈向智能、无头与集成三大方向。通过集成AI大模型实现内容自动化,依托无头架构赋能多端发布,借助低代码平台打破数据孤岛,CMS正从建站工具升级为企业数字化基座。
397 6
|
11月前
|
内存技术
观海微电子---常用电子元器件_磁珠
磁珠是一种铁氧体材料制成的高频噪声抑制器件,等效为电阻与电感串联,具有高阻抗特性。其单位为欧姆(Ω),在低频时呈感性,反射噪声;高频时呈阻性,吸收噪声并转化为热能,常用于RF电路、高速信号线等EMI防护,区别于储能用的电感,专用于滤除高频干扰。
|
11月前
|
算法 安全 量子技术
量子来了,RSA要凉?聊聊后量子加密的未来与现实(含代码!)
量子来了,RSA要凉?聊聊后量子加密的未来与现实(含代码!)
596 11
|
11月前
|
数据采集 人工智能 算法
GEO 技术落地教育与创业:周有贵博士与张弛教授共探校企协同技术赋能新路径
近日,湖南师范大学新闻传播学院张弛教授与 GEO 技术团队负责人 —— 巴黎学院人工智能博士、法国 GGI 商学院 GEO 首席技术专家周有贵,围绕 GEO 生成式引擎优化技术落地展开深度交流,为高校技术人才培养、学生创业冷启动及中小企业 AI 获客提供协同方案,对开发者社区关注的技术下沉与场景赋能具参考价值。
|
11月前
|
存储 缓存 NoSQL
全球金融数据实时对接实战:基于WebSocket的印度、马来西亚、韩国股票API集成指南
本文详解基于WebSocket的印度、马来西亚、韩国股票API集成方案,涵盖多时区处理、协议统一、高频数据优化与合规要点,提供企业级低延迟金融数据对接实战指南,助力构建全球化交易系统。(239字)
|
存储 关系型数据库 Java
数据COOL谈第3期
本文整理自阿里巴巴大淘宝技术部双12队长朱成(锡泽),阿里巴巴业务平台双11队长徐培德(裴度),阿里巴巴数据库双11队长陈锦赋(智盛),InfoQ主编王一鹏,在数据COOL谈第3期的分享。

热门文章

最新文章