Example 4 : Thin lens camera
2016-06-14 11:52
351 查看
main.c
主要的思想都在代码的注释里面,
比较重要的就是,
1. aperture 个人理解就是,A real pinhole camera. 中的那个pinhole的R(半径)。
2.
![](https://img-blog.csdn.net/20160614113329531?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
S与整个view(由(u0,v0),(u1, v1)构成的)有比例关系。
although s is arbitrary as long as it is positive, the bigger it is the bigger the window height and width have to be to get the same image. The ratio of v1 - v0 to 2s is the tangent of half of the "vertical field-of-view." This is another way to fix some
viewing parameters.
3. 整体思路
![](https://img-blog.csdn.net/20160614113643422?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
q点是根据aperature随机生成,如果aperature是0的话,那么就没有模糊效果,因为起点没有任何变化,那么,就相当于之前的muilt sample。
只有当aperature不为0的时候,生成的q是随机的,对应不在s距离上的物体,射线射到的这些物体上的hitPoint偏差较大,所以形成模糊。
#include <stdio.h> #include <math.h> #include <il/il.h> #include "vec3.h" #include "sample.h" #include "shapes.h" #define IMAGE_WIDTH 512 #define IMAGE_HEIGHT 384 #define NUM_SAMPLES 16 shape_t shapes[4]; light_t lights[1]; typedef struct camera_s { vec3 eye; vec3 lookat; vec3 up; float d; // dist to perfect focus float aperature; float l,r,t,b; // extents of view } camera_t; unsigned char floattochar(float c) { int i = (int)c; if (i <= 0) return 0; if (i >= 255) return 255; else return (unsigned char)(c); } int main(int argc, int argv) { int r, c, s; float x_samples[NUM_SAMPLES]; float y_samples[NUM_SAMPLES]; float xl_samples[NUM_SAMPLES]; float yl_samples[NUM_SAMPLES]; float t_samples[NUM_SAMPLES]; unsigned char image[IMAGE_WIDTH * IMAGE_HEIGHT * 3]; float aspect; vec3 total, color, hitpos; vec3 start, end, dir; hit_t hit; camera_t cam; vec3 cam_f, cam_r, cam_u; ILuint iname; ilInit(); ilEnable(IL_FILE_OVERWRITE); // 高,宽比 aspect = (float) IMAGE_HEIGHT / (float)IMAGE_WIDTH; VectorSet(dir, 0, 0, -1); // 初始化球和三角形 shapes[0].type = SHAPE_SPHERE; VectorSet(shapes[0].sphere.center, -2.6f, -0.5f, -1.5f); shapes[0].sphere.radius = 1; VectorSet(shapes[0].move_velocity, 0, 0, 0); VectorSet(shapes[0].color, 1, 0, 0); shapes[1].type = SHAPE_SPHERE; VectorSet(shapes[1].sphere.center, 2.6f, 0.5f, -4); shapes[1].sphere.radius = 1; VectorSet(shapes[1].move_velocity, 0, 0, 0); VectorSet(shapes[1].color, 0, 1, 0); shapes[3].type = SHAPE_TRI; VectorSet(shapes[2].tri.verts[2], 0, 0.2f, -5); VectorSet(shapes[2].tri.verts[1], 0, -0.4f, -1); VectorSet(shapes[2].tri.verts[0], 0, 0.6f, -2); VectorSet(shapes[2].move_velocity, 0, 0, 0); VectorSet(shapes[2].color, 1, 1, 0); // 初始化光源 VectorSet(lights[0].ambient, 0.1f, 0.1f, 0.1f); VectorSet(lights[0].diffuse, 1, 1, 1); VectorSet(lights[0].specular, 0.1f, 0.1f, 0.1f); VectorSet(lights[0].pos, -2, 2, -2); // 初始化摄像机 VectorSet(cam.eye, -5,0,-2.8f); VectorSet(cam.lookat, 0,0,-2.8f); VectorSet(cam.up, 0,1,0); // To specify the aperture of the lens we could just specify R, // a large hole = (pinhole) = (aperture) cam.aperature = 0.25f; // 相当于s, the distance from e to the viewing rectangle; // 这里进行调节参数的话,就可以使得哪一些物体清晰,哪一些物体是模糊,主要是看这个the viewing rectangle的位置,因为要发射线到这个 // the viewing rectangle 上的pixel中 cam.d = 2.5f; cam.l = -0.5f; cam.r = 0.5f; cam.t = 0.5f*aspect; cam.b = -0.5f*aspect; // we calculate the rest // cam_f == cam_forward VectorSub(cam.lookat, cam.eye, cam_f); VectorNormalize(cam_f); // cam_r == cam_right CrossProduct(cam_f, cam.up, cam_r); VectorNormalize(cam_r); // cam_u == cam_up CrossProduct(cam_r, cam_f, cam_u); VectorNormalize(cam_u); for (r=0; r<IMAGE_HEIGHT; r++) { for (c=0; c<IMAGE_WIDTH; c++) { // pixel samples sample_multi_jitter_2d(NUM_SAMPLES, x_samples, y_samples); filter_cubic(NUM_SAMPLES, x_samples); filter_cubic(NUM_SAMPLES, y_samples); // time samples sample_jitter_1d(NUM_SAMPLES, t_samples); filter_cubic(NUM_SAMPLES, t_samples); sample_shuffle(NUM_SAMPLES, t_samples); // lens samples sample_multi_jitter_2d(NUM_SAMPLES, xl_samples, yl_samples); sample_shuffle_2d(NUM_SAMPLES, xl_samples, yl_samples); VectorSet(total, 0, 0, 0); for (s=0; s<NUM_SAMPLES; s++) { // 这里范围就变成了[-0.5, 0.5] xl_samples[s] -= 0.5f; yl_samples[s] -= 0.5f; VectorCopy(cam.eye, start); // if cam.aperature = 0, all xl_samples[s] is miss VectorMA(start, cam.aperature*xl_samples[s], cam_r, start); VectorMA(start, cam.aperature*yl_samples[s], cam_u, start); // ((((x_samples[s]+0.5f+c) / ((float)IMAGE_WIDTH )))*(cam.r-cam.l) + cam.l);主要的功能就是把 // 512 *512 的pixel 映射到 cam.rltb这个view上 // 为什么要乘上 cam.d(s) // note that although s is arbitrary as long as it is positive, the bigger it is // the bigger the window height and width have to be to get the same image.The // ratio of v\ - v0 to 2s is the tangent of half of the "vertical field-of-view." This // is another way to fix some viewing parameters. // 就是,2s 与 (v1 - v0)成比例,如果 假设了v1 = -v0的话,那么,s就与v1,v0成比例 x_samples[s] = cam.d*((((x_samples[s]+0.5f+c) / ((float)IMAGE_WIDTH )))*(cam.r-cam.l) + cam.l); y_samples[s] = cam.d*((((y_samples[s]+0.5f+r) / ((float)IMAGE_HEIGHT)))*(cam.t-cam.b) + cam.b); VectorCopy(cam.eye, end); VectorMA(end, cam.d, cam_f, end); VectorMA(end, x_samples[s], cam_r, end); VectorMA(end, y_samples[s], cam_u, end); // VectorSub(a,b,c) ==> c = a - b, b->a // start -> end VectorSub(end, start, dir); VectorNormalize(dir); if (shape_intersect_all(start, dir, t_samples[s], &hit)) { VectorMA(start, hit.t, dir, hitpos); shape_shade(hit.shape, hitpos, t_samples[s], color); VectorAdd(total, color, total); } // background else { total[0] += 0.2f; total[1] += 0.2f; total[2] += 0.2f; } } VectorScale(total, 255.0f / NUM_SAMPLES, total); image[(r*IMAGE_WIDTH + c)*3 + 0] = floattochar(total[0]); image[(r*IMAGE_WIDTH + c)*3 + 1] = floattochar(total[1]); image[(r*IMAGE_WIDTH + c)*3 + 2] = floattochar(total[2]); } } /* write the image */ ilGenImages(1, &iname); ilBindImage(iname); ilTexImage(IMAGE_WIDTH, IMAGE_HEIGHT, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, image); ilSaveImage("out.png"); ilDeleteImages(1, &iname); return 0; }
主要的思想都在代码的注释里面,
比较重要的就是,
1. aperture 个人理解就是,A real pinhole camera. 中的那个pinhole的R(半径)。
2.
S与整个view(由(u0,v0),(u1, v1)构成的)有比例关系。
although s is arbitrary as long as it is positive, the bigger it is the bigger the window height and width have to be to get the same image. The ratio of v1 - v0 to 2s is the tangent of half of the "vertical field-of-view." This is another way to fix some
viewing parameters.
3. 整体思路
q点是根据aperature随机生成,如果aperature是0的话,那么就没有模糊效果,因为起点没有任何变化,那么,就相当于之前的muilt sample。
只有当aperature不为0的时候,生成的q是随机的,对应不在s距离上的物体,射线射到的这些物体上的hitPoint偏差较大,所以形成模糊。
相关文章推荐
- Ogre学习记录(二)-RaySceneQuery
- [Unity3D] 关于触屏用Ray来Hit场景中GameObject的笔记(copy的,转不来)
- Unity3D中Layers和LayerMask解析
- unity之Ray、RaycastHit 、Raycast
- Unity3D学习笔记07:射线Ray实现点击拾取
- Example 1 : A Single Sample Ray Tracer
- Example 2 : Multi Sampling And Filtering Methods
- Example 3 : motion blur And Shade(Shadow)
- focus towards ray ban wayfarer the
- RISELab实验室正在开发的Ray项目初步尝试记录
- UGUI内核大探究(十八)Raycaster
- Camera Ray Generation
- Understanding Photometric and Radiometric units and their application to computer graphics
- Example 6 : Bounding Volume Heirarchy And Bump Lit
- Example 5 : Texturing
- 数字电子钟实验设计(proteus)
- jQuery.Validate
- 乐学成语(数据库的应用)
- Android--从零单排系列(5)--常用传感器的使用
- Java BigDecimal类用法详解