每日编程实践:Perlin 噪声程序化纹理生成
每日编程实践:Perlin 噪声程序化纹理生成🎯 项目概述在本项目中,我实现了一个经典的 Perlin 噪声生成器,用于创建自然的程序化纹理。Perlin 噪声由 Ken Perlin 于 1985 年发明,广泛应用于计算机图形学中的地形生成、云层模拟、水波效果等领域。 项目时间: 2026-02-10代码语言: C++代码行数: 230 行核心算法: Perlin Noise + Octave Noise Perlin 噪声原理Perlin 噪声通过以下步骤生成: 网格定义: 将空间划分为均匀的网格 梯度分配: 为每个网格点生成随机的梯度向量 平滑插值: 使用 fade 函数平滑插值网格点间的值 多层叠加: 通过 Octave Noise 添加多层次细节 核心数学实现Fade 函数(6t⁵ - 15t⁴ + 10t³)123double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10);} 这个函数确保插值在网格边界处平滑过渡,避免出现明显的不连续性。 梯度计算123456d...
05.载入3D模型|模型加载、简单着色与纹理映射
05.载入3D模型|模型加载、简单着色与纹理映射本项目代码已托管至github,将会随着博客实时更新进度每一节的工程我都会创建一个新的分支,分支名由这一节的数字决定。 https://github.com/chiuhoukazusa/LearningTinyrenderer/tree/05 前言在上一节的工作完成后,我们离渲染出一个正常的三维模型还剩下两步,纹理映射和着色,当然前提是得先把模型给加载了。 这一节先来尝试纹理映射和简单着色模型。 上一节我们说过要引入一个读取obj的头文件,但我觉得完全可以自己写一个简单的objloader,那就不引入了吧。 OBJ-MTL文件格式obj是最广泛使用的3维模型的格式,实际上obj只是一个纯文本文件,我们可以梳理出他的大致结构。而mtl也是一个纯文本文件,基本上和obj对应,会记录一些材质信息。 我们以games202的吉祥物为例来理解一下obj和mtl文件的结构: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
04.在MVP之后|裁剪、三角形光栅化与深度测试
04.在MVP之后|裁剪、三角形光栅化与深度测试本项目代码已托管至github,将会随着博客实时更新进度每一节的工程我都会创建一个新的分支,分支名由这一节的数字决定。 https://github.com/chiuhoukazusa/LearningTinyrenderer/tree/04 前言上一节中我们已经实现了一个简单的光栅化,但是这其实是完全不足够的,一个合理的三角形光栅化过程值得开一整节去叙述。 但这一节讲的将不仅仅是光栅化的过程,严格意义上讲,三角形光栅化基本上就是寻找三角形并且对一些属性插值的过程。但实际上图形渲染管线还有很多杂七杂八的步骤,我也将在这一节中进行讨论。 一般来说,MVP变换到光栅化,中间还应当有一个裁剪的步骤。而光栅化后就是着色,也是我们fragment shader工作的地方。着色后需要一个深度测试检测遮挡,用来判断哪些面是应该渲染的,当然着色后可能会有很多种不同的测试,但是我们这里先只讨论深度测试。 所有的测试都完成后会进入屏幕后处理阶段,可以做一些滤镜的效果,也可以做知名的RayMarching算法来构建诸如大气散射体积云等效果,当然也可以什么...
03.HelloTriangles|MVP变换
03.HelloTriangles|MVP变换本项目代码已托管至github,将会随着博客实时更新进度每一节的工程我都会创建一个新的分支,分支名由这一节的数字决定。 https://github.com/chiuhoukazusa/LearningTinyrenderer/tree/03 前言在上一节中,我们实现了一个基本可用的3d数学库,我们马上就会使用到他们。 这一节中我们将实现渲染的第一个流程,MVP变换。这一节的目标就是实现games101的作业1的效果,我们将会传入跟101作业中一样的参数,并检验产生的三角形是否一致。 MVP变换并不是有了上一节的矩阵运算法则基础就一下子就可以讲清的,要理解MVP变换,要先了解矩阵与图形变换的关系。 本节引用的图片来自《Fundamentals of Computer Graphics Fifth Edition》和《Physically Based Rendering From Theorty To Implementation Third Edition》,下文将分别简述为虎书和PBRT-v3。 变换矩阵(Transformatio...
02.简单3D数学库|封装向量类和矩阵类
02.简单3D数学库|封装向量类和矩阵类本项目代码已托管至github,将会随着博客实时更新进度每一节的工程我都会创建一个新的分支,分支名由这一节的数字决定。 https://github.com/chiuhoukazusa/LearningTinyrenderer/tree/02 前言在上一节的工程中,给定两个点,我们已经做到成功画出一条唯一确定的线段了。但是为了我们以后方便,我们显然需要封装向量类和矩阵类。当然我们可以直接使用Eigen库来完成这个问题,Eigen库非常的好用,但是我更想自己写一个试试。我们要做的其实完全不复杂,仅仅是封装几个类,并且没有什么性能要求,不会涉及到使用一些指令集来进行加速。所有的一切都将只用一些比较简单的c++代码进行实现。 本节代码参考了一部分pbrt-v3的配套代码中的geometry.h文件中的实现方式和DirectXMath库的设计方式,来封装一些简单的涉及3d数学的类。以下是pbrt-v3的源码: https://github.com/mmp/pbrt-v3 我们需要做的pbrt-v3中的数学库实现相当细致,不仅仅只是封装了向量和矩阵,...
01.一切的开始|Bresenham算法绘制线段
01.一切的开始|Bresenham算法绘制线段本项目代码已托管至github,将会随着博客实时更新进度每一节的工程我都会创建一个新的分支,分支名由这一节的数字决定。 https://github.com/chiuhoukazusa/LearningTinyrenderer/tree/02 前言看着一片黑屏的渲染器和空空如也的cpp文件,我们可能无从下手,那就让我们回忆一下相关图形学知识。 我们都知道模型是由三角面构成的,三角面首先得有三角形,三角形又得有三条边。所以绘制线段就是我们要做的第一步。 绘制一条从(x0, y0)到(x1, y1)的线段因为我们是在像素上操作,所以我们就将传进来的这四个参数当做是int类型处理。 我们都知道直线拥有一个点斜式方程。 y=kx+by = kx + b y=kx+b 我们能得到y的增量和x的增量之间的关系 △y=k△x△y = k△x △y=k△x 那么我们让x每次增加一个像素的距离,这样每次△y就是一个固定的值,加上后让y再四舍五入到对应的像素点,把像素点画出来就行。 听起来很简...
00.图形学入门之重新造轮子|软件光栅器
00.图形学入门之重新造轮子|软件光栅器“纸上得来终觉浅,绝知此事要躬行。”图形学的理论知识相当多,但终归还是要落到代码上来,毕竟这是一门工程性质的学科,想检验自己的理论知识就去实现它。 为什么要做软件光栅?图形学理论实践我认为在一头冲进opengl、dx11/12、vulkan这些之前,我们可以先来关注一下这些图形api都是怎么运作的。同时我也刚学完了games101的课程,目前还没接触太多高质量实时渲染相关的知识。我认为在此之前先给自己101的课程来一个总结,来一个实践更容易巩固自己的相关知识基础,并且把自己在101的作业中实现的功能都尽量在自己的渲染器里实现一遍。 C++工程能力锻炼这个也许是更重要的原因。理论学的再多也只是理论,就像你在大学里可能会学建筑力学、结构力学、工程地质学等等理论,但是如果不去工地上真真切切地戴着安全帽打一打灰,你也不可能成为一个优秀的工程师。这在所有工科都是通用的经验。C++素以复杂、难学出名,如果不去真的在写代码,很容易陷入“看啥啥简单”的陷阱。我自己的C++水平也非常的不乐观,所以我决定在项目中锻炼锻炼C++。 我们的目标我目前的想...








