Three.js 中的光照模型

Three.js 中的光照模型

在这里插入图片描述

Three.js 的一个伟大抽象就是统一了所有材质的光照模型, 无论 PBR 或者 Phong。都只用两个函数给全部囊括了。
就是 RE_Direct(直接反射) 和 RE_IndirectDiffuse(间接反射)。真正做到了大一统。下面以Phong为例,具体看一下如何落地。

省流版本:

// 直接反射
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

// 间接反射
vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

  vec3 outgoingLight =
  // 直接漫反射
  reflectedLight.directDiffuse +
  // 间接漫反射
  reflectedLight.indirectDiffuse +
  // 直接高光
  reflectedLight.directSpecular +
  // 间接高光
  reflectedLight.indirectSpecular;
1、一些概念
  • Incident, 入射光
  • Irradiance, 辐照度, 量化接收光源能量的多少
  • 直接光照, 是指光源直接照射到物体表面产生的光照效果
  • 间接光照, 是指光源经过其他物体反射或散射后照射到物体表面的光照效果。
2、RE_Direct

RE_Direct 计算直接光照的反射效果, 包括直接漫反射和直接高光反射。

3、RE_IndirectDiffuse

RE_IndirectDiffuse_BlinnPhong 函数用于计算间接漫反射的效果。包括间接漫反射和间接高光反射。

4、Phone 实现细节

片元着色器:

varying vec3 vViewPosition;

//
#define RE_Direct				RE_Direct_BlinnPhong
#define RE_IndirectDiffuse		RE_IndirectDiffuse_BlinnPhong

// 直接反射 + 间接反射总结果
struct ReflectedLight {
    // 直接漫反射
    vec3 directDiffuse;
    // 直接高光
    vec3 directSpecular;
    // 间接漫反射
    vec3 indirectDiffuse;
    // 间接高光
    vec3 indirectSpecular;
};

// 入射光参数
struct IncidentLight {
    vec3 color;
    vec3 direction;
    bool visible;
};

struct BlinnPhongMaterial {
    vec3 diffuseColor;
    vec3 specularColor;
    float specularShininess;
    float specularStrength;
};

void RE_Direct_BlinnPhong(
    const in IncidentLight directLight,
    const in vec3 geometryPosition,
    const in vec3 geometryNormal,
    const in vec3 geometryViewDir,
    const in vec3 geometryClearcoatNormal,
    const in BlinnPhongMaterial material,
    inout ReflectedLight reflectedLight
) {
    float dotNL = saturate( dot( geometryNormal, directLight.direction ) );
    vec3 irradiance = dotNL * directLight.color;
    reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
    reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;
}

void RE_IndirectDiffuse_BlinnPhong(
    const in vec3 irradiance,
    const in vec3 geometryPosition,
    const in vec3 geometryNormal,
    const in vec3 geometryViewDir,
    const in vec3 geometryClearcoatNormal,
    const in BlinnPhongMaterial material,
    inout ReflectedLight reflectedLight
) {
    reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}



uniform vec3 diffuse;
uniform float opacity;
uniform vec3 specular;
uniform vec3 ambientLightColor;

struct BlinnPhongMaterial {
    vec3 diffuseColor;
    vec3 specularColor;
    float specularShininess;
    float specularStrength;
};

// 方向光信息
struct DirectionalLight {
    vec3 direction;
    vec3 color;
};

uniform DirectionalLight directionalLights[ 1 ];

// 入射的方向光转为通用的入射光信息
void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {
  light.color = directionalLight.color;
  light.direction = directionalLight.direction;
  light.visible = true;
}

vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
    vec3 irradiance = ambientLightColor;
    return irradiance;
}

void main() {
  vec4 diffuseColor = vec4( diffuse, opacity );

  ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );

  vec4 sampledDiffuseColor = texture2D( map, vMapUv );
  diffuseColor *= sampledDiffuseColor;

  float specularStrength = 1.0;

  BlinnPhongMaterial material;
  material.diffuseColor = diffuseColor.rgb;
  material.specularColor = specular;
  material.specularShininess = shininess;
  material.specularStrength = specularStrength;

  vec3 geometryPosition = - vViewPosition;
  vec3 geometryNormal = normal;
  vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
  vec3 geometryClearcoatNormal = vec3( 0.0 );

  // 入射光信息
  IncidentLight directLight;

  // 方向光
  DirectionalLight directionalLight;
  directionalLight = directionalLights[ 0 ];
  getDirectionalLightInfo( directionalLight, directLight );

  // 直接反射
  RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

  // 间接反射
  vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
  RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );

   vec3 outgoingLight =
    // 直接漫反射
    reflectedLight.directDiffuse +
    // 间接漫反射
    reflectedLight.indirectDiffuse +
    // 直接高光
    reflectedLight.directSpecular +
    // 间接高光
    reflectedLight.indirectSpecular;
}

顶点着色器:

vec3 transformed = vec3( position );
vec4 mvPosition = vec4( transformed, 1.0 );
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;

vViewPosition = - mvPosition.xyz;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSF视频文件格式转换WMV格式(2024年可用)

如果大家看过一些高校教学讲解视频的话,很可能见过这样一个难得的格式,".csf ",非常漂亮 。 用暴风影音都可以打开观看,会自动下载解码。 但是一旦我们想要利用或者上传视频的时候就麻烦了,一般网站不认这…

开放式耳机哪个品牌质量最好最耐用?2024热门红榜耳机真实测评

随着人们生活质量的提高,喜爱运动的小伙伴也越来越多了,开放式蓝牙耳机的佩戴舒适度与稳定性这两个优势在很多运动场景中可以为用户带来更好的使用体验。此外,我们的音频使用、通话、游戏等应用场景在不断拓宽,蓝牙耳机的使用时间…

qt可点击的QLabel

需求——问题与思路 使用wpf实现一个可点击的超链接label相当简单(如下图),但是qt的QLabel不会响应点击事件,那就从QLabel继承一个类,然后在该类中重写mousePressEvent函数,并在该函数中对左键点击事件做响…

FPGA工程师有前途吗 ?FPGA崛起之路

全球 FPGA 市场规模犹如滚雪球般逐年扩大。 根据Gartner Group预测,2020-2026年全球FPGA市场规模从55.85亿美元增至96.9亿美元,年均复合增长率为9.6%。 众多国际知名科技企业,如赛灵思、Lattice等,纷纷加大在 FPGA 研发和应用方…

linux操作系统数据盘挂载目录home改到www

云服务器开通后安装宝塔面板,数据盘默认挂载在 /home目录,通常这个目录不是我们需要的,数据盘需要挂载更换到/www目录。 如图所示数据盘/dev/mapper/ao-home 挂载到/home目录 但是我们需要它挂载到/www目录 以下操作是将数据盘/dev/mapper/…

希尔排序的实现

引言 排序在我们生活中十分常见,无论是购物软件中的商品推荐还是名次、排名都与排序算法息息相关。希尔排序是排序中较快的一种,而希尔排序实现的基础是插入排序。 排序的实现 插入排序(以升序为例) 插入排序的原理是从第二个数…

非静压模型SWASH学习(8)——三维孤立波在锥形岛屿上的爬坡过程(Runup of solitary waves on a conical island)

三维孤立波在锥形岛屿上的爬坡过程(Runup of solitary waves on a conical island) 算例简介模型配置网格及参数设置网格与地形初始条件与边界条件数值求解方法输出设置模拟时间 波浪(孤立波)入射边界的时间序列.bnd文件模拟结果注…

基于OpenCV与Keras的停车场车位自动识别系统

本项目旨在利用计算机视觉技术和深度学习算法,实现对停车场车位状态的实时自动识别。通过摄像头监控停车场内部,系统能够高效准确地辨认车位是否被占用,为车主提供实时的空闲车位信息,同时为停车场管理者提供智能化的车位管理工具…

Python基础小知识问答系列-记录最后N个元素

1. 问题: 怎么复制变量内容? 进行可迭代的操作过程中,如何记录最后几次操作的内容? 2. 解决方式: 对于非数值类型的变量,复制变量内容时,使用"*"。 记录最后n个元素&#xff…

重大丨深中通道今通车!继港珠澳大桥后,三思再度点亮世界工程

6月30日下午3时,国家重大工程深中通道正式通车试运营,向世界再次展示中国智慧和基建实力。已承接过包括港珠澳大桥海底隧道在内2500多条隧道照明工程的上海三思电子工程有限公司,为这座超级工程提供了LED隧道照明、东西人工岛照明及显示、管理…

【力扣】赎金信

🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 给你两个字符串…

私有云统一多云管理平台主要服务内容

私有云统一多云管理平台,作为企业IT架构现代化的关键组成部分,旨在为企业提供高效、灵活、安全的云计算资源管理解决方案。这类平台通过整合和优化不同云环境(包括私有云、公有云、混合云)的管理,帮助企业打破云孤岛,实现资源的统…

【MySQL备份】Percona XtraBackup增量备份实战篇

目录 1.前言 2.准备工作 2.1.环境信息 2.2.创建备份目录 2.3.配置/etc/my.cnf文件 2.4.授予root用户BACKUP_ADMIN权限 3.增量备份 3.1.第一步:全量备份 3.2.第二步:增量备份 3.3.第三步:再次增量备份 4.准备备份 4.1.准备全量备…

秋招Java后端开发冲刺——基础篇5(String集合)

一、String String类是Java中字符串操作类,位于java.lang包下String类型对象的底层使用字符数组char[]存储字符串,由final修饰且没有提供公共的修改方法,因此String对象是不可变的。常见方法 方法名作用trim()去掉字符串首尾空字符split(分…

【面试系列】产品经理高频面试题及详细解答

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、…

我在国企当合同工的那段日子

心血来潮 25号考完了,非常不理想,果然700页的东西不是一个月能搞完的。不对,我今儿写日志是为了纪念一下我的第一家公司,咋扯到别的了…言归正传,我在第一家公司待了仨年,可能是年纪到了(26岁咋还不退休啊…

发送微信消息和文件

参考:https://www.bilibili.com/video/BV1S84y1m7xd 安装: pip install PyOfficeRobotimport PyOfficeRobotPyOfficeRobot.chat.send_message(who"文件传输助手", message"你好,我是PyOfficeRobot,有什么可以帮助…

SpringBoot中整合ONLYOFFICE在线编辑

SpringBoot整合OnlyOffice SpringBoot整合OnlyOffice实现在线编辑1. 搭建私有的OnlyOffice的服务2. SpringBoot进行交互2.1 环境2.2 我们的流程2.3 接口规划2.3.1 获取编辑器配置的接口2.3.2 文件下载地址2.3.3 文件下载地址 3. 总结4. 注意4.1 你的项目的地址一定一定要和only…

gcc versions later than 10 are not supported!

如何修改Linux服务器gcc和g版本 查看gcc和g版本 gcc -vg -v修改gcc和g版本 家目录创建./local/bin文件夹 mkdir -p ~/.local/bin把 ~/.local/bin 加到你的 PATH 里 打开~/.bashrc 然后 export PATH~/.local/bin:$PATH后source ~/.bashrc将gcc和g需要的版本加入 ~/.local/bin…

Elasticsearch-Rest-Client

Elasticsearch-Rest-Client&#xff1a;官方RestClient&#xff0c;封装了ES操作&#xff0c;API层次分明&#xff0c;上手简单。 1. 导入依赖 <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high…