体渲染绘制地球¶
1 参考¶
2 纹理贴图¶
使用 vtkTexturedSphereSource 可以快速构建一个贴图地球。
Sphere → Texture → Mapper → Actor
2.1 关键代码¶
vtkNew<vtkTexturedSphereSource> sphere;
sphere->SetPhiResolution(64);
sphere->SetThetaResolution(64);
sphere->SetRadius(1.0);
vtkNew<vtkImageReader2Factory> factory;
vtkImageReader2* reader = factory->CreateImageReader2("earth.jpg");
reader->SetFileName("earth.jpg");
vtkNew<vtkTexture> texture;
texture->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(sphere->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->SetTexture(texture);
3 体渲染¶
![]() |
![]() |
|---|---|
构建一个球形体素场,并基于 NASA 地形数据进行体渲染。
自定义隐函数 → 体素采样 → VolumeMapper → Volume
3.1 自定义隐函数¶
继承 vtkImplicitFunction,在 EvaluateFunction 中完成:
-
判断点是否位于球壳
-
计算球坐标
-
映射到纹理坐标
-
从地形灰度图采样
-
返回标量值
_球面映射公式
`r = sqrt(x² + y² + z²)
若在球壳附近:
|r - R| < ε
计算:
映射到纹理:
读取灰度值并映射为高程:
double topoValue = 6400.0 * (static_cast<double>(*topoPixel) / 255.0);
double bathValue = -8000.0 * (1.0 - static_cast<double>(*bathPixel) / 255.0);
pixel = topoValue + bathValue;
返回该值作为体素标量。
3.2 构建体数据¶
vtkNew<vtkSampleFunction> sample;
sample->SetImplicitFunction(earthSphere);
sample->SetSampleDimensions(255,255,255);
sample->SetModelBounds(-1,1,-1,1,-1,1);
生成 vtkImageData 体素场。
3.3 体渲染参数¶
透明度函数
opacityFunction->AddPoint(-8100, 0.0);
opacityFunction->AddPoint(-8000, 1.0);
opacityFunction->AddPoint(6400, 1.0);
opacityFunction->AddPoint(6500, .0);
颜色函数
vtkNew<vtkColorTransferFunction> colorFunction;
// 海洋深度 (-8000 到 0)
colorFunction->AddRGBPoint(-8000, 0.0, 0.0, 0.2); // 深海沟
colorFunction->AddRGBPoint(-4000, 0.0, 0.1, 0.4); // 深海
colorFunction->AddRGBPoint(-2000, 0.0, 0.2, 0.6); // 中深海
colorFunction->AddRGBPoint(-500, 0.1, 0.4, 0.8); // 浅海
colorFunction->AddRGBPoint(-100, 0.15, 0.5, 0.85); // 近海
colorFunction->AddRGBPoint(0, 0.3, 0.6, 0.3); // 海岸线(改为绿色调)
// 陆地高程 (0 到 6400)
colorFunction->AddRGBPoint(50, 0.3, 0.65, 0.25); // 海岸湿地
colorFunction->AddRGBPoint(200, 0.2, 0.75, 0.2); // 低地平原(鲜绿)
colorFunction->AddRGBPoint(500, 0.4, 0.85, 0.3); // 平原(亮绿,突出)
colorFunction->AddRGBPoint(800, 0.5, 0.8, 0.35); // 高平原
colorFunction->AddRGBPoint(1200, 0.65, 0.75, 0.35); // 丘陵过渡
colorFunction->AddRGBPoint(1800, 0.75, 0.7, 0.3); // 丘陵(黄绿)
colorFunction->AddRGBPoint(2500, 0.7, 0.55, 0.25); // 低山(褐色)
colorFunction->AddRGBPoint(3500, 0.65, 0.45, 0.2); // 中山
colorFunction->AddRGBPoint(4500, 0.6, 0.35, 0.15); // 高山(深褐)
colorFunction->AddRGBPoint(5000, 0.7, 0.7, 0.7); // 雪线开始
colorFunction->AddRGBPoint(5500, 0.85, 0.85, 0.85); // 积雪
colorFunction->AddRGBPoint(6400, 1.0, 1.0, 1.0); // 雪峰(纯白)

