0,引入
其实,这一章节的标题原本想用“Q91:真实地模拟透明材质(Realistic Transparency)(5)——Wine Glass”,以便和之前透明材质相关章节联系起来。比如:
Q91:真实地模拟透明材质(Realistic Transparency)(4)——Fish Bowl
http://blog.csdn.net/libing_zeng/article/details/65442187
Q91:真实地模拟透明材质(Realistic Transparency)(3)——A Glass of Water
http://blog.csdn.net/libing_zeng/article/details/64439600
但是,考虑到这一章节的主角还是“回旋曲面”。
1,理论介绍
1.1 概述
我们要画这么一个酒杯,直接贴结果图形了:
这个酒杯是由四部分组成:
曲面1:外面的“凸”回旋曲面(法向量向外);
曲面2:里面的“凹”回旋曲面(法向量向里);
曲面3:连接凸、凹两回旋曲面上边沿的“部分圆环”曲面;
曲面4:连接凸、凹两回旋曲面下边沿的“圆带”曲面;
也是直接贴图啦。
曲面1:外面的“凸”回旋曲面(法向量向外);
曲面2:里面的“凹”回旋曲面(法向量向里);
曲面3:连接凸、凹两回旋曲面上边沿的“部分圆环”曲面;
曲面4:连接凸、凹两回旋曲面下边沿的“圆带”曲面;
1.2 相关参数的计算
曲面2(凹回旋面)的参数:
曲面1(凸回旋面)的参数:
曲面3(部分圆环)的参数:
再次看看“三次b-spline曲线”的参数方程:
对于凸、凹两回旋曲面上边沿,则有:
1,s=0;
2,对应控制点是:六个控制点中的前四个。
所以,部分圆环的sweeping半径为(1.5+1.7)/2=1.6;圆环的管道半径为(1.7-1.5)/2=0.1。圆环的中心在y=22/6平面上。
所以:
曲面4(圆带)的参数:
和曲面3的参数求法有点类似。对于凸、凹两回旋曲面下边沿,则有:
1,s=1;
2,对应控制点是:六个控制点中的后四个。
所以,“圆带”的内经为8.5/6;外径为9.7/6;圆带中心在y=-11/6平面上。
所以,
1.3 玻璃材质参数
直接看代码截图:
2,测试图形
2.1 测试代码
在“Q100”对应代码的基础上换掉build()即可。之前的代码链接:
http://download.csdn.net/detail/libing_zeng/9808046
build():
#include "World.h"
#include "Ambient.h"
#include "Pinhole.h"
#include "Directional.h"
#include "PointLight.h"
#include "RayCast.h"
#include "Whitted.h"
#include "Matte.h"
#include "Plane.h"
#include "Phong.h"
#include "MultiJittered.h"
#include "AmbientOccluder.h"
#include "Emissive.h"
#include "AreaLight.h"
#include "Rectangle.h"
#include "AreaLighting.h"
#include "Instance.h"
#include "Disk.h"
#include "Grid.h"
#include "CubicNoise.h"
#include "Image.h"
#include "FBmTextureRamp.h"
#include "InstanceTexture.h"
#include "SV_Matte.h"
#include "SV_Phong.h"
#include "Wood.h"
#include "Checker3D.h"
#include "Dielectric.h"
#include "Annulus.h"
#include "TorusPartConvex.h"
#include <iostream>
#include <fstream>
using namespace std;
#define TYPE 1
// TYPE == 1: marble, sandstone
// TYPE == 2: wood
void
World::build(void){
int num_samples = 16;
vp.set_hres(300);
vp.set_vres(300);
vp.set_samples(num_samples);
vp.set_max_depth(4);
// tracer_ptr = new RayCast(this);
tracer_ptr = new Whitted(this);
Pinhole* pinhole_ptr = new Pinhole;
pinhole_ptr->set_eye(0, 20, 80);
pinhole_ptr->set_lookat(0, 0, 0);
pinhole_ptr->set_view_distance(3600);
pinhole_ptr->compute_uvw();
set_camera(pinhole_ptr);
PointLight* point_light_ptr = new PointLight;
point_light_ptr->set_location(30, 10, 30);
point_light_ptr->scale_radiance(3.0);
point_light_ptr->set_cast_shadow(false);
add_light(point_light_ptr);
Grid* grid_ptr1 = new Grid;
Point2D ctrl_points1[6] = {Point2D(-1.0, 5.0), Point2D( 2.0, 4.0),
Point2D( 2.0, 1.0), Point2D(-0.5, 1.0),
Point2D( 1.5, -3.0), Point2D( 3.0, 0.0)};
grid_ptr1->tessellate_flat_rotational_sweeping(200, 50, ctrl_points1, 6, true);
grid_ptr1->setup_cells();
Grid* grid_ptr2 = new Grid;
Point2D ctrl_points2[6] = {Point2D(-0.8, 5.0), Point2D( 2.2, 4.0),
Point2D( 2.2, 1.0), Point2D(-0.3, 1.0),
Point2D( 1.7, -3.0), Point2D( 3.2, 0.0)};
grid_ptr2->tessellate_flat_rotational_sweeping(200, 50, ctrl_points2, 6, false);
grid_ptr2->setup_cells();
TorusPartConvex* tori_ptr = new TorusPartConvex(1.6, 0.1, 0, 360, 0, 90);
Annulus* annulus_ptr2 = new Annulus(Point3D(0, -11.0/6.0, 0), Normal(0, -1, 0), 8.5/6.0, (8.5/6.0 + 0.2));
// glass-air interface
float c = 2;
RGBColor glass_color(0.27*c, 0.49*c, 0.42*c);
RGBColor water_color(0.75, 1, 0.75);
Dielectric* glass_ptr = new Dielectric;
glass_ptr->set_ks(0.5);
glass_ptr->set_exp(2000.0);
glass_ptr->set_eta_in(1.50); // glass
glass_ptr->set_eta_out(1.0); // air
glass_ptr->set_cf_in(glass_color);
glass_ptr->set_cf_out(white);
Instance* instance_ptr1 = new Instance(grid_ptr1);
instance_ptr1->scale(0.8);
instance_ptr1->translate(0, -1, 0);
instance_ptr1->set_material(glass_ptr);
// add_object(instance_ptr1);
Instance* instance_ptr2 = new Instance(grid_ptr2);
instance_ptr2->scale(0.8);
instance_ptr2->translate(0, -1, 0);
instance_ptr2->set_material(glass_ptr);
// add_object(instance_ptr2);
Instance* instance_ptr3 = new Instance(tori_ptr);
instance_ptr3->translate(0, 22.0/6.0, 0);
instance_ptr3->scale(0.8);
instance_ptr3->translate(0, -1, 0);
instance_ptr3->set_material(glass_ptr);
// add_object(instance_ptr3);
Instance* instance_ptr4 = new Instance(annulus_ptr2);
instance_ptr4->scale(0.8);
instance_ptr4->translate(0, -1, 0);
instance_ptr4->set_material(glass_ptr);
add_object(instance_ptr4);
//------------------------------Checker3D
Checker3D* texture_ptr1 = new Checker3D();
texture_ptr1->set_size(1.0);
texture_ptr1->set_color1(0.0, 1.0, 0.0);
texture_ptr1->set_color2(1.0, 1.0, 1.0);
// textured material:
SV_Matte* matte_ptr1 = new SV_Matte;
matte_ptr1->set_ka(0.25);
matte_ptr1->set_kd(0.75);
matte_ptr1->set_cd(texture_ptr1);
Plane* plane_ptr1 = new Plane(Point3D(0, -3, 0), Normal(0, 1, 0));
plane_ptr1->set_material(matte_ptr1);
add_object(plane_ptr1);
//------------------------------Checker3D
Checker3D* texture_ptr2 = new Checker3D();
texture_ptr2->set_size(1.0);
texture_ptr2->set_color1(0.0, 1.0, 0.0);
texture_ptr2->set_color2(1.0, 1.0, 1.0);
// textured material:
SV_Matte* matte_ptr2 = new SV_Matte;
matte_ptr2->set_ka(0.25);
matte_ptr2->set_kd(0.75);
matte_ptr2->set_cd(texture_ptr2);
Plane* plane_ptr2 = new Plane(Point3D(0, 0, -5), Normal(0, 0, 1));
plane_ptr2->set_material(matte_ptr2);
add_object(plane_ptr2);
}
对于玻璃材质,有两点注意一下:
2.2 输出图形
前边是max_depth为4的图形;后边是max_depth为10的图形
(大家一起来找茬,哈哈!max_depth=10的图形看起来亮一些。)
(生成max_depth=10的图形耗时4398s)
3,其他说明
无。