Each face has 3 colors (one for each vertex). I want to use Gouraud shading to blend these colors. So far, I have taken some inspiration from the FXyz library.
My current approach uses the setTextureModeVertices3D
from the FXyz library. But this uses density maps, which does not work in my case because the colors don't come from a mathematical formula. My initial idea was to implement it as follows:
- Calculate the color for each vertex in the mesh.
- Extract a list of all the unique colors
- Make a palette of the unique colors
val palette = object : ColorPalette {
override fun getNumColors() = colors.size
override fun getColor(i: Int) = colors.getOrNull(i)?: Color.BLACK
}
- Make a map with as key the point value (x,y,z) and with as value the index of the color
- Make a density function that returns the color index from the aforementioned map.
{ point3F ->
val key = Triple(point3F.x.toInt(), point3F.y.toInt(), point3F.z.toInt())
pointColorIndexMap[key]!!
}
I have a feeling my only option is to create one large image where I put in all shaded triangles, and then references those. But I am unsure what the best technique would be here. Any help is appreciated!
Edit:
This is the code I currently use (this is written in Kotlin):
override fun updateMesh() {
val definition = model.modelDefinition
val (colors1, colors2, colors3) = definition.calculateFaceColors()
val uniqueColorHSBValues = (colors1 + colors2 + colors3).toSet().toList()
val uniqueColors = uniqueColorHSBValues.map { ModelUtil.hsbToColor(it, null) }
val palette = object : ColorPalette {
override fun getNumColors() = uniqueColors.size
override fun getColor(i: Int) = uniqueColors.getOrNull(i)?: Color.BLACK
}
val pointColorIndexMap = HashMap<Triple<Int, Int, Int>, Int>()
for (face in 0 until definition.getFaceCount()) {
val type = definition.getFaceTypes()?.get(face)?.toInt()?.let { it and 3}?:0
val (p1, p2, p3) = definition.getPoints(face)
if (type == RENDER_SHADED_TRIANGLE) {
pointColorIndexMap[p1] = uniqueColorHSBValues.indexOf(colors1[face])
pointColorIndexMap[p2] = uniqueColorHSBValues.indexOf(colors2[face])
pointColorIndexMap[p3] = uniqueColorHSBValues.indexOf(colors3[face])
} else if (type == RENDER_FLAT_TRIANGLE) {
pointColorIndexMap[p1] = uniqueColorHSBValues.indexOf(colors1[face])
pointColorIndexMap[p2] = uniqueColorHSBValues.indexOf(colors1[face])
pointColorIndexMap[p3] = uniqueColorHSBValues.indexOf(colors1[face])
}
}
setTextureModeVertices3D(palette) { point3F ->
val key = Triple(point3F.x.toInt(), point3F.y.toInt(), point3F.z.toInt())
pointColorIndexMap[key]!!
}
val meshHelper = MeshHelper(atlas)
updateMesh(meshHelper)
}