Colouring individual triangles in a TriangleMesh through texture map is inaccurate

我的未来我决定 提交于 2019-12-24 07:42:00

问题


The problem I am having is that I want to color complex models (+4k triangles) without having to split the models up into many TriangleMesh objects.

From my understanding this can only be done through mapping the colors onto an image and then calculate the texture coordinates of each color pixel in the image. Which I have done below:

        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)
        }

I expected the colors would be displayed accurately, however they are not. I am thinking this has to do with the division part not being very accurate and therefore in models that use many colors sometimes the uv coordinate no longer maps to the intended color in the generated image.

In the current code an image of height=1 and width=color_count is generated. So each x value represents the index of the color. I have also tried generating more rectangular palettes to reduce the amount of divisions, this helped in some cases but not in others depending on how many colors are present in the model.

Edit: got it to work with the following code:

        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)
        }

来源:https://stackoverflow.com/questions/58021812/colouring-individual-triangles-in-a-trianglemesh-through-texture-map-is-inaccura

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!