我遇到的问题是我想给复杂的模型上色(+ 4k三角形),而不必将模型分成许多TriangleMesh对象。
根据我的理解,这只能通过将颜色映射到图像上,然后计算图像中每个颜色像素的纹理坐标来完成。我在下面做了以下操作:
val uniqueColors = colors.toHashSet()
val colorTexCoordsMap = HashMap<Color, FloatArray>()
val atlas = WritableImage(uniqueColors.size, 1)
for((index, color) in uniqueColors.withIndex()) {
colorTexCoordsMap[color] = floatArrayOf(index.toDouble().div(uniqueColors.size).toFloat(), 0.5f)
atlas.pixelWriter.setColor(index, 0, color)
}
atlasMaterialProperty.set(PhongMaterial().also {
it.diffuseMap = atlas
})
val out = File("model-${definition.id}-${uniqueColors.size}-atlas.png")
val bim = SwingFXUtils.fromFXImage(atlas, null)
ImageIO.write(bim, "png", out)
for(face in 0 until definition.faceCount){
val color = colors[face]
val uv = colorTexCoordsMap[color]!!
val vertex1 = definition.faceVertexIndices1[face]
val vertex2 = definition.faceVertexIndices2[face]
val vertex3 = definition.faceVertexIndices3[face]
val vx1 = definition.vertexPositionsX[vertex1]
val vy1 = definition.vertexPositionsY[vertex1]
val vz1 = definition.vertexPositionsZ[vertex1]
val vx2 = definition.vertexPositionsX[vertex2]
val vy2 = definition.vertexPositionsY[vertex2]
val vz2 = definition.vertexPositionsZ[vertex2]
val vx3 = definition.vertexPositionsX[vertex3]
val vy3 = definition.vertexPositionsY[vertex3]
val vz3 = definition.vertexPositionsZ[vertex3]
val vertex1Index = cacheVertex(vertex1, vx1, vy1, vz1)
val vertex2Index = cacheVertex(vertex2, vx2, vy2, vz2)
val vertex3Index = cacheVertex(vertex3, vx3, vy3, vz3)
val texIndex = cacheUV(uv[0], uv[1])
faces.addAll(
vertex1Index, texIndex,
vertex2Index, texIndex,
vertex3Index, texIndex
)
faceSmoothingGroups.addAll(0)
}
我希望颜色会准确显示,但是颜色却不能正确显示。我认为这与除法部分不够精确有关,因此在使用多种颜色的模型中,有时uv坐标不再映射到生成图像中的预期颜色。
在当前代码中,将生成高度= 1且宽度= color_count的图像。因此,每个x值代表颜色的索引。我还尝试生成更多的矩形调色板以减少分割量,这在某些情况下有帮助,但在其他情况下则无济于事,这取决于模型中存在多少种颜色。
编辑:使其与以下代码一起使用:
for((index, color) in uniqueColors.withIndex()) {
val u = (index.toDouble() / uniqueColors.size + (1.0 / uniqueColors.size / 2.0)).toFloat()
val v = 0.5f
val texIndex = cacheUV(u, v)
colorTexCoordsMap[color] = texIndex
atlas.pixelWriter.setColor(index, 0, color)
}