Three.js 中的光照模型

news2024/10/7 7:22:59

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.coloradmin.cn/o/1885825.html

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

相关文章

人工智能在音乐创作中的双刃剑:创新与挑战

AI在创造还是毁掉音乐? 简介 最近一个月,轮番上线的音乐大模型,一举将素人生产音乐的门槛降到了最低,并掀起了音乐圈会不会被AI彻底颠覆的讨论。短暂的兴奋后,AI产品的版权归属于谁,创意产业要如何在AI的阴…

机器学习实战20-利用AnoSVGD算法探索多指标的异常检测的应用

大家好,我是微学AI,今天给大家介绍一下机器学习实战20-利用AnoSVGD算法探索多指标的异常检测的应用。SVGD(Stein Variational Gradient Descent)是一种通用的变分推断算法,它是优化中梯度下降的自然对应物。SVGD通过应用一种功能性梯度下降来…

用C#的MediaDevices程序集打开MTP设备(用usb线连接的手机)的文件夹

一、任务描述 1、可以访问MTP设备的桌面程序。 MTP设备:支持媒体传输协议(MTP)的设备,MTP简单来说就是一种PC与其他设备相连的一种协议,智能手机、平板电脑、数码相机等可以通过 USB 连接到电脑,并通过 MTP 协议传输媒体文件。点…

【开发环境】MacBook M2安装git并拉取gitlab项目,解决gitlab出现Access Token使用无效的方法

文章目录 安装Homebrew安装git打开IDEA配置git打开IDEA拉取项目 安装Homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"在iTerm等命令行工具打开后,输入上面的命令 之后根据中文提示完成Homebrew的下载…

奇葩公司又发微博了,网友表示“乐”

多益网络 近日,多益网络官方微博发帖,公然表示对法院仲裁结果不服,认为劳动法有极多问题。 大家不要看微博内容似乎振振有词,极有可能只是多益网络单方面的选择性表达,毕竟多益网络的臭名早就家喻户晓。 况且对前员工直…

mybatis、mybatis-plus插件开发,实现数据脱敏功能

首先说一下mybatis中四大组件的作用,下面开发的插件拦截器会使用 四大组件Executor、StatementHandler、ParameterHandler、ResultSetHandler Executor: Executor 是 MyBatis 中的执行器,负责 SQL 语句的执行工作。它通过调度 StatementHan…

蓝桥杯算法双周赛

四、赛后真题解析 比赛赛后将提供免费直播讲解,主讲人:待定。时间:07 月 13 日(比赛当日)晚 21 时。观看直播地址:第3场蓝桥算法季度赛赛后题解直播 - 蓝桥云课 - 哔哩哔哩直播,二次元弹幕直播…

为什么电量传感器在储能BMS应用中如此重要?

在储能系统中电池的充放电状态和使用寿命是保障系统健康稳定持久运行的关键因素,因此建立稳定可靠准确的电量检测方案至关重要。电流传感器在估算和延长电池使用寿命方面发挥着至关重要的作用,是储能电池检测系统中重要的一环。 关键词:电量…

vue选择上下周,拖拽列表,随机背景色

安装拖拽插件 npm install vuedraggable <template><!--排产计划--><div class"app-container"><div class"mainbox"><div class"table-container table-fullscreen"><div class"title-name">…

向openHarmony设备添加gdb调试工具

1. 下载gdb源码 国内从官网下载源码比较慢&#xff0c;可以从清华的镜像网站&#xff08;清华大学开源软件镜像站 | Tsinghua Open Source Mirror&#xff09;上下载。下载地址&#xff1a; Index of /gnu/gdb/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 选择…

喜讯|华院计算认知智能引擎算法平台荣登BPAA大赛创新组TOP50

6月25日&#xff0c;备受瞩目的BPAA第四届全球应用算法模型典范大赛&#xff08;以下简称“BPAA大赛”&#xff09;正式揭晓了《第四届全球应用算法模型典范大赛创业组TOP50榜单》和《第四届全球应用算法模型典范大赛创新组TOP50榜单》。其中&#xff0c;华院计算技术&#xff…

Python课程设计:python制作俄罗斯方块小游戏

基于python的俄罗斯方块小游戏 目录 基于python的俄罗斯方块小游戏 1.概述 1.1 摘要 1.2 开发背景 1.3 开发环境 1.4 实现功能 2.代码描述 2.1 模块导入 2.2 初始化变量 2.3 播放音乐 2.4 创建方块类 2.5 绘制游戏地图 2.6 游戏初始化 2.7 绘制有边框矩形 2.8 …

go使用grpc编辑器 windows

先看最后效果&#xff1a; 当我执行 protoc --go_out. proto.proto 会生成proto.pb.go文件&#xff0c;主要存储的是封装好的结构体 执行 protoc --go-grpc_out. proto.proto 会生成对应的方法 那么现在提供解决方案&#xff1a; https://github.com/protocolbuffers…

kafka的架构

一、架构图 Broker&#xff1a;一台 kafka 服务器就是一个 broker。一个kakfa集群由多个 broker 组成。一个 broker 可以容纳多个 topic。 Producer&#xff1a;消息生产者&#xff0c;就是向 kafka broker 发消息的客户端 Consumer&#xff1a;消息消费者&#xff0c;向 kafk…

软考中级系统集成项目管理工程师备考笔记

目录 一&#xff0c;通用内容 &#xff08;一&#xff09;信息与信息化 1.1&#xff0c;信息 信息基本概念 信息的传输模型 信息的质量属性 1.2&#xff0c;信息系统 信息系统的基本概念 信息系统定义 信息系统集成 1.3&#xff0c;信息化 信息化层次 信息化的核心…

Prometheus在金融行业信息系统运维管理中的应用:实践与案例分析

Prometheus在金融行业信息系统运维管理中的应用&#xff1a;实践与案例分析 Prometheus是一款开源的监控系统和时序数据库&#xff0c;被广泛应用于各种行业的运维管理中&#xff0c;特别是在金融行业。它具有强大的数据采集和分析能力&#xff0c;能够实时监控系统的性能和状…

华为eNSP模拟器安装详细步骤

安装准备 安装eNSP需要先安装三个依赖软件才能运行&#xff0c;分别是VirtualBox、WinPcap、Wireshark 下载地址如下 eNSP&#xff1a;http://cloud.rsecc.cn/softlink/eNSP%20V100R003C00SPC100%20Setup.exe VirtualBox&#xff1a;http://cloud.rsecc.cn/softlink/Virtua…

Steam页面打不开?steam显示当前游戏不可用是怎么回事

Steam是全球最大的游戏综合发行平台&#xff0c;每年为无数玩家呈现了多款精彩游戏&#xff0c;不过由于网络问题或其他异常因素影响&#xff0c;有很多玩家会在访问steam或steam的游戏商品页时&#xff0c;遇到Steam提示当前游戏在您平台不可用、打不开游戏页面的情况&#xf…

自动化测试报告pytest-html样式美化

最近我将 pytest-html 样式优化了 一版 先看优化前&#xff1a; 优化后&#xff1a; 优化内容包括&#xff1a; 删除部分多余字段新增echart图表部分字体大小、行间距、颜色做了美化调整运行环境信息移至报告最后部分字段做了汉化处理&#xff08;没全部翻译是因为&#xf…

七天速通javaSE:第七天 面向对象:封装继承与多态

文章目录 前言一、封装1. 属性私有2. get&#xff0c;set3. 修饰符的可访问性4. 特点总结 二、继承1. 子承父业&#xff1a;extends2. 区分父子&#xff1a;super2.1 属性2.2 方法重写 三、多态&#xff08;不同类继承同一个类&#xff09; 前言 一、封装 概念&#xff1a;封装…