当前位置: 首页 > web >正文

前向渲染和延迟渲染

🌈 前向渲染(Forward Rendering)和延迟渲染(Deferred Rendering)——详细阶段对比

这两种渲染方式都属于 基于光照的渲染管线(Lighting Pipeline),区别在于光照和材质的计算时机不同


🎯 一、前向渲染(Forward Rendering)

✅ 渲染阶段流程:

每个物体 → 顶点着色器 → 光栅化 → 片元着色器(计算光照) → 合并输出到帧缓冲

🚩 每个阶段解释:

阶段作用关键点
1️⃣ 顶点着色器处理模型的顶点(变换到屏幕空间)模型、视图、投影矩阵
2️⃣ 光栅化将三角形“填充”为像素(片元)GPU自动处理
3️⃣ 片元着色器每个像素计算颜色,此时就计算光照!光照开销大
4️⃣ 合并输出输出最终像素颜色到帧缓冲支持透明效果

🟢 优点:

  • 实现简单,渲染路径直接

  • 透明对象支持良好

  • 所有硬件都支持

🔴 缺点:

  • 每个像素都要重复计算光照

  • 光源多了性能急剧下降

  • 阴影、全局光照不易扩展


🎯 二、延迟渲染(Deferred Rendering)

✅ 渲染阶段流程(更复杂):

1. 几何阶段(Geometry Pass):所有物体 → 写入 G-buffer(记录位置、法线、材质信息)2. 光照阶段(Lighting Pass):每个像素 → 读取 G-buffer → 统一计算光照3. 合成阶段(Composition Pass):合成所有信息输出最终颜色

🚩 阶段细节:

阶段内容数据
1️⃣ 几何阶段所有物体写入 G-buffer位置、法线、反射率、颜色、深度等
2️⃣ 光照阶段使用 G-buffer 对每个像素统一处理光照高效统一处理多个光源
3️⃣ 合成阶段最终输出颜色图像可加后期处理(Bloom、HDR等)

🟢 优点:

  • 多光源性能优越(只计算一次像素)

  • 易于集成后处理效果(如Bloom、SSA0)

  • 几何与光照解耦,灵活

🔴 缺点:

  • 不支持透明对象(因为没有透明顺序)

  • 消耗显存大(多个G-buffer)

  • 不适合低端设备


🧪 对比总结表:

比较项前向渲染延迟渲染
光照计算每物体每像素每像素一次,统一光照
光源数量少则性能好,多则急剧下降多光源效率更高
支持透明✅ 支持良好❌ 支持差
后处理较困难容易扩展
内存占用高,需要多个缓冲区
实现复杂度高,需要设计G-buffer

📘 初学者建议:

建议说明
学习顺序先理解前向渲染,再学习延迟渲染
推荐路径Cocos / Unity 都默认使用前向渲染,也提供延迟渲染(在高质量设置中)
着重点理解 为什么延迟渲染更适合多光源环境,以及 它为何不适合处理透明物体

📎 附加资料(可选)

  • G-buffer 通常包含哪些内容:

    • worldPos: 世界坐标

    • normal: 法线向量

    • albedo: 反照率

    • specular: 镜面系数

    • depth: 深度信息

新的一篇==========================================

延迟渲染的几何阶段和光照阶段(Lighting Pass)都会走顶点着色器和片段着色器,不过有区别

下面我给你详细拆解这个流程,作为初学者能快速理解:


🌟 延迟渲染的两个主要阶段回顾:

阶段用途使用顶点/片元着色器?说明
1️⃣ 几何阶段(G-Buffer Pass)把场景信息写入 G-Buffer(颜色、法线、深度等)✅ 会走顶点和片元着色器每个物体一个一个画
2️⃣ 光照阶段(Lighting Pass)利用 G-buffer 数据,逐像素计算光照✅ 也会走顶点和片元着色器通常只画一个全屏 Quad

🧩 光照阶段怎么还用“顶点着色器”?

这个顶点着色器非常简单!

我们会画一个 全屏幕的矩形(Full-Screen Quad),通常由 2 个三角形组成。

顶点着色器的作用是:

  • 把这 4 个顶点从局部坐标变换到屏幕坐标。

  • 输出纹理坐标(UV)给片元着色器。

📌 示例顶点着色器代码(伪代码):

attribute vec2 a_position;
varying vec2 v_uv;void main() {v_uv = a_position * 0.5 + 0.5; // [-1,1] → [0,1]gl_Position = vec4(a_position, 0.0, 1.0); // 投影到屏幕空间
}

💡 光照阶段的“片元着色器”做了什么?

片元着色器会:

  • 从 G-buffer 读取当前像素的:

    • 位置(或重建位置)

    • 法线

    • 材质属性(如颜色、金属度、粗糙度)

  • 对每个光源进行逐像素光照计算

  • 输出最终颜色

📌 示例片元着色器伪代码:

varying vec2 v_uv;uniform sampler2D u_albedo;
uniform sampler2D u_normal;
uniform sampler2D u_position;void main() {vec3 albedo = texture2D(u_albedo, v_uv).rgb;vec3 normal = texture2D(u_normal, v_uv).xyz;vec3 position = texture2D(u_position, v_uv).xyz;vec3 lightDir = normalize(lightPos - position);float NdotL = max(dot(normal, lightDir), 0.0);vec3 color = albedo * lightColor * NdotL;gl_FragColor = vec4(color, 1.0);
}

✅ 所以总结:

阶段顶点着色器作用片元着色器作用
几何阶段变换物体顶点位置输出 G-buffer 数据
光照阶段绘制全屏 Quad(输出 UV)从 G-buffer 获取数据进行光照计算

🚀 延伸补充:

  • 全屏 Quad 不需要复杂变换,所以光照阶段的顶点着色器很简单,不涉及模型矩阵。

  • 光照阶段最关键的是片元着色器中的光照计算

  • 多数延迟渲染框架中,光照阶段只有一个 Draw Call,但可以处理成百上千个光源。

新的一篇==========================================


✅ 回答:

是的,延迟渲染中的 Lighting Pass 也会走一遍顶点着色器和片段(片元)着色器。

但:

  • 顶点着色器很简单,仅用于生成一个全屏四边形(Full-Screen Quad)。

  • 真正进行光照计算的是片元着色器


🌈 延迟渲染两个阶段对比(都走完整管线):

Pass 阶段走顶点着色器?走片元着色器?用途
Geometry Pass(几何阶段)✅ 是✅ 是渲染场景所有物体,写入 G-Buffer(颜色、法线、深度等)
Lighting Pass(光照阶段)✅ 是✅ 是渲染一个全屏 Quad,从 G-Buffer 读取数据,计算光照

🔍 Lighting Pass 为何还要走顶点着色器?

因为我们需要在屏幕上画一个全屏幕矩形(Full-Screen Quad)

这个矩形也有顶点,需要送进 GPU 渲染:

过程如下:

1️⃣ 顶点着色器:- 输入全屏 Quad 的顶点位置(例如左下角 [-1,-1])- 输出到裁剪空间(gl_Position)- 生成对应 UV 坐标传给片元着色器2️⃣ 光栅化:- 把这个矩形切成像素3️⃣ 片元着色器:- 对每个像素,从 G-Buffer 取出该点的材质、法线、深度信息- 计算光照结果(如漫反射、镜面反射、PBR 等)

✅ Lighting Pass 的顶点着色器通常如下(GLSL 示例):

attribute vec2 a_position;  // [-1,-1] ~ [1,1]
varying vec2 v_uv;void main() {gl_Position = vec4(a_position, 0.0, 1.0);v_uv = a_position * 0.5 + 0.5;  // 映射到 [0,1] UV
}

✅ Lighting Pass 的片元着色器通常如下:

varying vec2 v_uv;uniform sampler2D u_albedo;
uniform sampler2D u_normal;
uniform sampler2D u_position;void main() {vec3 albedo = texture2D(u_albedo, v_uv).rgb;vec3 normal = texture2D(u_normal, v_uv).xyz;vec3 position = texture2D(u_position, v_uv).xyz;vec3 lightDir = normalize(lightPos - position);float NdotL = max(dot(normal, lightDir), 0.0);vec3 color = albedo * lightColor * NdotL;gl_FragColor = vec4(color, 1.0);
}

🧠 总结:

内容是否走说明
Geometry Pass 顶点着色器每个物体都跑一次,做变换
Geometry Pass 片元着色器输出材质信息到 G-Buffer
Lighting Pass 顶点着色器只画一个全屏 Quad,输出 UV
Lighting Pass 片元着色器每像素从 G-Buffer 取数据并计算光照
http://www.xdnf.cn/news/9704.html

相关文章:

  • 利用仿真软件学习一下RC无源滤波和有源滤波电路
  • 【部署】手搓一个dify可用的rerank模型接口服务
  • VSCode Agent 和 Cursor Agent 系统提示词对比
  • There is a chart instance already initialized on the dom. 柱状图初始化时报前面这个错误如何解决?
  • Python异常处理:优雅地应对程序运行时的“意外”
  • 三轴云台之不完全微分PID控制算法篇
  • 可视化数据大屏适配方案之Scale等比缩放
  • java上机测试错题回顾(3)
  • YOLOv11冻结训练+微调策略实战教程(含效果对比分析)
  • 运维三剑客——grep
  • 【动态规划】子数组系列(二)
  • GEO革命:重新定义AI时代的内容规则
  • 代码随想录算法训练营第五十二天
  • 【笔试训练4】Fibonacci数列|单词搜索|杨辉三角
  • 11、总账管理(GL)数字化转型:财务核心支柱,承担着业务系统复杂多变的重任
  • 测试W5500的第9步_使用SNTP实现网络时间同步
  • 尚硅谷redis7 63-69 redis哨兵监控之理论简介
  • javase JDK 环境变量配置
  • 关于线程死锁的相关知识
  • PortSwigger-01-信息泄露
  • 借助Java,让Cloudflare API为你的网站管理加速
  • 篇章五 数据结构——链表(一)
  • 【CAPL实战】LIN校验和测试
  • 电脑硬盘空间大量被占用怎么办
  • 低功耗双目云台监控设备采用国标控制装置
  • 扩散模型原理详解:从噪声到艺术的神奇之旅
  • win32相关(进程间通信)
  • RISC-V特权模式及切换
  • Python中质数筛选及优化效率对比
  • 什么是事务?事务的四大特性(ACID)?