全局光照RSM

news2024/11/18 13:47:42

Reflective Shadow Maps(RSM)

一切被直接光照照到的物体,会作为次级光源。

问题1:哪些面片被直接照亮

使用ShadowMap就可以知道哪些面片被直接照亮

问题2:各个面片对P点的贡献分别是多少。

在这里插入图片描述
对渲染方程代入如上计算,得到如下结果
在这里插入图片描述
在上式中, L i ( q → p ) L_i(q\rightarrow p) Li(qp)可优化为如下函数
因为:
f r = ρ / π , ρ 为反射率 L i = f r ⋅ ϕ d A , ϕ 是直接光照的光强 f_r = \rho / \pi,\rho 为反射率\\ \quad\\ L_i = f_r \cdot \frac{\phi}{dA},\phi 是直接光照的光强 fr=ρ/πρ为反射率Li=frdAϕϕ是直接光照的光强
因此有次级光源光强
E p ( x , n ) = ϕ p m a x { 0 , d o t ( n p , ( x − x p ) } m a x { 0 , d o t ( n , x p − x ) } ∣ ∣ x − x p ∣ ∣ 4 E_p(x,n)=\phi_p \frac{max\{0,dot(n_p,(x-x_p)\}max\{0,dot(n,x_p-x)\}}{||x-x_p||^4} Ep(x,n)=ϕp∣∣xxp4max{0,dot(np,(xxp)}max{0,dot(n,xpx)}

L 0 = E p ( x , n ) ∗ f r ( p , p → q , w o ) L_0 = E_p(x,n) * f_r(p,p\rightarrow q,w_o) L0=Ep(x,n)fr(p,pq,wo)

其他近似

  1. 不考虑Visbility项,认为次级光源不会被遮挡。
  2. 不对所有次级光源采样,只对该点在ShadowMap中周围的部分像素采样。

ShadowMap记录值

  1. 深度
  2. 世界坐标
  3. 法线
  4. 次级光源强度 ϕ \phi ϕ

特点与效果

对于特定情况效果比较好,如手电筒(用RSM做手电筒!!!?)
好处:非常好写,第一个Path生成RSM,第二个path用眼睛看向场景。
问题:

  1. 直接光源较多时,间接光源也会成倍增多
  2. 不会计算反射光的可见性检查
  3. 次级光源效果和运行速度,会根据采样率的不同的不同

如何实现

第一步,先找到哪些物体表面能够被直接照亮,使用ShadowMap,认为每一个ShadowMap的像素就是一个次级光源。
第二步,次级光源如何贡献到点P:我们认为所有的反射物(次级光源),都是Diffuse的

RSM与VPL(Virtual Point Light 虚拟点光源)

RSM与离线渲染中的VPL方式是比较相似的,RSM是硬件加速版本的VPL(Virtual Point Light 虚拟点光源)。

RSM实现步骤

第一个Pass

在摄像机视角渲染整个场景,并记录场景中可见的像素点的颜色视口矩阵下的法线视口矩阵下的坐标

得到一组场景信息,可以理解为GBuffer。
在这里插入图片描述

第2个Pass

从光源视口下看向场景,生成RSM图。
记录的从光源视口下可见像素点的反射光颜色值相机视角下的法线相机视角下的坐标光源视角下的坐标
得到的结果是一组256x256的RSM图
在这里插入图片描述在这里插入图片描述
············反射光颜色值 ······························· 相机视角下的法线 ··················
在这里插入图片描述在这里插入图片描述

··········· 相机视角下的坐标 ·························· 光源视角下的坐标(主要保存z轴深度)·······························

第3个Pass

1.将Pass1中保存的像素坐标转化到与RSM相同的光源坐标

	ivec2 FragPos = ivec2(gl_GlobalInvocationID.xy);//当前执行单元在全局工作组中的位置的有效索引
	vec3 FragViewNormal = normalize(texelFetch(u_NormalTexture, FragPos, 0).xyz);
	vec3 FragAlbedo = texelFetch(u_AlbedoTexture, FragPos, 0).xyz;
	vec3 FragViewPos = texelFetch(u_PositionTexture, FragPos, 0).xyz;

	// 获取 摄像机视口下像素 在光源视口下的位置坐标
	vec4 FragPosInLightSpace = u_LightVPMatrixMulInverseCameraViewMatrix * vec4(FragViewPos, 1);
	FragPosInLightSpace /= FragPosInLightSpace.w;
	vec2 FragNDCPos4Light = (FragPosInLightSpace.xy + 1) / 2;

2. 计算该像素点的直接光照

如果该像素点在光照空间外,则只提供一个基本的环境光照。
当该像素在光照空间内,首先判断该点是否在阴影中

  • 如果在阴影中,则只计算环境光照
  • 如果不在阴影中,则计算直接光照
// 直接光照&环境光照
	vec3 testOutput;
	vec3 DirectIllumination;
	// 如果该像素在RSM范围之外,以0.1倍源像素作为其环境光照
	// FragPosInLightSpace.z范围在【-1,0】的区间中.属于可被光照直接照射的范围
	// 这里可通过与RSM中的深度进行比较,来确定是否有阴影生成,或是否可被作为次级光源
	if(	FragPosInLightSpace.z < -1.0f || FragPosInLightSpace.z > 0.0f||\
		FragPosInLightSpace.x >=  1.0f || FragPosInLightSpace.x <= -1.0f||\
		FragPosInLightSpace.y >=  1.0f || FragPosInLightSpace.y <= -1.0f )//
	{
		DirectIllumination = vec3(0.1) * FragAlbedo;
		testOutput = vec3(0.f,0.f,0.f);
	}
	else//反之,将原像素经过夹角衰减后的值作为直接光照
	{	
		// view space下的光照坐标
		vec3 RSWLightPosition =texture(u_RSMLightPositionTexture,FragNDCPos4Light.xy).xyz;
		
		// 判断是否在阴影中(近小【-1】远大【0】)
		if(RSWLightPosition.z + 0.001 > FragPosInLightSpace.z){//不在阴影中
			DirectIllumination = FragAlbedo* max(dot(-u_LightDirInViewSpace, FragViewNormal), 0.1);// ;
		}
		else{//在阴影中
		   DirectIllumination = vec3(0.1) * FragAlbedo;
		}
	}

在这里插入图片描述

3. 计算该像素点的间接光照

将该着色点投影到光照视口下的点,则已知该点在RSM纹理上的xy轴位置。

在RSM图中,在(x,y)像素上以R为半斤的周围进行随机采样,每一个采样点作为次级光源进行光照计算。

// 计算间接光照
	vec3 IndirectIllumination = vec3(0);
	float RSMTexelSize = 1.0 / u_RSMSize;
	for(int i = 0; i < u_VPLNum; ++i)
	{
		if(FragPosInLightSpace.z > -1.0f && FragPosInLightSpace.z <0.0f){
			//获取随机采样数组
			vec3 VPLSampleCoordAndWeight = u_VPLsSampleCoordsAndWeights[i].xyz;
			// 在光源视口下的该像素点周围一圈进行采样
			vec2 VPLSamplePos = FragNDCPos4Light + u_MaxSampleRadius * VPLSampleCoordAndWeight.xy * RSMTexelSize;
			// 在RSM图中获取采样点的次级光源颜色值
			vec3 VPLFlux = texture(u_RSMFluxTexture, VPLSamplePos).xyz;
			// 获取采样点在摄像机视口坐标下的的法线和位置坐标
			vec3 VPLNormalInViewSpace = normalize(texture(u_RSMNormalTexture, VPLSamplePos).xyz);
			vec3 VPLPositionInViewSpace = texture(u_RSMPositionTexture, VPLSamplePos).xyz;
			// 计算该采样点对该像素的间接光照值
			IndirectIllumination += calcVPLIrradiance(VPLFlux, VPLNormalInViewSpace, VPLPositionInViewSpace, FragViewPos, FragViewNormal, VPLSampleCoordAndWeight.z);
		}
	}
	IndirectIllumination *= FragAlbedo;

	//间接光
	vec3 Result = IndirectIllumination / u_VPLNum;

在这里插入图片描述

4. 将直接光照与间接光照加起来

得到结果,渲染!

vec3 Result = DirectIllumination  + IndirectIllumination / u_VPLNum ;

在这里插入图片描述
区别【好像没太大区别 dog.jpg】
在这里插入图片描述

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

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

相关文章

CRM客户管理系统能在线使用吗?

经常有朋友私信小编&#xff0c;mac系统/windows系统可以下载使用吗&#xff1f;在哪里下载&#xff1f;其实&#xff0c;Zoho CRM在线即可使用&#xff0c;完全不用下载客户端&#xff01;下面我们就说说&#xff0c;CRM管理系统如何在线用。 Zoho CRM是一款帮助企业进行客户…

恒运资本:什么是五日线?

在股票买卖中&#xff0c;五日线是一种常见的技术剖析指标&#xff0c;用于判别股市的趋势和价格改变。五日线也被称为移动平均线&#xff0c;它是以最近五个买卖日的收盘价为基础核算出的平均值。五日线能够协助出资者识别短期商场意向&#xff0c;及时调整出资战略&#xff0…

Mybatis 框架 ( 四 ) QueryWrapper

4.5.Wrapper条件构造器 Wrapper &#xff1a; 条件构造抽象类&#xff0c;最顶端父类 AbstractWrapper &#xff1a; 用于查询条件封装&#xff0c;生成 sql 的 where 条件 QueryWrapper &#xff1a; Entity 对象封装操作类&#xff0c;不是用lambda语法 UpdateWrapper &am…

【前端】禁止别人调试自己的前端页面代码

无限debugger 前端页面防止调试的方法主要是通过不断 debugger 来疯狂输出断点&#xff0c;因为 debugger 在控制台被打开的时候就会执行由于程序被 debugger 阻止&#xff0c;所以无法进行断点调试&#xff0c;所以网页的请求也是看不到的代码如下&#xff1a; /** * 基础禁止…

参照错误原因排查

报错如下&#xff0c;弹框参照框不显示&#xff1a; 首先定位到错误代码行&#xff0c;排查后发现调用方式、参数均没问题 再到参照引入源头&#xff0c;结合network检测资源加载情况&#xff0c;发现静态资源js文件均正常获取 可以基本判断是参照组件那边出现问题&#xff0c…

算法通关村第十八关——回溯是怎么回事(青铜)

算法通关村第十八关——回溯是怎么回事&#xff08;青铜&#xff09; 前言1. 从N叉树说起1.1 N叉树的定义和特点1.2 N叉树的遍历方式1.3 N叉树在回溯算法中的应用 2. 为什么有的问题暴力搜索也不行2.1 暴力搜索的局限性 3. 回溯递归局部枚举放下前任3.1 回溯算法的基本思想和原…

运维Shell脚本牛刀小试(九): 重定向操作符“>“及双重定向“>>“

运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 运维Shell脚本小试牛刀(三)::$(cd $(dirname $0)&#xff1b; pwd)命令详解 运维Shell脚本小试牛刀(四): 多层嵌套if...elif...elif....else fi_蜗牛杨哥的博客-CSDN博客 Cenos7安装小火车程序动画 运维Shell脚本小试…

c高级day4(9.11)shell脚本(case ....in语句,循环语句,select ...in和case...In结合,辅助控制关键字,函数)

1.实现一个对数组就和的函数&#xff0c;数组通过实参传递给函数 2.写一个函数&#xff0c;输出当前用户的uid和gid&#xff0c;并使用变量接收结果 #!/bin/bash read -a arr sum0 function add() { …

s2019nh62分数减法

代码&#xff1a; #include<bits/stdc.h> using namespace std; int m1,z1,m2,z2,zd,zx,s1,s2,f1,f2,c,da; int main() {cin>>z1>>m1; //分子1和分母1cin>>z2>>m2; //分子2和分母2zd__gcd(m1,m2); //求两个分母的最大公因数来求最小公倍数z…

数据分析工具有哪些,哪个好学?

Tableau、帆软BI、思迈特BI、SpeedBI数据分析云……这些都是比较常见的BI数据分析工具。从学习成本、操作难度以及数据可视化分析效果来看&#xff0c;SpeedBI数据分析云都表现地可圈可点。 1、不需下载安装、学习成本低 SpeedBI数据分析云是一款SaaS BI数据分析工具&#xf…

IO和进程day05(进程与线程)

今日任务 1.代码 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/wait.h> #include <pthread.h>…

pytorch代码实现之CoordConv卷积

CoordConv卷积 在深度学习领域&#xff0c;几乎没有什么想法能像卷积那样产生如此大的影响。对于任何涉及像素或空间表示的问题&#xff0c;普遍的直觉认为卷积神经网络可能是合适的。在本文中&#xff0c;我们通过看似平凡的坐标变换问题展示了一个惊人的反例&#xff0c;该问…

如何使用bat脚本启动指定目录下的jar包

士别三日&#xff0c;当刮目相待。——《三国志》 为了将一个java程序封装成一个简单易用的小工具&#xff0c;使用bat脚本启动jar包。 在txt文档中&#xff0c;键入&#xff1a; echo off java -jar %~dp0core\demo.jar 注意&#xff1a; 1、其中“core”是文件夹的名称&am…

与读者互动,扩大影响:提升公众号文章阅读量的关键

如何提升公众号文章阅读量 公众号已成为许多个人和企业推广与传播的重要平台。然而&#xff0c;仅仅拥有一个公众号并发布文章并不足以吸引大量读者和提高阅读量。在当今信息爆炸的时代&#xff0c;如何让你的公众号文章脱颖而出并吸引更多读者的关注是一个关键问题。本文将为…

气象观测站:实时监测、应用广泛

对于许多人来说&#xff0c;气象观测站可能只是一种能够预测天气的设备&#xff0c;但实际上&#xff0c;它所涉及的原理和优势却远不止于此。 二、气象观测站的优势 全面覆盖 气象观测站能够全面覆盖气象要素的各个方面&#xff0c;从温度、湿度、气压到风速、风向等。这些…

日志是你的朋友:为什么每个开发者都应该写日志

大家好&#xff0c;我是小米&#xff0c;一个热衷于技术分享的程序员。今天我想和大家聊一聊一个在编写代码时常常被忽视&#xff0c;却极为重要的话题——为什么要写有意义的日志。 在日常的编程工作中&#xff0c;我们经常听到“日志”这个词&#xff0c;但是有些人可能并不…

C++重载输入和输出运算符

在C++中,标准库本身已经对左移运算符<<和右移运算符>>分别进行了重载,使其能够用于不同数据的输入输出,但是输入输出的对象只能是 C++ 内置的数据类型(例如 bool、int、double 等)和标准库所包含的类类型(例如 string、complex、ofstream、ifstream 等)。 …

C 风格文件输入/输出---无格式输入/输出---(std::getchar,std::putchar,std::ungetc)

C 标准库的 C I/O 子集实现 C 风格流输入/输出操作。 <cstdio> 头文件提供通用文件支持并提供有窄和多字节字符输入/输出能力的函数&#xff0c;而 <cwchar>头文件提供有宽字符输入/输出能力的函数。 无格式输入/输出 从 stdin 读取字符 std::getchar int getch…

零基础Linux_3(基本指令_下)目录/文件的复制移动查看打包+其它指令

此篇接着上篇&#xff0c;所以目录也接着上篇了&#xff0c;上篇链接&#xff1a;零基础Linux_2(基本指令_上)目录/文件的显示跳转创建删除_GR_C的博客-CSDN博客 目录 6. 复制文件或目录 cp 源文件 目标文件(拷贝源文件到目标文件) cp -r 源目录 目标目录(拷贝源目录到目标…

苹果笔推荐购买吗?苹果ipad触控笔推荐

电容笔什么牌子好用&#xff1f;最近看到很多人在问这个问题。也是&#xff0c;现在的电容笔品牌太多了&#xff0c;选的人眼花缭乱的&#xff0c;不了解电容笔的人都不知道应该怎么选。下面&#xff0c;根据我多年使用电容笔的经验&#xff0c;来给大家推荐四款性价比高的电容…