当前位置: 首页 > news >正文

中小型网站建设的基本流程如何快速备案网站

中小型网站建设的基本流程,如何快速备案网站,沈阳鹊起网站建设,郑州网站开发定制前言 本篇博客参照自《Ray Tracing: The Next Week》教程#xff0c;地址为#xff1a;https://raytracing.github.io/books/RayTracingTheNextWeek.html 该教程在ray tracing in one weekend的基础上#xff0c;增加了运动模糊、BVH树、Texture映射、柏林噪声、光照、体积…前言 本篇博客参照自《Ray Tracing: The Next Week》教程地址为https://raytracing.github.io/books/RayTracingTheNextWeek.html 该教程在ray tracing in one weekend的基础上增加了运动模糊、BVH树、Texture映射、柏林噪声、光照、体积渲染等内容。 渲染器的构建过程 与我的上一篇系列笔记类似我会顺序罗列我认为重要的部分。 运动模糊 这一点和散焦模糊有些类似也是模仿真实相机拍摄到的现象即当相机的快门按下时运动的物体会发生模糊。 要实现这一点方法是在发射采样光线时令光线在快门的这一段时间内随机发射再混合采样结果。为光线增加了一个时间t属性。 于此同时为场景种添加相应的运动物体比如运动的球体在1秒的时间内球体会在某一个方向上移动。这时因为光线包含时间属性t时刻的光线r会打到在该时刻对应位置的物体表面上。 最后渲染时则是将在快门这一时间段内所有的光线追踪结果混合。 以下是运动模糊的渲染结果 BVH树 BVH树是一种空间划分的数据结构可以有效提高光线与物体求交的效率。 在该教程中BVH树的建立分为以下几步 将所有图元包裹在一个大的包围盒中。 进行BVH树的划分。 一直分到BVH树的叶子节点只有一个图元为止。 作者在划分BVH树时不希望留下空子树的问题因此在划分子树时若当前只剩下一个图元文中会令这个图元既属于左子树又属于右子树。另外在划分过程中对于[begin, end]范围内的图元中点为mid文中会将[begin, mid]划归左子树[mid, end]划归右子树相当于mid这个位置的图元既属于左子树又属于右子树。这种划分方式属于作者的喜好有它的优势。 一个BVH树的例子如下 包围盒 BVH树采用的包围盒应当便于计算相交且紧密AABB包围盒符合这个条件。 三维场景内的AABB包围盒为包含目标图元且边平行于坐标轴的最小六面体。 如何计算射线与AABB包围盒的相交拿二维场景举例如下图所示射线在与x的两个边界相交时对应的相交位置为t1、t2射线在与y的两个边界相交时对应的相交位置为t3、t4如果射线与这个2D AABB包围盒相交则t1、t2与t3、t4 的范围重叠。 三维空间中与上述类似当射线与x、y、z方向的对应平面相交时如果范围有重合则说明射线与包围盒相交。 如何求解射线与对应平面的交点因为边界都是轴对齐的将射线的方程带入对应边界的x、y或z值即可。 BVH树的划分 BVH树的划分主要分为三个步骤 随机选择一个轴对BVH树种的图元进行排序对这些图元进行二分构建子BVH树 文中给出的方法是每次随机选出一个轴当然也可以轮流选择x、y、z轴。在排序时依据的排序规则是每个图元对应轴的最小值。在C中可以构建box_x_compare、box_y_compare、box_z_compare然后调用sort方法对数组进行排序。 最终按照文中给出的BVH树构建方法光线追踪的渲染过程有所加速。 纹理映射 在光线追踪中纹理映射是一个反向寻找的过程即通过射线与物体的交点反向推算出交点在纹理中的颜色、凹凸等其他属性。这和光栅化不同光栅化是通过纹理获得物体所有表面的颜色等属性然后通过光栅化的过程投射给图像。 文中介绍了几种纹理分别是纯色纹理、空间纹理、以及利用uv坐标的纹理。 纯色纹理。与uv坐标和空间坐标都无关利用纯色纹理的材质物体表面的所有颜色都一样。 空间纹理。采样和物体表面的空间坐标有关和uv坐标无关即物体表面某一点的颜色由该点的世界坐标(x, y, z)计算得出。 方格纹理就是一种空间纹理对于任意一点其颜色的计算是这样的对于坐标(x, y, z)首先向下取整得到三个整数结果(⌊x⌋,⌊y⌋,⌊z⌋)将这三个结果相加并进行模2运算得到0或1。如果结果为0将映射到偶数颜色如果结果为1将映射到奇数颜色。 方格纹理的一个例子如下 利用uv坐标的纹理。需要知道如何根据物体表面的三维坐标计算uv纹理坐标再利用纹理坐标做颜色运算。因为场景中目前提供的模型都是球体且目前也不涉及旋转因此这里的uv坐标直接沿着球面计算。 球面的uv坐标用经纬度表示其中u Φ / 2πv θ / πΦ为对应点在单位球中的经度θ为对应点在单位球中的纬度。球面上点的三维关系与经纬度的关系如下 y − c o s ( θ ) x − c o s ( ϕ ) s i n ( θ ) z s i n ( ϕ ) s i n ( θ ) y -cos(\theta)\\ x -cos(\phi)sin(\theta)\\ z sin(\phi)sin(\theta) y−cos(θ)x−cos(ϕ)sin(θ)zsin(ϕ)sin(θ) 从而可得 ϕ a t a n 2 ( − z , x ) π θ a r c c o s ( − y ) \phi atan2(-z, x) \pi\\ \theta arccos(-y) ϕatan2(−z,x)πθarccos(−y) 注意这里因为atan2的数值范围为-π到π但是为了让u映射到[0, 1]范围需要加上一个π。 利用uv坐标的纹理效果如下 柏林噪声 柏林噪声是一种自然噪声生成算法。文中主要利用柏林噪声生成空间纹理。 教程中一步步地给出3D柏林噪声的迭代改进过程。 第零次迭代按照上述方格纹理的思路首先生成一个大小为256的double数组ranfloat其中的每个值为从0到1的随机。对于物体表面的每一个点根据其三维坐标(x, y, z)得出一个指向ranfloat的下标并根据这个下标计算出方格的灰阶。其计算代码如下 int i static_castint(4 * x) % 256; int j static_castint(4 * y) % 256; int k static_castint(4 * z) % 256;int index i ^ j ^ k; double grayscale ranfloat[index];这一步可以得出一种类似瓦片的效果这种纹理是重复的。 第一次迭代在上述瓦片贴图的基础上加一些随机具体到计算主要是对上述代码中的ijk进行随机。这一部分的计算代码如下 static int* perlin_generate_perm(){int p new int[256];for(int i 0;i256;i) p[i] i;for(int i 255;i0;i--){int target random_int(0, i); // 返回一个[0, i]范围的整数swap(p[i], p[target]);}return p; } // noise函数内部 {...int* perm_x perlin_generate_perm();int* perm_y perlin_generate_perm();int* perm_z perlin_generate_perm();i perm_x[i];j perm_y[j];k perm_z[k];... }这一步的纹理效果 第二次迭代在生成噪声时进行线性插值。这一步是将一个点周围8个位置的值做平均加权运算得出当前位置的灰阶。其核心计算代码如下 static double trilinear_interp(double c[2][2][2], double u, double v, double w){double accum 0.0;for (int i0; i 2; i)for (int j0; j 2; j)for (int k0; k 2; k)accum (i*u (1-i)*(1-u))*(j*v (1-j)*(1-v))*(k*w (1-k)*(1-w))*c[i][j][k];return accum; }// noise函数内部 {...int u x - floor(x); // floor为向下取整运算int v y - floor(y);int w z - floor(z);int i static_castint(floor(x));int j static_castint(floor(y));int k static_castint(floor(z));double c[2][2][2];for(int di0;di 2;di){for(int dj0;dj2;dj){for(int dk0;dk2;dk){c[di][dj][dk] ranfloat[perm_x[(idi) % 256] ^perm_y[(jdj) % 256] ^perm_z[(kdk) % 256]];}}}double grayscale trilinear_interp(c, u, v, w);... }此时得出的结果 第三次迭代采用Hermitian插值而不是线性插值来得到uvw的值让结果更平滑消除上述明显的网格特征。添加代码 u u*u*(3-2*u); v v*v*(3-2*v); w w*w*(3-2*w);这一步得出的结果 第四次迭代调整噪声贴图的频率方法就是将一个比例系数scale乘以(x, y, z)坐标值scale越大频率就越大。我的理解是这种噪声的生成有一个模式每经过一定的间隔就会得出相似的噪声结果。把坐标值增大再来采样等效于将模式的间隔缩小这样导致的结果便是噪声图看起来频率更高。 这一步得出的效果如下 第五次迭代上面的结果看起来仍然有些块状或许是因为这种模式的最小值和最大值总是恰好落在(x, y, z)都为整数的坐标上。因为当(x, y, z)为整数时u, v, w的值均为0此时trilinear_interp的结果为c[0][0][0]等于这个点没有和周围做平均运算。 可以用随机vec3数组ranvec代替之前的随机double数组ranfloat进行采样。在加权平均时用权重向量和周围点的随机向量做点积累加获得当前点的采样值。这样可以避免最小和最大值总是恰好落在整数坐标上。由于乘出来的值有可能小于零需要做0.5 * (grayscale 1.0)的归一化操作。 这一步的核心代码如下 static double perlin_interp(vec3 c[2][2][2], double u, double v, double w) {double uu u*u*(3-2*u);double vv v*v*(3-2*v);double ww w*w*(3-2*w);double accum 0.0;for (int i0; i 2; i)for (int j0; j 2; j)for (int k0; k 2; k) {vec3 weight_v(u-i, v-j, w-k);accum (i*uu (1-i)*(1-uu))* (j*vv (1-j)*(1-vv))* (k*ww (1-k)*(1-ww))* dot(c[i][j][k], weight_v);}return accum; } // noise函数内部 {...double u x - floor(x);double v y - floor(y);double w z - floor(z);int i static_castint(floor(x));int j static_castint(floor(y));int k static_castint(floor(z));vec3 c[2][2][2];for (int di0; di 2; di)for (int dj0; dj 2; dj)for (int dk0; dk 2; dk)c[di][dj][dk] ranvec[perm_x[(idi) % 256] ^perm_y[(jdj) % 256] ^perm_z[(kdk) % 256]];double grayscale perlin_interp(c, u, v, w);... }这一步的结果如下图 第六次迭代制造湍流效果。将多个不同频率的噪声以不同的权重相加这就是湍流。湍流部分的计算代码如下 double turb(const point3 p, int depth7) const {double accum 0.0;double temp_p p;double weight 1.0;for (int i 0; i depth; i) {accum weight*noise(temp_p);weight * 0.5;temp_p * 2;}return fabs(accum); }这一步得出的效果如下 注这里的噪声图颜色很深是因为这里的效果没有做归一化操作而是直接把小于零的结果直接取绝对值了。 第七次最后一次迭代调整相位。将得出的灰度值送入正弦函数做计算可以得到起伏的结果。利用相位迭代可以实现类似大理石表面的纹理效果。这一步的核心代码如下 double s scale * p; color color(1,1,1) * 0.5 * (1 sin(s.z() 10*noise.turb(s)));效果图如下 平行四边形 除了球体之外教程中终于添加了另外一种图元平行四边形。 平行四边形用一个基点和两个向量表示基点Q、两个边向量u和v。 如何实现射线与平行四边形的求交主要分三步。 找到包含这个平行四边形的平面。 判断射线与这个平面的相交情况。 判断交点是否在这个平行四边形内。 找到四边形的平面 可以用u和v的叉乘得出平面法线再将基点Q带入便可得出这个平面方程。 判断射线与这个平面的相交 射线由一个基点和一个方向向量表示判断射线与这个平面的相交可以将射线的方程带入平面的方程。如果射线与平面平行或共面则认为不相交如果不平面则求出这个交点判断是否在射线的有效范围内。我们可以得到以下的式子。 平面方程 A x B y C z D 射线方程 R ( t ) P t d 代入可得 n ∗ ( P t d ) D 解方程 n ∗ P n ∗ t d D n ∗ P t ( n ∗ d ) D t D − n ∗ P n ∗ d 平面方程Ax By Cz D \ 射线方程R(t) \mathbf P t\mathbf d\\ 代入可得\mathbf n * (\mathbf P t\mathbf d) D \\ 解方程\mathbf n *\mathbf P \mathbf n * t\mathbf d D\\ \mathbf n *\mathbf P t(\mathbf n *\mathbf d) D\\ t \frac{D - \mathbf n * \mathbf P}{\mathbf n * \mathbf d} 平面方程AxByCzD 射线方程R(t)Ptd代入可得n∗(Ptd)D解方程n∗Pn∗tdDn∗Pt(n∗d)Dtn∗dD−n∗P​ 如果t属于射线范围[t_min, t_max]之内则认为射线与这个平面相交。 判断交点是否在这个平行四边形内 将平面的点转换成以u、v为基底的二维坐标系中对于任意一个点P可以表示为P Q αu βv。做以下运算 令 p P − Q α u β v p 是从 Q 到 P 的向量 将 u 、 v 向量分别与 p 叉乘 v × p α ( v × u ) β ( v × v ) α ( v × u ) u × p α ( u × u ) β ( u × v ) β ( u × v ) 向量的除法不能直接进行两边点乘 n n ∗ ( v × p ) n ∗ α ( v × u ) n ∗ ( u × p ) n ∗ β ( u × v ) 则 α n ∗ ( v × p ) n ∗ ( v × u ) β n ∗ ( u × p ) n ∗ ( u × v ) 令 w n n ∗ ( u × v ) n n ∗ n α w ∗ ( p × v ) β w ∗ ( u × p ) 令 p \mathbf P -\mathbf Q \alpha \mathbf u \beta \mathbf v p是从Q到P的向量 \\ \\将u、v向量分别与p叉乘\\ \mathbf v \times \mathbf p \alpha (\mathbf v \times \mathbf u) \beta (\mathbf v \times \mathbf v) \alpha (\mathbf v \times \mathbf u)\\ \mathbf u \times \mathbf p \alpha (\mathbf u \times \mathbf u) \beta (\mathbf u \times \mathbf v) \beta (\mathbf u \times \mathbf v)\\ \\ 向量的除法不能直接进行两边点乘n\\ \mathbf n * (\mathbf v \times \mathbf p) \mathbf n * \alpha (\mathbf v \times \mathbf u)\\ \mathbf n * (\mathbf u \times \mathbf p) \mathbf n * \beta (\mathbf u \times \mathbf v)\\则 \\ \alpha \frac{\mathbf n * (\mathbf v \times \mathbf p)}{\mathbf n * (\mathbf v \times \mathbf u)}\\ \beta \frac{\mathbf n * (\mathbf u \times \mathbf p)}{\mathbf n * (\mathbf u \times \mathbf v)}\\ \\ 令 w \frac{\mathbf n}{\mathbf n * (\mathbf u \times \mathbf v)} \frac{\mathbf n}{\mathbf n * \mathbf n} \\ \alpha \mathbf w * (\mathbf p \times \mathbf v)\\ \beta \mathbf w * (\mathbf u \times \mathbf p) 令pP−Qαuβvp是从Q到P的向量将u、v向量分别与p叉乘v×pα(v×u)β(v×v)α(v×u)u×pα(u×u)β(u×v)β(u×v)向量的除法不能直接进行两边点乘nn∗(v×p)n∗α(v×u)n∗(u×p)n∗β(u×v)则αn∗(v×u)n∗(v×p)​βn∗(u×v)n∗(u×p)​令wn∗(u×v)n​n∗nn​αw∗(p×v)βw∗(u×p) 要判断点是否在平行四边形中判断α和β在[0, 1]范围内即可。 平行四边形的绘制结果 灯光 文中将能发光的特性作为一个灯光材质。 灯光材质会有一个主动发光的函数这样在光线打到灯光材质表面时会增加一项主动发光所产生的颜色。对于不发光的材质而言主动发光产生的颜色为零。 同时设置背景颜色当射线最终没有打到物体时赋予默认背景颜色而不是根据画布位置得出的渐变色。 得到的灯光效果如下 实例化 这一部分主要引入了模型的移动和旋转。 所谓实例是已放置到场景中的几何图元的副本它完全独立于图元的其他副本并且可以移动或旋转。 模型移动 在这个过程的实现中文中没有直接移动模型的坐标而是反向变换光线的原点位置然后与模型做求交运算。具体而言主要分为以下三步 将射线的原点反向移动偏移量 判断添加偏移后的射线是否与物体存在交点如果存在判断在何处 给交点的位置增加偏移量 这一过程也可以从坐标变化的角度来思考 将射线从世界坐标系转换到物体局部坐标系判断射线在物体坐标系内是否与物体存在交点如果存在判断在何处将交点从物体局部坐标系转换到世界坐标系 文中将移动封装成了一个可击中对象相当于构建了一个实例这部分的代码如下 class translate : public hittable {public:bool hit(const ray r, interval ray_t, hit_record rec) const override {// 将射线的原点反向移动偏移量ray offset_r(r.origin() - offset, r.direction(), r.time());// 判断添加偏移后的射线是否与物体存在交点如果存在判断在何处if (!object-hit(offset_r, ray_t, rec))return false;// 给交点的位置增加偏移量rec.p offset;return true;}private:shared_ptrhittable object;vec3 offset; };模型旋转 模型的旋转与上述的构建过程类似不过稍微复杂。 文中给出的旋转表示方法是欧拉角表示法。当射线变换到有旋转的物体坐标系时不仅原点位置改变射线的方向也会改变。这一过程如下 将光线的原点和方向从世界坐标系变换到物体坐标系判断光线在物体坐标系内与物体是否相交以及交点在何处将交点的位置以及交点处的法线从物体坐标系变换到世界坐标系 旋转同样被封装成了一个可击中对象相当于一个实例这部分的核心代码如下 class rotate_y : public hittable {public:bool hit(const ray r, interval ray_t, hit_record rec) const override {// 将光线从世界坐标系转换到物体局部坐标系auto origin r.origin();auto direction r.direction();origin[0] cos_theta*r.origin()[0] - sin_theta*r.origin()[2];origin[2] sin_theta*r.origin()[0] cos_theta*r.origin()[2];direction[0] cos_theta*r.direction()[0] - sin_theta*r.direction()[2];direction[2] sin_theta*r.direction()[0] cos_theta*r.direction()[2];ray rotated_r(origin, direction, r.time());// 判断是否有交点以及交点在何处if (!object-hit(rotated_r, ray_t, rec))return false;// 将交点从物体局部坐标系转换到世界坐标系auto p rec.p;p[0] cos_theta*rec.p[0] sin_theta*rec.p[2];p[2] -sin_theta*rec.p[0] cos_theta*rec.p[2];// 将交点处的法线从物体局部坐标系转换到世界坐标系auto normal rec.normalnormal[0] cos_theta*rec.normal[0] sin_theta*rec.normal[2];normal[2] -sin_theta*rec.normal[0] cos_theta*rec.normal[2];rec.p p;rec.normal normal;return true;} };运用平移和旋转渲染出的cornell场景如下 体积物体 这一部分将的是对于类似雾这种对象的光线追踪渲染不过为了简便文中只举例了密度恒定且边界不变的情况。 光线在射向这类物体时有概率直接穿透也有概率散射开来。 对于这样的物体文中主要设置了两种参数一个是密度另一个是边界。 在做射线求交运算时会设置计算两个碰撞点分别代表射入和射出的点并根据密度参数和随机值计算得出一个新的碰撞点用来做计算。如果这个点不在体积内则判定这个射线没有和物体相交如果在体积内则判定为相交进行计算。 判定相交时射入的光线会在碰撞点处随机散射。 这一步的渲染效果 最终效果 和上一部教程一样作者给出了一个大场景渲染出一个最终效果。 这里我为了能够尽快得出渲染结果将采样次数降低牺牲了质量此时的渲染结果如下 完整代码 这一次同样上传在网盘上 链接https://pan.baidu.com/s/1hspYR2VGNlxynRJYa9jHug?pwdqyfj 提取码qyfj –来自百度网盘超级会员V6的分享 ps: 只分享了源码没有什么依赖库应该可以直接跑出ppm格式的图片。 参考 https://www.cnblogs.com/wickedpriest/p/12269564.html https://baike.baidu.com/item/%E5%8C%85%E5%9B%B4%E7%9B%92/4562345 https://blog.csdn.net/weixin_44176696/article/details/118655688
http://www.zqtcl.cn/news/902159/

相关文章:

  • 网站的反爬一般怎样做网站右键屏蔽
  • 茂名做网站dyiee青岛宣传片制作公司
  • 凡科网可以自己做网站吗编程常用网站
  • 做网站练手项目公司营业执照可以做几个网站
  • 聚通达网站建设网站并发要求
  • 网站建设预算申请如何写服装店网页设计素材
  • 做网站设计的公司柳州芜湖又出现一例
  • 重庆网站网站建设东莞市网站建设公司哪家好
  • php做网站如何架构wordpress 排版
  • wordpress免费网站模板下载地址在北京注册公司需要多少钱
  • 做的网站打不开高端网站名字
  • 个人网站建设报告西安网站开发高端网站开发
  • “网站建设:上海珍岛”网站备案信息查询系统
  • 北京哪个公司做网站专业建站培训
  • 郑州知名网站推广网站管理设置
  • 建设工程网站资质人员查询常州模板网站建设价格
  • 自己建网站做app手机网站列表页源码
  • 企业网站模板seo网站建设关键词优化
  • 平面毕业设计作品网站推广普通话ppt
  • p2p网站开发思路方案免费建简单网站
  • 微信朋友圈的网站连接怎么做互联网工程有限公司
  • 高大上企业网站优秀的门户网站
  • 做seo对网站推广有什么作用自己做电商网站吗
  • 网站从哪些方面来做泉州网页搜索排名提升
  • 网站建设可以给公司带来想做网站开发兼职
  • 天津市免费建站精美大气的餐饮类企业网站
  • 购物网站那个信用好又便宜手机模板的网站
  • 建筑企业资质查询网站怎么查网络服务商
  • 汉川市城乡建设局网站企业销售网站建设
  • 梅州建设网站域名购买流程