GAMES202作业3

news2025/1/10 11:45:00

EvalDiffuse

  • 对于一个diffuse的着色点,它的BRDF为:
  • \frac{\rho}{\pi} \cdot cos(wi,n)
/*
 * Evaluate diffuse bsdf value.
 *
 * wi, wo are all in world space.
 * uv is in screen space, [0, 1] x [0, 1].
 *
 */
vec3 EvalDiffuse(vec3 wi, vec3 wo, vec2 uv) {
    vec3 albedo = GetGBufferDiffuse(uv);
    vec3 normal = GetGBufferNormalWorld(uv);
    float cosine = max(0.0, dot(wi, normal));
    return albedo * cosine * INV_PI;
}

EvalDirectionalLight

  • 就是针对每个顶点考虑可见度的光照计算
vec3 EvalDirectionalLight(vec2 uv) {
    float visibility = GetGBufferuShadow(uv);

    vec3 Le = uLightRadiance * visibility;
    return Le;
}

直接光照的检验

可以检验直接光照是否正确

void main() {
  float s = InitRand(gl_FragCoord.xy);
  vec3 w0 = normalize(uCameraPos - vPosWorld.xyz);
  vec3 wi = normalize(uLightDir);
  vec2 screenUV = GetScreenCoordinate(vPosWorld.xyz);
  //vec3 L = vec3(0.0);
  vec3 L = EvalDiffuse(wi, w0, screenUV) * EvalDirectionalLight(screenUV);
  //L = GetGBufferDiffuse(GetScreenCoordinate(vPosWorld.xyz));
  vec3 color = pow(clamp(L, vec3(0.0), vec3(1.0)), vec3(1.0 / 2.2));
  gl_FragColor = vec4(vec3(color.rgb), 1.0);
}

Screen Space Ray Tracing

实现SSR的找交点的算法,通过倍增的方式快速找到交点,但是这里我感觉如果和课上的内容一样,应该还有一步存储一个step中最浅高度的做法,这里我没写这一步,偷懒了。。。

bool RayMarch(vec3 ori, vec3 dir, out vec3 hitPos) {
    float step = 0.08;
    float mulStep = 1.0;
    const int num_step = 50; //max steps
    bool intersect = false;
    vec3 curPos = ori;
    for(int i = 0; i < num_step; i++){
        vec3 wpos = curPos + step * mulStep * dir;
        intersect = false;
        if(outScreen(wpos)){
            return false;
        }
        if(Front(wpos)){
            curPos = wpos;
            mulStep *= 2.0;
        }
        else{
            intersect = true;
            if(mulStep <= 1.0){//close
                float d1 = GetGBufferDepth(GetScreenCoordinate(curPos)) - GetDepth(curPos);
                float d2 = GetDepth(wpos) - GetGBufferDepth(GetScreenCoordinate(wpos));
                if(d1 > 0.0 && d2 > 0.0){
                    curPos = wpos;
                    hitPos = curPos;
                    return true;
                }

            }
        }
        if(intersect){
            mulStep /= 2.0;
        }
    }
    return false;
}

写一个验证的逻辑

vec3 EvalReflect(vec3 wo, vec3 Pos, vec2 uv){
    vec3 normal = normalize(GetGBufferNormalWorld(uv));
    vec3 hitPos;
    if(RayMarch(Pos, reflect(-wo, normal), hitPos)){
        return GetGBufferDiffuse(GetScreenCoordinate(hitPos));
    }
    else{
        return vec3(0.);
    }
}

间接光照

  • 首先前面两个就是采样和判断射线是否和其它物体有交点,这就是之前的光线追踪的做法
  • 如果没有交点,计算直接光照
  • 如果有交点以后,因为我们认为间接光照源都是漫反射材质,所以只需要使用第一大步计算的两个函数来计算交点间接光照物体对着色点的光照贡献。
  • 根据蒙特卡洛方法

  • 对于间接光照而言在计算hitpoint的时候就考虑了visibility。所以乘一个着色点的bsdf,除以采样概率
  • 最后除以采样的次数。

我们需要使用作业框架提供的函数LocalBasis(vec3 n, out vec3 b1, out vec3 b2),取得两个切线向量,然后组成TBN矩阵把这个局部向量转换成世界坐标下的方向向量,也就是我们世界空间下的步进方向。

void main() {
  float s = InitRand(gl_FragCoord.xy);
  vec3 w0 = normalize(uCameraPos - vPosWorld.xyz);
  vec3 wi = normalize(uLightDir);
  vec2 screenUV = GetScreenCoordinate(vPosWorld.xyz);
  //vec3 L = vec3(0.0);
  //vec3 L = EvalDiffuse(wi, w0, screenUV) * EvalDirectionalLight(screenUV);
  //vec3 L = EvalReflect(w0, vPosWorld.xyz, screenUV);
  //L = GetGBufferDiffuse(GetScreenCoordinate(vPosWorld.xyz));
  vec3 normal = normalize(GetGBufferNormalWorld(screenUV));
  vec3 L = EvalDiffuse(wi, w0, screenUV) * EvalDirectionalLight(screenUV);
  vec3 inL = vec3(0.);
  for(int i = 0; i < SAMPLE_NUM ; i++){
    float pdf;
    vec3 localPos = SampleHemisphereCos(s, pdf);
    vec3 b1;
    vec3 b2;
    LocalBasis(normal, b1, b2);
    vec3 dirSam = normalize(mat3(normal, b1, b2) * localPos);
    vec3 hitPos;
    if(RayMarch(vPosWorld.xyz, dirSam, hitPos)){
      vec2 hitScreenUV = GetScreenCoordinate(hitPos);
      inL += ((EvalDiffuse(dirSam, w0, screenUV) * EvalDiffuse(wi, -dirSam, hitScreenUV) * EvalDirectionalLight(hitScreenUV)) /pdf);
    }
  }
  L += inL;
  L /= float(SAMPLE_NUM);
  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.js

// Add shapes
//loadGLTF(renderer, 'assets/cube/', 'cube1', 'SSRMaterial');
loadGLTF(renderer, 'assets/cube/', 'cube2', 'SSRMaterial');
// loadGLTF(renderer, 'assets/cave/', 'cave', 'SSRMaterial');

采样20次后,可以看到一个不错的color bleeding现象

//engine.js

// Add shapes
//loadGLTF(renderer, 'assets/cube/', 'cube1', 'SSRMaterial');
//loadGLTF(renderer, 'assets/cube/', 'cube2', 'SSRMaterial');
loadGLTF(renderer, 'assets/cave/', 'cave', 'SSRMaterial');

提高

参考

Bonus 1:实现Mipmap优化的 Screen Space Ray Tracing(Hiz优化)

  • 还记得上面我们说的就是理论上应该是和一个步长的最大的最浅的深度进行比较

  • 一个简单的优化思路是,我们使用深度图Mipmap,与常见Mipmap不同,这里使用的Mipmap不是记录更大一层的Mipmap对应的四个像素的平均值,而是记录四个像素的最小值。

  • 有了最小深度的Mipmap后,我们相当于有了一个场景深度的加速结构,处于上层的Mipmap中的一个像素对应的深度反映了下层的Mipmap的一片区域的最小深度,如果当前光线与较上层的Mipmap无相交,则与下层的Mipmap也无相交。
  • 有了这个结构后,我们就可以动态调整步进距离了,我们可以尝试先步进一个小的距离,若与场景物体无相交,则可以逐步提高当前采样的Mipmap等级,因为高层Mipmap的一个像素对应了低层Mipmap的一个区域,提高了Mipmap等级也意味着步进距离也可以跟着增大了,若在高层Mipmap判断与场景物体有相交,意味着光线在这片区域内存在与场景物体的交点,则需要降低Mipmap等级直到找到具体的相交位置点。

占个坑以后看参考

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

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

相关文章

【Linux】基本认知全套入门

目录 Linux简介 Linux发行版本 发行版选择建议 Centos-社区企业操作系统 Centos版本选择 Linux系统目录 Linux常用命令 SSH客户端 Linux文件操作命令 vim重要快捷键 应用下载与安装 netstat&#xff0c;ps与kill命令使用 Linux应用服务化 Linux用户与权限 Linu…

接口自动化测试实战

测试前准备&#xff1a; 1、项目的介绍 是一个什么项目、项目技术、项目要测的接口和业务流程、业务路径测试用例&#xff08;通过业务流程来梳理业务路径&#xff09; 2、链接和登录密码&#xff1a; 客达天下http://huike-crm.itheima.net/#/clue 客达天下账号admin&…

支持向量机-笔记

支持向量机&#xff08;Support Vector Machine, SVM&#xff09; 是一种强大的监督学习算法&#xff0c;广泛应用于分类和回归任务&#xff0c;特别是在分类问题中表现优异。SVM 的核心思想是通过寻找一个最优超平面&#xff0c;将不同类别的数据点进行分割&#xff0c;并最大…

【YOLO学习】YOLOv4详解

文章目录 1. 整体网络结构1.1 结构图1.2 创新点概括 2. 输入端创新点2.1 Mosaic数据增强2.2 cmBN策略 3. Backbone创新点3.1 CSPDarknet533.2 Mish函数3.3 Dropblock正则化 4. Neck创新点4.1 SPP模块4.2 PAN 5. Prediction5.1 Loss5.2 NMS 1. 整体网络结构 1.1 结构图 1.2 创新…

PostgreSQL学习笔记三:数据类型和运算符

数据类型和运算符 PostgreSQL 支持多种数据类型和运算符&#xff0c;以下是一些常见的数据类型和运算符的概述&#xff1a; 数据类型 基本数据类型 整数类型&#xff1a; SMALLINT&#xff1a;2 字节&#xff0c;范围 -32,768 到 32,767。INTEGER&#xff1a;4 字节&#xff0…

vue3 vue2

vue3.0是如何变快的&#xff1f; diff算法优化 vue2的虚拟dom是进行全局的对比。vue3 新增了静态标记&#xff08;patchFlag&#xff09; 在与上次虚拟节点进行比较的时候&#xff0c;只对比带有patch Flag的节点&#xff0c;并且可以通过flag的信息得知当前节点要对比的具体内…

先进封装技术 Part03---重布线层(RDL)的科普

先进封装核心技术之一:重布线层(RDL)的科普文章 1、 引言 随着电子设备向更小型化、更高性能的方向发展,传统的芯片互连技术已经无法满足日益增长的需求。在这样的背景下,RDL(Re-distributed Layer,重布线层)技术应运而生,成为先进封装技术中的核心之一。 2、 RDL技术…

yolov8.yaml

前面说了yolov8的核心代码放在ultralytics里面&#xff0c;今天我们一起学习一下 YOLOv8模型下的Ultralytics文件目录结构。每个文件夹都有不同的作用&#xff0c;以下是对各个文件夹的解释&#xff1a; assets: 这个文件夹通常存放与模型相关的资源文件&#xff0c;可能包括训…

MySQL五千万大表查询优化实战

背景 DBA同事在钉钉发了两张告警截图&#xff0c;作为“始作俑者”的我很心虚&#xff0c;因为刚才是我在管理后台查询数据&#xff0c;结果很久都没出来&#xff0c;并且用多个维度查了N次 问题分析 这是当天上线的功能&#xff0c;完事我立马锁定SQL然后开启排查 # 原SQL&a…

系统性能优化

在程序员的职业生涯中&#xff0c;解决当前系统问题&#xff0c;优化性能&#xff0c;是走向高阶的必经之路。如果一辈子做着后台开发&#xff0c;写着CRUD&#xff0c;QPS低于10&#xff0c;那确实没必要去做性能优化&#xff0c;因为根本用不上。性能优化范围很广&#xff0c…

排序|插入排序|希尔排序|直接选择排序|堆排序的实现即特性(C)

插入排序 基本思想 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a; 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。 单趟 当插入第 i ( i ≤ 1…

人数识别 人员超员识别系统 作业区域超员预警系统 ai#YOLO视觉

在当今复杂的生产作业与社会管理场景中&#xff0c;人员管理的精准性和高效性变得愈发重要。人数识别、人员超员识别系统、作业区域超员预警系统以及特殊岗位人员达标监测等&#xff0c;都是保障安全生产、提高运营效率和维护社会秩序的关键要素。随着人工智能(AI)技术的飞速发…

【Python实例】Python读取并绘制nc数据

【Python实例】Python读取并绘制nc数据 准备&#xff1a;安装netCDF库等读取nc数据相关信息绘制图形利用basemap绘图 参考 准备&#xff1a;安装netCDF库等 以【1960-2020年中国1km分辨率月降水数据集】中2020年降水为例。 先在Panopoly中查看数据属性&#xff0c;如下&#…

单细胞转录组 —— kb-python 原始数据处理

单细胞转录组 —— kb-python 原始数据处理 前言 kallisto|bustools 是一种用于预处理 scRNA-seq 数据的工作流程。 数据预处理步骤包括&#xff1a; 将 reads 与其来源细胞关联起来&#xff1b;根据唯一分子标识符&#xff08;UMI&#xff09;对 reads 进行去重&#xff1…

西门子S7-200 SMART高速计数器指令向导

在 Micro/WIN SMART 中的命令菜单中选择 Tools&#xff08;工具&#xff09;> Wizards&#xff08;向导&#xff09;中选择 High Speed Counter&#xff08;高速计数器向导&#xff09; &#xff0c;也可以在项目树中选择 Wizards&#xff08;向导&#xff09;文件夹中的 Hi…

下载相应版本的PyTorch

1、前置条件 下载某个版本的Python&#xff0c;本文涉及的Python版本为3.10 2、查看该Python版本可以下载的whl文件格式 pip debug --verbose 从上图可以发现python3.10可以下载格式为cp310-cp310-win_amd64的whl文件 PyTorch各稳定版本下载链接&#xff1a;https://downloa…

GNN与Transformer创新结合!模型性能起飞!

近年来&#xff0c;图神经网络&#xff08;GNN&#xff09;和Transformer模型因其在处理复杂数据结构和序列依赖性方面的卓越表现而受到广泛关注。这种优势使得将GNN与Transformer结合成为图表示学习领域的一个新兴且充满潜力的研究方向。通过结合这两种模型&#xff0c;我们不…

软考下午题1-数据流图

问题一&#xff1a;求实体的名称 例题&#xff1a; 1.提问方式-如问题1 从子图(0层数据流图)找比较快 外部实体可以是 人、物体、系统 在子图中找到加工&#xff0c;与文章中加工文字相对应&#xff0c;继续读文章&#xff0c;可以找到实体 E1-巴士列表文件 E2-机械师 E3-会…

《深度学习》LSTM 长短期记忆网络 结构及原理解析

目录 一、关于LSTM网络 1、什么是LSTM网络 举例&#xff1a; 2、RNN网络的结构 3、Tanh双曲正切函数 二、LSTM网络结构 1、遗忘门 1&#xff09;功能 2&#xff09;步骤 2、输入门 1&#xff09;功能 2&#xff09;步骤 3、输出门 1&#xff09;功能 2&#xff09;步骤…

斯坦福 CS229 I 机器学习 I 构建大型语言模型 (LLMs)

1. Pretraining -> GPT3 1.1. Task & loss 1.1.1. 训练 LLMs 时的关键点 对于 LLMs 的训练来说&#xff0c;Architecture&#xff08;架构&#xff09;、Training algorithm/loss&#xff08;训练算法/损失函数&#xff09;、Data&#xff08;数据&#xff09;、Evalu…