失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 路径追踪 随机追踪法提速一倍

路径追踪 随机追踪法提速一倍

时间:2019-03-01 01:07:08

相关推荐

路径追踪 随机追踪法提速一倍

随机2分之一进行 光线追踪,另一半取前一个像素颜色,效果还行,速度提升一倍

#include <iostream>#include <vector>#include <random>#include <stdlib.h>#include <glm/glm.hpp> // 数学库支持#include <omp.h> // openmp多线程加速#include<freeglut.h>#include<ctime>#include<mmintrin.h>using namespace glm;using namespace std;int frames; clock_t clocks;// --------------------- end of include --------------------- //#define PI 3.1415926f// 采样次数const int SAMPLE = 1;int p7;// 输出图像分辨率const int WIDTH = 300;const int HEIGHT = WIDTH;// 相机参数const double SCREEN_Z = 1.1; // 视平面 z 坐标const vec3 EYE = vec3(0, 0, 4.0); // 相机位置// 颜色const vec3 RED(1, 0.5, 0.5);const vec3 GREEN(0.5, 1, 0.5);const vec3 BLUE(0.5, 0.5, 1);const vec3 YELLOW(1.0, 1.0, 0.1);const vec3 CYAN(0.1, 1.0, 1.0);const vec3 MAGENTA(1.0, 0.1, 1.0);const vec3 GRAY(0.5, 0.5, 0.5);const vec3 WHITE(1, 1, 1);// --------------- end of global variable definition --------------- //// 光线typedef struct Ray{vec3 startPoint = vec3(0, 0, 0); // 起点vec3 direction = vec3(0, 0, 0);// 方向}Ray;// 物体表面材质定义typedef struct Material{bool isEmissive = false; // 是否发光vec3 normal = vec3(0, 0, 0); // 法向量vec3 color = vec3(0, 0, 0);// 颜色double specularRate = 0.0f;// 反射光占比double roughness = 1.0f; // 粗糙程度double refractRate = 0.0f;// 折射光占比double refractAngle = 1.0f;// 折射率double refractRoughness = 0.0f; // 折射粗糙度double 清漆 = 0.5f;vec3 baseColor = vec3(0.3, 0.3, 0.3);float metallic = 0.8f;float clearcoat = 0.8f;float clearcoatGloss = 0.8f;}Material;// 光线求交结果typedef struct 光线求交结果{bool 是否命中 = false; // 是否命中double 与交点的距离 = 0.0f; // 与交点的距离vec3 光线命中点 = vec3(0, 0, 0); // 光线命中点Material material; // 命中点的表面材质}光线求交结果;class Shape{public:Shape() {}virtual 光线求交结果 intersect(Ray ray) {return 光线求交结果(); }};std::vector<Shape*> shapes; // 几何物体的集合// 三角形class Triangle : public Shape{public:Triangle() {}Triangle(vec3 P1, vec3 P2, vec3 P3, vec3 C){p1 = P1, p2 = P2, p3 = P3;material.normal = normalize(cross(p2 - p1, p3 - p1)); material.color = C;}vec3 p1, p2, p3; // 三顶点Material material; // 材质// 与光线求交光线求交结果 intersect(Ray ray){光线求交结果 res;vec3 S = ray.startPoint; // 射线起点vec3 d = ray.direction; // 射线方向vec3 N = material.normal; // 法向量if (dot(N, d) > 0.0f) N = -N; // 获取正确的法向量// 如果视线和三角形平行if (fabs(dot(N, d)) < 0.00001f) return res;// 距离float t = (dot(N, p1) - dot(S, N)) / dot(d, N);if (t < 0.0005f) return res; // 如果三角形在相机背面// 交点计算vec3 P = S + d * t;// 判断交点是否在三角形中vec3 c1 = cross(p2 - p1, P - p1);vec3 c2 = cross(p3 - p2, P - p2);vec3 c3 = cross(p1 - p3, P - p3);vec3 n = material.normal; // 需要 "原生法向量" 来判断if (dot(c1, n) < 0 || dot(c2, n) < 0 || dot(c3, n) < 0) return res;// 装填返回结果res.是否命中 = true;res.与交点的距离 = t;res.光线命中点 = P;res.material = material;res.material.normal = N; // 要返回正确的法向return res;};};// 球class Sphere : public Shape{public:Sphere() {}Sphere(vec3 o, double r, vec3 c) {O = o; R = r; material.color = c; }vec3 O; // 圆心double R; // 半径Material material; // 材质// 与光线求交光线求交结果 intersect(Ray ray){光线求交结果 res;vec3 S = ray.startPoint; // 射线起点vec3 d = ray.direction; // 射线方向float OS = length(O - S);float SH = dot(O - S, d);float OH = sqrt(pow(OS, 2) - pow(SH, 2));if (OH > R) return res; // OH大于半径则不相交float PH = sqrt(pow(R, 2) - pow(OH, 2));float t1 = length(SH) - PH;float t2 = length(SH) + PH;float t = (t1 < 0) ? (t2) : (t1); // 最近距离vec3 P = S + t * d;// 交点// 防止自己交自己if (fabs(t1) < 0.0005f || fabs(t2) < 0.0005f) return res;// 装填返回结果res.是否命中 = true;res.与交点的距离 = t;res.光线命中点 = P;res.material = material;res.material.normal = normalize(P - O); // 要返回正确的法向return res;}};Shape* 屏幕优先物体[WIDTH*HEIGHT][4];//Shape* 屏幕优先物体[WIDTH *HEIGHT];//std::vector<Shape*> 屏幕优先物体;Shape* shape2 = new Shape; int 深度A = 0;// 返回距离最近 hit 的结果光线求交结果 shoot(std::vector<Shape*>& shapes, Ray ray, int 像素, int 深度){光线求交结果 res, r;res.与交点的距离 = 1145141919.810f; // infint 第一层记忆 = 0;if (p7 > 50) {if (像素 > 0 && 深度 == 0) {r = 屏幕优先物体[像素][深度]->intersect(ray);if (r.是否命中 && r.与交点的距离 < res.与交点的距离) {std::cout << "像素 " << 像素 << std::endl;res = r; // 记录距离最近的求交结果return res;}}}if (深度A == 0) {深度A++; 第一层记忆 = 1;r = shape2->intersect(ray);if (r.是否命中 && r.与交点的距离 < res.与交点的距离) {res = r; // 记录距离最近的求交结果return res;}}/*if (p7 > 4 && 深度 == 0) {std::cout << "像素 " << 像素 << std::endl;}*/for (int k = 0; k < shapes.size(); ++k){r = shapes[k]->intersect(ray);if (r.是否命中 && r.与交点的距离 < res.与交点的距离) {res = r; // 记录距离最近的求交结果//if (深度 == 0 ) {屏幕优先物体[像素][深度] = shapes[k];//}if (第一层记忆 == 1) {shape2 = shapes[k];}return res;}}return res;}// 0-1 随机数生成std::uniform_real_distribution<> dis(0.0, 1.0);random_device rd;mt19937 gen(rd());double randf(){return dis(gen);}// 单位球内的随机向量vec3 randomVec3(){vec3 d;do{d = 2.0f * vec3(randf(), randf(), randf()) - vec3(1, 1, 1);} while (dot(d, d) > 1.0);return normalize(d);/*double r1 = randf(), r2 = randf();double z = sqrt(1.0f - r2);double phi = 2 * 3.1415926 * r1;float x = cos(phi) * sqrt(r2);float y = sin(phi) * sqrt(r2);return normalize(vec3(x, y, z));*/}// 法向半球随机向量vec3 randomDirection(vec3 n){/*// 法向半球vec3 d;do{d = randomVec3();} while (dot(d, n) < 0.0f);return d;*/// 法向球return normalize(randomVec3() + n);}// 1 ~ 8 维的 sobol 生成矩阵const uint V[8 * 32] = {2147483648, 1073741824, 536870912, 268435456, 134217728, 67108864, 33554432, 16777216, 8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1,2147483648, 3221225472, 2684354560, 4026531840, 2281701376, 3422552064, 2852126720, 4278190080, 2155872256, 3233808384, 2694840320, 4042260480, 2290614272, 3435921408, 2863267840, 4294901760, 2147516416, 3221274624, 2684395520, 4026593280, 2281736192, 3422604288, 2852170240, 4278255360, 2155905152, 3233857728, 2694881440, 4042322160, 2290649224, 3435973836, 2863311530, 4294967295,2147483648, 3221225472, 1610612736, 2415919104, 3892314112, 1543503872, 2382364672, 3305111552, 1753219072, 2629828608, 3999268864, 1435500544, 2154299392, 3231449088, 1626210304, 2421489664, 3900735488, 1556135936, 2388680704, 3314585600, 1751705600, 2627492864, 4008611328, 1431684352, 2147543168, 3221249216, 1610649184, 2415969680, 3892340840, 1543543964, 2382425838, 3305133397,2147483648, 3221225472, 536870912, 1342177280, 4160749568, 1946157056, 2717908992, 2466250752, 3632267264, 624951296, 1507852288, 3872391168, 790208, 3020685312, 2181169152, 3271884800, 546275328, 1363623936, 4226424832, 1977167872, 2693105664, 2437829632, 3689389568, 635137280, 1484783744, 3846176960, 2044723232, 3067084880, 2148008184, 32, 537002146, 1342505107,2147483648, 1073741824, 536870912, 2952790016, 4160749568, 3690987520, 2046820352, 2634022912, 1518338048, 801112064, 2707423232, 4038066176, 3666345984, 1875116032, 2170683392, 1085997056, 579305472, 3016343552, 4217741312, 3719483392, 407232, 2617981952, 1510979072, 755882752, 2726789248, 4090085440, 3680870432, 1840435376, 2147625208, 1074478300, 537900666, 2953698205,2147483648, 1073741824, 1610612736, 805306368, 2818572288, 335544320, 2113929216, 3472883712, 2290089984, 3829399552, 3059744768, 1127219200, 3089629184, 4199809024, 3567124480, 1891565568, 394297344, 3988799488, 920674304, 4193267712, 2950604800, 3977188352, 3250028032, 129093376, 2231568512, 2963678272, 4281226848, 432124720, 803643432, 1633613396, 2672665246, 3170194367,2147483648, 3221225472, 2684354560, 3489660928, 1476395008, 2483027968, 1040187392, 3808428032, 3196059648, 599785472, 505413632, 4077912064, 1182269440, 1736704000, 853440, 2221342720, 3329785856, 2810494976, 3628507136, 1416089600, 2658719744, 864310272, 3863387648, 3076993792, 553150080, 272922560, 4167467040, 1148698640, 1719673080, 075780, 2149644390, 3222291575,2147483648, 1073741824, 2684354560, 1342177280, 2281701376, 1946157056, 436207616, 2566914048, 2625634304, 3208642560, 2720006144, 209876, 111673344, 2354315264, 3464626176, 4027383808, 2886631424, 3770826752, 1691164672, 3357462528, 1993345024, 3752330240, 873073152, 2870150400, 1700563072, 87021376, 1097028000, 1222351248, 1560027592, 2977959924, 23268898, 437609937};// 格林码 uint grayCode(uint i) {return i ^ (i >> 1);}// 生成第 d 维度的第 i 个 sobol 数float sobol(uint d, uint i) {uint result = 0;uint offset = d * 32;for (uint j = 0; i; i >>= 1, j++)if (i & 1)result ^= V[j + offset];return float(result) * (1.0f / float(0xFFFFFFFFU));}vec3 SampleHemisphere(float xi_1, float xi_2) {float z = xi_1;float r = max(0.0, sqrt(1.0 - z*z));float phi = 2.0 * PI * xi_2;return vec3(r * cos(phi), r * sin(phi), z);}// 生成第 i 帧的第 b 次反弹需要的二维随机向量vec2 sobol低差异序列(uint i, uint b) {float u = sobol(b * 2, grayCode(i));float v = sobol(b * 2 + 1, grayCode(i));return vec2(u, v);}// 将向量 v 投影到 N 的法向半球vec3 toNormalHemisphere(vec3 v, vec3 N) {vec3 helper = vec3(1, 0, 0);if (abs(N.x)>0.999) helper = vec3(0, 0, 1);vec3 tangent = normalize(cross(N, helper));vec3 bitangent = normalize(cross(N, tangent));return v.x * tangent + v.y * bitangent + v.z * N;}// 余弦加权的法向半球采样vec3 漫反射重要性采样(float xi_1, float xi_2, vec3 N) {// 均匀采样 xy 圆盘然后投影到 z 半球float r = sqrt(xi_1);float theta = xi_2 * 2.0 * PI;float x = r * cos(theta);float y = r * sin(theta);float z = sqrt(1.0 - x*x - y*y);// 从 z 半球投影到法向半球vec3 L = toNormalHemisphere(vec3(x, y, z), N);return L;}// GTR1 重要性采样vec3 SampleGTR1(float xi_1, float xi_2, vec3 V, vec3 N, float alpha) {float phi_h = 2.0 * PI * xi_1;float sin_phi_h = sin(phi_h);float cos_phi_h = cos(phi_h);float cos_theta_h = sqrt((1.0 - pow(alpha*alpha, 1.0 - xi_2)) / (1.0 - alpha*alpha));float sin_theta_h = sqrt(max(0.0, 1.0 - cos_theta_h * cos_theta_h));// 采样 "微平面" 的法向量 作为镜面反射的半角向量 h vec3 H = vec3(sin_theta_h*cos_phi_h, sin_theta_h*sin_phi_h, cos_theta_h);H = toNormalHemisphere(H, N); // 投影到真正的法向半球// 根据 "微法线" 计算反射光方向vec3 L = reflect(-V, H);return L;}// GTR2 重要性采样vec3 SampleGTR2(float xi_1, float xi_2, vec3 V, vec3 N, float alpha) {float phi_h = 2.0 * PI * xi_1;float sin_phi_h = sin(phi_h);float cos_phi_h = cos(phi_h);float cos_theta_h = sqrt((1.0 - xi_2) / (1.0 + (alpha*alpha - 1.0)*xi_2));float sin_theta_h = sqrt(max(0.0, 1.0 - cos_theta_h * cos_theta_h));// 采样 "微平面" 的法向量 作为镜面反射的半角向量 h vec3 H = vec3(sin_theta_h*cos_phi_h, sin_theta_h*sin_phi_h, cos_theta_h);H = toNormalHemisphere(H, N); // 投影到真正的法向半球// 根据 "微法线" 计算反射光方向vec3 L = reflect(-V, H);return L;}float sqr(float x) {return x*x;}float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay) {return 1 / (PI * ax*ay * sqr(sqr(HdotX / ax) + sqr(HdotY / ay) + NdotH*NdotH));}// 按照辐射度分布分别采样三种 BRDFvec3 SampleBRDF(float xi_1, float xi_2, float xi_3, vec3 V, vec3 N, Material material) {float alpha_GTR1 = mix(0.1, 0.001, material.clearcoatGloss);float alpha_GTR2 = max(0.001f, sqr(material.roughness));// 辐射度统计float r_diffuse = (1.0 - material.metallic);float r_specular = 1.0;float r_clearcoat = 0.25 * material.clearcoat;float r_sum = r_diffuse + r_specular + r_clearcoat;// 根据辐射度计算概率float p_diffuse = r_diffuse / r_sum;float p_specular = r_specular / r_sum;float p_clearcoat = r_clearcoat / r_sum;// 按照概率采样float rd = xi_3;// 漫反射if (rd <= p_diffuse) {return 漫反射重要性采样(xi_1, xi_2, N);}// 镜面反射else if (p_diffuse < rd && rd <= p_diffuse + p_specular) {return SampleGTR2(xi_1, xi_2, V, N, alpha_GTR2);}// 清漆else if (p_diffuse + p_specular < rd) {return SampleGTR1(xi_1, xi_2, V, N, alpha_GTR1);}return vec3(0, 1, 0);}float GTR1(float NdotH, float a) {if (a >= 1) return 1 / PI;float a2 = a*a;float t = 1 + (a2 - 1)*NdotH*NdotH;return (a2 - 1) / (PI*log(a2)*t);}float GTR2(float NdotH, float a) {float a2 = a*a;float t = 1 + (a2 - 1)*NdotH*NdotH;return a2 / (PI * t*t);}// 获取 BRDF 在 L 方向上的概率密度float BRDF_Pdf(vec3 V, vec3 N, vec3 L, Material material) {float NdotL = dot(N, L);float NdotV = dot(N, V);if (NdotL < 0 || NdotV < 0) return 0;vec3 H = normalize(L + V);float NdotH = dot(N, H);float LdotH = dot(L, H);// 镜面反射 -- 各向同性float alpha = max(0.001f, sqr(material.roughness));float Ds = GTR2(NdotH, alpha);float Dr = GTR1(NdotH, mix(0.1, 0.001, material.清漆)); // 清漆// 分别计算三种 BRDF 的概率密度float pdf_diffuse = NdotL / PI;float pdf_specular = Ds * NdotH / (4.0 * dot(L, H));float pdf_clearcoat = Dr * NdotH / (4.0 * dot(L, H));// 辐射度统计float r_diffuse = (1.0 - material.metallic);float r_specular = 1.0;float r_clearcoat = 0.25 * material.clearcoat;float r_sum = r_diffuse + r_specular + r_clearcoat;// 根据辐射度计算选择某种采样方式的概率float p_diffuse = r_diffuse / r_sum;float p_specular = r_specular / r_sum;float p_clearcoat = r_clearcoat / r_sum;// 根据概率混合 pdffloat pdf = p_diffuse * pdf_diffuse+ p_specular * pdf_specular+ p_clearcoat * pdf_clearcoat;pdf = max(1e-10f, pdf);return pdf;}template<class T>T clamp2(T x, T min, T max){if (x > max)return max;if (x < min)return min;return x;}float SchlickFresnel(float u) {float m = clamp2((float)1 - u, 0.0f, 1.0f);float m2 = m*m;return m2*m2*m; // pow(m,5)}vec3 BRDF_Evaluate(vec3 V, vec3 N, vec3 L, Material material) {vec3 Cdlin = material.baseColor;float NdotL = dot(N, L);float NdotV = dot(N, V);//if (NdotL < 0 || NdotV < 0) return 0;vec3 H = normalize(L + V);float NdotH = dot(N, H);float LdotH = dot(L, H);// 漫反射float Fd90 = 0.5 + 2.0 * LdotH * LdotH * material.roughness;float FL = SchlickFresnel(NdotL);float FV = SchlickFresnel(NdotV);float Fd = mix(1.0f, Fd90, FL) * mix(1.0f, Fd90, FV);vec3 diffuse = Fd * Cdlin / PI;diffuse.x *= (1.0 - material.metallic);diffuse.y *= (1.0 - material.metallic);diffuse.z *= (1.0 - material.metallic);return diffuse;}//路径追踪 -- 重要性采样版本vec3 pathTracingImportanceSampling(光线求交结果 hit, int maxBounce) {vec3 Lo = vec3(0);// 最终的颜色vec3 history = vec3(1); // 递归积累的颜色for (int bounce = 0; bounce<maxBounce; bounce++) {vec3 V = -vec3(0.001, 0.001, 0.001);vec3 N = hit.material.normal;// 获取 3 个随机数 float xi_1 = rand() % 500;floatxi_2 = rand() % 1500;floatxi_3 = rand() % 3000;//vec3 L;vec2 uv = sobol低差异序列(p7, 1);//L = 漫反射重要性采样(uv.x, uv.y, res.material.normal);//L = SampleHemisphere(uv.x, uv.y);//L = toNormalHemisphere(L, randomRay.direction);//randomRay.direction = L;// 采样 BRDF 得到一个方向 Lvec3 L = SampleBRDF(uv.x, uv.y, xi_3, V, N, hit.material);float NdotL = dot(N, L);if (NdotL <= 0.0) break;// 发射光线Ray randomRay;randomRay.startPoint = hit.光线命中点;randomRay.direction = L;光线求交结果 newHit = shoot(shapes, randomRay, 0, maxBounce);// 获取 L 方向上的 BRDF 值和概率密度vec3 f_r = BRDF_Evaluate(V, N, L, hit.material);//vec3 f_r = vec3(0.001,0.001,0.001);float pdf_brdf = BRDF_Pdf(V, N, L, hit.material);if (pdf_brdf <= 0.0) break;// 未命中 if (!newHit.是否命中) {vec3 color = vec3(1, 1, 1);Lo += history * color * f_r * NdotL / pdf_brdf;break;}// 命中光源积累颜色vec3 Le = newHit.material.color;Lo += history * Le * f_r * NdotL / pdf_brdf;// 递归(步进)hit = newHit;history *= f_r * NdotL / pdf_brdf; // 累积颜色}return Lo;}uint wang_hash(uint seed) {seed = uint(seed ^ uint(61)) ^ uint(seed >> uint(16));seed *= uint(9);seed = seed ^ (seed >> 4);seed *= uint(0x27d4eb2d);seed = seed ^ (seed >> 15);return seed;}vec3 pix;vec2 CranleyPattersonRotation(vec2 p) {uint pseed = uint(uint((pix.x * 0.5 + 0.5) * WIDTH) * uint(1973) +uint((pix.y * 0.5 + 0.5) * HEIGHT) * uint(9277) +uint(114514 / 1919) * uint(26699)) | uint(1);float u = float(wang_hash(pseed)) / 4294967296.0;float v = float(wang_hash(pseed)) / 4294967296.0;p.x += u;if (p.x>1) p.x -= 1;if (p.x<0) p.x += 1;p.y += v;if (p.y>1) p.y -= 1;if (p.y<0) p.y += 1;return p;}// 路径追踪vec3 路径追踪(vector<Shape*>& shapes, Ray ray, int depth){if (depth > 4) return vec3(1);光线求交结果 res = shoot(shapes, ray, 0, depth);if (!res.是否命中) return vec3(0); // 未命中// 如果发光则返回颜色if (res.material.isEmissive) return res.material.color;// 有 P 的概率终止double r = randf();float P = 0.8;if (r > P) return vec3(0);// 否则继续Ray randomRay;randomRay.startPoint = res.光线命中点;//randomRay.direction = randomDirection(res.material.normal);vec3 L;vec2 uv = sobol低差异序列(p7 + 1, 1);uv = CranleyPattersonRotation(uv);L = 漫反射重要性采样(uv.x, uv.y, res.material.normal);//L = SampleHemisphere(uv.x, uv.y);//L = toNormalHemisphere(L, randomRay.direction);randomRay.direction = L;vec3 color = vec3(0);float cosine = fabs(dot(-ray.direction, res.material.normal));// 根据反射率决定光线最终的方向r = randf();if (r < res.material.specularRate) // 镜面反射{vec3 ref = normalize(reflect(ray.direction, res.material.normal));randomRay.direction = mix(ref, randomRay.direction, res.material.roughness);color = 路径追踪(shapes, randomRay, depth + 1) * cosine;}else if (res.material.specularRate <= r && r <= res.material.refractRate) // 折射{vec3 ref = normalize(refract(ray.direction, res.material.normal, float(res.material.refractAngle)));randomRay.direction = mix(ref, -randomRay.direction, res.material.refractRoughness);color = 路径追踪(shapes, randomRay, depth + 1) * cosine;}else // 漫反射{vec3 srcColor = res.material.color;vec3 ptColor = 路径追踪(shapes, randomRay, depth + 1) * cosine;color = ptColor*srcColor; // 和原颜色混合}//color=pathTracingImportanceSampling(res, depth);return color / P;}vec3 光线追踪(std::vector<Shape*>& 场景, Ray ray, int 光追深度){float 反光;光线求交结果 res;res = shoot(shapes, ray, 0, 光追深度);if (!res.是否命中) return vec3(0); // 未命中// 如果发光则返回颜色if (res.material.isEmissive) return res.material.color;// 否则继续Ray randomRay;randomRay.startPoint = res.光线命中点;randomRay.direction = randomDirection(res.material.normal);vec3 color = vec3(0);float cosine = fabs(dot(-ray.direction, res.material.normal));反光 = res.material.specularRate;if (反光 > 0 && 光追深度 > 0){vec3 ref = normalize(reflect(ray.direction, res.material.normal));randomRay.direction = mix(ref, randomRay.direction, res.material.roughness);color = 光线追踪(shapes, randomRay, 光追深度 - 1) * cosine;}return color;}int ll = 0; vec3 微积分 = vec3(0, 0, 0); vec3 微积分2 = vec3(0, 0, 0); vec3 前面原色 = vec3(0, 0, 0);GLuint texture;typedef unsigned int Color;static Color buffer[HEIGHT][WIDTH];vec3 累计积分[WIDTH * HEIGHT];vec3 上个原色;vec3 离线交点颜色[WIDTH][HEIGHT]; vec3 离线交点颜色2[WIDTH][HEIGHT];vec3 离线交点积分[WIDTH][HEIGHT]; int 离线交点积分2[WIDTH][HEIGHT];vec3 屏幕颜色记忆[WIDTH][HEIGHT]; vec3 期待渲染近似效果[WIDTH][HEIGHT];光线求交结果 离线交点;int a = 400; int 矩形 = 50;double* image = new double[WIDTH * HEIGHT * 3];double* imageA = new double[WIDTH * HEIGHT * 3];vec3 小图采样2; vec3 小图采样3; vec3 小图采样A[HEIGHT][WIDTH]; vec3 小图积分A[HEIGHT][WIDTH];vec3 小图积分[HEIGHT][WIDTH];// ---------------------------- end of functions ---------------------------- //int 采样进度 = 1;// 每次采样的亮度int 采样亮度 = 20;// 每次采样的亮度int AC = 0;int 小图渲染次数 =1; //这里决定开局的亮度和清晰度,否则开始很暗int 对焦清晰度 = 200;int 第一帧亮度 = 300;int 多少次结束 = 100+1;#include <thread>#include <iostream>DWORD WINAPI myfun1(LPVOID lpParameter); //声明线程函数DWORD WINAPI myfun2(LPVOID lpParameter);//分别实现线程函数,并返回值DWORD WINAPI myfun1(LPVOID lpParameter){int 幸运阈值3 = 0;int 幸运阈值 = 1; int 幸运阈值2 = 1;vec3 AA = vec3(0.1, 0.2, 0.2); vec3 BB = vec3(2, 2, 2);vec3 小图采样; int 渲染进度; int 小图指针; Ray 离线光; int 对焦值, 对焦A, 对焦B, 对焦C;int j变量值记录;vec3 color;Ray ray; vec3 s;光线求交结果 res;采样进度++;if (采样进度 >1) {采样亮度 = 5; 对焦清晰度 = 2; AC = 1;}double BRIGHTNESS = (2.0f * 3.1415926f) * (1.0f / double(采样亮度));double* p;double A4 = 0.05;if (p7 < 多少次结束){p = image;for (int i = 0; i < HEIGHT; i += 2){for (int j = 0; j < WIDTH; j++){++幸运阈值;if (幸运阈值 >对焦清晰度) {幸运阈值 = 1; }if (幸运阈值 != rand() % 对焦清晰度) {//像素坐标转投影平面坐标double x = 2.0 * double(j) / double(WIDTH) - 1.0;double y = 2.0 * double(HEIGHT - i) / double(HEIGHT) - 1.0;// MSAAx += (randf() - 0.5f) / double(WIDTH);y += (randf() - 0.5f) / double(HEIGHT);vec3 coord = vec3(x, y, SCREEN_Z);// 计算投影平面坐标vec3 direction = normalize(coord - EYE); // 计算光线投射方向// 生成光线ray.startPoint = coord;ray.direction = direction;// 与场景的交点深度A = 0;res = shoot(shapes, ray, i + j, 0);color = vec3(0, 0, 0);if (res.是否命中){// 命中光源直接返回光源颜色if (res.material.isEmissive){color = res.material.color;}// 命中实体则选择一个随机方向重新发射光线并且进行路径追踪else{// 根据交点处法向量生成交点处反射的随机半球向量Ray randomRay;randomRay.startPoint = res.光线命中点;//randomRay.direction = randomDirection(res.material.normal);vec3 L;vec2 uv = sobol低差异序列(p7 + 1, 1);//uv = CranleyPattersonRotation(uv);L = 漫反射重要性采样(uv.x, uv.y, res.material.normal);//L = SampleHemisphere(uv.x, uv.y);//L = toNormalHemisphere(L, randomRay.direction);randomRay.direction = L;// 根据反射率决定光线最终的方向double r = randf();int b = 0;if (r < res.material.specularRate) // 镜面反射{vec3 ref = normalize(reflect(ray.direction, res.material.normal));randomRay.direction = mix(ref, randomRay.direction, res.material.roughness);微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);color = 微积分;b = 1;}else if (res.material.specularRate <= r && r <= res.material.refractRate) // 折射{vec3 ref = normalize(refract(ray.direction, res.material.normal, float(res.material.refractAngle)));randomRay.direction = mix(ref, -randomRay.direction, res.material.refractRoughness);微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);color = 微积分;b = 1;}else // 漫反射{s = res.material.color;微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);//微积分 = 微积分+ 微积分;color = 微积分 *s;}/*小图积分A[i][j] = color;小图采样A[i][j] = res.material.color;*/上个原色 = res.material.color;离线交点颜色[i][j] = res.material.color;离线交点积分[i][j] += 微积分;小图采样 = color;/*小图采样 = color * 离线交点积分[i][j - 1];小图采样 /= 2;*//* 小图采样A[i][j - 1] *= 0.1;小图采样 = 小图采样 + 小图采样A[i][j - 1];小图采样 /=4;*/}int a5 = 1000;if (p7 > 10){a5 = 1000 + p7;}double BRIGHTNESS2 = (2.0f * 3.1415926f) * (1.0f / double(a5));小图采样 *= BRIGHTNESS2;}}else{小图采样 = 上个原色 * 微积分;//小图采样 *= 0.01;int a5 = 1000;if (p7 > 200){a5 = p7 + 1000;}double BRIGHTNESS2 = (2.0f * 3.1415926f) * (1.0f / double(a5));小图采样 *= BRIGHTNESS2;}/*if (p7<2) {double BRIGHTNESS2 = (2.0f * 3.1415926f) * (1.0f / double(第一帧亮度));小图采样 = 离线交点颜色[i][j] * 小图积分[i][j];小图采样 *= BRIGHTNESS2;}*/if (p7<2) {屏幕颜色记忆[i][j] = res.material.color;}*p += 小图采样.x; p++; // R 通道小图采样2.x = *p;*p += 小图采样.y; p++; // G 通道小图采样2.y = *p;*p += 小图采样.z; p++; // B 通道小图采样2.z = *p;buffer[i][j] = RGB(小图采样2.x * 255, 小图采样2.y * 255, 小图采样2.z * 255);}}}return 0;}DWORD WINAPI myfun2(LPVOID lpParameter){int 幸运阈值3 = 0;int 幸运阈值 = 1; int 幸运阈值2 = 1;vec3 AA = vec3(0.1, 0.2, 0.2); vec3 BB = vec3(2, 2, 2);vec3 小图采样; int 渲染进度; int 小图指针; Ray 离线光; int 对焦值, 对焦A, 对焦B, 对焦C;int j变量值记录;vec3 color;Ray ray; vec3 s;光线求交结果 res;double BRIGHTNESS = (2.0f * 3.1415926f) * (1.0f / double(采样亮度));double* p;double A4 = 0.05;if (p7 < 多少次结束){p = image;for (int i = 1; i < HEIGHT; i += 2){for (int j = 0; j < WIDTH; j++){++幸运阈值;if (幸运阈值 >对焦清晰度) {幸运阈值 = 1; }if (幸运阈值 != rand() % 对焦清晰度) {// 像素坐标转投影平面坐标double x = 2.0 * double(j) / double(WIDTH) - 1.0;double y = 2.0 * double(HEIGHT - i) / double(HEIGHT) - 1.0;// MSAAx += (randf() - 0.5f) / double(WIDTH);y += (randf() - 0.5f) / double(HEIGHT);vec3 coord = vec3(x, y, SCREEN_Z);// 计算投影平面坐标vec3 direction = normalize(coord - EYE); // 计算光线投射方向// 生成光线ray.startPoint = coord;ray.direction = direction;// 与场景的交点深度A = 0;res = shoot(shapes, ray, i + j, 0);color = vec3(0, 0, 0);if (res.是否命中){// 命中光源直接返回光源颜色if (res.material.isEmissive){color = res.material.color;}// 命中实体则选择一个随机方向重新发射光线并且进行路径追踪else{// 根据交点处法向量生成交点处反射的随机半球向量Ray randomRay;randomRay.startPoint = res.光线命中点;//randomRay.direction = randomDirection(res.material.normal);vec3 L;vec2 uv = sobol低差异序列(p7 + 1, 1);//uv = CranleyPattersonRotation(uv);L = 漫反射重要性采样(uv.x, uv.y, res.material.normal);//L = SampleHemisphere(uv.x, uv.y);//L = toNormalHemisphere(L, randomRay.direction);randomRay.direction = L;// 根据反射率决定光线最终的方向double r = randf();int b = 0;if (r < res.material.specularRate) // 镜面反射{vec3 ref = normalize(reflect(ray.direction, res.material.normal));randomRay.direction = mix(ref, randomRay.direction, res.material.roughness);微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);color = 微积分;b = 1;}else if (res.material.specularRate <= r && r <= res.material.refractRate) // 折射{vec3 ref = normalize(refract(ray.direction, res.material.normal, float(res.material.refractAngle)));randomRay.direction = mix(ref, -randomRay.direction, res.material.refractRoughness);微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);color = 微积分;b = 1;}else // 漫反射{s = res.material.color;微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);//微积分 = 微积分+ 微积分;color = 微积分 *s;}/*小图积分A[i][j] = color;小图采样A[i][j] = res.material.color;*/上个原色 = res.material.color;离线交点颜色[i][j] = res.material.color;离线交点积分[i][j] += 微积分;小图采样 = color;/*小图采样 = color*离线交点积分[i][j-1];小图采样 /= 2;*//* 小图采样A[i][j - 1] *= 0.1;小图采样 = 小图采样 + 小图采样A[i][j - 1];小图采样 /=4;*/}int a5 = 1000;if (p7 > 10){a5 = 1000 + p7;}double BRIGHTNESS2 = (2.0f * 3.1415926f) * (1.0f / double(a5));小图采样 *= BRIGHTNESS2;}}else{小图采样 = 上个原色 * 微积分;//小图采样 *= 0.01;int a5 = 1000;if (p7 > 200){a5 = p7 + 1000;}double BRIGHTNESS2 = (2.0f * 3.1415926f) * (1.0f / double(a5));小图采样 *= BRIGHTNESS2;}/*if (p7<2) {double BRIGHTNESS2 = (2.0f * 3.1415926f) * (1.0f / double(第一帧亮度));小图采样 = 离线交点颜色[i][j] * 小图积分[i][j];小图采样 *= BRIGHTNESS2;}*/*p += 小图采样.x; p++; // R 通道小图采样2.x = *p;*p += 小图采样.y; p++; // G 通道小图采样2.y = *p;*p += 小图采样.z; p++; // B 通道小图采样2.z = *p;buffer[i][j] = RGB(小图采样2.x * 255, 小图采样2.y * 255, 小图采样2.z * 255);}}}return 0;}void 渲染() {//if (p7 < 1) {//vec3 color;Ray ray;光线求交结果 res;//double* p2 = imageA;//for (int i5 = 0; i5 <小图渲染次数; i5++)//{//for (int i = 0; i < 矩形; i++)//{//for (int j = 0; j < 矩形; j++)//{//// 像素坐标转投影平面坐标//double x = 2.0 * double(j) / double(矩形) - 1.0;//double y = 2.0 * double(矩形 - i) / double(矩形) - 1.0;//// MSAA//x += (randf() - 0.5f) / double(矩形);//y += (randf() - 0.5f) / double(矩形);//vec3 coord = vec3(x, y, SCREEN_Z);// 计算投影平面坐标//vec3 direction = normalize(coord - EYE); // 计算光线投射方向//// 生成光线//ray.startPoint = coord;//ray.direction = direction;//// 与场景的交点//深度A = 0;//res = shoot(shapes, ray, i + j, 0);//color = vec3(0, 0, 0);//if (res.是否命中)//{//// 命中光源直接返回光源颜色//if (res.material.isEmissive)//{//color = res.material.color;//}//// 命中实体则选择一个随机方向重新发射光线并且进行路径追踪//else//{//// 根据交点处法向量生成交点处反射的随机半球向量//Ray randomRay;//randomRay.startPoint = res.光线命中点;//vec3 L;//vec2 uv = sobol低差异序列(p7, 0);////uv = CranleyPattersonRotation(uv);//L = 漫反射重要性采样(uv.x, uv.y, res.material.normal);//randomRay.direction = L;//double r = randf();//if (r < res.material.specularRate) // 镜面反射//{//vec3 ref = normalize(reflect(ray.direction, res.material.normal));//randomRay.direction = mix(ref, randomRay.direction, res.material.roughness);////微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);//color = 微积分;//}//else if (res.material.specularRate <= r && r <= res.material.refractRate) // 折射//{//vec3 ref = normalize(refract(ray.direction, res.material.normal, float(res.material.refractAngle)));//randomRay.direction = mix(ref, -randomRay.direction, res.material.refractRoughness);////微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);//color = 微积分;//}//else // 漫反射//{////vec3 s = res.material.color;////微积分 = 路径追踪(shapes, randomRay, 0);//微积分 = 光线追踪(shapes, randomRay, 4);////color = 微积分;//color = 微积分;//}//小图积分A[i][j] += color;//小图采样A[i][j] = res.material.color;//}//}//}//}//}//p2 = imageA;double* p = image; int t2; double FC = 1.0f; double FB = 0.0f; int L = WIDTH / 矩形;//for (int i = 0; i < WIDTH; i++)//{//for (int j = 0; j < HEIGHT; j++)//{//int t = 0;//if (i / 10 < 20)//{//t = 1;//}//else//{//t = 0;//}//{//int t2 = 0;//if (j / 10 < 20)//{//t2 = 1;//}//else//{//t2 = 0;//}//离线交点颜色[i][j] = 小图采样A[i / L + t][j / L + t2];//小图积分[i][j] = 小图积分A[i / L + t][j / L + t2];//}//}//}//}HANDLE h1, h2;//声明句柄变量h1 = CreateThread(NULL, 0, myfun1, NULL, 0, NULL);//创建线程1h2 = CreateThread(NULL, 0, myfun2, NULL, 0, NULL);//创建线程2glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer);glLoadIdentity();glBegin(GL_QUADS);glTexCoord2f(0, 0);glVertex2f(-1, 1);glTexCoord2f(0, 1);glVertex2f(-1, -1);glTexCoord2f(1, 1);glVertex2f(1, -1);glTexCoord2f(1, 0);glVertex2f(1, 1);glEnd();glutSwapBuffers();++frames;if (clock() - clocks > CLOCKS_PER_SEC){char title[64];sprintf(title, " FPS:%d", frames);glutSetWindowTitle(title);clocks = clock();frames = 0;}//++p7;std::cout << "fps: 共 " << ++p7 << std::endl;}int main(){Shape* 单个数据 = new Shape;for (int i = 0; i < WIDTH * HEIGHT; ++i) {for (int i2 = 0; i2 < WIDTH * HEIGHT; ++i2) {屏幕优先物体[i][i2] = 单个数据;}}Sphere s1 = Sphere(vec3(-0.65, -0.7, 0.0), 0.3, GREEN);Sphere s2 = Sphere(vec3(0.0, -0.3, 0.0), 0.4, WHITE);Sphere s3 = Sphere(vec3(0.65, 0.1, 0.0), 0.3, BLUE);s1.material.specularRate = 0.3;s1.material.roughness = 0.1;s2.material.specularRate = 0.3;s2.material.refractRate = 0.95;s2.material.refractAngle = 0.1;//s2.material.refractRoughness = 0.05;s3.material.specularRate = 0.3;shapes.push_back(&s1);shapes.push_back(&s2);shapes.push_back(&s3);shapes.push_back(new Triangle(vec3(-0.15, 0.4, -0.6), vec3(-0.15, -0.95, -0.6), vec3(0.15, 0.4, -0.6), YELLOW));shapes.push_back(new Triangle(vec3(0.15, 0.4, -0.6), vec3(-0.15, -0.95, -0.6), vec3(0.15, -0.95, -0.6), YELLOW));Triangle tt = Triangle(vec3(-0.2, -0.2, -0.95), vec3(0.2, -0.2, -0.95), vec3(-0.0, -0.9, 0.4), YELLOW);//tt.material.specularRate = 0.1;//tt.material.refractRate = 0.85;//tt.material.refractRoughness = 0.3;//shapes.push_back(&tt);// 发光物//Triangle l1 = Triangle(vec3(0.0, 0.99, 0.4), vec3(-0.4, 0.99, -0.4), vec3(-0.4, 0.99, 0.4), WHITE);//Triangle l2 = Triangle(vec3(0.4, 0.99, 0.4), vec3(0.4, 0.99, -0.4), vec3(-0.4, 0.99, -0.4), WHITE);//l1.material.isEmissive = true;//l2.material.isEmissive = true;//shapes.push_back(&l1);//shapes.push_back(&l2);// 背景盒子// bottomshapes.push_back(new Triangle(vec3(1, -1, 1), vec3(-1, -1, -1), vec3(-1, -1, 1), WHITE));shapes.push_back(new Triangle(vec3(1, -1, 1), vec3(1, -1, -1), vec3(-1, -1, -1), WHITE));// topshapes.push_back(new Triangle(vec3(1, 1, 1), vec3(-1, 1, 1), vec3(-1, 1, -1), WHITE));shapes.push_back(new Triangle(vec3(1, 1, 1), vec3(-1, 1, -1), vec3(1, 1, -1), WHITE));// backshapes.push_back(new Triangle(vec3(1, -1, -1), vec3(-1, 1, -1), vec3(-1, -1, -1), CYAN));shapes.push_back(new Triangle(vec3(1, -1, -1), vec3(1, 1, -1), vec3(-1, 1, -1), CYAN));// left//shapes.push_back(new Triangle(vec3(-1, -1, -1), vec3(-1, 1, 1), vec3(-1, -1, 1), BLUE));//shapes.push_back(new Triangle(vec3(-1, -1, -1), vec3(-1, 1, -1), vec3(-1, 1, 1), BLUE));// right//shapes.push_back(new Triangle(vec3(1, 1, 1), vec3(1, -1, -1), vec3(1, -1, 1), RED));//shapes.push_back(new Triangle(vec3(1, -1, -1), vec3(1, 1, 1), vec3(1, 1, -1), RED));Triangle l3 = Triangle(vec3(1, 1, 1), vec3(1, -1, -1), vec3(1, -1, 1), WHITE);shapes.push_back(&l3);l3.material.isEmissive = true;Triangle l4 = Triangle(vec3(1, -1, -1), vec3(1, 1, 1), vec3(1, 1, -1), WHITE);shapes.push_back(&l4);l4.material.isEmissive = true;Triangle l5 = Triangle(vec3(-1, -1, -1), vec3(-1, 1, 1), vec3(-1, -1, 1), WHITE);shapes.push_back(&l5);l5.material.isEmissive = true;Triangle l6 = Triangle(vec3(-1, -1, -1), vec3(-1, 1, -1), vec3(-1, 1, 1), WHITE);shapes.push_back(&l6);l6.material.isEmissive = true;int argc = 1;char* argv[] = {"MFC_GLUT" };clocks = clock();frames = 0;glutInitWindowSize(400-100, 400 - 100);glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);glutCreateWindow("RayTracing");glutDisplayFunc(渲染);glutIdleFunc(渲染);glEnable(GL_TEXTURE_2D);glGenTextures(1, &texture);glBindTexture(GL_TEXTURE_2D, texture);glTexImage2D(GL_TEXTURE_2D, 0, 4, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// 线形滤波glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// 线形滤波glutMainLoop();return 0;}

如果觉得《路径追踪 随机追踪法提速一倍》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。