3

我正在尝试从噪声纹理生成高度图。据我了解,为了get_pixel()在这种情况下调用图像,必须首先锁定图像。但是,当我尝试运行该程序时,它退出并出现错误:Invalid call. Nonexistent function 'lock' in base 'StreamTexture'.

如果我尝试在不锁定图像的情况下运行它,我会收到错误:Invalid call. Nonexistent function 'get_pixel' in base 'StreamTexture'.

我确定我所遵循的说明是针对我正在运行的同一版本的 Godot(3.1),那么为什么引擎会告诉我这些lock()并且get_pixel()是不存在的功能呢?

我的代码在这里:

extends Spatial

var width
var height
var heightData = {}
var vertices = PoolVector3Array()
var drawMesh = Mesh.new()

func _ready():
    var noiseTexture = load("res://noiseTexture.png")
    width = noiseTexture.get_width()
    height = noiseTexture.get_height()

    noiseTexture.lock()
    for x in range(0, width):
        for y in range(0, height):
            heightData[Vector2(x,y)] = noiseTexture.get_pixel(x,y).r
    noiseTexture.unlock()

    for x in range(0, width-1):
        for y in range(0, height-1):
            createQuad(x,y)

    var surfTool = SurfaceTool.new()
    surfTool.begin(Mesh.PRIMITIVE_TRIANGLES)

    for i in vertices.size():
        surfTool.add_vertex(vertices[i])

    surfTool.commit(drawMesh)
    $MeshInstance.mesh = drawMesh

func createQuad(x,y):
    #First half
    vertices.push_back(Vector3(x, heightData[Vector2(x,y)], -y))
    vertices.push_back(Vector3(x, heightData[Vector2(x,y+1)], -y-1))
    vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y+1)], -y-1))
    #Second Half
    vertices.push_back(Vector3(x, heightData[Vector2(x,y)], -y))
    vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y+1)], -y-1))
    vertices.push_back(Vector3(x+1, heightData[Vector2(x+1,y)], -y))

任何帮助是极大的赞赏。

编辑 - 我已经(尝试)实施评论中建议的更改(但我仍然不知道如何处理颜色变量)并附上了我生成的代码的屏幕截图以及我的一些评论试图向自己解释为什么这个过程应该有效(我认为)。它还显示了我的节点结构,这就是我选择将其显示为图像的原因。但是,当我尝试运行它时,程序崩溃并显示错误。

高度图失败

4

2 回答 2

3

检查文档StreamTexture没有办法lock

我认为您要使用的类是Image. 该类Texture通常用于在屏幕上绘图应用于Material

var noiseImage = Image.new()
noiseImage.load("res://noiseTexture.png")
noiseImage.lock() # Lock the image here
var color = noiseImage.get_pixel(10, 10) # Replace with your height map population

PS:

只是让您知道,我在这里遇到了很多内存使用问题,所以请确保您也进行测试(尽管 C# 的垃圾收集器很糟糕)。您可能需要处理图像、表面工具和阵列网格(如果您移除地形对象)以保持最佳性能。

于 2019-06-01T05:40:32.050 回答
0

我在生成高度图地形时遇到了类似的问题。

nathanfranke是正确的,他的解决方案会奏效。

如果您出于某种原因使用 anImageTexture您可以调用get_data()它来获取底层图像。然后你就像内森在他的回答中所说lock()的那样打电话。Image

注意检查您的坐标get_pixel()是否正确。您可以通过单击代码行的最左边缘来设置断点。我提到这一点是因为我非常沮丧,直到我意识到我的坐标计算都是 int 导致采样像素始终位于 <0,0> 处。

这是我的代码的一部分,用于将图像采样到 HeightMapShape.map_data 以用于 Bullet 高度图碰撞:

var map_w = shape.map_width
var map_h = shape.map_depth
var img_w = img.get_width()
var img_h = img.get_height()
img.lock()

for y in range(0, map_h):
    py = float(img_h) * (float(y) / float(map_h))

    for x in range(0, map_w):
        px = float(img_w) * (float(x) / float(map_w))
        index = y * img_h + x
        pix = img.get_pixel(px, py)
        shp.map_data[index] = pix.r * heightmap_height + heightmap_offset
于 2019-10-09T20:12:06.423 回答