performance - para - Muchas mallas con la misma geometría y material, ¿puedo cambiar sus colores?
mallas deportivas para mujer (2)
Tengo un gran número (~ 1000) de THREE.Mesh
objetos que se han construido a partir del mismo THREE.Geometry
y THREE.MeshPhongMaterial
(que tiene un mapa).
Me gustaría tintar (colorear) estos objetos individualmente.
De manera ingenua, intenté cambiar la propiedad mesh.material.color
, pero cambiar esta propiedad en cualquiera de los objetos cambia el color de todos los objetos a la vez. Esto tiene sentido, ya que solo hay un material que se comparte entre todos los objetos.
Mi siguiente idea fue crear un THREE.MeshPhongMaterial
separado para cada objeto. Entonces, ahora tengo un gran número de THREE.Mesh
objetos que se han construido a partir del mismo THREE.Geometry
, pero tienen THREE.MeshPhongMaterials
individuales (que comparten la misma textura). Esto me permite cambiar los colores individualmente, pero el rendimiento es peor. Chrome Profilier muestra que la aplicación está gastando mucho tiempo haciendo cosas materiales, como cambiar texturas.
El color del material es solo un uniforme en el shader. Por lo tanto, actualizar ese uniforme debería ser bastante rápido.
Pregunta: ¿Hay alguna forma de anular un color de material desde el nivel de malla?
Si lo hubiera, creo que podría compartir el material entre todos mis objetos y recuperar mi rendimiento, sin dejar de cambiar los colores individualmente.
[He probado en v49 y v54, tienen un rendimiento y una degradación idénticos]
actualización: he construido un caso de prueba, y la caída del rendimiento debido a esto es más pequeña de lo que pensé que era, pero aún es medible.
Aquí hay dos enlaces:
- http://danceliquid.com/docs/threejs/material-test/index.html?many-materials=false
- http://danceliquid.com/docs/threejs/material-test/index.html?many-materials=true
En el primer caso, solo hay dos materiales, en el segundo caso, cada cubo tiene su propio material. Mido la tasa de cuadros del primer caso para ser 53 fps en esta máquina, y la tasa de cuadros del segundo es 46 fps. Esto es aproximadamente una caída del 15%.
En ambos casos, el color del material de cada cubo se cambia cada fotograma. En el caso de muchos materiales, en realidad vemos que cada cubo adquiere su propio color, en el caso de solo dos materiales, los vemos todos con el mismo color (como se esperaba).
Sí. Por objeto, clone su material usando material.clone()
, modifique su emissive
y color
, y configure el material del objeto para este clon. Los sombreadores y atributos se copian por referencia, así que no se preocupe de que esté clonando todo el material cada vez; de hecho, las únicas cosas que se copian por valor son los uniformes (como el emissive
y el color
). Así que puedes cambiar estos por objeto individual.
Personalmente, guardo el material original en una propiedad separada y personalizada del objeto para que pueda volver a él fácilmente más tarde; Depende de cuales sean tus necesidades.
Si está escribiendo sus propios sombreadores, puede usar una variable uniform
para un tinte general (no específico de vértice) y pasarla al sombreador para tener en cuenta el color general. vec4f_t
y vec4f()
no son estándar en la parte C, pero probablemente su código ya tenga equivalentes.
DO:
vec4f_t hue = vec4f(....); // fill in as desired
// load the shader so that GLuint shader_id is available.
// "hue" is a uniform var in the vertexshader
GLUint hue_id = glGetUniformLocation(shader_id, "hue");
// later, before rendering the object:
glUniform4fv(hue_id, 1, &hue);
the.vertexshader:
uniform vec4 hue; // add this and use it in the texture''s color computation