【从UnityURP开始探索游戏渲染】专栏-直达

环境光实现流程

环境光在基于物理的渲染(PBR)中主要通过以下流程实现:

  • 环境贴图采样‌:获取周围环境的辐照度
  • 漫反射计算‌:处理非金属材质的漫反射部分
  • 镜面反射计算‌:处理金属和高光的反射部分
  • 环境光遮蔽‌:考虑几何遮蔽和环境遮挡
  • 最终混合‌:将环境光与其他光照成分结合

主要环境光实现模型

1. 球谐光照(Spherical Harmonics)

原理‌:

  • 将环境光信息编码为球谐系数
  • 使用低阶多项式近似环境光照

公式‌:

$L(θ,ϕ)≈\sum_{l=0}n\sum_{m=−l}lc_lmY_lm(θ,ϕ)$

特点‌:

  • 内存占用小
  • 计算效率高
  • 适合动态场景

2. 预计算辐照度贴图(Precomputed Radiance Transfer)

原理‌:

  • 预计算环境光对场景的影响
  • 存储为立方体贴图或2D贴图

实现方式‌:

  • 漫反射:预卷积的辐照度图
  • 镜面反射:预过滤的反射探针

3. 屏幕空间反射(Screen Space Reflection)

原理‌:

  • 直接在屏幕空间追踪光线
  • 实时计算环境反射

特点‌:

  • 无需预计算
  • 消耗较大GPU资源
  • 只能反射屏幕内可见内容

Unity URP的环境光实现方案

核心方案:反射探针 + 球谐光照

实现代码‌:

hlsl
// 环境光漫反射计算
half3 ambientDiffuse = SampleSH(normalWS) * surfaceData.albedo; // 环境光镜面反射计算
half3 reflectVector = reflect(-viewDirectionWS, normalWS);
half3 ambientSpecular = GlossyEnvironmentReflection(
reflectVector,
positionWS,
surfaceData.roughness,
1.0
); // 最终环境光
half3 ambient = ambientDiffuse * (1 - surfaceData.metallic) +
ambientSpecular * surfaceData.metallic;

选择原因‌:

  • 性能与质量平衡‌:

    • 球谐光照提供高效的漫反射环境光
    • 反射探针处理高质量的镜面反射
  • 动态场景支持‌:

    • 反射探针可实时更新
    • 球谐系数可动态计算
  • 移动端优化‌:

    hlsl
    // 移动端简化版
    half3 ambient = SampleSH(normalWS) * surfaceData.albedo;
    half3 specular = surfaceData.metallic * SAMPLE_TEXTURECUBE_LOD(
    _GlossyEnvironmentCube,
    sampler_GlossyEnvironmentCube,
    reflectVector,
    surfaceData.roughness * UNITY_SPECCUBE_LOD_STEPS
    );
  • 艺术家友好‌:

    • 直观的反射探针放置
    • 自动生成的球谐光照

关键实现细节

  • 反射探针系统‌:

    • 立方体贴图预过滤
    • 多级mipmap存储不同粗糙度的反射
    • 混合探针权重计算
  • 球谐光照计算‌:

    • 使用3阶球谐(9个系数)
    • 场景光照烘焙为球谐系数
    • 实时动态物体也能接收球谐光照
  • 环境光遮蔽集成‌:

    hlsl
    ambient *= lerp(1.0, occlusion, _AmbientOcclusionParam.w);
  • 性能分级处理‌:

    hlsl
    #if defined(_ENVIRONMENTREFLECTIONS_OFF)
    half3 ambientSpecular = 0;
    #else
    // 完整反射计算
    #endif

各模型性能对比

模型 内存占用 GPU消耗 动态支持 视觉质量
球谐光照 极低 极低 ★★★★★ ★★☆☆☆
反射探针 中-高 ★★★☆☆ ★★★★☆
SSR ★★★★☆ ★★★★☆
URP混合方案 ★★★★☆ ★★★★☆

Unity URP的选择优势

分级渲染支持‌:

  • 高端设备:完整反射探针+球谐
  • 移动设备:简化版球谐光照

场景适应性‌:

  • 室内场景:高密度反射探针
  • 开放世界:球谐为主+关键区域探针

动态GI支持‌:

  • 可与光照探针系统配合
  • 支持实时环境光更新

扩展性强‌:

  • 容易集成SSR等后期效果
  • 支持自定义环境光遮蔽

Unity URP的环境光实现方案在保持实时性能的同时,通过精心设计的混合策略提供了足够高质量的全局光照效果,特别适合需要跨平台部署的项目。随着硬件发展,URP也在逐步引入更多实时全局光照技术,如Enlighten和GPU Lightmapper的集成,但核心的环境光处理架构仍保持这一基本设计理念。


【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,)

【光照】[PBR][环境光]实现方法解析的更多相关文章

  1. Python的方法解析顺序(MRO)[转]

    本文转载自: http://hanjianwei.com/2013/07/25/python-mro/ 对于支持继承的编程语言来说,其方法(属性)可能定义在当前类,也可能来自于基类,所以在方法调用时就 ...

  2. sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO

    sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO 今天在弄一个 sqlalchemy 的数据库基类的时候,遇到了跟多继承相关的一个小问题,因此顺便看了一 ...

  3. iOS 详解NSXMLParser方法解析XML数据方法

    前一篇文章已经介绍了如何通过URL从网络上获取xml数据.下面介绍如何将获取到的数据进行解析. 下面先看看xml的数据格式吧! <?xml version="1.0" enc ...

  4. 四种方法解析JSON数据

    (1)使用TouchJSon解析方法:(需导入包:#import "TouchJson/JSON/CJSONDeserializer.h") //使用TouchJson来解析北京的 ...

  5. Method Resolution Order – Python类的方法解析顺序

    在支持多重继承的编程语言中,查找方法具体来自那个类时的基类搜索顺序通常被称为方法解析顺序(Method Resolution Order),简称MRO.(Python中查找其它属性也遵循同一规则.)对 ...

  6. 【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析

    作者 : 韩曙亮 转载请著名出处 :  http://blog.csdn.net/shulianghan/article/details/38487967 一. MediaPlayer 状态机 介绍 ...

  7. 2019-2-20C#开发中常用加密解密方法解析

    C#开发中常用加密解密方法解析 一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是 message-digest algorithm 5[|ˈmes ...

  8. C#中用DateTime的ParseExact方法解析日期时间(excel中使用系统默认的日期格式)

    最近做的项目中服务器是英文的系统,系统需要通过excel的单元格导入日期,excel中的日期格式是系统默认的日期格式,如下图所示 以上日期格式,会跟着操作系统设置的日期格式相同例如我的中文系统的日期格 ...

  9. JSON.parse() 方法解析一个JSON字符串

    JSON.parse() 方法解析一个JSON字符串,构造由字符串描述的JavaScript值或对象.可以提供可选的reviver函数以在返回之前对所得到的对象执行变换. 语法EDIT JSON.pa ...

  10. python 方法解析顺序 mro

    一.概要: mor(Method Resolution Order),即方法解析顺序,是python中用于处理二义性问题的算法 二义性: 1.两个基类,A和B都定义了f()方法,c继承A和B那么C调用 ...

随机推荐

  1. 对于linux 程序内存的使用量

    简介 如何查看一个linux程序是否产生内存泄露了呢?? 可以使用valgrind 一般的命令是 valgrind --leak-check=full --show-reachable=yes --t ...

  2. PostgreSQL 数据库中 ETL 操作的实战技巧

    在当今数字化时代,数据已成为企业最为宝贵的资产之一,而数据库则是存储与管理这些关键数据的核心.PostgreSQL 作为一款功能强大的开源关系型数据库,在众多领域都发挥着重要作用.今天,就让我们深入探 ...

  3. 理解 Streamlit 的客户端-服务器架构

    Streamlit 应用程序具有客户端-服务器结构. 您应用程序的 Python 后端即为服务器.您通过浏览器看到的前端即为客户端. 当您在本地开发应用程序时,您的计算机同时运行服务器和客户端.如果有 ...

  4. SciTech-BigDataAIML-LLM-PE(Positional Encoding)位置编码: Absolute(绝对)Position + Relative(相对)Position + Rotate(旋转)Position

    SciTech-BigDataAIML-LLM PE(Positional Encoding)位置编码: BOW(Bag of Words)词袋模型:丢弃Word位置信息, 只统计Word之间的 Co ...

  5. 安装centos7的时候 启动会提示Please make your choice from above问题解决 -九五小庞

    依次输入 1 .2.q.yes 就可以了 许可协议

  6. Win10正式版搜索框不能用的问题

    有一位雨林木风官网的用户反馈说,他使用的win10正式版电脑的任务栏上搜索框无法正常使用,搜索不了文件的问题.下面,ylmf 系统小编分享具体的解决方法,有出现这个问题的小伙伴可以一起来看看了. 方法 ...

  7. 记一次项目上MySQL死锁Deadlock的排查优化过程

    起因是最近两天收到了线上项目的告警通知,隔一段时间会出现几笔MySQL的死锁Deadlock的错误,错误日志如下: updating database. Cause: com.mysql.cj.jdb ...

  8. 我的代码背叛了我?为什么 a=1, b=2,最后x和y都等于0?

    随着多核架构的普及,并发编程已成为开发者不可或缺的核心技能.在学习过程中,开发者常会遇到这样的困惑:正确编写的单线程代码,为何在并发环境下可能瞬间失效?看似有序的语句执行后,为何结果却混乱不堪?这些问 ...

  9. Linux/CentOS系统中​​僵尸进程的成因、影响与解决方案

    以下是一份针对Linux/CentOS系统中​​僵尸进程的成因.影响与解决方案​​的详细技术解析: ️ ​​一.僵尸进程的成因​​ 僵尸进程(Zombie Process)是子进程终止后未被父进程完全 ...

  10. pygame小游戏打飞机_2模块显示

    加入游戏背景 通过 pygame.image.load 函数引入背景图片,赋值给变量 bgImg 调用 screen.bilt 函数绘制背景图 # 引用pygame import pygame # 使 ...