♻️ 资源大小32.4MB➡️资源下载https://download.csdn.net/download/s1t16/87453204三维造型与渲染一、算法选型光线追踪(Ray Tracing) 光子映射(Photon Mapping)代码片段class RayTracer { unsigned max_dep; //最大追踪深度 unsigned light_quality; //软阴影质量点光源采样次数/面光源单位面积采样次数 double ambient; //环境光系数 Photonmap *photonmap; //光子图由PhotonTracer得到 Color trcDiff(HitInfo* info, Scene* scene, double ambient); //追踪漫反射光 Color trcRfle(HitInfo* info, Scene* scene, int dep, double decay); //追踪反射光 Color trcRfra(HitInfo* info, Scene* scene, int dep, double decay); //追踪折射光 Color Trace(const Ray ray, Scene* scene, int dep, double decay); //追踪光线ray public: RayTracer(); ~RayTracer(); void setMaxDepth(unsigned dep) { max_dep dep; } void setLightQuality(unsigned quality) { light_quality quality; } void setAmbient(double _ambient) { ambient _ambient; } Film* Run(Scene *scene, Sampler *sampler); //主循环 };class Photontracer { Scene* scene; Photonmap* photonmap; void PhotonTracing( Photon , int dep ); //追踪光子 bool PhotonDiffusion( HitInfo* , Photon , int dep , double* prob ); //光子漫反射 bool PhotonReflection( HitInfo* , Photon , int dep , double* prob );//光子反射 bool PhotonRefraction( HitInfo* , Photon , int dep , double* prob );//光子折射 public: void SetScene( Scene* input ) { scene input; } Photonmap* GetPhotonmap() { return photonmap; } void Run(); };效果展示二、附加功能1. 鱼眼镜头效果与广角镜头效果相机位于原点360 度拍摄具体来说将 camera 类与 sampler 类分离开通过 sampler 的派生类实现不同的镜头效果。Vector3 FishEyeSampler::point(int i, int j, int ss_i, int ss_j) const override { double u, v; if(n_SS 1) { u w * (2 * j ((double)(2 * ss_j 1) / w_SS)) / w_pix - w; v -h * (2 * i ((double)(2 * ss_i 1) / h_SS)) / h_pix h; } else { u ((double)(2 * j 1) / w_pix - 1.0) * w; v (1.0 - (double)(2 * i - 1) / h_pix) * h; } return Vector3( u, v, sqrt(1 - u * u - v * v) ); } Vector3 WideAngleSampler::point(int i, int j, int ss_i, int ss_j) const override { double u, v; if(n_SS 1) { u w * (2 * j ((double)(2 * ss_j 1) / w_SS)) / w_pix - w; v -h * (2 * i ((double)(2 * ss_i 1) / h_SS)) / h_pix h; } else { u ((double)(2 * j 1) / w_pix - 1.0) * w; v (1.0 - (double)(2 * i - 1) / h_pix) * h; } double phi sqrt(u * u v * v); return Vector3( cos(v) * sin(u), sin(v), cos(v) * cos(u) ); }2. 超采样抗锯齿(SSAA)sampler 类同时支持 SSAA效率有所牺牲代码见上3. 软阴影AreaLight 类分块采样PointLight 类通过抖动实现软阴影效果。下图为具有 4 个面光源的场景注意软阴影效果上述所有展示图中均有软阴影本场景的效果更为明显。代码片段light.hColor AreaLight::GetIrd(HitInfo * info, Scene * scene, unsigned quality) { int qualt_x_aera quality * area; if(qualt_x_aera 1) qualt_x_aera 1; Color result Color::black(); for(int i -2; i 2; i) for(int j -2; j 2; j) for(int k qualt_x_aera; k 0; --k) { Vector3 S((rand(i, i 1)) / 2, (rand(j, j 1)) / 2, 0.0); result raw_sum(result, CaQIrd(M * S, info, scene)); } result result / (qualt_x_aera * 16); return result; } Color PointLight::GetIrd(HitInfo* info, Scene* scene, unsigned quality) { Color result Color::black(); quality 4; for(int i quality; i 0; --i) { Vector3 S O Vector3::rand_unity() * jiggle; //抖动软阴影 result raw_sum(result, CaQIrd(S, info, scene)); } result result / (quality); return result; }4. 纹理贴图上述展示图中的棋盘格为图片纹理可更换为别的纹理图片。下图将纹理更换为木纹代码片段class Texture { public: int w_pix, h_pix; std::vectorColor map; Color at(double u, double v) { u * h_pix, v * w_pix; int i (int)u, j (int)v; u - i, v - j; if(w_pix * i j w_pix 1 w_pix * h_pix) return 0.25 * (map[w_pix * i j] * (1-u) * (1-v) map[w_pix * i j 1] * (1-u) * v map[w_pix * i j w_pix] * u * (1-v) map[w_pix * i j w_pix 1] * u * v); else return 0.25 * map[w_pix * i j]; } };5. 参数曲面实现了 Bezier 曲线回转体的求交但迭代时容易出现收敛到错解的情况导致噪点出现故未在最终展示图中添加。下图为一个单独的参数曲面材质具有一定透明度、镜面反射率可以看到仍有一些噪点存在。迭代过程如下////牛顿法迭代 《计算机图形学基础教程(第2版)》P107 int newton_cnt 0; do { dC_dt d_, dS_du dS_dt(u, v), dS_dv dS_dtheta(u, v); f (e_ t0 * d_ - S(u, v)); double D mix(dC_dt, dS_du, dS_dv); if(fabs(D) EPS) { t0 rand(-0.02, 0.02), u rand(-0.02, 0.02), v rand(-0.02, 0.02); --newton_cnt; dt 1; continue; } dt -mix(dS_du, dS_dv, f) / D; du -mix(dC_dt, dS_dv, f) / D; dv mix(dC_dt, dS_du, f) / D; t0 dt * newton_leap, u du * newton_leap, v dv * newton_leap; if(u EPS || u - 1.0 -EPS) u rand(0, 1), newton_cnt - 1; } while(f.length() 0.001 newton_cnt 10); if(f.length() 0.002 t0 EPS) break; //ok } if(f.length() 0.002 || t0 EPS) return false;附编译环境Visual Studio 2017 OpenCV-3.4.1-vc14_vc15编译选项Release x64