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

商城网站建设精英知识搜索引擎

商城网站建设精英,知识搜索引擎,西安市工程建设信息网,提卡网站建设由于此次试验需要加载模型,涉及到本地环节,如果是windows系统,需要对main函数中的路径稍作改变: 这么写需要: #include "windows.h" 该段代码: #include "windows.h" int main(int ar…

由于此次试验需要加载模型,涉及到本地环节,如果是windows系统,需要对main函数中的路径稍作改变:

这么写需要:
#include "windows.h"

该段代码:


#include "windows.h"
int main(int argc, const char** argv)
{std::vector<Triangle*> TriangleList;float angle = 140.0;bool command_line = false;std::string filename = "output.png";objl::Loader Loader;std::string obj_path = "\\..\\..\\test\\models\\spot\\";char pathBuf[MAX_PATH];char* p;if (GetModuleFileNameA(NULL, pathBuf, MAX_PATH)){p = strrchr(pathBuf, '\\');if (p){*p = '\0';std::string exe_path = pathBuf;obj_path = exe_path + obj_path;}}bool loadout = Loader.LoadFile("D:\\opencode\\games101\\test\\test\\models\\spot\\spot_triangulated_good.obj");

同时在windows下计算很卡,可能软件模拟计算量很大的原因;

使用c++17及以上版本,

\spot_triangulated_good.obj 中的描述了顶点信息

输入到三角形列表中: 

但是 在使用的时候:

fragment_shader 即下面的着色模型:中去如何消费这个图片


    std::function<Eigen::Vector3f(fragment_shader_payload)> active_shader = normal_fragment_shader;  用于设置着色模型

着色模型

1.normal模型
// 根据法线进行不同着色
Eigen::Vector3f normal_fragment_shader(const fragment_shader_payload& payload)
{Eigen::Vector3f return_color = (payload.normal.head<3>().normalized() + Eigen::Vector3f(1.0f, 1.0f, 1.0f)) / 2.f;Eigen::Vector3f result;result << return_color.x() * 255, return_color.y() * 255, return_color.z() * 255;return result;
}

这个函数并不是光照模型,只是根据不同法线返回不同颜色值。
第一行的代码,首先取出当前待着色像素点的法向量的X,Y,Z坐标并归一化,故此时X,Y,Z都在[-1,1]之间,加上(1.0f, 1.0f, 1.0f)后,变为[0,2],再除以2,即得[0,1],再分别乘以255即可得到各个颜色值了。

效果:

2.phong模型

Eigen::Vector3f phong_fragment_shader(const fragment_shader_payload& payload)
{// 泛光、漫反射、高光系数Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);Eigen::Vector3f kd = payload.color;Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);// 灯光位置和强度auto l1 = light{{20, 20, 20}, {500, 500, 500}};auto l2 = light{{-20, 20, 0}, {500, 500, 500}};std::vector<light> lights = {l1, l2};// 光照Eigen::Vector3f amb_light_intensity{10, 10, 10};// 环境光强度Eigen::Vector3f eye_pos{0, 0, 10};// 相机位置float p = 150;// ping point的信息Eigen::Vector3f color = payload.color;Eigen::Vector3f point = payload.view_pos;// view spaceEigen::Vector3f normal = payload.normal;Eigen::Vector3f result_color = {0, 0, 0};// 光照结果Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);// 遍历每一束光for (auto& light : lights){Eigen::Vector3f l = (light.position - point).normalized(), v = (eye_pos - point).normalized();// 光照方向和观察方向Eigen::Vector3f h = (l + v).normalized();// 半程向量Eigen::Vector3f I = light.intensity;// 光强float r2 = (light.position - point).dot(light.position - point);Eigen::Vector3f Ld = kd.cwiseProduct(I / r2) * std::max(0.0f, normal.dot(l));//cwiseProduct()函数允许Matrix直接进行点对点乘法,而不用转换至ArrayEigen::Vector3f Ls = ks.cwiseProduct(I / r2) * std::pow(std::max(0.0f, normal.dot(h)), p);result_color += La + Ld + Ls;}//Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);//result_color += La;return result_color * 255.f;
}

直接根据公式写就行,这里我认为环境光应该放在循环外,不过这样渲出来的结果相比说说明偏暗,但后面的displacement又要放在外面否则偏亮。

phong模型渲染结果:

3.texture模型
Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
{Eigen::Vector3f return_color = {0, 0, 0};if (payload.texture){return_color = payload.texture->getColor(payload.tex_coords.x(), payload.tex_coords.y());// 获取材质颜色信息}Eigen::Vector3f texture_color;texture_color << return_color.x(), return_color.y(), return_color.z();Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);Eigen::Vector3f kd = texture_color / 255.f;// 材质颜色影响漫反射系数Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);auto l1 = light{{20, 20, 20}, {500, 500, 500}};auto l2 = light{{-20, 20, 0}, {500, 500, 500}};std::vector<light> lights = {l1, l2};Eigen::Vector3f amb_light_intensity{10, 10, 10};Eigen::Vector3f eye_pos{0, 0, 10};float p = 150;Eigen::Vector3f color = texture_color;Eigen::Vector3f point = payload.view_pos;Eigen::Vector3f normal = payload.normal;Eigen::Vector3f result_color = {0, 0, 0};Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);for (auto& light : lights){Eigen::Vector3f l = (light.position - point).normalized(), v = (eye_pos - point).normalized();// 光照方向和观察方向Eigen::Vector3f h = (l + v).normalized();// 半程向量Eigen::Vector3f I = light.intensity;// 光强float r2 = (light.position - point).dot(light.position - point);Eigen::Vector3f Ld = kd.cwiseProduct(I / r2) * std::max(0.0f, normal.dot(l));//cwiseProduct()函数允许Matrix直接进行点对点乘法,而不用转换至ArrayEigen::Vector3f Ls = ks.cwiseProduct(I / r2) * std::pow(std::max(0.0f, normal.dot(h)), p);result_color += La + Ld + Ls;}// Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);// result_color += La;return result_color * 255.f;
}

 

    Eigen::Vector3f getColor(float u, float v){// 限制(u, v)坐标范围u = std::fmin(1, std::fmax(u, 0));v = std::fmin(1, std::fmax(v, 0));auto u_img = u * (width-1);auto v_img = (1 - v) * (height-1);auto color = image_data.at<cv::Vec3b>(v_img, u_img);// 四舍五入return Eigen::Vector3f(color[0], color[1], color[2]);}

更换一个材质:

4 displacement_fragment_shader 

Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payload)
{Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);Eigen::Vector3f kd = payload.color;Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);auto l1 = light{{20, 20, 20}, {500, 500, 500}};auto l2 = light{{-20, 20, 0}, {500, 500, 500}};std::vector<light> lights = {l1, l2};Eigen::Vector3f amb_light_intensity{10, 10, 10};Eigen::Vector3f eye_pos{0, 0, 10};float p = 150;Eigen::Vector3f color = payload.color; Eigen::Vector3f point = payload.view_pos;Eigen::Vector3f normal = payload.normal;float kh = 0.2, kn = 0.1;float x = normal.x();float y = normal.y();float z = normal.z();Eigen::Vector3f t{ x * y / std::sqrt(x * x + z * z), std::sqrt(x * x + z * z), z*y / std::sqrt(x * x + z * z) };Eigen::Vector3f b = normal.cross(t);Eigen::Matrix3f TBN;TBN <<  t.x(), b.x(), normal.x(),t.y(), b.y(), normal.y(),t.z(), b.z(), normal.z();float u = payload.tex_coords.x();float v = payload.tex_coords.y();float w = payload.texture->width;float h = payload.texture->height;float dU = kh * kn * (payload.texture->getColor(u + 1 / w , v).norm() - payload.texture->getColor(u, v).norm());float dV = kh * kn * (payload.texture->getColor(u, v + 1 / h).norm() - payload.texture->getColor(u, v).norm());Eigen::Vector3f ln{-dU, -dV, 1};//与凹凸贴图的区别就在于这句话point += (kn * normal * payload.texture->getColor(u , v).norm());normal = (TBN * ln).normalized();Eigen::Vector3f result_color = {0, 0, 0};for (auto& light : lights){Eigen::Vector3f l = (light.position - point).normalized();      // 光Eigen::Vector3f v = (eye_pos - point).normalized();		        // 眼Eigen::Vector3f h = (l + v).normalized();                       // 半程向量double r_2 = (light.position - point).dot(light.position - point);Eigen::Vector3f Ld = kd.cwiseProduct(light.intensity / r_2) * std::max(0.0f, normal.dot(l));    //cwiseProduct()函数允许Matrix直接进行点对点乘法,而不用转换至Array。Eigen::Vector3f Ls = ks.cwiseProduct(light.intensity / r_2) * std::pow(std::max(0.0f, normal.dot(h)), p);result_color += (Ld + Ls);   }Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);result_color += La; return result_color * 255.f;
}

 draw函数(顶点、三角形处理阶段) 

void rst::rasterizer::draw(std::vector<Triangle*>& TriangleList) {float f1 = (50 - 0.1) / 2.0;// zfar和znear距离的一半float f2 = (50 + 0.1) / 2.0;// zfar和znear的中心z坐标Eigen::Matrix4f mvp = projection * view * model;// 计算MVP变换矩阵// 遍历每个小三角形for (const auto& t : TriangleList){Triangle newtri = *t;// 计算viewspace_pos,其中viewspace_pos的坐标是经过MV变换,没有经过P投影变换// 所以默认在相机坐标系而不是世界坐标系// 记录三角形顶点MV变换后坐标std::array<Eigen::Vector4f, 3> mm{(view * model * t->v[0]),(view * model * t->v[1]),(view * model * t->v[2])};std::array<Eigen::Vector3f, 3> viewspace_pos;// 存入viewspace_posstd::transform(mm.begin(), mm.end(), viewspace_pos.begin(), [](auto& v) {return v.template head<3>();});// 得到经过mvp后的坐标Eigen::Vector4f v[] = {mvp * t->v[0],mvp * t->v[1],mvp * t->v[2]};// 换算齐次坐标for (auto& vec : v) {vec.x() /= vec.w();vec.y() /= vec.w();vec.z() /= vec.w();}// 计算在MV转换后各顶点的法向量// 利用原来点法向量推出MV变换后法向量// 因为光线作用是在view_space下进行的Eigen::Matrix4f inv_trans = (view * model).inverse().transpose();Eigen::Vector4f n[] = {inv_trans * to_vec4(t->normal[0], 0.0f),inv_trans * to_vec4(t->normal[1], 0.0f),inv_trans * to_vec4(t->normal[2], 0.0f)};// 视口变换 得到顶点在屏幕上的坐标 即screen spacefor (auto& vert : v){vert.x() = 0.5 * width * (vert.x() + 1.0);vert.y() = 0.5 * height * (vert.y() + 1.0);// 为了Zbuffer保留Z值// (透视)投影变换最后一步是从正交投影变换到正则立方体// 而这一步就是把正则立方体的z值还原到正交投影时的z值,即原始z值vert.z() = vert.z() * f1 + f2;}// 记录经过MVP视口变换后的顶点坐标// 完成顶点变换,变换到屏幕空间for (int i = 0; i < 3; ++i){//screen space coordinatesnewtri.setVertex(i, v[i]);}// 记录顶点的法向量for (int i = 0; i < 3; ++i){//view space normalnewtri.setNormal(i, n[i].head<3>());}// 设置颜色newtri.setColor(0, 148, 121.0, 92.0);newtri.setColor(1, 148, 121.0, 92.0);newtri.setColor(2, 148, 121.0, 92.0);// 对这个小三角形进行光栅化// 传入viewspace_pos的坐标,光线的作用是在viewspace下的rasterize_triangle(newtri, viewspace_pos);}
}
//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) 
{auto v = t.toVector4(); //v[0],v[1],v[2]分别为三角形的三个顶点,是四维向量//比较三个顶点的横纵坐标,确定包围盒的边界并取整double min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));double max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));double min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));double max_y = std::max(v[0][1], std::max(v[1][1], v[2][1]));min_x = static_cast<int>(std::floor(min_x));min_y = static_cast<int>(std::floor(min_y));max_x = static_cast<int>(std::ceil(max_x));max_y = static_cast<int>(std::ceil(max_y));//此处实现的是MSAAstd::vector<Eigen::Vector2f> pos{                               //对一个像素分割四份 当然你还可以分成4x4 8x8等等甚至你还可以为了某种特殊情况设计成不规则的图形来分割单元{0.25,0.25},                //左下{0.75,0.25},                //右下{0.25,0.75},                //左上{0.75,0.75}                 //右上};for (int i = min_x; i <= max_x; ++i){for (int j = min_y; j <= max_y; ++j){int count = 0; //开始遍历四个小格子,获得平均值for (int MSAA_4 = 0; MSAA_4 < 4; ++MSAA_4){if (insideTriangle(static_cast<float>(i+pos[MSAA_4][0]), static_cast<float>(j+pos[MSAA_4][1]),t.v))++count;}if(count) //至少有一个小格子在三角形内{//此处是框架中代码,获得z,见原程序注释://    * v[i].w() is the vertex view space depth value z.//    * Z is interpolated view space depth for the current pixel//    * zp is depth between zNear and zFar, used for z-bufferauto[alpha, beta, gamma] = computeBarycentric2D(i + 0.5, j + 0.5, t.v);float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();zp *= Z;//endif (depth_buf[get_index(i, j)] > zp){depth_buf[get_index(i, j)] = zp;//更新深度//这里注意,虽然说明上说"反转了z,保证都是正数,并且越大表示离视点越远",//但经过我的查看,实际上并没有反转,因此还是按照-z近大远小来做,当然也可以在上面补一个负号不过没必要//利用重心坐标插值各种值auto interpolated_color = interpolate(alpha, beta, gamma, t.color[0], t.color[1], t.color[2], 1);auto interpolated_normal = interpolate(alpha, beta, gamma, t.normal[0], t.normal[1], t.normal[2], 1).normalized();auto interpolated_texcoords = interpolate(alpha, beta, gamma, t.tex_coords[0], t.tex_coords[1], t.tex_coords[2], 1);auto interpolated_shadingcoords = interpolate(alpha, beta, gamma, view_pos[0], view_pos[1], view_pos[2], 1);//shadingcoords是由view_pos插值得到,也就是物体表面的点在相机坐标系的位置。他们会在shader中被用到,来计算光照等信息。//此处是框架中代码,获得z,见原程序注释:fragment_shader_payload payload(interpolated_color, interpolated_normal, interpolated_texcoords, texture ? &*texture : nullptr);payload.view_pos = interpolated_shadingcoords;auto pixel_color = fragment_shader(payload);//end// 设置颜色set_pixel(Eigen::Vector2i(i, j), pixel_color * (count / 4.0));}}}}
}

完整代码:vs2022

http://www.fp688.cn/news/143442.html

相关文章:

  • 中山地区做网站公司品牌推广文案
  • 灰色行业老域名做网站不收录关键词优化顾问
  • 贵阳企业建站系统模板高端网站定制公司
  • 金融企业网站建设公司推广赚钱的平台有哪些
  • 杭州口碑最好的装修公司山东关键词优化联系电话
  • html做动态网站吗网站seo优化技能
  • java 开发手机网站开发百度一下首页网页
  • 网站开发设计合同seo按照搜索引擎的什么对网站
  • 微网站如何做宣传网站seo优化是什么
  • 查看网站外链湖南 seo
  • 本人找做钢筋笼的活网站百度广告联盟怎么赚钱
  • 网站无法连接到服务器网络营销的方法有哪些?
  • 毕设做网站怎么弄代码设计百度seo多少钱一个月
  • 网站三级分销怎么做百度网址大全网站大全
  • 计算机是学什么内容的东莞网络优化哪家公司好
  • 互联网情况下做企业网站的有点网络营销策划书格式
  • 网站流量显示厦门seo新站策划
  • 深圳网站建设创造者百度的网址是多少
  • 中山网站建设的价格站长之家关键词挖掘
  • 网站需求报告怎么写百度首页推广广告怎么做
  • Wordpress右侧返回顶部按钮常见的系统优化软件
  • 公司网站搭建百度人工在线客服
  • 红色色系做网站的配色百度一下网页版浏览器
  • 成都网站建设哪儿济南兴田德润怎么联系花生壳免费域名注册
  • 国内做服装的网站有哪些方面做竞价托管的公司
  • 淘宝上做网站的生意怎么样百度一下官网入口
  • 国外网站代做软文是什么
  • 网站素材免费seo技术优化
  • 做网站游戏需要什么软文交易平台
  • 电脑建设银行怎样设置网站查询密码线上渠道推广怎么做