简体   繁体   English

如何在 javascript 中将 png 图像的像素的 512x512 高度图数组放大到 2017x2017 像素,以用作虚幻引擎 4 中的高度图?

[英]How do you upscale a 512x512 to 2017x2017 heightmap array of pixels of a png image in javascript for use as a heightmap in Unreal Engine 4?

I am converting a 512 x 512 32 bit rgb png with encoded height values to a 16 bit grayscale png depicting height values for a height map.我正在将具有编码高度值的 512 x 512 32 位 rgb png 转换为描绘高度图高度值的 16 位灰度 png。

This is the conversion code这是转换代码

Image converted used image-js图像转换使用image-js

image = 32 bit rgb png image arraybuffer

image.getPixelsArray() returns an array of pixels with r, g, b channels

async function getHeightArrayStats(image) {
  let decodedHeightArray = []
  let stats = {}
  stats.minElevation = Number.MAX_VALUE;
  stats.maxElevation = Number.MIN_VALUE;
  stats.height = image.height;
  stats.width = image.width;
  let pixelsArray = image.getPixelsArray()
  for (const pixel of pixelsArray) {
    let r = pixel[0]
    let g = pixel[1]
    let b = pixel[2]
    //Conversion function from mapbox to convert pixel values to height values in meters
    // height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)
    let height = getHeightFromRgb(r, g, b)

    if (height > stats.maxElevation) {
      stats.maxElevation = height;
    }
    if (height < stats.minElevation) {
      stats.minElevation = height;
    }

    decodedHeightArray.push(height)
  }
  console.log(decodedHeightArray)
  return {decodedHeightArray, stats}
}

I then convert that image to 16bit grayscale png using the same width and height as original image然后我使用与原始图像相同的宽度和高度将该图像转换为 16 位灰度 png

async function convertImage(width, height, decodedHeightArray) {
  let newImage = new Image(width, height, decodedHeightArray, {kind: 'GREY', 16})//kind = color and bit depth
  return newImage
} 

Next I resize the 16bit 512 x 512 to 2017 x 2017 using image-js and BICUBIC interpolation接下来我使用 image-js 和 BICUBIC 插值将 16 位 512 x 512 调整为 2017 x 2017

const newImage = rgbImage.resize({
    interpolationType: "BICUBIC", // or "BILINEAR" or "NEAREST", in order of decreasing quality
    width: 2017,
    preserveAspectRatio: true // Or height: number
  });

After the conversion I create a new Landscape size of 2017 in Unreal Engine using the newly created heightmap image.转换后,我使用新创建的高度图图像在虚幻引擎中创建了一个新的 2017 年地形尺寸。 Unreal Engine also provides a formula to convert the terrain scale/Z scale so the terrain will look like it should.虚幻引擎还提供了一个公式来转换地形比例/Z 比例,使地形看起来应该如此。

I calculate the Z-scale in this function我在这个函数中计算 Z 尺度

getUnrealZScale(maxElevation) {
  let cm = (maxElevation * 100)
  let zscale = (cm * 0.001953125)
  return zscale
},

The maxElevation is calcualted from the getHeightArrayStats function above using the original 32bit rgb image maxElevation 是根据上面的 getHeightArrayStats 函数使用原始 32 位 rgb 图像计算得出的

The problem I am having is that I am getting a stepping result when importing the resized 2017 16bit image into Unreal Engine.我遇到的问题是,在将调整大小的 2017 16 位图像导入虚幻引擎时,我得到了步进结果。

Attached are the input and output images as well as pictures of landscape in Unreal using these images附上输入输出图像以及使用这些图像在虚幻中的风景图片

32 bit 512 x 512 Rgb height value encode terrain png from mapbox来自 mapbox 的 32 位 512 x 512 Rgb 高度值编码地形 png

在此处输入图片说明

Here is the converted 16bit downsized from 512k to 505k per Unreal Landscape size specs.这是根据 Unreal Landscape 尺寸规范从 512k 缩小到 505k 的转换后的 16 位。 Zoom in to see the black and white height.放大以查看黑白高度。 I also added a Blur filter to soften the edges.我还添加了一个模糊滤镜来柔化边缘。 img.blurFilter() from image-js来自 image-js 的 img.blurFilter()

在此处输入图片说明

Here is the image of the Unreal Landscape after importing the above image, no Z-scale applied since the image was only slightly downsized.这是导入上述图像后的 Unreal Landscape 图像,由于图像仅略微缩小了尺寸,因此未应用 Z 缩放。 I think this is the correct way to do it.我认为这是正确的方法。 This looks decent and is about what I expected.这看起来不错,符合我的预期。 Next is the upscale where my problem is.接下来是我的问题所在的高档。

在此处输入图片说明

16 bit heightmap scaled to 2017x2017 16 位高度图缩放至 2017x2017

https://imgur.com/uwcvAxM https://imgur.com/uwcvAxM

Result in Unreal with no Z-scale applied you can see the stepping.结果在未应用 Z 比例的 Unreal 中,您可以看到步进。

在此处输入图片说明

Do I need to increase the pixels per inch?我需要增加每英寸的像素吗? I thought that was what the interpolation was doing.我认为这就是插值正在做的事情。 Can I just calculate it manually when I process my decodedHeightArray?当我处理我的decodedHeightArray 时,我可以手动计算它吗? If so how?如果是这样怎么办?

Also a big thanks to @traktor for help with the conversion code.也非常感谢@traktor 对转换代码的帮助。

How do you convert a 32bit RGB png with encoded height values to 16 bit png using browser side javascript? 如何使用浏览器端 javascript 将具有编码高度值的 32 位 RGB png 转换为 16 位 png?

Increasing the size from 512 x 512 to 2017 x 2017 results in almost the same pixel depth expanded to 4 pixels.将尺寸从 512 x 512 增加到 2017 x 2017 会导致几乎相同的像素深度扩展到 4 像素。 Hence the stepping.因此踏步。

By doing the 32 to 16 bit first you are losing the precision needed for the expansion.通过先执行 32 到 16 位,您将失去扩展所需的精度。

  1. Expand the image at 32 bit image to the final size, 32 bpp.将 32 位图像的图像扩展到最终大小 32 bpp。

  2. Blur the image to provide the gradient.模糊图像以提供渐变。

  3. Downsample the resulting image to 16 bits.将生成的图像下采样到 16 位。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM