此示例使用 C# 和 XAML 绘制覆盖有阴影高度图的 3D 表面。示例释了如何在三维表面上覆盖图像。此示例执行的操作类似。但是,它不是简单地使用包含网格的现有图像,而是生成一个阴影图像以显示表面的高度。
下面的CreateAltitudeMap方法生成纹理位图。
该方法首先计算所绘制区域的表面函数值。它计算将要创建的图像中每个像素的值,在本例中为 512×512 像素图像。然后,代码使用 LINQ Min和Max方法获取数组中的最大值和最小值。
然后,代码会创建一个BitmapPixelMaker对象。它会循环遍历图像中的像素,并使用相应的函数值来确定像素的颜色。代码使用MapRainbowColor方法(稍后介绍)将每个函数值映射到适当的颜色。
该方法最后调用BitmapPixelMaker对象的MakeBitmap方法来创建WriteableBitmap,然后使用位图的Save扩展方法将结果保存到文件中。
MapRainbowColor 方法使用以下代码将给定边界之间的值映射到颜色。
// Map a value to a rainbow color.
private void MapRainbowColor(double value,
double min_value, double max_value,
out byte red, out byte green, out byte blue)
{
// Convert into a value between 0 and 1023.
int int_value = (int)(1023 * (value - min_value) /
(max_value - min_value));
// Map different color bands.
if (int_value < 256)
{
// Red to yellow. (255, 0, 0) to (255, 255, 0).
red = 255;
green = (byte)int_value;
blue = 0;
}
else if (int_value < 512)
{
// Yellow to green. (255, 255, 0) to (0, 255, 0).
int_value -= 256;
red = (byte)(255 - int_value);
green = 255;
blue = 0;
}
else if (int_value < 768)
{
// Green to aqua. (0, 255, 0) to (0, 255, 255).
int_value -= 512;
red = 0;
green = 255;
blue = (byte)int_value;
}
else
{
// Aqua to blue. (0, 255, 255) to (0, 0, 255).
int_value -= 768;
red = 0;
green = (byte)(255 - int_value);
blue = 255;
}
}
代码首先缩放该值,使其范围从 0 到 1023。根据值是 0 - 255、256 - 511、512 - 767 还是 768 - 1023 范围,代码将颜色转换为彩虹的不同部分。
将网格映射到表面上的程序 类似。以下代码显示了此示例如何使用CreateAltitudeMap方法保存的纹理图像来创建表面的材质。
// Create the altitude map texture bitmap.
private void CreateAltitudeMap()
{
// Calculate the function's value over the area.
const int xwidth = 512;
const int zwidth = 512;
const double dx = (xmax - xmin) / xwidth;
const double dz = (zmax - zmin) / zwidth;
double[,] values = new double[xwidth, zwidth];
for (int ix = 0; ix < xwidth; ix++)
{
double x = xmin + ix * dx;
for (int iz = 0; iz < zwidth; iz++)
{
double z = zmin + iz * dz;
values[ix, iz] = F(x, z);
}
}
// Get the upper and lower bounds on the values.
var get_values =
from double value in values
select value;
double ymin = get_values.Min();
double ymax = get_values.Max();
// Make the BitmapPixelMaker.
BitmapPixelMaker bm_maker =
new BitmapPixelMaker(xwidth, zwidth);
// Set the pixel colors.
for (int ix = 0; ix < xwidth; ix++)
{
for (int iz = 0; iz < zwidth; iz++)
{
byte red, green, blue;
MapRainbowColor(values[ix, iz], ymin, ymax,
out red, out green, out blue);
bm_maker.SetPixel(ix, iz, red, green, blue, 255);
}
}
// Convert the BitmapPixelMaker into a WriteableBitmap.
WriteableBitmap wbitmap = bm_maker.MakeBitmap(96, 96);
// Save the bitmap into a file.
wbitmap.Save("Texture.png");
}
// Make the surface's material using an image brush.
ImageBrush texture_brush = new ImageBrush();
texture_brush.ImageSource =
new BitmapImage(new Uri("Texture.png", UriKind.Relative));
DiffuseMaterial surface_material =
new DiffuseMaterial(texture_brush);
源码:
https://download.****.net/download/ljygood2/90120994