Three.js: Error de SkinnedMesh cuando está lejos de la raíz de la escena (0,0,0)

Creado en 9 feb. 2018  ·  113Comentarios  ·  Fuente: mrdoob/three.js

Creo que encontré un error en tu SkinnedMesh (probado en iPhone 6 y 8).

Si esto ya se informó, lo siento, no lo encontré en la lista de problemas :(

Parece que el skin de gpu no funciona correctamente y se está volviendo loco en el móvil.
Cuando un SkinnedMesh se mueve o se mueve en posiciones de alto valor (por ejemplo: x: 0, y: 0, z: 1000), el desollado ya no es preciso y comienza la danza de la araña.

La escala de la malla está afectando al error.

Parece que los valores de los huesos del esqueleto no se calculan correctamente en cada fotograma y el bonesTexture / bonesMatrix en el sombreador de piel está empujando los vértices en el lugar equivocado.
Este es solo mi sentimiento, por supuesto.

Hice muchas pruebas antes de publicar esto ... buscando una pista en mis exportaciones animadas, pero encontré que el error está sucediendo con cualquier tipo de formatos (GLTF, FBX, Collada, JSON, ...) y modelos del repositorio ThreeJS.

Eso es muy molesto porque significa que no podemos desarrollar un juego de corredor simple con un avatar en ejecución (avatar.position.z aumentando entonces) sin tener este problema: ((
Todavía no sé cómo lo manejaré ya que morphTargets no es una opción :(

Espero que ustedes puedan ayudar aquí.

Hice ejemplos claros con fuente limpia para exponer el problema. Es bastante fácil verificarlo en un teléfono inteligente:

Aparecen solo en dispositivos móviles (z = 10000):
http://cornflex.org/webgl/skinning-bug.html

Con floatVertexTextures establecido en falso (z = 10000):
http://cornflex.org/webgl/skinning-bug2.html

Empeora con la distancia (z aumentando):
http://cornflex.org/webgl/skinning-bug3.html

Muy, muy lejos del centro (z = 70000000)> error que también aparece en el escritorio, pero ciertamente debido a un problema de precisión flotante:
http://cornflex.org/webgl/skinning-bug4.html

Vista previa de video en mi entorno de juego:
Este es un mundo de escala realista (1,0 m = 1,0 unidad de tres js).
El error aparece solo después de 50-60 m desde la raíz de la escena y empeora con la distancia:
http://cornflex.org/webgl/skin-bug.mp4

MUY IMPORTANTE
La malla utilizada en el repositorio ThreeJS es demasiado grande. Tiene como 20 metros de altura.
Es por eso que el valor z tiene que ser mayor para ver el error.
Si esta malla se reduce a un tamaño realista, entonces el error comienza a aparecer incluso a 100 m.

Versión Three.js
  • [x] Desarrollo
  • [x] r89
  • [X] ...
Navegador
  • [ ] Todos ellos
  • [ ] Cromo
  • [] Firefox
  • [ ] Explorador de Internet
  • [x] Safari
SO
  • [ ] Todos ellos
  • [] Windows
  • [ ] Mac OS
  • [] Linux
  • [] Android
  • [x] iOS
Requisitos de hardware (tarjeta gráfica, dispositivo VR, ...)

iPhone 6, 8

Bug

Comentario más útil

Me gustaría destacar esta sección del usuario zeoverlord :

La fluctuación es natural para los flotantes, las variables perderán precisión cuanto mayor sea el número, por lo que la precisión es mejor cuanto más cerca de 1.0 esté. Ahora bien, esto no es realmente un problema, pero significa que si está haciendo muchos cálculos matriciales con números grandes, tendrá mucha degradación de precisión (también conocida como jittering). Por lo tanto, debe hacer todas sus matemáticas en torno al origen con números razonables y luego traducirlo

Todos 113 comentarios

Um, tu demostración se ve bien en mi Pixel.

Problemas confirmados en mi iPhone SE -

img_6324

Problemas de precisión de WebGL en iOS quizás

Pero los dispositivos iOS en realidad usan la ruta de código basada en texturas flotantes de la implementación de skinning, ¿verdad? ¿Puede verificar esto con la siguiente prueba de conformidad?

https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/extensions/oes-texture-float.html

iPhone SE tiene cinco fallas en esa página. 😕

Hice un pequeño screencast para mostrarte en mi proyecto:
http://cornflex.org/webgl/skin-bug.mp4

Si el avatar se aleja demasiado de 0,0,0, la máscara comienza a tener muchos errores, como puede ver.
Hice un perfil profundo del esqueleto y los huesos. Todo parece estar bien, excepto que la geometría se "retrae" de alguna manera ... Pensé en la raíz de la animación incorrecta, pero nuevamente, todo parece estar bien en Threejs con eso ...

El problema está claramente relacionado con el esqueleto y la textura de los huesos del sombreador Skinning.
También pensé en la precisión, pero como dijo Mugen, el dispositivo iOS debería admitir eso con facilidad.

... por qué solo en iphone entonces: /

Estoy bastante atascado ... Estoy reorientando a secuencias png como plan de respaldo ... :(

Lo más probable es que esto se deba a que el iphone 6 no soporta suficientes huesos.

Tuve exactamente el mismo problema.

Verifique su límite óseo aquí: https://virtulo.us/2/vr/test

No lo creo.
Si la malla de piel permanece en 0,0,0, no hay ningún problema: /
Incluso estoy pensando en mover todos los activos en lugar del avatar ... (esta es mi solución alternativa # 2) pero seguramente preferiría que el esqueleto funcione tan bien como el escritorio, por supuesto.

Un amigo acaba de informar el mismo error en el iPhone 8

Después de mirar las fuentes de ThreeJS durante 2 días ... creo que hay un problema cuando se actualiza bonesTexture.
Parece que esta textura no se actualiza correctamente y luego empuja los vértices a las posiciones originales ... pero podría estar equivocado, por supuesto.

img_1411

Hmmm ... aquí tengo algunos FALLADOS, mira:

img_1412

Quizás el problema esté relacionado con estos fallos. Mi Pixel, por ejemplo, pasa todas las pruebas.

Probemos algo: Vaya a WebGLCapabilities y establezca el valor de floatVertexTextures en false (esto evitará el uso de la textura flotante). Cree una compilación y use esta versión three.js en su aplicación. Tengo curiosidad por lo que sucede 😊.

https://github.com/mrdoob/three.js/blob/099e4364541502fdf22fc7b1c0f54239d2ba1708/src/renderers/webgl/WebGLCapabilities.js#L105

Ya probé floatVertexTextures = false en el renderizador.
La piel deja de volverse loca pero ya no hay animación: /
Empujaré una muestra.

Aquí estás:
http://cornflex.org/webgl/skinning-bug2.html

renderer.capabilities.floatVertexTextures = false;

=> Ya no se ejecuta la animación

img_1413

Sí, lo mismo en mi Pixel (el escritorio funciona). Supongo que estamos alcanzando un límite uniforme.

Hice una última muestra, con un error que aparece progresivamente:
http://cornflex.org/webgl/skinning-bug3.html

Empieza desde 0,0,0 y va hacia adelante ... espera unos segundos ... la piel empieza a volverse loca.

Es bastante extraño que todo esté bien en 0,0,0. no es

z: 1255> todavía está bien
z: 18870> piel loca

img_1415

img_1414

Como dije, hice un perfil profundo de todo el esqueleto y las posiciones de los huesos en el lado de la CPU. Todos los valores parecen estar bastante bien. La única pista que tengo es que los bonesTexture y los bonesMatrixes no funcionan correctamente en iOS cuando la malla se aleja de 0,0,0.

Revisé las posiciones de los huesos porque es un comportamiento típico de los huesos firmes del nodo raíz o cosas así ... pero no ...

Verifiqué la precisión de flotación en el lado de la GPU en sus sombreadores de piel, pero nuevamente ... nada parece tener un impacto.

Muy extraño, nadie movió un SkinnedMesh dentro de una escena y nunca informó esto: /

Una pregunta más: ¿Tiene el mismo problema con Chrome?

Mismo problema, sí.

img_1416

Suena como un problema de precisión. ¿Has intentado reducir la escena? (11195 son 11 kilómetros).

Otra opción sería mover la escena en lugar del personaje. Suele ser una solución común para escenas grandes.

Además, supongo que el código de desuello está en el espacio mundial. Podríamos investigar esto.

Veo que tu recuento de huesos es 67.

Mi (esposa) iphone 6 tiene un límite máximo de huesos de hardware de 27.

Las deformaciones que veo son idénticas a las que vi en su teléfono en mi juego (y el mismo problema que tenía antes de que mi animador arreglara las mallas de los brazos). Me sorprendería que esto no fuera al menos parte de su problema.

¿Por qué empeora con el tiempo? Ni idea. Alguien más mencionó algo similar, no estoy seguro de si está relacionado: https://discourse.threejs.org/t/updated-with-fiddle-as-animations-go-faster-there-is-increasing-error-in-accuracy/ 1707/6

Otra cosa molesta que encontré en iphones (iphone 6 al menos): DEBO usar alta precisión de sombreado, mediump y lowp no distorsionan la malla de la misma manera aterradora (como mi problema óseo en el teléfono), pero las texturas se ven extraño y confuso / pixelado mientras anima.

¿Cuál es su límite óseo de hardware en el dispositivo que está probando?

@mrdoob Ya intenté reducir la escala, pero el desollado se vuelve loco mucho más rápido de hecho: /
Si reduce la escala a 0.1, entonces el error aparece 10 veces más rápido.

La demostración que utilicé aquí para explicar proviene de los ejemplos de threejs.
En mi juego, la escala no es tan grande, pero el error es el mismo, solo que aparece más rápido.

De hecho, el desollado parece realizarse en el espacio mundial o en el espacio local, pero se estira cuando se aleja del centro. Por eso está funcionando bastante bien en 0,0,0.

Mover todo el mundo en lugar del avatar es mi solución # 2.
Debes admitir que es una mala elección cuando desarrollaste toda la rutina de un juego de corredores en el espacio mundial ya con física y todo. Y z = 11000 no está tan lejos para un juego de corredor: / ... y es solo un hombre corriendo, no un barco.

Hice muchos juegos con ThreeJS, pero es la primera vez que uso un skinnedmesh. Este error de iOS es realmente molesto.

Solución alternativa n. ° 1: haré 6 secuencias png como animaciones de hoja de sprites. Entonces puedo mantener una lógica de espacio-mundo. La fecha límite no está lejos :(

@titansoftime El problema también está apareciendo en el iPhone 8 de mi esposa. Esto no está relacionado solo con el iPhone 6.
Además, si tiene un problema de huesos máximos, tendrá errores desde el principio. Aquí, puede ver que no tiene errores en 0,0,0. Entonces el límite de los huesos no es el problema. El cálculo del espacio mundial de los huesos y la matriz de huesos en los sombreadores de piel es, en mi opinión.

¿Qué es el Max Hardware Bones del iPhone 8?

Yo no sé. Y no estoy seguro de que dependa del dispositivo.

Pero de nuevo ... En mi opinión, no está relacionado en absoluto con el valor de maxbones.

La muestra funciona correctamente en el iphone 6,8, X ... incluso 5 ... solo cuando SkinnedMesh se mantiene en 0,0,0
https://threejs.org/examples/webgl_loader_fbx.html

Si maxbones fuera un problema, tampoco tendríamos un buen pelado a 0,0,0.

Me gustaría destacar esta sección del usuario zeoverlord :

La fluctuación es natural para los flotantes, las variables perderán precisión cuanto mayor sea el número, por lo que la precisión es mejor cuanto más cerca de 1.0 esté. Ahora bien, esto no es realmente un problema, pero significa que si está haciendo muchos cálculos matriciales con números grandes, tendrá mucha degradación de precisión (también conocida como jittering). Por lo tanto, debe hacer todas sus matemáticas en torno al origen con números razonables y luego traducirlo

Mmmh, muy interesante @ Mugen87! Parece que vio la fuga.

z: 1255> todavía está bien
z: 18870> piel loca

El error puede estar de tu lado.
Un error común: el modificador de piel no se aplicó correctamente.
Error 1: vértices controlados por demasiados huesos
Error 2: vértices sin peso (o con un peso muy pequeño).

Cuando SkinnedMesh está cerca del origen (0,0,0), no notará estos errores.
Pero cuando se aleja ... le echará la culpa a la precisión del dispositivo móvil.
Entonces, lo primero que debe hacer es rediseñar (correctamente esta vez) el modificador de piel.

@RemusMar ¿
El ejemplo que expuse vino directamente de las fuentes de ThreeJS.

Muy bien mencionado en mi descripción;)

Hice muchas pruebas antes de publicar esto ... buscando una pista en mis exportaciones animadas, pero encontré que el error está sucediendo con cualquier tipo de formatos (GLTF, FBX, Collada, JSON, ...)

Hice un ejemplo claro con fuente limpia para exponer el problema. Es bastante fácil verificarlo en un teléfono inteligente:

http://cornflex.org/webgl/skinning-bug.html

El ejemplo que expuse vino directamente de las fuentes de ThreeJS.

¿Y qué?

Cómo el error puede estar de mi lado cuando esto sucede con todos los ejemplos de skinnedmesh de ThreeJS :)

Tu dijiste:

El error puede estar de tu lado.
Un error común: el modificador de piel no se aplicó correctamente.
Error 1: vértices controlados por demasiados huesos
Error 2: vértices sin peso (o con un peso muy pequeño).

FBX es de ThreeJS ... y puedes probar con GLTF o cualquier otro formato. El problema es el mismo.

var loader = nuevo THREE.FBXLoader ();
loader.load ('https://threejs.org/examples/models/fbx/xsi_man_skinning.fbx', OnFBXLoaded);

@ Mugen87 ha encontrado una pista. Esperemos que el tipo que hizo la malla de piel de gpu pueda arreglarlo.

Cómo el error puede estar de mi lado cuando esto sucede con todos los ejemplos de skinnedmesh de ThreeJS

Dije "El error podría estar de tu lado".
La línea de fondo:
Utilice un SkinnedMesh simple con un modificador de piel correctamente aplicado:

  • max 4 huesos por vértice
  • todos los pesos = 1.0000

Vea si puede reproducir el error.

¿Estas loco? :)
Este error no puede estar de mi lado ... los modelos (fbx, gltf, dae, lo que sea) y el código fuente provienen de ThreeJS.

Por favor lea las publicaciones de @ Mugen87 .

Utilice un SkinnedMesh simple con un modificador de piel correctamente aplicado:

  • max 4 huesos por vértice
  • todos los pesos = 1.0000

Vea si puede reproducir el error.

Tengo que irme ahora.
salud

Hmmm. ¿Saben qué chicos? Esto también está sucediendo en el escritorio :(

Como la malla de ejemplo de ThreeJS es enorme (100 m de altura), la coloqué muy, muy lejos: z = 10000000
Y mira, mismo problema:
http://cornflex.org/webgl/skinning-bug4.html

Definitivamente es algo relacionado con las posiciones de los huesos del espacio mundial y los cálculos de bonesMatrix, como lo expone @ Mugen87 :

https://www.opengl.org/discussion_boards/archive/index.php/t-159613.html
https://www.opengl.org/discussion_boards/archive/index.php/t-159364.html

Como se explicó antes a @mrdoob , ya intenté reducir la escala de la malla, pero el problema es aún peor ... incluso en el escritorio y el error no está tan lejos de 0,0,0 entonces.

En mi propio juego (con escalas realistas 1: 1), el error ya aparece en z: 100.

Sigues usando mallas peladas mal diseñadas ...
De todos modos, para cerrar este tema, aquí está el estudio de caso de 1 a 1,000,000 (¡¡¡un millón !!!):
http://necromanthus.com/Test/html5/Lara_1000000.html
Haga clic en el escenario para cambiar entre Y = 0 e Y = 1000000
Un cambio de iluminación global menor está disponible por interruptor.
Entonces, si la malla sin piel está diseñada correctamente, el resultado es (casi) perfecto.
salud

Lo investigaremos después del lanzamiento de este mes.

@mrdoob Gracias.

@RemusMar Sigues ignorando lo que se dijo aquí. Por favor, vuelva a leer el hilo completo :)

Te acabo de dar un ejemplo práctico, pero todavía no lo entiendes.
http://necromanthus.com/Test/html5/Lara_1000000.html

Y sigues hablando de malas prácticas .
Tenga en cuenta lo siguiente:
El número de dígitos de punto flotante de precisión simple es 7.
Eso cubre 1234,567 y 123456.7
La mayoría de los mapas de peso vienen con 4 decimales, pero incluso uno solo proporciona resultados decentes.
Por esta razón, todos los motores 3D recomendaron un valor máximo de 10,000 para el tamaño mundial.
De 0000.001 a 9999.999
Todos queremos mundos 3D "infinitos" o enormes, pero eso no es posible.
Lo que estás haciendo está completamente mal desde muchos puntos de vista:
diseño de juegos, performances, animaciones y colisiones.
Espero que tengas la imagen principal ahora.

@RemusMar
Entendí bastante bien lo que dijiste, pero desafortunadamente tu modelo tiene el mismo problema ... en menor grado pero sigue ahí:
http://cornflex.org/webgl/skin-bug2.mp4

Fuente:
http://cornflex.org/webgl/skinning-bug5.html

Y si doy una posición superior a z = 60000, empeora ... y hasta 100000 es completamente invisible.

Todos queremos mundos 3D "infinitos" o enormes, pero eso no es posible.

LOL, no quiero un mundo enorme infinito ... solo quiero hacer un juego de corredor, como lo hice muchas veces antes con ThreeJS ... pero esta vez necesito un skinnedmesh como avatar.

Mi escena: http://cornflex.org/webgl/skin-bug.mp4

Si no podemos animar un avatar que corra varios metros ... ¿entonces cuál es el punto? (en escala realista 1m = 1 unidad threejs, el error ya aparece desde 100).

Por cierto, tu modelo mide 150 m de altura ... esta no es una escala realista.
EDITAR:
Aquí la misma escena con escala (0.01, 0.01, 0.01) en su modelo, para obtener un tamaño realista (alrededor de 1.5 m entonces). Como puede ver, ya está funcionando en z = 300 en dispositivos móviles:
http://cornflex.org/webgl/skin-bug3.mp4

Lo que estás haciendo está completamente mal desde muchos puntos de vista:
diseño de juegos, performances, animaciones y colisiones.

LOL LOL ... Sugiero visitar mis sitios web y blog sobre la creación de juegos (http://quentinlengele.com, http://cornflex.org, http://www.ddrsa.com, http://br9732.com )

EDITAR: su escena no es visible en iOS, pantalla vacía (http://necromanthus.com/Test/html5/Lara_1000000.html).
img_1418

El desollado parece realizarse en el espacio mundial o en el espacio local, pero se estira cuando se mueve lejos del centro. Por eso está funcionando bastante bien en 0,0,0.

Veamos:

vec3 transformed = vec3( position );
...
#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += boneMatX * skinVertex * skinWeight.x;
    skinned += boneMatY * skinVertex * skinWeight.y;
    skinned += boneMatZ * skinVertex * skinWeight.z;
    skinned += boneMatW * skinVertex * skinWeight.w;
    transformed = ( bindMatrixInverse * skinned ).xyz;
#endif

¿No me parece un espacio mundial? en una malla regular, transformed se establece en el atributo position , es decir, coordenadas locales.

entonces, pase lo que pase, sucede en el lado js, ​​donde se calculan las matrices de unión y hueso. tal vez la matriz de unión se estira mucho, y las matrices de huesos podrían manipularse para operar en otras coordenadas que no requieren tanto estiramiento en la matriz de unión ... o algo así

(editar: nvm, creo que me equivoqué)

me

@makc Desafortunadamente, no veo suficientes datos relevantes en su copia / pegado del sombreador de piel para saber si el cálculo se realiza en las coordenadas espaciales locales o mundiales.

Como dije, seguramente hay algo mal con el cálculo de las matrices de huesos o tal vez el orden del cálculo de estas matrices no sea correcto. Como puede ver en el foro OpenGL y como mencionó @ Mugen87 , esta es la pista más relevante, al menos para mí:

La fluctuación es natural para los flotantes, las variables perderán precisión cuanto mayor sea el número, por lo que la precisión es mejor cuanto más cerca de 1.0 esté. Ahora bien, esto no es realmente un problema, pero significa que si está haciendo muchos cálculos matriciales con números grandes, tendrá mucha degradación de precisión (también conocida como jittering). Por lo tanto, debe hacer todas sus matemáticas en torno al origen con números razonables y luego traducirlo

Nuevamente, como se explicó, la escala del objeto está afectando al error.
El ejemplo con las fuentes ThreeJS presenta ese error solo en z = 100000, pero se debe a que el tamaño de la malla (que también proviene de la fuente ThreeJS) es enorme. El chico que corre mide 150 m de altura.

Cuando estás haciendo un juego, no usas ese tipo de escala, por supuesto. Siempre intentas mantener tu mundo con 1 m = 1 unidad. Esto es incluso obligatorio para obtener una buena física y comportamiento.

El problema aquí es cuando usa un SkinnedMesh con un tamaño realista: el error ya aparece en z = 300.

En cualquier motor, puede colocar un SkinnedMesh al ponerlo en x: 30000, y: 60000, z: 140000000 y no hay ningún problema con los huesos y el desollado. Sin nerviosismo.

Seguramente entiendo bastante bien que estamos trabajando en un núcleo de Javascript aquí ... pero aún así.

Los trolls que pretenden que "todos queremos mundos infinitos pero es imposible" necesitan volver a la escuela y aprender las transformaciones matriciales. O mejor mirar los juegos de mundo abierto y preguntarse cómo su avatar puede ser "desollado" tan lejos de la raíz de la escena 0,0,0 ...

Debo decir que este error es divertido. Aquí, pude reproducirlo en el escritorio, pero 60K no fueron suficientes para quedarse sin precisión:
needs more zeroes

ok, entonces en z = 1e8, esto es lo que tenemos con el sombreador actual:

screen shot 2018-02-14 at 1 15 56

y esto es lo que tenemos si cambiamos el sombreador a esto (una ligera variación de mi prueba de arriba de mi cabeza anterior que edité):

#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += ( bindMatrixInverse * boneMatX ) * skinVertex * skinWeight.x;
    skinned += ( bindMatrixInverse * boneMatY ) * skinVertex * skinWeight.y;
    skinned += ( bindMatrixInverse * boneMatZ ) * skinVertex * skinWeight.z;
    skinned += ( bindMatrixInverse * boneMatW ) * skinVertex * skinWeight.w;
    transformed = skinned.xyz;
#endif

screen shot 2018-02-14 at 1 16 54

todavía inestable, pero se ve mucho mejor :) ahora, ¿qué significa esto en el contexto de este problema?

Primero, no puedes simplemente copiar y pegar este truco en el sombreador. Quiero decir, puede, pero reemplaza 1 multiplicación de matriz con 4. lo que propongo en su lugar es a) fusionar la matriz ósea con la inversa de la matriz de unión en el lado js y pasar como un solo uniforme, ob) crear otro uniforme solo para esto pedazo de sombreador. Entonces resolvería este problema (algo) y disminuiría el número de multiplicaciones de matrices en el sombreador (en 1).

Oh y

Trolls aquí pretendiendo "todos queremos mundos infinitos pero es imposible"

Creo que lo que estaban tratando de decir es que podrías solucionar el problema sin arreglar la biblioteca de tu lado. No es necesario que debería, pero podría.

@makc Muchas gracias por su tiempo en esto.
Desafortunadamente, es demasiado tarde. Tengo que entregar el viernes. Usé secuencias PNG como solución.

Si desea depurar esto lo suficientemente profundo. ¿Podría intentar utilizar un tamaño de malla realista?
Una vez más, este modelo de Lara también tiene algo así como 60 m de altura si mal no recuerdo.

Tengo bastante curiosidad por ver si su parche también funciona a una escala realista, por supuesto :)

Ah, y ... ¿estás haciendo tu prueba en iOS?
Como se explica en este hilo, esto ocurre principalmente en dispositivos iOS (6, 8).
En el escritorio, solo los valores muy grandes traen el problema.

Gracias de nuevo

@OrtOfOn puede probar el parche @makc agregando esto en la parte superior de su código:

THREE.ShaderChunk.skinning_vertex = `
#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += ( bindMatrixInverse * boneMatX ) * skinVertex * skinWeight.x;
    skinned += ( bindMatrixInverse * boneMatY ) * skinVertex * skinWeight.y;
    skinned += ( bindMatrixInverse * boneMatZ ) * skinVertex * skinWeight.z;
    skinned += ( bindMatrixInverse * boneMatW ) * skinVertex * skinWeight.w;
    transformed = skinned.xyz;
#endif
`;

TRES.WebGLShader: Shader no pudo compilar. : /

patch

Oh hombre. terminó con comillas incorrectas y formato de una línea. ¿Cómo se copia y pega así?

Además, lo hice para ver estas imágenes locas, que satisfacen mi curiosidad. Confío en que alguien más lo tomará de aquí :)

@makc CTRL + C / CTRL + V ... solo desde aquí ...: /

Desafortunadamente, el error es menos fuerte que antes, pero sigue ahí :(

Probado en iOS (parche aplicado):

Malla a escala 1.0 (avatar de unos 20 m de altura exactamente), posición z = 10000
http://cornflex.org/webgl/skin-patch1.mp4

Malla a escala 0.1 (avatar alrededor de 2 m de altura), posición z = 3000
http://cornflex.org/webgl/skin-patch2.mp4

@mrdoob Intentaré reproducir :) Apareció en una sola línea. Estaba escribiendo en la página cuando vi aparecer tu respuesta y no parecía que apareciera normalmente, lo prometo: p ... obtendré estos puntos de bonificación, verás :)

EDITAR: ¿Por cierto, editaste tu publicación? :)

Creo que el efecto residual puede no estar relacionado con el desollado y afectar realmente a todo, pero no se nota porque no hay animación.

@OrtOfOn en tu lugar, trataría de envolver toda tu escena (con una cámara) en Object3D adicional y establecer las coordenadas de este objeto en -1 * las coordenadas de avatar en cada fotograma. Esto lo mantendría en las coordenadas mundiales 0,0,0 para siempre.

@markc Realmente no me gusta hacer trampa de esta manera. El juego y la escena no están diseñados para ser torturados de esa manera y, como primer juego móvil, los perfs deben ser óptimos, por supuesto.

Además ... no es mi caso, pero imagina esto con varios enemigos en SkinnedMesh, viniendo de todas partes ...

No tuve otra opción porque la fecha límite y reemplacé SkinnedMesh con animaciones de hojas de sprites (el cliente está bien). De lo contrario, no lo hice excepto para encontrarme con algo como esto. Utilizo ThreeJS en casi todos los proyectos web y estoy muy, muy contento con él.

No queremos "mundos infinitos", pero queremos poder utilizar estas bonitas funciones de SkinnedMesh y animaciones en las coordenadas del espacio mundial, como hacemos en los motores famosos :)

Estoy un poco decepcionado de alguna manera ... porque hice un guión de Animator muy bueno basado en características de crossfade e inspirado en mecanim ... Para el próximo proyecto seguramente: /

@markc Realmente no me gusta hacer trampa de esta manera.

No creo que sea trampa en absoluto. Así funcionan todas las simulaciones espaciales. De hecho, el renderizado 3D en tiempo real básicamente está desviando toda la escena, por lo que el centro es donde está la cámara.

@mrdoob sí, sé que ni siquiera existe una cámara. El poder de las matrices :) (Yo mismo hago algunos desarrolladores nativos de WebGL / OpenGL).

De todos modos, poner toda la escena en un objeto de juego me parece un poco bárbaro ... especialmente para que funcione una animación con máscara.

@OrtOfOn en realidad puedes usar la escena en sí. Por ejemplo, en el ejemplo de Lara, haz esto:

scene.add(camera);
scene.position.z = -60000;

y está bien (editar: sin embargo, hay algo mal con la luz cuando haces esto .... @mrdoob ?)

@makc Gracias de nuevo por proponer parches.

No quiero ser pesimista en absoluto, pero algo me dice que la iluminación no será el único problema al hacer este tipo de manipulaciones. Es por eso que llamo a estos trucos y trampas debido a la incertidumbre del resultado y las consecuencias para otras partes del proceso.

Desafortunadamente, las personas que crean juegos tienen física, lanzadores de rayos, partículas, ... muchas cosas que están diseñadas y deben diseñarse para estar en el espacio mundial con escalas realistas.

Además, tengo mucha curiosidad por ver estos parches en acción con más de un SkinnedMesh, como enemigos que se esconden o aparecen en algunos lugares de la escena. Porque, ¿cuál es el punto de estar restringido a un solo avatar de malla de piel en 0,0,0 entonces?

Profundizaré en la fuente tan pronto como pueda, pero tengo que entregar algo en 2 días ... así que las animaciones de mi hoja de sprites están bastante bien por ahora con suerte.

Porque, ¿cuál es el punto de estar restringido a un solo avatar de malla de piel en 0,0,0 entonces?

El punto es que es muy poco probable que renderice simultáneamente la máscara en 0,0,0 y otra máscara en z = 60000. Solo unas pocas máscaras alrededor de 0,0,0 llegarán a la pantalla, y no estarán lo suficientemente lejos para desencadenar el error.

@makc Nuevamente, su parche es válido en el escritorio, pero no está probando el caso en dispositivos iOS, donde el error ya está apareciendo a varios metros de 0,0,0 con mallas escaladas realistas. Hice suficientes videos para mostrarlo. Este, por ejemplo, presenta el error solo en z = 100: /
http://cornflex.org/webgl/skin-bug.mp4

¿Siempre usas avatar de 20 metros de altura en tus juegos? :)
Debido a que el número en el que se centró (60000) solo se usa para exponer el error en el escritorio (con esa enorme lara o una enorme muestra de threejs fbx) ... no en el móvil. Y mi avatar no llega tan lejos, por supuesto ...

Confirmaría que esto es un problema de iOS. Desde al menos la generación 6S / 6S +, iOS ha tenido un problema con floatVertexTextures. La solución que hemos estado usando es deshabilitar esa función en iOS. Esto limita los huesos que podemos usar, pero tenemos que limitarlos de todos modos para admitir teléfonos más cutres.

Como los dispositivos iOS fallan en la prueba de conformidad publicada por @ Mugen87 , probablemente sería una buena idea deshabilitar floatVertexTextures, o probablemente incluso floatFragmentTextures, en iOS de forma predeterminada, ya que claramente no implementa correctamente una función que anuncia.

@ daniel-nth supongo que tiene sentido. Sin embargo ... @OrtOfOn decía que z = 60K reproduce el problema en el escritorio ... No tengo ningún problema con 60K en el escritorio, solo 1e8 fue suficiente para "reproducir". Entonces, tal vez este problema sea realmente al menos 3 problemas separados:

  • texturas flotantes en ios,
  • algo a 60K en el escritorio de @OrtOfOn ,
  • quedando sin precisión en 1e8 debido a un mal orden de multiplicación de matrices en el bit del sombreador de huesos (el que me metí arriba),
  • tal vez algo más en el sombreador de vértices, ya que la chica todavía estaba un poco temblorosa después del parche.

Hola chicos,
Primero, gracias por volver a este error. Todavía no encontré tiempo para profundizar :(

@ daniel-nth La escala del objeto está afectando al error:

En iOS, con este enorme objeto "Lara" (altura = 120, escala = 1), el error aparece en z = 60000 de hecho. Pero, si toma una malla de tamaño realista (altura = 1.8, escala = 1), ya aparece solo en z = 100.

Cuanto más grande sea la malla, además la traducción debe ser para ver el error.

Como ya se probó y se informó en este hilo, deshabilitar floatTexture en los resultados de iOS sin ningún tipo de piel.

También sospecho una mala multiplicación de matrices o un orden de barras de multiplicación de la matriz de huesos.

En iOS, con este enorme objeto "Lara" (altura = 120, escala = 1), el error aparece en z = 60000

@OrtOfOn espera, ¿entonces en iOS? pero también dijiste:

el número en el que se centró (60000) solo se usa para exponer el error en el escritorio (con esa enorme lara o una enorme muestra de threejs fbx) ... no en el móvil.

En iOS, con este enorme objeto "Lara" (altura = 120, escala = 1), el error aparece en z = 60000 de hecho.

No es enorme en absoluto.
Y todavía no comprendes la relación entre el tamaño del modelo y la escala mundial.
Por última vez:
http://necromanthus.com/Test/html5/Lara_1000000.html
Altura del modelo aprox. = 75 y escala mundial = 9,999,999.
De Z = 0 a Z = 1,000,000 (¡¡¡un millón !!!)
Debido a que el número de dígitos de punto flotante de precisión simple es 7, ¡no quedan decimales!
Funciona perfectamente en todas las computadoras portátiles y de escritorio que tengo.
Aún más:
funciona perfectamente en Android 6 y 7 y en varios teléfonos móviles Samsung.

lara_1000000

@RemusMar en su ejemplo, ingrese esto en la consola:

camera.position.z += 1e8;
scene.children[2].position.z += 1e8;

verás algo como esto:
screen shot 2018-03-03 at 15 48 53

screen shot 2018-03-03 at 15 51 41
es trippy

Te daré que z = 1e6 tampoco se ve mal. alrededor de 1e7 ya se nota, y 1e8 es una locura

@OrtOfOn Configurando las capacidades.floatVertexTextures en falso funciona para nosotros en iOS. Sospecho que su modelo usa muchos huesos para encajar en los uniformes.

Te daré que z = 1e6 tampoco se ve mal. alrededor de 1e7 ya se nota, y 1e8 es una locura

Lo sé, pero para esos valores estás fuera de precisión.
Para la precisión del peso del vértice de la malla sin piel, el tamaño máximo mundial es 9.999.999
Eso se traduce en distancias máximas de unos pocos millones, no más.
salud

@makc De hecho, obtuve los números incorrectos para el escritorio. Tiene que ser muy grande, tienes razón y de hecho mencioné en el hilo anteriormente: / https://github.com/mrdoob/three.js/issues/13288#issuecomment -364650679

@ daniel-nth Es bueno saberlo, pero ¿estás seguro? Aquí está la prueba que hice aquí en este hilo, con el modelo 3d de las fuentes de threejs. Todavía puedes echar un vistazo al código. @ Mugen87 también hizo los mismos comentarios, sin animación con este modelo. https://github.com/mrdoob/three.js/issues/13288#issuecomment -364572653

Oh, veo que el modelo ya no está presente. 404 en https://threejs.org/examples/models/fbx/xsi_man_skinning.fbx

@ daniel-nth Si estás usando un nuevo modelo con menos huesos, entonces te creo;)

@RemusMar Muy de acuerdo contigo sobre las distancias evocadas en las últimas publicaciones. Los números (1e6, 1e8, 1e9, ...) ciertamente resultarán con mala precisión. No hay duda de eso. Pero por favor deja de trollearme. Deja de fingir que no entiendo nada y pregúntate si una malla de avatar con una altura de 120 no es enorme. Para mí, es muy grande y poco utilizable en un desarrollo de juegos con otros objetos realistas a escala hechos por artistas, raycasts, física, iluminación ... y se entregará en 3 semanas.

Insisto: mantener los activos a una escala realista con unidades métricas es algo obligatorio para construir un juego basado en la física correctamente :)

Lástima que, en iOS, no pueda ejecutar mi avatar a más de 100 m en estas condiciones de escala realistas: /

ACTUALIZACIÓN: De todos modos, @ daniel-nth parece decirnos que ahora está funcionando con floatTexture desactivado y un recuento de huesos muy limitado.

Pero por favor deja de trolearme
Insisto: mantener los activos a una escala realista con unidades métricas es algo obligatorio para construir un juego basado en la física correctamente :)

No te estoy trolleando.
Pero 1,5 unidades no significa 1,5 metros
salud

@OrtOfOn

Insisto: mantener los activos a una escala realista con unidades métricas es algo obligatorio para construir un juego basado en la física correctamente :)

pero esta escala es un valor arbitrario autoimpuesto. también podría decidir usar centímetros, y luego "una malla de avatar con una altura de 120" es en realidad más pequeña que la media.

@makc Seguro, pero el motor de física / libs esperan que uses valores métricos. ¿Ya intentó hacer algo de física en objetos escalados o con valores no métricos? Rápidamente se vuelve horrible de desarrollar y obtiene resultados inesperados y poco realistas. Todas sus fuerzas deben ser revisadas y escaladas también. Funcionará, pero no con precisión.

Por supuesto, depende del nivel de precisión que necesite alcanzar y valores como 1e6, 1e7, ... son demasiado grandes y presentarán problemas de precisión. Y nunca necesitará mover una malla desollada tan lejos. Estuvimos de acuerdo en eso. Pero, en iOS, deberíamos poder mover una malla de piel gpu (1,5 unidades de altura) en un rango de varios cientos de unidades, al menos.

pero el motor de física / libs esperan que uses valores métricos.

Eso no es cierto.
Los metros, centímetros, pulgadas, etc. son irrelevantes.
Como dije (varias veces) antes, todo lo que importa es el tamaño del mundo (escala) y la precisión.
Tenga en cuenta lo siguiente:
si tiene una malla sin piel con una altura = 1,5 unidades, el mapa de pesos de vértice le obliga a utilizar 2-3 decimales como mínimo.
Para el motor de física (si lo hay), es posible que necesite 3-4 decimales para obtener resultados aceptables.
Si la precisión global requiere 4 decimales, su tamaño máximo mundial es 999 (porque el número de dígitos de punto flotante de precisión simple es 7).
En otras palabras, puede usar distancias de algunos cientos si desea animaciones decentes y física decente.
Espero que tengas la imagen completa esta vez.
salud

@RemusMar Me detendré aquí. Parece que no lo hizo o no quiso probar su caso en un dispositivo iOS. No puede usar "distancia de unos pocos cientos" en estos dispositivos con mallas de piel gpu. La malla se vuelve loca muy rápidamente. Ese es el punto de este hilo y solo quería informarlo al principio. Eso es todo.

Espero que haya entendido que todas sus propuestas y muestras no funcionan en dispositivos iOS, según lo informado por otras personas aquí y por mis capturas de pantalla: /

No puede usar "distancia de unos pocos cientos" en estos dispositivos con mallas de piel gpu.

Estás equivocado de nuevo.
Vea la captura de pantalla anterior (Android 7 - teléfono móvil Samsung).
Altura del modelo = 75 (radio de la esfera delimitadora aprox. 38) y distancia 1.000.000 (¡¡¡un millón !!!)
O altura del modelo = 1,5 y distancia 20.000.

PD
No es mi problema que iOS siempre fue una colección de errores.

@RemusMar No me equivoco, troll. Estoy hablando de iOS y estás hablando de otro dispositivo ... ¿estás loco ??

No es mi problema si odias tanto a Apple. Cuando uno de mis clientes quiere un juego 3D basado en la web hecho con ThreeJS, no le digo "vete a la mierda con tus iphones" ... Si lo haces, lo siento por ti.

Fin de la transmisión aquí ... Ya no puedo seguir esto.

@OrtOfOn Sí, el modelo que usé tiene 19 huesos, el 404 fbx tiene 67.

https://github.com/mrdoob/three.js/issues/13288#issuecomment -364550036 tenía un enlace a una página que muestra el límite de hueso uniforme. La fórmula que usa la página es Math.floor((data.webgl.params.MAX_VERTEX_UNIFORM_VECTORS - 20) / 4); No estoy seguro si eso es 100% exacto para three.js, pero reporta 27 incluso en iPhone X, que desafortunadamente es menos de la mitad incluso de un Galaxy S3, pero aún es suficiente para un juego WebGL móvil. Rápidamente revisé mi carpeta de trabajo y en los 26 proyectos WebGL, solo uno tiene un modelo con más huesos, y ese modelo permanece en 0,0,0.

@OrtOfOn : Estoy teniendo problemas similares con una escena fija y moviendo un personaje sin piel por la escena. el personaje se estremece terriblemente en ios. el recuento de huesos es 22. Las dimensiones de la escena son razonables. Creo que el problema es que el uso de texturas de vértice lo limita a flotantes de 32 bits, junto con la afirmación anterior de que Threejs calcula la piel en el espacio mundial.

Estoy investigando la afirmación del espacio mundial ahora, y espero implementar la forma adecuada de calcular las posiciones verticales en el espacio local y luego traducir el objeto, como debería ser. Nunca he oído hablar de nadie que utilice el desollado para colocar el objeto en el espacio mundial, así que no estoy seguro de por qué el implementador habría hecho tal cosa.

Volveré a publicar cuando tenga una solución.

solo para tu información, las texturas flotantes en ios no solo se rompen con los sombreadores de vértices. Recientemente estuve cambiando texturas flotantes a texturas enteras para arreglar las bandas de color en ios, por lo que es un problema universal de ios. probablemente también podría usar texturas enteras para arreglar los huesos en ios, si realmente quisiera; aquí está el fragmento relevante del sombreador de otra persona:

vec2 encodeFloatRG( float v )
{
    vec2 kEncodeMul = vec2(1.0, 255.0);
    float kEncodeBit = 1.0/255.0;
    vec2 enc = kEncodeMul * v;
    enc = fract (enc);
    enc.x -= enc.y * kEncodeBit;
    return enc;
}

float decodeRGFloat( vec2 enc )
{
    vec2 kDecodeDot = vec2(1.0, 1.0/255.0);
    return dot( enc, kDecodeDot );
}

... de hecho, probablemente podría (supongo que aquí, realmente no probé algo así) hacer que las texturas de hueso flotante también funcionen, si acepta la precisión de ios como límite de precisión global y almacena dos flotantes en la textura en lugar de uno

Resolví el problema por completo al hacer que threejs realizara el cálculo de la piel en el espacio local, donde pertenece, y traduce el modelo a las coordenadas del mundo real de la manera estándar a través de la matriz del espacio mundial.

Los problemas anteriores están completamente solucionados para la creación de piel en iOS. También debo señalar que esta solución es universal: funciona perfectamente en todos los navegadores de escritorio, así como en los dispositivos Android que he probado. En mi humilde opinión, el skin del espacio local es el camino correcto a seguir en casi todos los casos, y este método debería ser el predeterminado para ThreeJS. @mrdoob : ¿cuál es su opinión sobre esto?

mesh = new THREE.SkinnedMesh(geo.geometry, mat);
mesh.bindMode = 'detached';
var skel = new THREE.Skeleton(bones, boneInvs);
var bsm = new THREE.Matrix4().fromArray(geoPrims.bsm);
mesh.bind(skel, bsm);

// make bsmInv identity for models that have multiple skins
mesh.bindMatrixInverse = new THREE.Matrix4();

// patch SkinnedMesh's updateMtxWorld:
// we're using local skinning, so don't keep resetting binMatrixInverse (leave identity)
// the reason we're using .bind here is for models that have more than one skin
mesh.updateMatrixWorld = PatchSkinnedMeshUpdateMW.bind(mesh);

// re-normalize since input data has been compressed
mesh.normalizeSkinWeights();

// remove bone roots and add to bone root list
for (var bi = 0, bl = bones.length ; bi < bl ; bi++) {
    if (bones[bi].parent && !bones[bi].parent.isBone) {
        bones[bi].parent.remove(bones[bi]);
        boneRoots.push(bones[bi]);
    }
}

Donde 'boneRoots' debe agregarse al objeto de la escena raíz (para que obtengan actualizaciones de la matriz pero no hereden todas las matrices en la jerarquía que conduce a la malla de piel real). Agregue estos boneRoots a la raíz de su escena (no se muestra el código).

Y aquí está el parche para reemplazar la implementación SkinnedMesh de threeJS (tenga en cuenta que esto solo es necesario ya que el updatematrixworld de threejs destruye el bindMatrixInverse que queremos mantener como identidad). Alternativamente, puede enlazar a THREE.Mesh..prototype.UpdateMatrixWorld directamente en lugar de usar una función de parche.

function PatchSkinnedMeshUpdateMW( force ) {
    THREE.Mesh.prototype.updateMatrixWorld.call( this, force );
}

@ denbo-ft Creo que eso me suena bien. ¿Le gustaría crear un PR para él?

@ denbo-ft Muchas gracias por sus esfuerzos. Perdón por la respuesta tardía, ya no seguía este hilo.

También tenemos este problema en nuestro producto: cualquier navegador (si se aleja lo suficiente de 0,0,0) pero es más notorio en iOS, ya que ocurre tan pronto como está a unas 2-3 unidades de distancia. Crítico para nosotros, pero al menos nos reímos mucho cuando vemos esto
image

Ok, parece que hay más personas que necesitan esto. Nunca he contribuido a un proyecto de código abierto de github, pero estoy familiarizado con git e intentaré crear un PR. :)

Igual que aquí. Mi SkinnedMesh parece un episodio del Dr. Katz, terapeuta profesional en iPhones.

FYI, mi publicación del 21 de mayo tiene la solución completa. No hay muchas correcciones para las fuentes de ThreeJS: la mayoría de las correcciones pertenecen a su cargador y / o código de configuración de escena para sus proyectos individuales.

La solución básica es usar el modo 'separado' (que no está documentado, por cierto) y colocar la jerarquía ósea en su escena en el nivel de la escena raíz, no en su lugar con la jerarquía de caracteres renderizable real. Luego, arregle una cosa simple desde el motor (SkinnedMesh.update), y debería estar listo.

Editar:
Tenemos un cargador y formato de archivo completamente personalizado para TJS, por lo que, desafortunadamente, para crear un PR completo con una solución de ejemplo, tendría que arreglar uno de los cargadores enlatados suministrados (como Collada). Buscaré hacer esto ahora

gracias, iba a dedicar algo de tiempo para tratar de entender y también aplicar su solución de una manera más genérica (la suya parecía un poco específica a su proyecto). ¿Podría compartir un poco más de contexto para su código?

Dr. Katz, terapeuta profesional

No estoy enganchado ni nada, pero maldita sea .

EDITAR:

He creado correctamente una solicitud de extracción; avíseme si hay algo adicional que pueda hacer.

Publicación original:

Tengo una sucursal local con los cambios, pero parece que no puedo empujar al origen. Incluso proporcionando mis credenciales de github, obtengo este error:

Empujando a https://github.com/mrdoob/three.js.git
remoto: Permiso para mrdoob / three.js.git denegado a denbo-ft.
fatal: no se puede acceder a ' https://github.com/mrdoob/three.js.git/ ': la URL solicitada devolvió el error: 403

Me encantaría recibir algunos consejos ya que esta es mi primera contribución a github. ¡Gracias!

Para su información, si el PR funciona para mrdoob y está integrado, hay un nuevo modo de enlace "local" que admite este cambio. No quería parchear o cambiar el modo de vinculación "separado" indocumentado ya que no hay ninguna indicación de quién o qué lo está usando y no quería romper algo de lo que no estaba al tanto. Pero me parece que pudo haber sido diseñado para este propósito.

Todo lo que binMode = "local" hace es no cambiar el bindMatrixInverse durante la actualización, a diferencia de "detached", que lo restablece a la inversa de bindMatrix, en lugar de dejarlo en la identidad.

Vea el ejemplo de webgl_loader_collada_skinning.html en este PR para ver los pocos cambios necesarios en el nivel de la escena con el fin de obtener la piel local adecuada en los personajes que se mueven por la escena.

La demostración del cargador DAE de stormtrooper se utilizó para probar esta solución. El personaje se alejó 2000 unidades del origen para estas pruebas. Capturas de pantalla a continuación.

Las fotos a continuación son de iPhone X / Safari 11

Antes de este cambio (en 2000,2000,2000):
img_0658

Después de este cambio:
img_0659

¿Crees que hay una manera de lograr esto sin tener los huesos en el nivel de la escena raíz y (0,0,0)? Estoy usando los huesos para unir cosas al avatar, hacer que mire puntos, etc., etc. Y supongo que no soy el único

Tienes dos opciones:

1) Mantenga los huesos en el espacio mundial en la raíz para beneficiarse del desollado local como se implementa en threejs. Luego, haz transformaciones adicionales si es absolutamente necesario adjuntar un arma a un hueso, por ejemplo, para colocarlo en el espacio de avatar.

2) Deja a Bones en el espacio de avatar como está y comienza a deformar en iOS.

Definitivamente haría el # 1. Siempre puedes hacer los cálculos para averiguar dónde debería estar el objeto adjunto en cualquier marco dado cuando ya tienes la posición del hueso y la posición del personaje. Pero, no hay una solución para el n. ° 2 porque la deformación se debe al empaquetado en el nivel HAL de los dispositivos iOS y no hay nada que pueda hacer al respecto. Claro, puede agregar trucos adicionales tratando de usar los diversos paquetes de HalfWord, etc., pero todos reducen el problema, no lo hacen desaparecer. El problema del desollado en ios desaparecerá por completo si lo hace en el espacio local (más específicamente, mantenga los huesos centrados en el origen del mundo para mantener los números lo más pequeños posible). Luego xform en espacio de caracteres para archivos adjuntos.

Más información:

El problema con la forma en que se implementa en TJS no es TJS específicamente, pero para resolver el problema del límite óseo debido al número limitado de uniformes por programa de sombreado, se están utilizando BoneTexture. Esta es una solución bastante estándar. Sin embargo, en iOS, los flotantes en texturas se cuantifican (empaquetan / comprimen) en algo más pequeño que 32 bits. Esto provoca la "mantis religiosa" u otros efectos extravagantes de los personajes cuando el tamaño / magnitud del número es "grande", es decir, más de unos pocos cientos.

Ok genial, ¿qué hacemos ahora? Bueno, cada gran característica de su juego (el motor del juego en realidad), generalmente requiere un estándar de práctica. Ejemplo: diga a los artistas que centren el personaje sobre el origen. Coloque el nodo raíz del personaje en los pies / suelo, cree los huesos y la piel de una manera particular. Luego escriba un exportador (o importador en el caso de TJS) y un importador que conozcan las reglas de su proceso. Luego, respalde la función final en el motor al cargar los activos que tienen esta configuración. Así es como hacemos las cosas en la industria de los videojuegos.

Es incontrolable e indeterminista (ambas cosas terribles para el desarrollo de juegos) esperar que CUALQUIER método de creación, CUALQUIER formato de archivo y CUALQUIER cargador genérico maneje todas las características de tu juego a la perfección. Debe haber algunos estándares y procesos en el camino.

Si tu personaje usa desollado y también necesita adjuntar geo para armas o lo que sea, piensa en lo que se requiere para que el motor se desolle y luego trabaja con eso. He ofrecido una solución de este tipo como ejemplo. Desafortunadamente, el PR no fue aceptado porque por alguna razón no quieren cambiar los cargadores. De todos modos, espero haber explicado el problema y la solución en el hilo anterior, así como el PR que envié.

Realmente no puedo contribuir a esto mucho más de lo que ya lo he hecho. Espero haber ayudado a algunas personas ...

¡Buena suerte!

El problema del desollado en iOS desaparecerá por completo si lo hace en el espacio local.

Como dije desde el principio, esa es una solución para una limitación (error) de iOS y tiene que desperdiciar poder de procesamiento para eso.
¡Esa no es una solución!
La solución real es aumentar la precisión del punto flotante en iOS (al valor normal de 7 dígitos).
http://davenewson.com/posts/2013/unity-coordinates-and-scales.html

@ denbo-ft Realmente implementé su PR (tenemos nuestro propio cargador) así que gracias por su contribución, fue apreciado. Esperaba otro enfoque ya que tenemos múltiples avatares en nuestras escenas, se mueven, agarran elementos, interactúan entre sí, etc. y tener el esqueleto en 0,0,0 nos obligaría a cambiar muchas cosas en nuestro código, riesgo de tener nuevos problemas, etc.

Pasé un tiempo pensando en el problema, pero no encontré una mejor solución. (Aún intentando)

@RemusMar

La verdadera solución es aumentar la precisión del punto flotante en iOS.

tal vez alguien debería preguntar primero a @grorg y compañía cuál es el problema con las texturas flotantes allí, y cómo es que es así porque tengo la sensación de que no es solo un error, sino la "solución" de Apple a algún otro problema

Tengo la sensación de que no es solo un error, sino la "solución" de Apple a algún otro problema.

Probablemente cierto.
Similar con el problema en Firefox Android: error informado, verificado por los desarrolladores, pero no solucionado en los últimos 5 meses (2 versiones).

Así es como funciona el desarrollo de software en estos días:
en lugar de arreglos en el lugar correcto, existen soluciones alternativas en terceros.
Resultado final: colecciones de errores, recursos desperdiciados y bloatware !!!

@jfcampos
Recomendaría mantener la jerarquía de huesos en la raíz y simplemente agregar una función para tomar la posición final de WS de cualquier hueso multiplicándola por martixWorld de la matriz de ubicación real del avatar. Es súper simple y le devolverá lo que tenía antes de la reparación.

Alternativamente, si tiene las chuletas, puede volver al método original (con el error), incluir las matrices locales en la textura del hueso, duplicando su uso de textura, luego modificar los fragmentos del sombreador para hacer el cálculo adicional en la gpu durante el desollado . Tenga en cuenta que esta solución, aunque "más limpia" desde la perspectiva del código, duplica (posiblemente cuadruplica) la cantidad de textura que se carga en la gpu en cada fotograma y, por lo tanto, es mucho menos eficiente que la sugerencia anterior. Pero por las razones que pueda tener y que no conozco, puede ser más beneficioso para usted hacerlo de la última manera.

De lo que antes no era una solución, ahora hay varias opciones aquí para ser compatibles con TODOS los dispositivos, lo cual es un requisito obvio para la mayoría de los proyectos.

Parece que tendré que ir con huesos en 0,0,0 y hacer algunos cálculos matriciales adicionales para las otras cosas. ¡Gracias!

@ denbo-ft es correcto. Este es un problema de three.js causado por el despellejamiento en el espacio mundial.

Como referencia, aquí es donde se realizó el cambio a world-space-skinning: https://github.com/mrdoob/three.js/pull/4812.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Horray picture Horray  ·  3Comentarios

Bandit picture Bandit  ·  3Comentarios

ghost picture ghost  ·  3Comentarios

fuzihaofzh picture fuzihaofzh  ·  3Comentarios

zsitro picture zsitro  ·  3Comentarios