我的软件渲染器终于初步完成了~

2023-11-15

记录一个大好事:在 2021年第一个月的上旬,我的软件着色器终于初具雏形了~
中间参考了 很多 资料

最初是 知乎上的系列教程

https://zhuanlan.zhihu.com/p/141210744

这个教程是基于 OpenGL ,右手坐标系实现的。是翻译的 github 上一个叫做 tinyrender 的 教程。结合原版食用效果更佳~
原版 github 上的图片都 看不到了,所以结合这篇知乎上的教程看,也很帮助人理解。

当时觉得比较困难的地方是 矩阵的推导,看这篇教程的时候完全没有去理解。后来觉得这样不行,翻出来在家里吃灰的两本书仔细参考:

第一本是<<3D数学基础:图形与游戏开发>> .这本书重点看了矩阵推导的部分。
由于一开始我看的教程是 基于 右手坐标系的 OpenGL 习惯的教程,而这本书所有地方全都是相反的,我去花时间掰顺了这方面的知识。在矩阵计算时候分为两套:

标准一:
左手坐标系 , 列矩阵(column major), 行向量, 向量 乘 Matrix 时 向量在左侧, 对向量做矩阵变换的时候 NewVertex = SrcVertex x Matrix1 x Matarix2 …

标准二:
右手坐标系,行矩阵(列矩阵的转置), 列向量, Matrix 乘 向量时 向量在右侧, 对向量做矩阵变换的时候 NewVertex = … x Matrix2 x Matrix1 x SrcVertex

上面值得一提的是 列矩阵,行矩阵。书里面的所有推导都是基于标准一的,所以那些结论中的 变换矩阵,在转换到 标准二的时候,都需要做转置!这些都是我亲自用笔来计算 得出的结论,如果不做转置那么结果整个就是错误的!

<<3D数学基础:图形与游戏开发>> 的推导部分虽然讲得很好,但是矩阵变换的部分却没有和实践联系起来。另一本书弥补了这一段的空白:<<3D 游戏大师变成技巧(上册)>>。

这本书从第6章第3节开始,和 整个第7章,就是在 讲解 矩阵的推算的。并且很有意思的是 给我感觉仿佛讲了两边。我当时的阅读顺序是先看的第 7 章矩阵推导的部分, 反过头来再看 第6章矩阵推导的部分,两部分结合起来,就觉得对矩阵推导成竹在胸了。

之前在看知乎上的材料的时候,我搭建了一个 基于 SDL2 的工作台,用于能够方便的 drawPixel(). 矩阵推导虽然我不是在知乎的链接上看明白的,但是 绘制直线 Bresenham 和 填充三角形的 线扫描算法,我是在那边看懂的。结合自己的 SDL2 的框架,先实现了一个简单的 2D 光栅渲染器。

在此之后,经过反复阅读上面两本书的矩阵推导部分,最后把矩阵变换录入到 我的 代码里。为了实现这个程序,我自己写了 基于 template 的vector 和 matrix , 重载了大部分常用的计算。其中有个很坑的地方: 在做 Matrix 和 Matrix 相乘的时候,我把 累积的 和 用 int 型保存了,但是这个问题在 Matrix 乘 Vector 的时候没有犯错。导致有一段时间,我的 Matrix 累成之后的 MVP 矩阵 和 我的 点坐标相乘结果是错误的,然而 每个矩阵 单独 和 点坐标 依次做乘法是正确的。这个问题让我查了三个中午。

准备好了 SDL2 绘点工作台,简单的 向量矩阵数学库,录入了 所有的 坐标变换矩阵公式之后,填充上一些 testcase 的顶点坐标信息(比如自己手填一个 Cube 的所有顶点坐标),一个 简单的软件光栅渲染器 就完成了!

下一步要做的是 面剔除,根据投影区域做剪裁,纹理采样,片段插值 ,增加光照等等。我要尽早挨个完成它们。

经过了这么 一个过程,渲染管线不再神秘,之前觉得 Vertex Shader 和 Fragment Shader 如何与宿主通信,以及这两个 shader 之间如何通信 这件事 也不再神秘。

我会在工作之余尽快把剩下的事情做完,摸透其中的原理,争取做到在公司内部做一次技术分享~

github 链接贴在这里

https://github.com/yunyou730/spinning

这个 repo 里面是一个 xcode 的 workspace .这个 workspace 里面的 AnyToy 工程无视~ tinyrender 工程是我看知乎帖子时候实现的版本,当时很多细节还没摸透。ayyrender 是我自己实现的版本,这个Demo 里面用到的代码每个字 都是自己理解之后手敲的,很有成就感。毕竟一个 从 2016年的时候就想做的事情,终于在 2021年开年有眉目了。在基础好的同学眼里看可能没什么,但是我已经是当年自己眼里的大神了~

我会继续完善它,陆续再记录一些实现细节吧

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的软件渲染器终于初步完成了~ 的相关文章

  • 接口未正确配置:wx.getLocation(暂无权限)

    原因 腾讯地理位置接口新增与相关流程 地理位置接口新增说明 由于精确地理位置接口只允许部分类目的小程序申请使用 为了满足开发者在更多场景使用地理位置接口 自 2022 年 7 月 14 日起 新增获取模糊地理位置接口 wx getFuzzy
  • 计算机网络第六章——应用层(下)

    等闲变却故人心 却道故人心易变 文章目录 用户代理就是用户和电子邮件系统之间的一个接口 通常都是运行在电脑中的一个程序 用户代理又可以称为电子邮件客户端软件 用户代理可以为用户提供一个比较友好的接口 邮件服务器作为一个服务器就需要长时间的工
  • 责任链模式(Chain of Responsibility) Java实现

    责任链模式 责任链模式 Chain of Responsibility 定义 责任链模式是一种对象的行为模式 在责任链模式里 很多对象由每一个对象对其下家的引用而连接起来形成一条链 请求在这个链上传递 直到链上的某一个对象决定处理此请求 发
  • 以太网(Ethernet)相关基础知识

    最近正好在学习以太网 感觉非常有用 进行一个总结 欢迎指正 如今 以太网已在现实中大量使用 低廉的价格和较快的速度都是它从许多网络中存活下来的因素 学校 公司中大多用得都是以太网 目录 以太网电缆 Ethernet Cabling 曼彻斯特
  • 移动端点击(click)事件延迟问题的解决方法

    移动端 click 事件会有 300ms 的延时 原因是移动端屏幕双击会缩放 double tap to zoom 页面 解决方案 1 禁用缩放 浏览器禁用默认的双击缩放行为并且去掉300ms 的点击延迟 2 利用touch事件自己封装这个
  • (mac)配置vue

    安装参考 https www jianshu com p cc722eba1f46 1 安装brew 一个安装 卸载软件的程序 https blog csdn net poppy rain article details 88406390
  • Java面试题第一季学习笔记

    Java面试题第一季 1 自增变量 2 单例设计 2 1 什么是Singleton 2 2 代码示例 3 类初始化 3 1 代码 3 2 考点 3 3 Override 重写 和Overload 重载 区别 4 方法的传递机制 4 1 代码
  • java 反射中的method.invoke()方法详解

    public class TestReflect public static void main String args String names tom tim allen alice Class
  • java关于ArrayList,Vector,LinkedList,Set及其面试题+LeetCode136两种方式实现

    ArrayList ArrayList的遍历补充 将list转换为数组 使用toArray 方法将列表转换为数组 再对数组进行遍历 Test void test01 List
  • vue3实现鼠标左键拖拽画矩形框框选功能

    vue3 elementuiPlus 实现鼠标左键拖拽画矩形框 框选列表功能 仿照桌面框选功能 效果如图 vue3鼠标框选 代码
  • Hibernate的核心配置

    Hibernate的设计思路 Hibernate是一种全自动化管理持久化对象的ORM框架 既提供了完全面向对象的封装完整的对象持久化接口 屏蔽db层的差异化 提升代码可移植性 也提供了操作HQL和SQL的半自动化DB访问接口 提供复杂查询的
  • JSVC的配置与使用详解

    JSVC是apache出的所谓common daemon的一个工具套件 他利用一个daemon程序 从而使tomcat这样的程序能在开机的时候自动启动 而且能使tomcat被 chkconfig这样的工具所管理 在之前的一篇文章中对jsvc
  • 算法岗面试问题总结(二)

    文章目录 1 SVM的loss是啥 2 kmeans聚类如何选择初始点 3 RF和GBDT谁更容易过拟合 偏差和方差 4 xgb的分类树也是用残差吗 不是的话是什么 5 讲讲数据倾斜怎么处理 6 请你说说SVM的优缺点 7 LR和SVM的联
  • C++中的typeInfo用法总结

    最近在做测试 在大型程序中 模板类型加上继承关系搞得我混乱 还好有tpyeinfo帮助捋顺关系 typeInfo与typeid简单总结说明 和sizeof这类的操作符一样 typeid是C 的关键字之一 typeid操作符的返回结果是名为t
  • jenkins学习笔记第十六篇 jenkins权限控制

    创建用户 对用户进行权限控制 在实际项目中 根据不同的用户 大致可分为 测试用户 开发用户 运维用户等 这时就需要给不同的用户赋予不能的权限 首选需要安装插件 Role based Authorization Strategy 这个插件主要
  • ctfshow-WEB-web14( 利用数据库读写功能读取网站敏感文件)

    ctf show WEB模块第14关是一个SQL注入漏洞 绕过switch循环后可以拿到一个登录界面 登录界面存在SQL注入 脱库以后会提示flag在另一个文件中 利用数据库的文件读写功能读取文件内容即可拿到flag 开局是一个switch

随机推荐

  • 智能优化算法之遗传算法(GA)的实现(基于二进制编码,Python附源码)

    文章目录 一 遗传算法的实现思路 二 基于二进制编码方式的遗传算法的实现 1 库的导入 2 目标函数 3 个体编码函数 4 个体解码函数 5 选择函数 6 交叉函数 7 变异函数 8 算法主流程 一 遗传算法的实现思路 遗传算法 Genet
  • Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比

    比较的指标 1 cpu 2 流量 3 电量 4 内存占用 5 联网时间 功能点 1 重试机制 2 提供的扩展功能 3 易用性 4 是否https 5 是否支持reflect api OkHttp有配套方法 6 缓存 重试 7 cookie支
  • Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解

    前往老猿Python博文目录 一 引言 对于带Logo 如抖音Logo 电视台标 的视频 有三种方案进行Logo消除 直接将对应区域用对应图像替换 直接将对应区域模糊化 通过变换将要去除部分进行填充 其中 方法1又可以使用三种方法 一是使用
  • C++之vector深度剖析

    C 之vector深度剖析 1 vector的介绍及使用 1 1 vector的介绍 1 2 vector的使用 1 2 1 vector的定义 1 2 2 vector iterator 的使用 1 2 3 vector 空间增长问题 1
  • python3-常用方法和函数总结(字符串)

    方法与函数的差别 调用方式 作用域 方法 对象 方法名 不释放空间 函数 函数名 自动释放空间 字符串常用函数与方法 函数 方法 说明 举例 capitalize 方法 将首字母变为大写 非首字母变为小写 str hEllo print s
  • UE4 DDC共享

    本人用的是源码引擎编译的 内网使用DDC 先创建一个共享文件夹 这个文件夹来保存共享资源 修改引擎的baseengine ini cpp DerivedDataBackendGraph Shared Type FileSystem Read
  • 栈内存与堆内存的区别

    栈内存和堆内存都是计算机中用于存储数据的内存区域 它们之间的主要区别在于 存储方式 栈内存采用 先进后出 的存储方式 而堆内存采用随机存储的方式 空间大小 栈内存的空间大小通常比堆内存的空间大小要小得多 生命周期 栈内存的生命周期比堆内存的
  • 使用Kotlin做一个简单的HTML构造器

    最近在学习Kotlin 看到了Kotlin Koans上面有一个HTML构造器的例子很有趣 今天来为大家介绍一下 最后实现的效果类似Groovy 标记模板或者Gradle脚本 就像下面 这是一个Groovy标记模板 这样的 html lan
  • Linux 下查看进程运行时长

    因为有一个Java程序运行中会持续输出大量的日志文件 可能导致磁盘空间不足 为了规避这个风险 需要根据程序运行时长估算磁盘使用量 1 查看进程的PID ps ef grep java 2 指定进程查看运行时长 PID ps o etime
  • SpringBoot优化

    一 SpringBoot全局异常处理 任何项目发生异常是不可避免的 使用全局异常捕获发生的异常是十分必要的 SpringBoot框架对全局异常捕 获提供了很好的支持 并且操作非常简单 我们只需要创建一个类和一个方法 并添加两个注解 Cont
  • LSTM分类模型

    LSTM文本分类模型 本文主要固定一个文本分类的流程 分为三个部分 数据处理 对分类文本数据集做简单的预处理 模型数据准备 处理上一步的结果 得到模型的输入样本 模型搭建和训练流程 模型使用BiLSTM 训练过程可以使用cpu或者GPU t
  • shell中的for循环的用法(C语言式)

    C语言式的for循环 用法 exp1 exp2 exp3 是三个表达式 其中exp2是判断条件 for循环根据exp2的结果来决定是否继续下一次的循环 statements是循环体语句 可以有一条 也可以有多条 do和done是shell中
  • Kotlin和Java中的IO操作

    Kotlin的特性 1 Kotlin提供了非常多 File Stream Reader Writer的拓展方法 2 使用use拓展自动关闭资源 3 小文件一次性读写操作 一 首先来看看繁琐的JavaIO操作 来读取一个文件 package
  • 有1、2、3、4四个数字,可以组成多少个互不相同且无重复的三位数?都是多少?

    这个题呢 顾名思义 就是说一个三位数的每一位都是1 2 3 4 个位十位百位上的数字不能重复 编程原理很简单 分别定义三个变量代表个位十位百位 然后使用for循环嵌套每一层循环代表一位数 如果个位十位百位都不相同 则输出 程序如下 incl
  • 微信订阅消息模板推送报错47003 data.time.value i,及解决方案

    今天又是枯燥的一天 依然敲着代码 客户有个微信消息推送的需求 找了下官方文档 微信消息推送文档 大致看了一下 需要模板ID和微信后台的小卡片参数名 随即便敲起了代码 首先定义模板类 代码如下 public class Template pr
  • 微信小程序实现一些炫酷的loading动画

    1 实现效果 2 实现原理 伪元素 css3动画 transform 3 实现代码 从上到下 从左到右依次的代码如下
  • 三款记事本替代工具 哪个最好用?

    三款记事本替代工具 哪个最好用 http www sina com cn 2008年08月27日 08 35 IT168 com Windows操作系统中自带了不少的实用小程序 但是它们大都功能简陋 有时无法满足我们的使用 此外还有一些Wi
  • MatplotLib 第二部分

    1 import numpy as np 2 import pandas as pd 3 import matplotlib pyplot as plt 4 5 导入数据 6 df pd read excel d test xlsx 7 p
  • 在VS中使用命令行参数

    在VS工具中 若要运行带有命令行参数的程序 有两种方法 方法一 在命令提示符中输入要运行的exe的文件名和要输入的参数 各参数之间用空格隔开 如exe文件为test exe 则输入 test 参数1 参数2 参数n 注意 exe文件应放在C
  • 我的软件渲染器终于初步完成了~

    记录一个大好事 在 2021年第一个月的上旬 我的软件着色器终于初具雏形了 中间参考了 很多 资料 最初是 知乎上的系列教程 https zhuanlan zhihu com p 141210744 这个教程是基于 OpenGL 右手坐标系