GAMES202——作业3 Screen Space Ray Tracing

news2024/11/15 8:30:57

任务

        为场景实现屏幕空间的全局光照效果

        1.直接光照:  实现ssrFragmentShader中的EvalDiffuse(wi, wo, uv) EvalDirectionalLight(uv) 函数,并在 main 函数中实现直接光照的效果。

        2.屏幕空间光线求交:实现RayMarch(ori, dir, out hitPos) 函数。RayMarch 函数的返回值为是否相交,当相交的时候需要将参数 hitPos设置为交点。参数 ori dir 为世界坐标系中的值,分别代表光线的起点和方向,其中方向向量为单位向量。

        3.间接光照:在 main 函数中实现间接光照,使用蒙特卡洛方法求解渲染方程。

实现

        EvalDiffuse

        该函数是计算diffuse材质的BSDF的,功能简单,其实就是之前101的内容。这里将EvalDiffuse看作渲染方程的f,但是由于计算间接光照的伪代码没有给出cos项,因此这里多乘以一个cos项。另外提一下,这里的INV_PI是PI的倒数,因为在计算机里乘法计算比除法计算更快,因此预定义一个INV_PI能加速渲染。

vec3 EvalDiffuse(vec3 wi, vec3 wo, vec2 uv) {
  vec3 diffuse  = GetGBufferDiffuse(uv);
  vec3 normal = GetGBufferNormalWorld(uv);
  float cos = max(0., dot(normal, wi));
  return diffuse * cos * INV_PI;
}
        EvalDirectionLight

        直接使用题目提供的API,简短两行

vec3 EvalDirectionalLight(vec2 uv) {
  float visibility = GetGBufferuShadow(uv);
  return visibility * uLightRadiance;
}
        RayMarch

        按照202课上的原理,在着色点的位置开始,以某个方向射出光线,一步步向前试探找到交点。有交点的条件是:试探的点的深度比屏幕空间的该位置的深度更深(也就是在屏幕空间一直走直到被遮挡住,这时候说明有交点)。

      

bool RayMarch(vec3 ori, vec3 dir, out vec3 hitPos) {
  //定义一个最大步数防止没有找到交点而无限前进
  const int maxStep = 100;
  float stepSize = 0.05;
  vec3 stepDir = normalize(dir) * stepSize;

  for(int step=0; step< maxStep ; step++){
    float depth = GetDepth(ori);
    vec2 screenUV = GetScreenCoordinate(ori);
    float screenDepth = GetGBufferDepth(screenUV);

    if(depth > screenDepth + 0.0001){
      hitPos = ori;
      return true;
    }

    ori += dir;
  }

  return false;
}
        main里用蒙特卡洛方法解渲染方程

        这里渲染方程没有cos项,cos项在上面的EvalDiffuse已经实现。

        将其转化为代码,这里有需要注意的地方就是direction是局部坐标系的。在101中的作业3里做bumper时,我们使用TBN矩阵来将切线坐标系转化为世界坐标系。将切线坐标系转化为世界坐标系其实还需要uv坐标来确定,因为需要知道某个三角形在纹理上的位置。而这里只涉及方向的转化不涉及位置,所以直接使用TBN矩阵就能获得direction转化到世界坐标的朝向。作业框架里给我们提供了LocalBasis函数来获取两个切线。因此获取坐标系的三个方向后,使用它们创建一个TBN矩阵。

vec3 inDirectLight = vec3(0.0);
  for(int i =0;i<SAMPLE_NUM;i++){
    float pdf;
    vec3 direction = SampleHemisphereUniform(s,pdf);

    vec3 b1,b2;
    LocalBasis(normal,b1,b2);
    mat3 rotateMatrix = mat3(normal,b1,b2);
    direction = normalize(rotateMatrix * direction);
    vec3 hitPos;
    if(RayMarch(pos,direction,hitPos)){
      vec2 hitUV = GetScreenCoordinate(hitPos);
      inDirectLight += EvalDiffuse(direction,wo,uv)/pdf * EvalDiffuse(wi,direction,hitUV) * EvalDirectionalLight(hitUV);
    }
  }
  inDirectLight /= float(SAMPLE_NUM);
  L += inDirectLight;

        整个的main代码

vec3 EvalReflect(vec3 wi,vec3 wo,vec2 uv){
  vec3 pos = GetGBufferPosWorld(uv);
  vec3 normal = GetGBufferNormalWorld(uv);

  vec3 dir = normalize(reflect(-wo,normal) );
  vec3 hitPos;
  if(RayMarch(pos,dir,hitPos)){
    vec2 hitUV = GetScreenCoordinate(hitPos);
    return GetGBufferDiffuse(hitUV);
  }

  return vec3(0.0,0.0,0.0);
}

#define SAMPLE_NUM 3

void main() {
  float s = InitRand(gl_FragCoord.xy);

  vec3 pos = vPosWorld.xyz;
  vec2 uv = GetScreenCoordinate(pos);
  vec3 wi = normalize(uLightDir);
  vec3 wo = normalize(uCameraPos - pos );
  vec3 normal = GetGBufferNormalWorld(uv);


  //vec3 L = vec3(0.0);
  //L = GetGBufferDiffuse(GetScreenCoordinate(vPosWorld.xyz));  //初始的无阴影着色

  vec3 L = EvalDiffuse(wi,wo,uv) * EvalDirectionalLight(uv);  //用于调试带阴影的着色
  //L = ( L + EvalReflect(wi,wo,uv) ) / 2.0;  //用于调试反射

  vec3 inDirectLight = vec3(0.0);
  for(int i =0;i<SAMPLE_NUM;i++){
    float pdf;
    vec3 direction = SampleHemisphereUniform(s,pdf);

    vec3 b1,b2;
    LocalBasis(normal,b1,b2);
    mat3 rotateMatrix = mat3(normal,b1,b2);
    direction = normalize(rotateMatrix * direction);
    vec3 hitPos;
    if(RayMarch(pos,direction,hitPos)){
      vec2 hitUV = GetScreenCoordinate(hitPos);
      inDirectLight += EvalDiffuse(direction,wo,uv)/pdf * EvalDiffuse(wi,direction,hitUV) * EvalDirectionalLight(hitUV);
    }
  }
  inDirectLight /= float(SAMPLE_NUM);
  L += inDirectLight; 

  vec3 color = pow(clamp(L, vec3(0.0), vec3(1.0)), vec3(1.0 / 2.2));
  gl_FragColor = vec4(vec3(color.rgb), 1.0);
}

结果

        无阴影的结果

        含阴影的结果

        调试反射的结果,上面彩色格子的是正方体的面,这里反射的是地板的光。下面灰色的是地板面,反射的是正方体的光照。

        调试间接光照的结果,这里在engine里将cube1换成了cube2。调试cave时,cave是有自己的摄像机属性和光源属性的,需要额外调一下。

        原来硬阴影的cube2

        间接光照的cube2

        硬阴影的cave

实现了间接光照的cave

bonus部分没做了,原理不会很难,就是对RayMarch的优化。但是看其他大佬的作业,大家需要改动的地方特别多,最近没什么时间就没去做了= =

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

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

相关文章

Open3D mesh 网格简化(顶点聚类)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始mesh 3.2聚类后的mesh Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff0…

开源 AI 智能名片 O2O 商城小程序:引入淘汰机制,激发社交电商新活力

摘要&#xff1a;本文深入探讨在社交电商领域中&#xff0c;开源 AI 智能名片 O2O 商城小程序如何通过设置淘汰机制&#xff0c;实现“良币驱逐劣币”&#xff0c;激励士气&#xff0c;为社交电商企业注入新的活力。通过分析缺乏淘汰机制的弊端以及设置淘汰机制的优势&#xff…

sickos 靶机渗透(wolf cms 渗透,squid 代理)

靶机信息 vulnhub靶机 主机发现 192.168.50.152 为靶机Ip ┌──(kali㉿kali)-[~/testSickos] └─$ sudo nmap -sn 192.168.50.0/24 [sudo] password for kali: Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-30 09:56 CST Nmap scan report for 192.168.50.1 …

Linux 下查找运行中的 Java 进程及 .jar 文件位置

在 Linux 环境中&#xff0c;有时我们需要查找正在运行的 Java 进程以及它们对应的 .jar 文件位置。本文将介绍如何使用命令行工具来实现这一目标。 前言 在 Linux 系统中&#xff0c;我们经常需要监控正在运行的应用程序&#xff0c;特别是在出现问题时&#xff0c;了解应用程…

使用API有效率地管理Dynadot域名,添加账户中的联系人信息

前言 Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮箱&…

Android 移除最近任务列表展示

Android 设置应用在最近任务列表不展示 android 中想要实现在最近任务列表中不展示,实现的方式很简单. 在Mainifests的MainActivity中添加: android:excludeFromRecents“true” 如下所示: <activity android:name".MainActivity"android:excludeFromRecents&…

Nvidia股价前景引投资者情绪波动:杠杆ETF数据透视市场风向

一、Nvidia业绩前瞻&#xff1a;看跌情绪升温 随着Nvidia&#xff08;NVDA&#xff09;季度业绩发布日的临近&#xff0c;市场中的投资者情绪似乎正经历着微妙的变化。据多家发行杠杆型交易所交易基金&#xff08;ETF&#xff09;的机构数据显示&#xff0c;投资者对看跌Nvidia…

【机器学习】支持向量机(SVM)的对偶性、核方法以及核技巧

引言 在SVM中&#xff0c;通过引入拉格朗日乘子&#xff0c;可以将原始问题转化为对偶问题&#xff0c;这种转换具有几个重要的优点&#xff0c;包括简化计算和提供更直观的优化问题的解释 文章目录 引言一、支持向量机&#xff08;SVM&#xff09;的对偶性1.1 原始问题&#x…

【知识库系列】MPR/多模态方向观察:图像视频与3D生成

多模态背后的backbone会长成什么样&#xff1f; 各种模态到梯度下降到最后会不会都差不多&#xff1f; Sora 是不是已经被追上了? 我们真的把视频数据都用好了吗&#xff1f; 知识库完整文档&#xff1a; MPR/多模态方向观察&#xff1a;图像视频与3D生成&#xff1a;https…

【Unity3D优化】优化内置shader的内存占用

一、性能分析 监控项目线上的崩溃情况&#xff0c;绝大多数崩溃都是因为低端设备&#xff0c;运行时内存不足&#xff0c;在运行过程中申请开辟新的内存时Crash了。因此&#xff0c;不定期继续优化内存占用。 性能分析首先主要靠Unity3d的Memory Profiler监控一些可追踪到的内存…

初识redis:学习Java客户端

Redis服务器在官网公开了使用的协议&#xff0c;叫做RESP。任何一个第三方都可以通过上述的协议&#xff0c;来实现出一个和redis服务器通信的客户端程序。 Java生态中&#xff0c;封装好了RESP协议&#xff0c;实现的redis客户端是有很多的&#xff0c;此处使用的是jedis&…

操作系统:实验三进程间通信实验

一、实验目的 1、了解什么是信号。 2、熟悉LINUX系统中进程之间软中断通信的基本原理。 3、理解进程的同步关系。 4、掌握用信号实现进程间的同步操作。 5、了解什么是管道。 6、熟悉UNIX/LINUX支持的管道通信方式。 二、实验内容 1、阅读下列程序&#xff0c;执行程序…

【js逆向专题】1.js语法基础

小节目标: 逆向工具准备熟悉 逆向的基本过程熟悉 JavaScript语法 一.前期准备 1. 技术准备 python基础语法爬虫基础功底JavaScript基础语法知识(可以自己偷偷的学习一些) 2. 工具准备 node解释器 官网地址:https://nodejs.org/zh-cn (推荐安装版本16版本) 把提供的软件…

网络层 IV(ARP、DHCP、ICMP)【★★★★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、地址解析协议&#xff08;ARP&#xff09;&#xff08;★★&#xff09; 在局域网中&#xff0c;由于硬件地址已固化在网卡上的 ROM 中&#xff0c;因此常常将…

Gartner报告解读:如何帮助企业完善数据分析与治理路线图

Gartner服务于全球100多个国家和地区的14,000余家机构&#xff0c;是一家深受客户信赖、观点客观的研究顾问公司。Garnter洞察、建议和工具可帮助您发现创新机遇&#xff0c;完成关键优先任务&#xff0c;助您成为企业不可或缺的战略专家和价值创造者。该公司是标普 500 指数成…

ET6框架(八)事件系统

文章目录 一、事件的定义二、定义异步事件 一、事件的定义 我们打开Client > Unity.Model > Codes > Model > Demo > EventType.cs 即可以查看目前工程中的事件 我们可以此添加事件结构体 我们还需要定义一个事件接收方法&#xff0c;创建路径文件夹及脚本 …

84、 k8s的pod基础+https-harbor

一、pod基础&#xff1a; pod进阶&#xff1a;探针&#xff08;面试必问—扩缩容&#xff0c;挂载&#xff09; 1.1、pod的定义 pod是k8s里面的最小单位&#xff0c;pod也是最小运行容器的资源对象。 容器时基于pod在k8s集群当中工作。 在k8s集群当中&#xff0c;一个pod就…

基于Android+SQLite数据库开发Java考试App

项目简介 Java课程考试App是基于AndroidStudio和SQLite数据库开发的一款App可以实现教师考生双端登录并使用相应功能。以Java课程作为设计主题&#xff0c;针对它们设计、实现一个考试APP。满足教师用户通过APP进行考生管理&#xff08;考生信息的增删改查&#xff09;、试题管…

Python 项目及依赖管理工具技术选型

Python 项目及依赖管理工具&#xff0c;类似于 Java 中的 Maven 与 Node 中的 npm webpack&#xff0c;在开发和维护项目时起着重要的作用。使用适当的依赖管理工具可以显著提高开发效率&#xff0c;减少依赖冲突&#xff0c;确保项目的稳定性、可靠性和安全性。 一、常见项目…

怎样把图片转换成pdf文件?分享图片转PDF的九个转换方法(新)

图片转为pdf怎么弄&#xff1f;图片和pdf是两种完全不同的文件类型&#xff0c;图片转pdf的是一个比较常见的格式转换需求&#xff0c;尤其是需要分享图片合集时。 图片转换成pdf文件可以借助专业的pdf转换器实现&#xff0c;只需要简单几个步骤就能轻松搞定。无论是图片转pdf&…