Three.js: Bug SkinnedMesh quando longe da raiz da cena (0,0,0)

Criado em 9 fev. 2018  ·  113Comentários  ·  Fonte: mrdoob/three.js

Acho que encontrei um bug em seu SkinnedMesh (testado no iPhone 6 e 8).

Se isso já foi relatado, sinto muito, não encontrei na lista de problemas :(

Parece que o gpu skinning não está funcionando corretamente e está ficando louco no celular.
Quando um SkinnedMesh está se movendo ou movido em posições de alto valor (ex: x: 0, y: 0, z: 1000), o esfolar não é mais preciso e começa a dança da aranha.

A escala da malha está afetando o bug.

Parece que os valores dos ossos do esqueleto não são calculados corretamente em cada quadro e bonesTexture / bonesMatrix no sombreador de esfola está empurrando os vértices no lugar errado.
Este é apenas meu sentimento, é claro.

Fiz muitos testes antes de postar isso ... procurando uma pista em minhas exportações animadas, mas descobri que o bug está acontecendo com qualquer tipo de formato (GLTF, FBX, Collada, JSON, ...) e modelos do repositório ThreeJS.

Isso é muito irritante porque significa que não podemos desenvolver um jogo de corredor simples com um avatar em execução (avatar.position.z aumentando então) sem ter este problema: ((
Ainda não sei como vou fazer isso, já que morphTargets não é uma opção :(

Espero que vocês possam ajudar aqui.

Fiz exemplos claros com fonte limpa para expor o problema. É muito fácil verificar isso em um smartphone:

Aparecendo apenas no celular (z = 10000):
http://cornflex.org/webgl/skinning-bug.html

Com floatVertexTextures definido como falso (z = 10000):
http://cornflex.org/webgl/skinning-bug2.html

Piorando com a distância (z aumentando):
http://cornflex.org/webgl/skinning-bug3.html

Muito, muito longe do centro (z = 70000000)> bug também aparecendo na área de trabalho, mas certamente devido ao problema de precisão de flutuação:
http://cornflex.org/webgl/skinning-bug4.html

Pré-visualização do vídeo no meu ambiente de jogo:
Este é um mundo em escala realista (1,0 m = 1,0 unidade de três).
O bug está aparecendo somente após 50-60m da raiz da cena e piorando com a distância:
http://cornflex.org/webgl/skin-bug.mp4

MUITO IMPORTANTE
A malha usada no repositório ThreeJS é muito grande. Tem cerca de 20 metros de altura.
É por isso que o valor z deve ser maior para ver o bug.
Se esta malha for reduzida em tamanho realista, o bug começa a aparecer mesmo a 100 m.

Versão Three.js
  • [x] Dev
  • [x] r89
  • [x] ...
Navegador
  • [ ] Todos eles
  • [ ] Cromada
  • [ ] Raposa de fogo
  • [] Internet Explorer
  • [x] Safari
SO
  • [ ] Todos eles
  • [ ] Janelas
  • [ ] Mac OS
  • [] Linux
  • [] Android
  • [x] iOS
Requisitos de hardware (placa gráfica, dispositivo VR, ...)

iPhone 6, 8

Bug

Comentários muito úteis

Gostaria de destacar esta seção do usuário zeoverlord :

O jittering é natural para floats, as variáveis ​​perderão a precisão quanto maior for o número, então a precisão é a melhor quanto mais próximo de 1.0 estiver. Agora, isso não é realmente um problema, mas significa que se você estiver fazendo muitos cálculos de matriz com números enormes, você terá muita degradação de precisão (também conhecido como jittering). Então você precisa fazer todas as suas contas em torno da origem com números razoáveis ​​e então traduzir

Todos 113 comentários

Hum, sua demonstração parece boa no meu Pixel.

Problemas confirmados no meu iPhone SE -

img_6324

Problemas de precisão WebGL no iOS, talvez

Mas os dispositivos iOS na verdade usam o caminho de código baseado em textura flutuante da implementação de skin, certo? Você pode verificar isso com o seguinte teste de conformidade?

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

O iPhone SE apresenta cinco falhas nessa página. 😕

Fiz um pequeno screencast para mostrar a vocês no meu projeto:
http://cornflex.org/webgl/skin-bug.mp4

Se o avatar for muito longe de 0,0,0, a pele começa a ficar realmente cheia de erros, como você pode ver.
Fiz um perfil profundo do esqueleto e dos ossos. Tudo parece bem, exceto que a geometria está "puxada para trás" de alguma forma ... Eu pensei sobre a raiz de animação ruim, mas, novamente, tudo parece bem no Threejs com isso ...

O problema está claramente vinculado ao esqueleto e à textura bonesTexture do sombreador Skinning.
Eu também pensei sobre a precisão, mas como Mugen disse, o dispositivo iOS deve suportar isso com facilidade.

... por que só no iphone então: /

Estou muito preso ... Estou reorientando para sequências de png como plano de backup ... :(

Isso é provavelmente devido ao iphone 6 não suportar ossos suficientes.

Eu tive o mesmo problema.

Verifique seu limite ósseo aqui: https://virtulo.us/2/vr/test

Acho que não.
Se a malha skinned permanece em 0,0,0, não há problema algum: /
Estou até pensando em mover todos os recursos em vez do avatar ... (esta é minha solução alternativa # 2), mas certamente preferiria que o esqueleto funcionasse tão bem quanto a área de trabalho, é claro.

Um amigo acabou de relatar o mesmo bug no iPhone 8

Depois de olhar as fontes do ThreeJS por 2 dias ... acho que há um problema quando o bonesTexture é atualizado.
Parece que esta textura não foi atualizada corretamente e então empurrou os vértices de volta para as posições originais ... mas eu posso estar errado, é claro.

img_1411

Hmmm ... aqui tenho alguns FALHADOS, olha:

img_1412

Talvez o problema esteja relacionado a essas falhas. Meu Pixel, por exemplo, passa em todos os testes.

Vamos tentar algo: Vá para WebGLCapabilities e defina o valor de floatVertexTextures para false (isso impedirá o uso da textura flutuante). Faça uma compilação e use esta versão three.js em seu aplicativo. Estou curioso para saber o que acontece 😊.

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

Já tentei floatVertexTextures = false no renderizador.
A pele para de ficar maluca, mas não há mais animação: /
Vou empurrar uma amostra.

Olha Você aqui:
http://cornflex.org/webgl/skinning-bug2.html

renderer.capabilities.floatVertexTextures = false;

=> Sem animação em execução

img_1413

Sim, mesmo no meu Pixel (Desktop funciona). Acho que estamos atingindo um limite uniforme.

Fiz uma última amostra, com o bug aparecendo progressivamente:
http://cornflex.org/webgl/skinning-bug3.html

Começa em 0,0,0 e segue em frente ... espere alguns segundos ... a pele começa a ficar louca.

É muito estranho, tudo está OK em 0,0,0. não é?

z: 1255> ainda está bem
z: 18870> pele maluca

img_1415

img_1414

Como eu disse, fiz um perfil profundo de todas as posições do esqueleto e dos ossos no lado da CPU. Todos os valores parecem estar bem. A única pista que tenho é que bonesTextures e bonesMatrixes não funcionam corretamente no iOS quando a malha está ficando longe de 0,0,0.

Eu verifiquei as posições dos ossos porque é um comportamento típico de ossos estáveis ​​do nó raiz ou coisas assim ... mas não ...

Eu verifiquei a precisão de flutuação no lado da GPU em seus shaders de pele, mas novamente ... nada parece ter um impacto.

Muito estranho ninguém moveu um SkinnedMesh dentro de uma cena e nunca relatou isso: /

Mais uma pergunta: você tem o mesmo problema com o Chrome?

Mesmo problema, sim.

img_1416

Parece um problema de precisão. Você já tentou reduzir a cena? (11195 é 11 quilômetros).

Outra opção seria mover a cena em vez do personagem. Tende a ser uma solução comum para grandes cenas.

Além disso, acho que o código de skinning está no espaço mundial. Podemos investigar isso.

Vejo que sua contagem de ossos é 67.

Meu iphone 6 (esposas) tem um limite máximo de ossos de hardware de 27.

As deformações que vejo são idênticas às que vi no telefone dela no meu jogo (e o mesmo problema que tive antes de meu animador consertar as armações das malhas). Eu ficaria surpreso se isso não fosse pelo menos parte do seu problema.

Por que fica pior com o tempo? Nenhuma idéia. Alguém mencionou algo semelhante, não tenho certeza se está relacionado: https://discourse.threejs.org/t/updated-with-fiddle-as-animations-go-faster-there-is-increasing-error-in-accuracy/ 1707/6

Outra coisa irritante que encontrei em iphones (iphone 6, pelo menos): DEVO usar precisão de shader highp, mediump e lowp não distorcer a malha da mesma forma assustadora (como meu problema ósseo no telefone), mas as texturas parecem estranho e distorcido / pixelado durante a animação.

Qual é o seu limite de osso de hardware no dispositivo que você está testando?

@mrdoob Eu já tentei diminuir, mas a esfola fica louca muito mais rápido, na verdade: /
Se você reduzir para 0,1, o bug aparecerá 10 vezes mais rápido.

A demonstração que usei aqui para explicar vem de três exemplos.
No meu jogo, a escala não é tão grande, mas o bug é o mesmo, só aparecendo mais rápido.

Na verdade, o esfola parece ser feito no espaço mundial, ou espaço local, mas ficando esticado quando movido para longe do centro. É por isso que está funcionando muito bem em 0,0,0

Mover todo o mundo em vez do avatar é a minha workaroung # 2.
Você deve admitir que é uma escolha ruim quando você desenvolveu toda a rotina de um jogo de corrida no espaço mundial já com física e tudo. E z = 11000 não é tão longe para um jogo de corrida: / ... e é apenas um homem correndo, não um navio.

Fiz muitos jogos com ThreeJS, mas é a primeira vez que uso uma skinnedmesh. Esse bug do iOS é realmente irritante.

Workaroung # 1: farei 6 sequências png como animações de spritesheet. Então, posso manter uma lógica do espaço mundial. O prazo não está longe :(

@titansoftime O problema está aparecendo no iPhone 8 da minha esposa também. Isso não está relacionado apenas ao iPhone 6.
Além disso, se você tiver um problema de ossos máximos, será problemático desde o início. Aqui, você pode ver que não há erros em 0,0,0. Então o limite dos ossos não é o problema. O cálculo do espaço mundial dos ossos e os ossosMatrix em shaders de esfola é IMO.

Quais são os ossos máximos de hardware do iPhone 8?

Eu não sei. E não tenho certeza se é dependente do dispositivo.

Mas, novamente ... IMO, não está relacionado ao valor maxbones.

O exemplo está funcionando corretamente no iphone 6,8, X ... até 5 ... somente quando o SkinnedMesh fica em 0,0,0
https://threejs.org/examples/webgl_loader_fbx.html

Se maxbones fosse um problema, também não teríamos um bom esfola a 0,0,0.

Gostaria de destacar esta seção do usuário zeoverlord :

O jittering é natural para floats, as variáveis ​​perderão a precisão quanto maior for o número, então a precisão é a melhor quanto mais próximo de 1.0 estiver. Agora, isso não é realmente um problema, mas significa que se você estiver fazendo muitos cálculos de matriz com números enormes, você terá muita degradação de precisão (também conhecido como jittering). Então você precisa fazer todas as suas contas em torno da origem com números razoáveis ​​e então traduzir

Mmmh, muito interessante @ Mugen87! Parece que você viu o vazamento.

z: 1255> ainda está bem
z: 18870> pele maluca

O erro pode estar do seu lado.
Um erro comum: o modificador de pele não foi aplicado corretamente.
Erro 1: vértices controlados por muitos ossos
Erro 2: vértices sem peso (ou com peso muito pequeno).

Quando SkinnedMesh está próximo da origem (0,0,0), você não notará esses erros.
Mas quando é movido para longe ... você vai culpar a precisão do dispositivo móvel.
Portanto, a primeira coisa a fazer é redesenhar (desta vez corretamente) o modificador de pele.

@RemusMar Você olhou o código-fonte da página?
O exemplo que expus veio direto das fontes do ThreeJS.

Muito bem mencionado na minha descrição;)

Fiz muitos testes antes de postar isso ... procurando uma pista em minhas exportações animadas, mas descobri que o bug está acontecendo com qualquer tipo de formato (GLTF, FBX, Collada, JSON, ...)

Fiz um exemplo claro com fonte limpa para expor o problema. É muito fácil verificar isso em um smartphone:

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

O exemplo que expus veio direto das fontes do ThreeJS.

E daí?

Como o erro pode estar do meu lado quando isso acontece com todos os exemplos de skinnedmesh de ThreeJS :)

Você disse:

O erro pode estar do seu lado.
Um erro comum: o modificador de pele não foi aplicado corretamente.
Erro 1: vértices controlados por muitos ossos
Erro 2: vértices sem peso (ou com peso muito pequeno).

FBX é da ThreeJS ... e você pode tentar com GLTF ou qualquer outro formato. O problema é o mesmo.

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

@ Mugen87 encontrou uma pista. Vamos torcer para que o cara que fez a malha skinned gpu consiga consertar.

Como o erro pode estar do meu lado quando isso acontece com todos os exemplos de skinnedmesh de ThreeJS

Eu disse "O erro pode estar do seu lado.".
O resultado final:
Use um SkinnedMesh simples com um modificador de pele devidamente aplicado:

  • no máximo 4 ossos por vértice
  • todos os pesos = 1,0000

Veja se você consegue reproduzir o bug.

Você está louco? :)
Este bug não pode estar do meu lado ... os modelos (fbx, gltf, dae, qualquer que seja) e o código-fonte vêm de ThreeJS.

Por favor, leia as postagens de @ Mugen87 .

Use um SkinnedMesh simples com um modificador de pele devidamente aplicado:

  • no máximo 4 ossos por vértice
  • todos os pesos = 1,0000

Veja se você consegue reproduzir o bug.

Eu tenho que ir agora.
Felicidades

Hmmm. Você sabe o que caras? Isso também está acontecendo em computadores :(

Como a malha do exemplo ThreeJS é enorme (100 m de altura), coloquei-a bem longe: z = 10000000
E veja, o mesmo problema:
http://cornflex.org/webgl/skinning-bug4.html

É definitivamente algo relacionado às posições dos ossos do espaço mundial e aos cálculos da Matriz de ossos, conforme exposto por @ 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 explicado antes para @mrdoob , eu já tentei

No meu próprio jogo (com escalas realistas 1: 1), o bug já está aparecendo em z: 100.

Você continua a usar malhas com pele mal projetada ...
Enfim, para encerrar este assunto, aqui está o estudo de caso de 1 a 1.000.000 (um milhão !!!):
http://necromanthus.com/Test/html5/Lara_1000000.html
Clique no palco para alternar entre Y = 0 e Y = 1000000
Uma pequena mudança global de iluminação está disponível por switch.
Portanto, se a malha descascada for adequadamente projetada, o resultado será (próximo de) perfeito.
Felicidades

Analisaremos isso após o lançamento deste mês.

@mrdoob Obrigado.

@RemusMar Você continua a ignorar o que foi dito aqui. Por favor, leia o tópico inteiro novamente :)

Acabei de dar um exemplo prático, mas você ainda não entendeu.
http://necromanthus.com/Test/html5/Lara_1000000.html

E você continua falando sobre más práticas .
Lembre-se do seguinte:
O número de dígitos de ponto flutuante de precisão simples é 7.
Isso cobre 1234.567 e 123456,7
A maioria dos mapas de peso vem com 4 decimais, mas mesmo um único fornece resultados decentes.
Por esta razão, todos os motores 3D recomendam um valor máximo de 10.000 para o tamanho mundial.
De 0000.001 a 9999.999
Todos nós queremos mundos 3D "infinitos" ou enormes, mas isso não é possível.
O que você está fazendo é completamente errado de muitos pontos de vista:
design de jogos, performances, animações e colisões.
Espero que você tenha a imagem principal agora.

@RemusMar
Eu entendi muito bem o que você disse, mas infelizmente seu modelo tem o mesmo problema ... em menor grau, mas ainda está lá:
http://cornflex.org/webgl/skin-bug2.mp4

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

E se eu der uma posição maior que z = 60000, está piorando ... e até 100000 fica completamente invisível.

Todos nós queremos mundos 3D "infinitos" ou enormes, mas isso não é possível.

LOL, eu não quero um mundo infinito enorme ... Eu só quero fazer um jogo de corrida, como fiz muitas vezes antes com o ThreeJS ... mas desta vez eu preciso de um skinnedmesh como avatar.

Minha cena: http://cornflex.org/webgl/skin-bug.mp4

Se não formos capazes de animar um avatar correndo por vários metros ... então qual é o ponto ?? (em escala realística 1m = 1 unidade de threejs, o bug já aparece a partir de 100).

BTW, o seu modelo tem cerca de 150m de altura ... esta não é uma escala realista.
EDITAR:
Aqui, a mesma cena com escala (0,01, 0,01, 0,01) em seu modelo, para obter um tamanho realista (cerca de 1,5m então). Como você pode ver, ele já está com defeito em z = 300 no celular:
http://cornflex.org/webgl/skin-bug3.mp4

O que você está fazendo é completamente errado de muitos pontos de vista:
design de jogos, performances, animações e colisões.

LOL LOL ... Sugiro visitar meus sites e blog sobre como fazer jogos (http://quentinlengele.com, http://cornflex.org, http://www.ddrsa.com, http://br9732.com )

EDITAR: sua cena não é visível no iOS, tela vazia (http://necromanthus.com/Test/html5/Lara_1000000.html).
img_1418

O esfola parece ser feito no espaço mundial, ou espaço local, mas ficando esticado quando movido para longe do centro. É por isso que está funcionando muito bem em 0,0,0

Vamos ver:

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

não parece espaço mundial para mim? na malha regular, transformed é definido como position attribute - isto é, coords locais.

portanto, tudo o que acontece, acontece no lado js, ​​onde as matrizes bind e bone são calculadas. talvez a matriz de ligação tenha muito alongamento e as matrizes ósseas possam ser alteradas para operar em outras coordenadas que não requeiram tanto alongamento na matriz de ligação ... ou algo assim

(editar: nvm, acho que entendi errado)

me

@makc Infelizmente, não vejo dados revalant suficientes em sua cópia / colagem do shader de skinning para dizer se o cálculo é feito em coordenadas espaciais locais ou mundiais.

Como eu disse, certamente há algo errado com o cálculo das matrizes de ossos ou talvez a ordem do cálculo dessas matrizes não esteja certa. Como você pode ver no fórum OpenGL e como @ Mugen87 mencionou, esta é a pista mais reveladora, pelo menos para mim:

O jittering é natural para floats, as variáveis ​​perderão a precisão quanto maior for o número, então a precisão é a melhor quanto mais próximo de 1.0 estiver. Agora, isso não é realmente um problema, mas significa que se você estiver fazendo muitos cálculos de matriz com números enormes, você terá muita degradação de precisão (também conhecido como jittering). Então você precisa fazer toda a sua matemática em torno da origem com números razoáveis ​​e então traduzir

Novamente, conforme explicado, a escala do objeto está afetando o bug.
O exemplo com fontes ThreeJS apresenta esse bug apenas em z = 100000, mas é porque o tamanho da malha (vindo também da fonte ThreeJS) é enorme. O menino correndo tem 150m de altura.

Quando você está fazendo um jogo, você não usa esse tipo de escala, é claro. Você sempre tenta manter seu mundo com 1m = 1unidade. Isso é ainda obrigatório para obter uma boa física e comportamento.

O problema aqui é quando você usa um SkinnedMesh com tamanho realista: o bug já está aparecendo em z = 300.

Em qualquer mecanismo, você pode colocar um SkinnedMesh em x: 30000, y: 60000, z: 140000000 e não há problemas com ossos e esfola. Sem tremores.

Certamente eu entendo muito bem que estamos trabalhando em um núcleo Javascript aqui ... mas ainda assim.

Trolls aqui fingindo "todos nós queremos mundos infinitos, mas é impossível" precisam voltar para a escola e aprender as transformações de matriz. Ou melhor, olhando para jogos de mundo aberto e perguntando-se como seu avatar pode ser "skinnedmeshed" tão longe da raiz da cena 0,0,0 ......

Devo dizer que esse bug é divertido. Aqui, eu poderia reproduzi-lo na área de trabalho, mas 60K não eram suficientes para ficar sem precisão:
needs more zeroes

ok, então em z = 1e8, aqui está o que temos com o sombreador atual:

screen shot 2018-02-14 at 1 15 56

e aqui está o que temos se mudarmos o sombreador para este (ligeira variação do meu teste inicial acima que eu editei):

#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

ainda instável, mas parece bem melhor :) agora, o que isso significa no contexto deste problema?

Primeiro, você não pode simplesmente copiar e colar esse hack no shader. Quer dizer, você pode, mas substitui 1 multiplicação de matriz por 4. o que proponho é a) mesclar a matriz óssea com o inverso da matriz de ligação no lado js e passar como um único uniforme, ou b) criar outro uniforme apenas para isso pedaço de sombreador. Isso resolveria esse problema (de alguma forma) e diminuiria o número de multiplicações de matrizes no sombreador (em 1).

Óh, e

Trolls aqui fingindo "todos nós queremos mundos infinitos, mas é impossível"

Acho que o que eles estavam tentando dizer é que você poderia contornar o problema sem consertar a biblioteca do seu lado. Não é necessário, deveria, mas poderia.

@makc Muito obrigado pelo seu tempo nisso.
Infelizmente, é tarde demais. Eu tenho que entregar sexta-feira. Usei sequências PNG como solução alternativa.

Se você quiser depurar isso profundamente o suficiente. Você poderia tentar usar um tamanho de malha realista?
Novamente, este modelo Lara também tem algo em torno de 60m de altura, se bem me lembro.

Estou muito curioso para ver se o seu patch está funcionando em escala realista também, é claro :)

Ah e ... você está fazendo seu teste no iOS?
Conforme explicado neste tópico, isso está acontecendo principalmente em dispositivos iOS (6, 8).
No Desktop, apenas valores muito elevados trazem o problema.

obrigado novamente

@OrtOfOn você pode tentar o patch @makc adicionando isto no topo do seu 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
`;

THREE.WebGLShader: Shader não conseguiu compilar. : /

patch

Oh cara. você acabou com aspas erradas e formatação de uma linha. como você copia e cola assim?

também, eu meio que fiz isso para ver essas imagens malucas, que satisfazem minha curiosidade. Eu confio que outra pessoa assumirá daqui :)

@makc CTRL + C / CTRL + V ... apenas daqui ...: /

Infelizmente, o bug é menos forte do que antes, mas ainda está lá :(

Testado em iOS (patch aplicado):

Malha na escala 1.0 (avatar com cerca de 20m de altura exatamente), posição z = 10000
http://cornflex.org/webgl/skin-patch1.mp4

Malha na escala 0,1 (avatar com cerca de 2m de altura), posição z = 3000
http://cornflex.org/webgl/skin-patch2.mp4

@mrdoob vou tentar reproduzir :) Ele apareceu em uma única linha. Eu estava escrevendo na página quando vi sua resposta pipocando e não parecia normal, eu prometo: p ... Vou pegar esses pontos bônus, você verá :)

EDIT: BTW, você editou sua postagem? :)

Eu acredito que o efeito residual pode não estar relacionado ao esfola e realmente afetar tudo, mas você não percebe porque não há animação.

@OrtOfOn em seu lugar, eu tentaria envolver toda a sua cena (com uma câmera) em Object3D extra e definir este objeto coords como -1 * avatar coords cada quadro. Isso o manteria em 0,0,0 coordenadas mundiais para sempre.

@markc Eu realmente não gosto de trapacear assim. A jogabilidade e a cena não foram projetadas para serem torturadas dessa maneira e, como um primeiro jogo para dispositivos móveis, o desempenho deve ser ideal, é claro.

Além disso ... não é meu caso, mas imagine isso com vários dos inimigos em SkinnedMesh, vindo de todos os lugares ...

Eu não tive escolha porque o prazo final e eu substituí o SkinnedMesh por animações de spritesheet (cliente está OK). Caso contrário, eu não fiz, exceto para encontrar algo assim. Eu uso o ThreeJS em quase todos os projetos da web e estou muito, muito feliz com isso.

Não queremos "mundos infinitos", mas queremos ser capazes de usar esses recursos de SkinnedMesh e animações em coordenadas do espaço mundial, como fazemos em motores famosos :)

De certa forma estou um pouco decepcionado ... porque fiz um script de Animator muito legal baseado em crossfade e inspirado no mecanim ... Para o próximo projeto com certeza:

@markc Eu realmente não gosto de trapacear assim.

Eu não acho que isso seja trapaça. É assim que funcionam todas as simulações espaciais. Na verdade, a renderização 3D em tempo real basicamente compensa a cena inteira, de modo que o centro está onde a câmera está.

@mrdoob sim, eu sei que nem mesmo uma câmera existe. Poder das matrizes :) (eu mesmo faço algum desenvolvimento nativo de WebGL / OpenGL).

De qualquer forma, colocar toda a cena em um objeto de jogo parece um pouco barbaríssimo para mim ... especialmente para fazer uma animação skinned funcionar.

@OrtOfOn, na verdade, você pode usar a própria cena. por exemplo, no exemplo lara, faça o seguinte:

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

e está tudo bem (editar: no entanto, há algo errado com a luz quando você faz isso .... @mrdoob ?)

@makc Obrigado novamente por propor patches.

Não quero ser pessimista, mas algo me diz que a iluminação não será o único problema com esse tipo de manipulação. É por isso que chamo esses truques e truques por causa da incerteza do resultado e das consequências para outras partes do pipeline.

Infelizmente, as pessoas que fazem jogos têm física, raycasters, partículas, ... muitas coisas que são projetadas e devem ser projetadas para estar no espaço mundial com escalas realistas.

Além disso, estou bastante curioso para ver esses patches em ação com mais de um SkinnedMesh, como inimigos se escondendo ou surgindo em alguns lugares da cena. Qual é o ponto de ficar restrito a um único avatar skinnedmesh em 0,0,0 então?

Vou cavar profundamente na fonte assim que puder, mas tenho que entregar algo em 2 dias ... então, espero que minhas animações de spritesheet estejam bem.

Qual é o ponto de ficar restrito a um único avatar skinnedmesh em 0,0,0 então?

A questão é que é altamente improvável que você renderize simultaneamente o skin em 0,0,0 e outro skin em z = 60000. Apenas algumas skins em torno de 0,0,0 chegarão à tela e não estarão longe o suficiente para acionar o bug.

@makc Novamente, seu patch é válido no desktop, mas você não está testando o caso em dispositivos iOS, onde o bug já está aparecendo a vários metros de 0,0,0 com malhas em escala realistas. Eu fiz vídeos suficientes para mostrar a ele. Este, por exemplo, apresenta o bug apenas em z = 100: /
http://cornflex.org/webgl/skin-bug.mp4

Você sempre usa avatares com 20 metros de altura em seus jogos? :)
Porque o número em que você se concentrou (60000) é usado apenas para expor o bug no desktop (com aquele lara muito grande ou uma amostra enorme do threejs fbx) ... não no celular. E meu avatar não vai tão longe, é claro ...

Eu confirmaria que este é um problema do iOS. Desde, pelo menos, a geração 6S / 6S +, o iOS tem problemas com floatVertexTextures. A correção que estamos usando é desativar esse recurso no iOS. Isso limita os ossos que podemos usar, mas temos que limitá-los de qualquer maneira para oferecer suporte a telefones piores.

Como os dispositivos iOS falham no teste de conformidade postado por @ Mugen87 , provavelmente seria uma boa ideia desabilitar floatVertexTextures, ou provavelmente até floatFragmentTextures, no iOS por padrão, já que claramente não implementa corretamente um recurso que anuncia suportar.

@ daniel-nth acho que faz sentido. Porém ... @OrtOfOn estava dizendo que z = 60K reproduz o problema no desktop ... Eu não tenho nenhum problema com 60K no desktop, apenas 1e8 foi suficiente para eu "reproduzir". Então, talvez esse problema seja realmente pelo menos 3 problemas separados:

  • texturas flutuantes no ios,
  • algo a 60K no desktop de @OrtOfOn ,
  • ficando sem precisão em 1e8 devido à má ordem de multiplicação da matriz no bit de sombreador de ossos (aquele em que mexi acima),
  • talvez algo mais no sombreador de vértice, já que a garota ainda estava um pouco trêmula após o patch.

Oi pessoal,
Em primeiro lugar, agradeço por voltar a este bug. Ainda não encontrei tempo para aprofundar :(

@ daniel-nth A escala do objeto está afetando o bug:

No iOS, com este enorme objeto "Lara" (altura = 120, escala = 1), o bug realmente aparece em z = 60000. Mas, se você pegar uma malha de tamanho realista (altura = 1,8, escala = 1), ela já aparece apenas em z = 100.

quanto maior a skinnedmesh, mais longe deve ser a tradução para ver o bug.

Conforme já testado e relatado neste tópico, a desativação de floatTextures nos resultados do iOS sem nenhum skinning.

Também suspeito de uma má multiplicação da matriz ou ordem de barra de multiplicação da matriz de ossos.

No iOS, com este objeto "Lara" muito grande (altura = 120, escala = 1), o bug aparece em z = 60000

@OrtOfOn espera, e daí ios? mas você também disse:

o número em que você se concentrou (60.000) é usado apenas para expor o bug no desktop (com aquele lara enorme ou uma amostra enorme do threejs fbx) ... não no celular.

No iOS, com este enorme objeto "Lara" (altura = 120, escala = 1), o bug realmente aparece em z = 60000.

Não é nada grande.
E você ainda não entende a relação entre o tamanho do modelo e a escala mundial.
Pela última vez:
http://necromanthus.com/Test/html5/Lara_1000000.html
Altura Modeil aprox = 75 e escala mundial = 9.999.999.
De Z = 0 a Z = 1.000.000 (um milhão !!!)
Como o número de dígitos de ponto flutuante de precisão simples é 7, não há decimais sobrando !!!
Funciona perfeitamente em todos os laptops e desktops que tenho.
Ainda mais:
ele funciona perfeitamente no Android 6 e 7 e em vários telefones celulares Samsung.

lara_1000000

@RemusMar em seu exemplo, insira isto no console:

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

você verá algo assim:
screen shot 2018-03-03 at 15 48 53

screen shot 2018-03-03 at 15 51 41
é tripulante

Vou lhe dizer que z = 1e6 também não parece ruim. por volta de 1e7 já é perceptível, e 1e8 é simplesmente louco

@OrtOfOn A configuração de

Vou lhe dizer que z = 1e6 também não parece ruim. por volta de 1e7 já é perceptível, e 1e8 é simplesmente louco

Eu sei, mas para esses valores você está impreciso.
Para a precisão do peso do vértice da malha descascada, o tamanho máximo do mundo é 9.999.999
Isso se traduz em distâncias máximas de alguns milhões, não mais.
Felicidades

@makc Na verdade, peguei os números errados para desktop. Tem que ser muito grande, você está certo e eu mencionei no tópico anterior, na verdade: / https://github.com/mrdoob/three.js/issues/13288#issuecomment -364650679

@ daniel-nth Bom saber, mas tem certeza? Aqui está o teste que fiz aqui neste tópico, com modelo 3D de fontes threejs. Você ainda pode dar uma olhada no código. @ Mugen87 também fez o mesmo feedback, sem animação com este modelo. https://github.com/mrdoob/three.js/issues/13288#issuecomment -364572653

Oh, vejo que o modelo não está mais presente. 404 em https://threejs.org/examples/models/fbx/xsi_man_skinning.fbx

@ daniel-nth Se você está usando um novo modelo com menos ossos, então eu acredito em você;)

@RemusMar concordou bastante com você sobre as distâncias evocadas nas últimas postagens. Os números (1e6, 1e8, 1e9, ...) certamente resultarão com precisão ruim. Não há dúvida acerca disso. Mas, por favor, pare de me enganar. Pare de fingir que não entendo nada e pergunte-se se uma malha de avatar com altura de 120 não é enorme. Para mim, é muito grande e não muito utilizável em um gamedev com outros objetos em escala realistas feitos por artistas, raycasts, física, iluminação ... e para ser entregue em 3 semanas.

Estou insistindo: manter ativos em escala realista com unidades métricas é algo obrigatório para construir um jogo baseado em física corretamente :)

Uma pena que, no iOS, eu não posso executar meu avatar mais de 100 m nestas condições de escala realistas: /

ATUALIZAÇÃO: De qualquer forma, @ daniel-nth parece nos dizer que agora está trabalhando com floatTextures desativado e uma contagem de ossos muito limitada.

Mas por favor pare de me trollar
Estou insistindo: manter ativos em escala realista com unidades métricas é algo obrigatório para construir um jogo baseado em física corretamente :)

Eu não estou te enganando.
Mas 1,5 unidades não significa 1,5 metros
Felicidades

@OrtOfOn

Estou insistindo: manter ativos em escala realista com unidades métricas é algo obrigatório para construir um jogo baseado em física corretamente :)

mas esta escala é algum valor auto-imposto arbitrário. você também pode decidir usar centímetros, e então "uma malha de avatar com altura de 120" é realmente menor do que a média.

@makc Claro, mas os mecanismos / libs de física esperam que você use valores métricos. Você já tentou fazer alguma física em objetos em escala ou com valores não métricos? Torna-se rapidamente horrível de se desenvolver e você obtém resultados inesperados e irrealistas. Todas as suas forças devem ser revisadas e dimensionadas também. Vai funcionar, mas não com precisão.

Obviamente, depende do nível de precisão que você precisa atingir e valores como 1e6, 1e7, ... são muito grandes e apresentarão problemas de precisão. E você nunca precisará mover uma skinnedmesh tão longe. Nós concordamos sobre isso. Mas, no iOS, devemos ser capazes de mover uma malha skinned gpu (1,5 unidades de altura) em um intervalo de várias centenas de unidades, pelo menos.

mas os mecanismos / libs de física esperam que você use valores métricos.

Isso não é verdade.
Metros, centímetros, polegadas, etc. são irrelevantes.
Como eu disse (várias vezes) antes, tudo o que importa é o tamanho do mundo (escala) e a precisão.
Lembre-se do seguinte:
se você tem uma malha skinned com altura = 1,5 unidades, você é forçado pelo mapa de pesos de vértice a usar 2-3 decimais pelo menos.
Para o mecanismo de física (se houver), você pode precisar de 3-4 decimais para resultados aceitáveis.
Se a precisão global requer 4 decimais, o tamanho máximo do mundo é 999 (porque o número de dígitos de ponto flutuante de precisão simples é 7).
Em outras palavras, você pode usar distâncias de algumas centenas se quiser animações e física decentes.
Espero que você tenha entendido tudo desta vez.
Felicidades

@RemusMar vou parar por aqui. Parece que você não testou ou não quer testar seu caso em um dispositivo iOS. Você não pode usar a "distância de algumas centenas" nesses dispositivos com skinnedmeshes gpu. A malha enlouquece muito rapidamente. Esse é o ponto deste tópico e eu só queria relatar isso no início. Então é isso.

Espero que você tenha percebido que todas as suas proposições e exemplos não funcionam em dispositivos iOS, conforme relatado por outras pessoas aqui e por minhas capturas de tela: /

Você não pode usar a "distância de algumas centenas" nesses dispositivos com skinnedmeshes gpu.

Você está errado de novo.
Veja a imagem acima (Android 7 - celular Samsung).
Altura do modelo = 75 (raio da esfera delimitadora de aprox. 38) e distância 1.000.000 (um milhão !!!)
Ou altura do modelo = 1,5 e distância 20.000.

ps
Não é meu problema que o iOS sempre foi uma coleção de bugs.

@RemusMar Não estou errado, seu troll. Estou falando de iOS e você está falando de outro dispositivo ... você está bravo ??

Não é meu problema se você odeia tanto a Apple. Quando um de meus clientes quer um jogo 3D baseado na web feito com ThreeJS, eu não digo a ele "foda-se com seus iphones" ... Se você fizer isso, sinto muito por você.

Fim da transmissão aqui ... Não posso acompanhar mais isso.

@OrtOfOn Sim, o modelo que usei tem 19 ossos, o 404 fbx tem 67.

https://github.com/mrdoob/three.js/issues/13288#issuecomment -364550036 tinha um link para uma página que mostra o limite uniforme do osso. A fórmula que a página usa é Math.floor((data.webgl.params.MAX_VERTEX_UNIFORM_VECTORS - 20) / 4); Não tenho certeza se isso é 100% preciso para three.js, mas informa 27 mesmo no iPhone X, que infelizmente é menos da metade até de um Galaxy S3, mas ainda bastante para um jogo WebGL móvel. Eu rapidamente naveguei pela minha pasta de trabalho e nos 26 projetos WebGL, apenas um tem um modelo com mais ossos, e esse modelo permanece em 0,0,0.

@OrtOfOn : Estou tendo problemas semelhantes com uma cena fixa e movendo um personagem sem pele pela cena. o personagem fica terrivelmente nervoso no iOS. a contagem de ossos é de 22. as dimensões da cena são razoáveis. Eu acredito que o problema é que o uso de texturas de vértice limita você a flutuadores de 32 bits, juntamente com a afirmação acima de que Threejs calcula o skinning no espaço mundial!

Estou olhando para a afirmação do espaço mundial agora e espero implementar a maneira adequada de calcular as posições vert no espaço local e, em seguida, traduzir o objeto - como deveria ser. Nunca ouvi falar de alguém usando skinning para colocar o objeto no espaço do mundo, então não tenho certeza por que o implementador teria feito tal coisa.

Postarei de volta quando tiver uma solução.

apenas fyi, texturas flutuantes em ios não são apenas quebradas com sombreadores de vértice. Recentemente, eu estava alterando texturas flutuantes para texturas inteiras para corrigir faixas de cores no iOS, então é um problema universal para iOS. você provavelmente poderia usar texturas inteiras para consertar os ossos no iOS também, se realmente quisesse - aqui está um trecho relevante do shader de outra pessoa:

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

... na verdade, você provavelmente poderia (estou assumindo aqui, realmente não tentei algo parecido) fazer texturas float bone funcionarem, também, se você aceitar a precisão ios como limite de precisão global e armazenar dois flutuadores na textura em vez de um

Resolvi o problema inteiramente fazendo com que threejs fizesse o cálculo de skinning no espaço local - onde ele pertence - e traduzisse o modelo para as coordenadas do mundo real da maneira padrão por meio da matriz espacial do mundo.

Os problemas acima são completamente corrigidos para skin no iOS. Devo também salientar que esta solução é universal - funciona perfeitamente em todos os navegadores de desktop, bem como nos dispositivos Android que testei. A redução do espaço local IMHO é a maneira correta de proceder em quase todos os casos, e este método deve ser o padrão para o ThreeJS. @mrdoob : qual é sua opinião sobre isso?

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

Onde 'boneRoots' deve ser adicionado ao objeto de cena raiz (para que eles obtenham atualizações de matriz, mas não herdam todas as matrizes na hierarquia que leva à malha de pele real). Adicione esses boneRoots à raiz da cena (código não mostrado).

E aqui está o patch para substituir a implementação de trêsJS 'SkinnedMesh (observe que isso só é necessário, já que threejs' updatematrixworld destrói o bindMatrixInverse que queremos manter como identidade). Como alternativa, você pode vincular a THREE.Mesh..prototype.UpdateMatrixWorld diretamente em vez de usar uma função de patch.

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

@ denbo-ft Acho que parece bom para mim. Você gostaria de criar um PR para isso?

@ denbo-ft Muito obrigado por seus esforços. Desculpe pelo atraso na resposta, eu não estava mais acompanhando este tópico.

também temos esse problema em nosso produto - qualquer navegador (se você chegar longe o suficiente de 0,0,0), mas mais perceptível no iOS, pois acontece assim que você estiver a cerca de 2-3 unidades de distância. Crítico para nós, mas pelo menos rimos muito quando vemos isso
image

Ok, parece que há mais pessoas que precisam disso. Nunca contribuí para um projeto de código aberto do github, mas estou familiarizado com o git e tentarei criar um PR. :)

O mesmo aqui. Meu SkinnedMesh parece um episódio do Dr. Katz, terapeuta profissional em iPhones.

Para sua informação, meu post de 21 de maio tem a solução completa. Não há muitas correções para as fontes do ThreeJS - a maioria das correções pertence ao seu carregador e / ou código de configuração de cena para seus projetos individuais.

A correção básica é usar o modo 'separado' (que não é documentado, aliás) e colocar a hierarquia óssea em sua cena no nível da cena raiz - não no lugar com a hierarquia real de personagens renderizáveis. Em seguida, consertar uma coisa simples do mecanismo (SkinnedMesh.update), e você deve estar pronto para ir.

Editar:
Temos um formato de arquivo e carregador totalmente personalizados para TJS, então, infelizmente, para criar um PR completo com uma solução de exemplo, eu teria que consertar um dos carregadores enlatados fornecidos (como Collada). Vou tentar fazer isso agora

obrigado, ia reservar um tempo para tentar entender e também aplicar sua solução de uma forma mais genérica (a sua parecia um pouco específica para o seu projeto). Você poderia compartilhar um pouco mais de contexto para o seu código?

Dr. Katz, terapeuta profissional

Não estou viciado nem nada, mas caramba .

EDITAR:

Criei com êxito uma solicitação pull - informe-me se houver algo adicional que eu possa fazer.

Postagem original:

Tenho uma filial local com as alterações, mas não consigo empurrar para a origem. Mesmo fornecendo meus creds do github, recebo este erro:

Empurrando para https://github.com/mrdoob/three.js.git
remoto: permissão para mrdoob / three.js.git negada para denbo-ft.
fatal: incapaz de acessar ' https://github.com/mrdoob/three.js.git/ ': O URL solicitado retornou o erro: 403

Adoraria alguns conselhos, já que esta é minha primeira contribuição para o github. obrigado!

Para sua informação, se o PR funciona para mrdoob e está integrado, há um novo modo de vinculação "local" que suporta essa mudança. Eu não queria corrigir ou alterar o modo de vinculação "desanexado" não documentado, pois não há indicação de quem ou o que o está usando e não queria quebrar algo que eu não sabia. Mas parece-me que pode ter sido planejado com esse propósito.

Tudo o que binMode = "local" faz não é alterar o bindMatrixInverse durante a atualização, ao contrário de "detached", que o redefine para o inverso de bindMatrix, em vez de deixar na identidade.

Veja o exemplo webgl_loader_collada_skinning.html neste PR para ver as poucas mudanças necessárias no nível da cena a fim de obter a pele local adequada nos personagens que se movem pela cena.

A demonstração do carregador da DAE do stormtrooper foi usada para testar essa correção. O personagem foi movido 2.000 unidades da origem para esses testes. Capturas de tela abaixo.

As fotos abaixo são do iPhone X / Safari 11

Antes dessa mudança (em 2.000, 2.000, 2.000):
img_0658

Após esta mudança:
img_0659

Você acha que existe uma maneira de conseguir isso sem ter os ossos no nível da cena raiz e (0,0,0)? Estou usando os ossos para anexar coisas ao avatar, fazer com que pareça pontos, etc. etc. E acho que não sou o único

Você tem duas opções:

1) Manter os ossos no espaço do mundo na raiz para se beneficiar da remoção local, conforme implementado no terceiro ano. Em seguida, faça transformações extras se for absolutamente necessário anexar uma arma a um Osso, por exemplo, para colocá-lo no espaço do avatar.

2) Deixe Bones no espaço do avatar como está e entre no iOS.

Eu definitivamente faria # 1. Você sempre pode fazer as contas para descobrir onde o objeto anexável deve estar em qualquer quadro quando você já tem a posição do osso e a posição do personagem. Mas, não há solução alternativa para o nº 2 porque a distorção é causada pela compactação no nível HAL dos dispositivos iOS e não há nada que você possa fazer a respeito. Claro, você pode adicionar outros hacks tentando usar as várias embalagens HalfWord etc acima, mas todos eles estão reduzindo o problema, não fazendo com que ele desapareça. O problema de esfola no iOS desaparecerá completamente se você fizer o esfola no espaço local (mais especificamente, mantenha os ossos centrados na origem do mundo para manter os números os menores possíveis). Em seguida, xform em espaço de caractere para anexos.

Mais informações:

O problema com a forma como ele é implementado no TJS não é o TJS especificamente, mas para resolver o problema do limite ósseo devido ao número limitado de uniformes por programa de sombreador, as texturas Bone estão sendo usadas. Esta é uma solução bastante padrão. No entanto, no iOS, flutuações em texturas estão sendo quantizadas - compactadas / compactadas - em algo menor que 32 bits. Isso causa o "louva-a-deus" ou outros efeitos malucos dos personagens quando o tamanho / magnitude do número é "grande", ou seja, mais de algumas centenas.

Ok, ótimo, o que fazemos agora? Bem, todas as grandes características do seu jogo (motor de jogo, na verdade), geralmente requerem Padrões de Prática. Exemplo: diga aos artistas para centrarem o personagem sobre a origem. Coloque o nó raiz do personagem nos pés / solo, crie os ossos e a pele de uma maneira particular. Em seguida, escreva um exportador (ou importador no caso do TJS) e um importador que estejam cientes das regras do seu processo. Em seguida, suporte o recurso final no mecanismo ao carregar os ativos que possuem essa configuração. É assim que fazemos as coisas na indústria de jogos.

É incontrolável e indeterminista (ambas coisas terríveis para o desenvolvimento de jogos) esperar QUALQUER método de autoria, QUALQUER formato de arquivo e QUALQUER carregador genérico para lidar com todos os recursos do seu jogo perfeitamente. Deve haver alguns padrões e processos ao longo do caminho.

Se seu personagem usa esfola e também precisa anexar geo para armas ou qualquer outra coisa, pense sobre o que é necessário para o motor esfolar, então trabalhe com isso. Ofereci uma dessas soluções como exemplo. Infelizmente, o PR não foi aceito porque eles, por algum motivo, não querem mudar os carregadores. de qualquer forma, espero ter explicado o problema e a solução no tópico acima, bem como o PR que enviei.

Eu realmente não posso contribuir para isso muito mais do que já contribuí. Espero ter ajudado algumas pessoas ...

Boa sorte!

O problema de esfola no iOS desaparecerá completamente se você fizer o esfola no espaço

Como eu disse desde o início, essa é uma solução alternativa para uma limitação (bug) do iOS e você tem que desperdiçar poder de processamento para isso.
Isso não é solução!
A solução real é aumentar a precisão do ponto flutuante no iOS (para o valor normal de 7 dígitos).
http://davenewson.com/posts/2013/unity-coordinates-and-scales.html

@ denbo-ft Na verdade, implementei seu PR (temos nosso próprio carregador), então, obrigado por sua contribuição, foi apreciado. Eu esperava por outra abordagem, já que temos vários avatares em nossas cenas, eles se movem, pegam itens, interagem entre si, etc. e ter o esqueleto em 0,0,0 nos forçaria a mudar muitas coisas em nosso código, arriscando ter novos problemas, etc.

Passei um tempo pensando sobre o problema, mas não encontrei uma solução melhor. (Ainda tentando)

@RemusMar

A solução real é aumentar a precisão do ponto flutuante no iOS

talvez alguém devesse primeiro perguntar a @grorg e co: qual é o problema com as texturas flutuantes aí, e como é que é assim? porque tenho a sensação de que não é apenas um bug, mas a "solução" da apple para algum outro problema

Tenho a sensação de que não é apenas um bug, mas a "solução" da Apple para algum outro problema

Provavelmente verdade.
Semelhante ao problema no Firefox Android: bug relatado, verificado por dev eles, mas não corrigido nos últimos 5 meses (2 lançamentos)!?!

É assim que o desenvolvimento de software funciona hoje em dia:
em vez de correções no lugar certo, existem soluções alternativas nos terceiros.
Resultado final: coleções de bugs, recursos desperdiçados e bloatware !!!

@jfcampos
Eu recomendaria manter a hierarquia do osso na raiz e simplesmente adicionar uma função para obter a posição WS final de qualquer osso, multiplicando-o pelo martixWorld da matriz de localização real do avatar. É super simples e devolverá o que você tinha antes da correção.

Alternativamente, se você tiver os chops, você pode retornar ao método original (com o bug), incluir as matrizes locais na textura do osso, dobrando seu uso de textura, então modificar os fragmentos de sombreador para fazer o cálculo extra no gpu durante a remoção . Tenha em mente que esta solução, embora "mais limpa" da perspectiva do código, está dobrando (possivelmente quadruplicando) a quantidade de textura que é carregada para a gpu a cada quadro e, portanto, muito menos eficiente do que a sugestão acima. Mas, por quaisquer motivos que você possa ter e dos quais eu não saiba, pode ser mais benéfico para você fazer da segunda maneira.

Do que antes não havia solução, agora existem várias opções aqui para ser compatível com TODOS os dispositivos, o que é um requisito óbvio para a maioria dos projetos.

Parece que vou ter que ir com bones em 0,0,0 e fazer alguns cálculos de matriz extras para as outras coisas. Obrigado!

@ denbo-ft está correto. Este é um problema three.js causado por esfola no espaço mundial.

Para referência, é aqui que a mudança para world-space-skinning foi feita: https://github.com/mrdoob/three.js/pull/4812.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

akshaysrin picture akshaysrin  ·  3Comentários

konijn picture konijn  ·  3Comentários

Bandit picture Bandit  ·  3Comentários

yqrashawn picture yqrashawn  ·  3Comentários

fuzihaofzh picture fuzihaofzh  ·  3Comentários