GAMES101-Assignment3

2024-02-12 04:12
文章标签 games101 assignment3

本文主要是介绍GAMES101-Assignment3,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GAMES101-Assignment3

参考文章:
1.《GAMES101》作业框架问题详解
2. Games101:作业3(管线分析、深度插值、libpng warning、双线性插值等)
3.【GAMES101】作业3(提高)与法线贴图原理和渲染管线框架分析

文件清单:
CMakeLists.txt(项目配置清单,cmake根据此清单进行系统构建、编译、测试)
OBJ_Loader.h(用于加载三维模型)
global.hpp(定义全局变量PI)
rasterizer.hpp(光栅器头文件)
Texture.hpp(声明纹理宽高和根据纹理坐标获取像素颜色的函数getColor)
Triangle.hpp(三角形的头文件,定义其相关属性)
Shader.hpp(声明颜色、法向量、纹理、纹理坐标,支持纹理映射,定义了fragment_shader_payload,其中包括了 Fragment Shader 可能用到的参数)
rasterizer.cpp(生成渲染器界面与绘制)
Texture.cpp(目前为空文件)
Triangle.cpp(画出三角形)
main.cpp


1.实验要求

2.实验内容及其结果

2.1 rasterize_triangle in rasterizer.cpp


barycentric

初始化空间中三角形三个点的颜色、法向量、纹理坐标、shading point位置,通过重心公式对三角形内的各个属性进行插值,计算得到的各个属性传入fragment_shader_payload

//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) 
{// TODO: From your HW3, get the triangle rasterization code.// TODO: Inside your rasterization loop://    * 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-buffer// 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;// TODO: Interpolate the attributes:// auto interpolated_color// auto interpolated_normal// auto interpolated_texcoords// auto interpolated_shadingcoords// Use: fragment_shader_payload payload( interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr);// Use: payload.view_pos = interpolated_shadingcoords;// Use: Instead of passing the triangle's color directly to the frame buffer, pass the color to the shaders first to get the final color;// Use: auto pixel_color = fragment_shader(payload);auto v = t.toVector4();// Define bound of box//INT_MAX: infnity represented by top limitation of integerint BoxMin_X =INT_MAX,BoxMin_Y=INT_MAX;//INT_MIN: infnity represented by bottom limitation of integerint BoxMax_X =INT_MIN,BoxMax_Y=INT_MIN;//iterate to find boundfor (int i = 0; i < 3; i++){BoxMin_X=std::min(BoxMin_X,(int)v[i][0]);BoxMin_Y=std::min(BoxMin_Y,(int)v[i][1]);BoxMax_X=std::max(BoxMax_X,(int)v[i][0]);BoxMax_Y=std::max(BoxMax_Y,(int)v[i][1]);}//iterate pixel inside of bounding boxfor (int i = BoxMin_X; i <= BoxMax_X; i++){for (int j = BoxMin_Y; j <= BoxMax_Y; j++){//float x=i+0.5,y=i+0.5;//check if center of current pixel is inside the triangleif (insideTriangle(i,j,t.v))//if centric pixel(x,y) is insidez. three point v[0],v[1],v[2]in triangle {//interpolated depth valueauto[alpha, beta, gamma] = computeBarycentric2D(i+0.5, j+0.5, t.v);float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();z_interpolated *= w_reciprocal;//interpolated depth value is compared with depth_bufferif (-z_interpolated < depth_buf[get_index(i,j)])//get buffer index of pixel(x,y){   //color interpolateauto interpolated_color = interpolate(alpha,beta,gamma,t.color[0],t.color[1],t.color[2],1);//normal vector interpolateauto interpolated_normal = interpolate(alpha,beta,gamma,t.normal[0],t.normal[1],t.normal[2],1).normalized();//texture coordinates interpolateauto interpolated_texcoords = interpolate(alpha,beta,gamma,t.tex_coords[0],t.tex_coords[1],t.tex_coords[2],1);//shading point coordinates interpolateauto interpolated_shadingcoords = interpolate(alpha,beta,gamma,view_pos[0],view_pos[1],view_pos[2],1);//interpolated attributes send to fragment_shader_payloadfragment_shader_payload payload(interpolated_color,interpolated_normal.normalized(),interpolated_texcoords,texture ? &*texture :nullptr);//send orignal coord to view_pospayload.view_pos = interpolated_shadingcoords;//update depth bufferdepth_buf[get_index(i,j)] = -z_interpolated;//update frame bufferframe_buf[get_index(i,j)] = fragment_shader(payload);//get color of 1 out of 3 vertex in triangle,then set this color to current pixelset_pixel({i,j},frame_buf[get_index(i,j)]);//set_pixel({i,j,1},t.getColor());//(x,y,1) homogeneous coord,num 1 represent a point}}}}
}

2.2 get_projection_matrix in main.cpp

MVP变换

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{// TODO: Use the same projection matrix from the previous assignmentsEigen::Matrix4f projection = Eigen::Matrix4f::Identity();// TODO: Implement this function// Create the projection matrix for the given parameters.// Then return it.// n=zNear f=zFar  // calculate r l t b according to eye_fov and aspect_ratio // tan(eye_fov/2)=t/|n|,aspect_ratio=r/t// t=2|n|tan(eye_fov/2),r=t*aspect_ratio,l=-r,b=-tfloat t=2*abs(zNear)*tan(eye_fov/2),b=-t;float r=aspect_ratio*t,l=-r;eye_fov=(eye_fov/180.0)*MY_PI;//angle to rad//perspective projection M_{projection}= M_{orthographics}*M_{persp to ortho}Eigen::Matrix4f M_persp_to_ortho,M_ortho,M_scale,M_translate;M_persp_to_ortho << zNear,0,0,0,0,zNear,0,0,0,0,zNear+zFar,-zNear*zFar,0,0,1,0;//M_{orthographics}=scale*translateM_scale << 2/(r-l),0,0,0,0,2/(t-b),0,0,0,0,2/(zNear-zFar),0,0,0,0,1;M_translate << 1,0,0,-(r+l)/2,0,1,0,-(t+b)/2,0,0,1,-(zNear+zFar)/2,0,0,0,1;M_ortho = M_scale*M_translate;projection = M_ortho*M_persp_to_ortho*projection;return projection;}

in main.cpp 激活相应 shader

编译后运行

./Rasterizer output.png normal

2.3 phong_fragment_shader in main.cpp

Blinn-phong 反射模型: 正确实现 phong_fragment_shader 对应的反射模型

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;//p value control range of specularEigen::Vector3f color = payload.color;Eigen::Vector3f point = payload.view_pos;Eigen::Vector3f normal = payload.normal;Eigen::Vector3f result_color = {0, 0, 0};Eigen::Vector3f l,v,dif,h,spe,amb;for (auto& light : lights){// TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* // components are. Then, accumulate that result on the *result_color* object.//light vector ll = (light.position - point).normalized();//view vector vv = (eye_pos - point).normalized();//distance r from light to shading point,namely norm of light vector//r = (light.position - point).dot(light.position - point);//diffuse L_d= kd(I/r^2)max(0,n dot l)dif = kd.cwiseProduct(light.intensity / (light.position - point).dot(light.position - point))*std::fmax(0, normal.dot(l));//normal is n vector//half vector h=(v+l)/norm(v+l)h = (v+l) / ((v+l).dot(v+l));//specular L_s=ks(I/r^2)max(0,n dot h)^pspe = ks.cwiseProduct(light.intensity / ((light.position - point).dot(light.position - point)))*pow(std::fmax(0,normal.dot(h.normalized())),p);//ambient La=kaIaamb = ka.cwiseProduct(amb_light_intensity);result_color += (dif + spe + amb);}return result_color * 255.f;
}

in main.cpp 激活相应 shader

编译后运行

./Rasterizer output.png phong

2.4 texture_fragment_shader in main.cpp

Texture mapping: 将 phong_fragment_shader 的代码拷贝到 texture_fragment_shader, 在此基础上正确实现 Texture Mapping.
phong_fragment_shader中color = payload_color
texture_fragment_shader中color = texture_color

Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
{Eigen::Vector3f return_color = {0, 0, 0};if (payload.texture){// TODO: Get the texture value at the texture coordinates of the current fragmentreturn_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();//ambient term coefficient kaEigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);//diffuse reflection coefficient kdEigen::Vector3f kd = texture_color / 255.f;//specular term coefficient ksEigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);//light's position and intensityauto 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;//color of textureEigen::Vector3f color = texture_color;//coord of shading pointEigen::Vector3f point = payload.view_pos;//normal vector of shading pointEigen::Vector3f normal = payload.normal;Eigen::Vector3f result_color = {0, 0, 0};Eigen::Vector3f l,v,dif,h,spe,amb;for (auto& light : lights){// TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* // components are. Then, accumulate that result on the *result_color* object.//light vector ll = (light.position - point).normalized();//view vector vv = (eye_pos - point).normalized();//distance r from light to shading point,namely norm of light vector//(light.position - point).dot(light.position - point)//diffuse L_d= kd(I/r^2)max(0,n dot l)dif = kd.cwiseProduct(light.intensity / ((light.position - point).dot(light.position - point)))*std::fmax(0, normal.dot(l));//normal is n vector//half vector h=(v+l)/norm(v+l)h = (v+l) / ((v+l).dot(v+l));//specular L_s=ks(I/r^2)max(0,n dot h)^pspe = ks.cwiseProduct(light.intensity / ((light.position - point).dot(light.position - point)))*pow(std::fmax(0,normal.dot(h.normalized())),p);//ambient La=kaIaamb = ka.cwiseProduct(amb_light_intensity);result_color += (dif + spe + amb);}return result_color * 255.f;
}

in main.cpp 激活相应shader

编译后运行

./Rasterizer output.png texture

2.5 bump mapping in main.cpp


Eigen::Vector3f bump_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;// TODO: Implement bump mapping here// Let n = normal = (x, y, z)// Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))// Vector b = n cross product t// Matrix TBN = [t b n]// dU = kh * kn * (h(u+1/w,v)-h(u,v))// dV = kh * kn * (h(u,v+1/h)-h(u,v))// Vector ln = (-dU, -dV, 1)// Normal n = normalize(TBN * ln)//------------------------//perturb the normal in 3D//original surface normal n(p)=(0,0,1)//derivative at p are //dp/du=c1*[h(u+1)-h(u)]//dp/dv=c2*[h(v+1)-h(v)]//perturbed normal is then n(p)=(-dp/du,-dp/dv,1).normalized()float x=normal.x(),y=normal.y(),z=normal.z();Eigen::Vector3f t{x*y / std::sqrt(x*x+z*z), x*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(),v = payload.tex_coords.y();float w = payload.texture->width,h = payload.texture->height;float dU = kh*kn*(payload.texture->getColor(u+1.0f/w,v).norm() - payload.texture->getColor(u,v).norm());float dV = kh*kn*(payload.texture->getColor(u,v+1.0f/h).norm() - payload.texture->getColor(u,v).norm());Eigen::Vector3f perturbed_n{-dU,-dV,1.0f};normal = TBN * perturbed_n;//-------------------------Eigen::Vector3f result_color = {0, 0, 0};result_color = normal.normalized();return result_color * 255.f;
}


编译后运行

./Rasterizer output.png bump

2.6 displacement mapping in main.cpp

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;// TODO: Implement displacement mapping here// Let n = normal = (x, y, z)// Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))// Vector b = n cross product t// Matrix TBN = [t b n]// dU = kh * kn * (h(u+1/w,v)-h(u,v))// dV = kh * kn * (h(u,v+1/h)-h(u,v))// Vector ln = (-dU, -dV, 1)// Position p = p + kn * n * h(u,v)// Normal n = normalize(TBN * ln)//------------------------//perturb the normal in 3D//original surface normal n(p)=(0,0,1)//derivative at p are //dp/du=c1*[h(u+1)-h(u)]//dp/dv=c2*[h(v+1)-h(v)]//perturbed normal is then n(p)=(-dp/du,-dp/dv,1).normalized()float x=normal.x(),y=normal.y(),z=normal.z();Eigen::Vector3f t{x*y / std::sqrt(x*x+z*z), x*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(),v = payload.tex_coords.y();float w = payload.texture->width,h = payload.texture->height;float dU = kh*kn*(payload.texture->getColor(u+1.0f/w,v).norm() - payload.texture->getColor(u,v).norm());float dV = kh*kn*(payload.texture->getColor(u,v+1.0f/h).norm() - payload.texture->getColor(u,v).norm());Eigen::Vector3f perturbed_n{-dU,-dV,1.0f};normal = TBN * perturbed_n;point += (kn * normal * payload.texture->getColor(u,v).norm()); //-------------------------Eigen::Vector3f result_color = {0, 0, 0};Eigen::Vector3f light_vec,view_vec,dif,half_vec,spe,amb;for (auto& light : lights){// TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* // components are. Then, accumulate that result on the *result_color* object.//light vector llight_vec = (light.position - point).normalized();//view vector vview_vec = (eye_pos - point).normalized();//+l??//distance r from light to shading point,namely norm of light vector//r = (light.position - point).dot(light.position - point);//diffuse L_d= kd(I/r^2)max(0,n dot l)dif = kd.cwiseProduct(light.intensity / (light.position - point).dot(light.position - point))*std::fmax(0, normal.dot(light_vec));//normal is n vector//half vector h=(v+l)/norm(v+l)half_vec = (view_vec+light_vec) / ((view_vec+light_vec).dot(view_vec+light_vec));//specular L_s=ks(I/r^2)max(0,n dot h)^pspe = ks.cwiseProduct(light.intensity / ((light.position - point).dot(light.position - point)))*pow(std::fmax(0,normal.dot(half_vec.normalized())),p);//ambient La=kaIaamb = ka.cwiseProduct(amb_light_intensity);result_color += (dif + spe + amb);}return result_color * 255.f;
}


编译后运行

./Rasterizer output.png displacement


这篇关于GAMES101-Assignment3的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/701642

相关文章

GAMES101(5~6节,光栅化)

光栅化Rasterization 透视投影已知field和近平面,如何推导宽度? 根据三角函数:tan field / 2 = (height / 2) / ||n||近平面,从而可以求出高度 因为知道宽高比,所以可以求出宽度,高度 * 宽/高 视口变换 经过MVP变换,顶点位于正则化空间坐标,是一个在 [-1,1] ^3 之间的 x, y, z 坐标构成(标准立方体),我们下一步需要做

Games101学习 - 线性代数综述

1. 叉积矩阵形式 叉乘矩阵形式通常在物理模拟中有运用,处理四元数旋转也类似这样的形式。 // 定义两个向量 A 和 BFVector A(1.0f, 2.0f, 3.0f);FVector B(4.0f, 5.0f, 6.0f);// 计算叉积FVector CrossProduct = FVector::CrossProduct(A, B);if (GEngine){GEngine

GAMES101图形学笔记1

一、图形学的应用 1.游戏渲染、光照 2.电影特效 3.面部、动作捕捉,如Avatar(阿凡达)中的面部捕捉 4.设计 建筑设计,汽车设计 5.虚拟现实VR 增强现实AR 6.数码插画 笔刷 PS软件等 7.模拟、仿真 8.GUI 界面设计等 9.字体设计typography 二、为什么学习图形学 1.图形学是一门Awesome的学科,能够创造很多有意思的东西,有意思的图像 2.了解并学习一

Games101-动画与模拟(求解常微分方程,刚体与流体)

Single Particle Simulation 规定了任何一个物体任何时刻的速度,知道它的初始位置,求它某个时间后的位置? 如果一个物体是匀速直线运动,用初始位置加上速度和时间的乘积即可 如上图,如果想描述一个粒子在一个速度场(理想的情况:只要知道位置,就知道它这个时刻的速度)中如何运动 任何一个粒子在上面的速度场会沿着类似水流的方向往前走 任何一个位置x和任何时间t,都知道有一个速度

Games101-相机与透镜

成像:光栅化成像(上图)和光线追踪成像(下图) 都是用合成的方法来成像。还可以用捕捉的方法来成像 利用小孔成像原理制作的相机就是针孔相机 如果一个相机没有针孔/透镜,是无法拍照的。 因为任何一个点都有可能收集到来自不同方向上的光。这个点本身作为传感器是不区分来自各个方向上的radiance。则各个方向上能量都被收集到一起,该点收集到的是irradiance,而不是radiance。最终所有东

Games101 光栅化笔记, 作业二

光栅化笔记 1、屏幕、像素、屏幕空间: (1)屏幕: 1、像素的二维数组 2、分辨率:数组的规模 3、典型的光栅成像设备 (2)像素的抽象理解: 1、内部颜色不会变化的小方块 2、RGB三者的颜色混合 (3)对光栅化的理解:对像素进行着色 (4)屏幕空间(在闫老师课上的规定): 1、屏幕的左下角是原点 2、x和y坐标都取整数,下图中蓝色像素坐标为(2,1) 3、像素的索引范围是(0,0)->

Games101 作业一 构建模型变换,和透视投影矩阵

知识总结:变换的流程 (1) 模型(Model)变换,pa中模型只绕z轴旋转 (2)视图(View)变换,作用是调整摄像机的位置 (3)投影(Projection)变换,pa中要求是透视投影,透视投影可看成挤压 + 正交变换 (4)视口(Viewport)变换,将投影变换所得的[-1,1]²变换到屏幕空间 代码分析: (1)获得视图变换矩阵(main.cpp) 视图变换的作用是移动摄像机,可看

17 - Games101 - 笔记 - 材质与外观

**17 **材质与外观 材质与BRDF 自然界中的材质:丝绸、头发、蝴蝶翅膀表面、寿司表面等等 图形学中的材质:同一个模型之所以渲染出不同结果的原因就是因为材质。在图形学中是给不同的物体指定不同的材质,知道它们如何和光线作用后就能正确的渲染。 漫反射 BRDF 漫反射材质:光线打到一个点上后均匀分散到各个不同方向上。 漫反射材质可以定义它在任何一个点上可以有不同的漫反射系数,虽

14 Games101 - 笔记 - 光线追踪(利用包围盒技术加速光线追踪(KD-Tree and BVH)

14 光线追踪(利用包围盒技术加速光线追踪(KD-Tree and BVH) 在上一节中,我们介绍了whited-style光线追踪的原理,以及实现细节。相比与光栅化中所使用的的Blinn-Phong模型,光线追踪显著了提升了图像质量,但随之而来的问题是渲染速度过慢。因为在判断光线与场景交点的时候,需要去进行所有三角形面与光线的求交,而且这仅仅是对一个像素而言。 那么总体来说光是进行光线与三角形

Games101-着色(着色频率、图形管线、纹理映射)

着色频率 从边界可以看出三个球,拥有完全相同的几何形状。但是着色之后结果各不相同 着色频率:着色要应用在哪些点上。 第一个球,把着色应用在一个面上。一个平面只做一次shading。 第二个球,每一个平面有4个顶点,每个顶点都算出对应的法线,进行shading。每3个顶点,可以围成一个三角形,三角形内部的颜色通过插值的方法计算 第三个球,着色应用在每一个像素上。求出每一个三角形的法线,将法线进行