Three.js: Iluminação seletiva

Criado em 10 ago. 2014  ·  101Comentários  ·  Fonte: mrdoob/three.js

Não tenho certeza se este é um recurso planejado ou talvez concluído, então tentarei explicar a tarefa primeiro.

Preciso fazer iluminação seletiva para salas diferentes. Por exemplo, tenho dois quartos. Uma luz deve afetar apenas objetos e paredes internas de uma sala. A segunda sala não deve ser afetada por esta luz.

Atualmente, se eu adicionar uma luz à cena, ela afetará todos os objetos à sua distância. E obtenho um efeito estranho quando a luz "atravessa a parede" da segunda sala.

Portanto, acho que preciso de algum tipo de grupos ou canais de iluminação, para poder definir os objetos que são afetados por uma fonte de luz e os objetos que são afetados por outra.

Não encontrei nada parecido em luzes ou objetos, então pensei que talvez pudesse ser um bom recurso de se ter.

E, aliás, se ainda não foi implementado, qual é a abordagem recomendada para resolver essas tarefas usando o estado atual de three.js?

Enhancement

Comentários muito úteis

Você tem um link para um exemplo de algo assim?

aqui, fiz um só para você: https://jsfiddle.net/f2Lommf5/524/

Todos 101 comentários

O que estou dizendo é basicamente ter um campo channel em THREE.Light e um campo lightChannel em THREE.Mesh ou algo parecido. Se o último for nulo, ele é afetado por todas as fontes de luz. Se este último não for nulo, será afetado apenas os canais de luz com o mesmo valor.

Ou talvez pudesse ser adicionado não à própria malha, mas para separar faces da geometria da malha.

Parece que você deseja usar sombras?

Bem, eu poderia conseguir algo assim com sombras (e já tentei), mas dá efeitos colaterais diferentes e sinto que é um hack, porque não preciso iluminar alguns objetos e depois projetar sombra sobre eles . Não devo acendê-los em primeiro lugar.

O que eu preciso é que uma fonte de luz específica não afete um conjunto de malhas, mas afete o outro conjunto.

Normalmente faço isso usando uma técnica como esta: Exemplo de tópico de discussão :

glEnable(GL_LIGHT0);
//...
glEnable(GL_LIGHTn);

// Draw the walls to room 1
DrawWalls(room[0]);

// Draw the contents of room 1
DrawContents(room[0]);

glDisable(GL_LIGHT0);
//...
glDisable(GL_LIGHTn);

// Draw the walls to room 2
DrawWalls(room[1]);

// Draw the contents of room 2
DrawContents(room[1]);

Portanto, parece um recurso diferente do que apenas sombras. Ou eu estou esquecendo de alguma coisa?

Sim ... acho que isso pode realmente ser útil. Não tenho certeza de como a API para ele deve ser.

Talvez a solução mais simples seja a mais eficaz aqui:

  1. Adicione channel (ou group ) a THREE.Light
  2. Adicione affectedByLightChannel (ou affectedByLightGroup ) a THREE.Mesh (ou talvez até mesmo a uma face na geometria)

O que você acha?

Talvez o 'associatedByLightChannel' seja muito longo e algo como 'lightChannel' funcione, mas acho que seria conveniente: apenas os números dos canais na fonte de luz e nos receptores.

Curtiu isso:

    light = new THREE.PointLight(0xFFF7D6, 1.0, 15)
    light.channel = 123
    testScene.add(light)

    testScene = new THREE.Scene
    geometry = new THREE.BoxGeometry(2,2,2)
    material = new THREE.MeshLambertMaterial 
        color: 0xffffff

    cube = new THREE.Mesh(geometry, material)
    cube.lightChannel = 123
    testScene.add(cube)

Se lightChannel for igual a 0, então ele é afetado por todos os canais. Se channel for igual a 0, isso afetará todas as malhas.

Portanto, seria totalmente compatível com as versões anteriores do comportamento atual.

Isso pode ser um pouco difícil de entender ... Talvez seja melhor algo assim:

cube.lightInfluences = [ light1, light2 ];

Parece absolutamente bom para mim.

Talvez seja um pouco mais difícil de usar em alguns casos, mas é mais fácil de entender, obviamente.

Que tal uma propriedade de máscara de número inteiro simples para malhas e luzes?

light = new THREE.PointLight(0xFFF7D6, 1.0, 15)
light.mask = 0xffffffff; // default mask
testScene.add(light);

cube = new THREE.Mesh(geometry, material)
cube.mask = 0xffffffff; // default
testScene.add(cube);

Os objetos são então iluminados por luzes apenas se o AND lógico de suas máscaras for diferente de zero.
Isso permitiria que as luzes fossem influenciadas por mais de um canal, sem métodos extras nos objetos.

Um padrão de máscara de 0xffffffff não afetaria o código existente.

O que @ satori99 disse.

Embora eu ache que mask deveria ser uma propriedade de Light e Mesh*Material . (Apenas os materiais afetados pelas luzes.)

Além disso, a propriedade também pode ser chamada de lightMask , lightChannel ou channel .

O problema da abordagem de canal / máscara é que o usuário precisará entender as operações bit a bit. Um pouco intenso demais se você comparar com o resto da API.

O que você pode fazer com as máscaras que não pode ser feito com a abordagem de array?

Eu poderia dar um exemplo da tarefa com duas salas acima.

O ponto principal de usar a abordagem de canal em vez da abordagem de array é que operações simples como 'mover a luz1 da sala 1 para a sala 2' se tornam mais complicadas se você usar arrays.

Em vez de apenas definir

light1.channel = 2

(anteriormente era definido como 1)

você teria que encontrar todos os objetos na sala 1 que tinham luz1 na matriz lightInfluences anteriormente, remover a luz de suas matrizes e adicioná-la a todos os objetos na sala 2.

Mesma história com a operação simples como 'mover o objeto 1 da sala 1 para a sala 2'. Em vez de definir seu canal de influência de 1 a 2, você precisaria encontrar todas as luzes naquela sala, removê-las de sua matriz de influência, encontrar todas as luzes na sala dois e adicioná-las.

Não é que isso não possa ser feito, é por isso que eu disse que a abordagem lightInfluences é absolutamente boa para mim. Mas as coisas do canal seriam a primeira coisa que eu implementaria acima para mim mesmo, apenas para tornar as operações comuns tão simples quanto uma atribuição.

Acho que deve ser implementado como uma máscara. (Se é implementado na CPU ou GPU é um problema para uma discussão posterior.)

Podemos mostrar por meio de exemplos como configurá-lo e os usuários podem seguir o padrão.

Se você acha que ainda é muito complicado, podemos criar uma API THREE.Channels para ele.

light.channels = new THREE.Channels();
...
light.channels.clear();
light.channels.add( channel );
light.channels.remove( channel );
light.channels.all();

Mesmos métodos para Mesh*Material .

Eu gosto dessa API :)
Eu posso ver isso funcionando para objetos e luzes, mas como você vê isso funcionando para materiais?

Apenas os materiais respondem às luzes. Isso teria que ser uma propriedade do material, eu acho.

Eu concordo com isso com @westlangley. As luzes dependem dos materiais.

Mesma história com a operação simples como 'mover o objeto 1 da sala 1 para a sala 2'.

Bem, isso é um problema. Channels não seria baseado em objetos.

Bem, isso é um problema. Os canais não seriam baseados em objetos.

Mas por que? É uma limitação técnica?

Porque isso meio que invalida toda a ideia de tudo isso. Porque pode haver objetos diferentes, que reaproveitam o mesmo material, mas um deles deve estar aceso e o outro - não deve.

Mas por que? É uma limitação técnica?

Não. É porque os objetos não respondem às luzes. Apenas os materiais fazem.

Porque pode haver objetos diferentes, que reaproveitam o mesmo material, mas um deles deve estar aceso e o outro - não deve.

Você pode usar o mesmo material para todos os objetos na cena - apenas clone o material para objetos cujo material requer diferentes valores uniformes. Deve haver apenas um programa de sombreador compartilhado por todos.

Acho que deve ser implementado como uma máscara. (Se é implementado na CPU ou GPU é um problema para uma discussão posterior.)

Isso pode ser tratado com certa facilidade na GPU diretamente?

Isso pode ser tratado com certa facilidade na GPU diretamente?

Sim, você precisaria passar os channels uniformes adicionais para as luzes e os materiais.

Que tal um sistema de gerenciamento de camadas? Eu agruparia as malhas em camadas e aplicaria as máscaras de lá (poderia afetar luzes, sombras, visibilidade, etc), a unidade seria um bom exemplo?

Sombras também é um tópico relacionado. Acho que também deveria haver algo como projeção seletiva de sombras. Como 'receiveShadowFrom = ...' (e uma lista de fontes) em vez de apenas 'receiveShadow = true'.

Porque quando você define luzes que afetam apenas uma sala específica (no meu exemplo), você também deseja imediatamente que essas luzes projetem sombras apenas nos objetos desta sala.

Os atributos das sombras devem realmente estar nos materiais e não nos objetos pelas mesmas razões acima neste tópico.

Os atributos das sombras devem realmente estar nos materiais e não nos objetos pelas mesmas razões acima neste tópico.

Sim, faz sentido!

Há algum plano para incluir esse recurso (como uma liberação planejada para o primeiro rascunho)?

Como solução alternativa, você pode atingir a maioria dos seus requisitos tendo uma cena separada para cada sala (e suas luzes)?

renderer.autoClear = false;
...
renderer.render( scene1, camera );
renderer.render( scene2, camera );

Hmm, vou tentar essa abordagem!

Iluminação / sombras seletivas são obrigatórias para as versões futuras da IMO.

BIG +9999 para este, eu adoraria poder selecionar se um material projeta uma sombra da fonte de luz A ou da fonte de luz B. Alguém tem uma solução atualmente diferente de duas cenas? Isso vai tornar as coisas muito dolorosas para mim ...

puta merda, como isso ainda não foi implementado? após +9999 de rohan)

Haha, meu palpite é que é meio difícil de implementar @tsone, você pode fornecer algumas informações sobre esse commit? Navegando em um cliente de telefone agora

como é difícil de implementar se esses são apenas uniformes que passam para os materiais. tudo o que eles precisam fazer é substituir a lista global de luzes por aquela definida em material, se houver, em algum lugar profundo no renderizador webgl.

Aqui está um JSFiddle simples que testa a implementação de camadas do branch Dev:
https://jsfiddle.net/Angrypickle/t8f7q3vo/4/
Infelizmente, no momento, parece que não está funcionando corretamente. Ou estou fazendo algo errado?

sim. Camadas ainda não funcionam com luzes. Eles funcionam com câmera / objeto! 😊

Roger isso, senhor! Aqui está um JSFiddle atualizado que usa câmeras sobrepostas para obter iluminação seletiva com camadas:
https://jsfiddle.net/Angrypickle/t4a1eusL/
Parece funcionar corretamente no desktop e no celular. Alguém viu algo profundamente ruim com essa abordagem? Pelo menos até que as luzes sejam conectadas à funcionalidade das camadas?

Alguém viu algo profundamente ruim com essa abordagem?

claro que é ruim. em vez de ter uma única câmera navegando pela cena, as pessoas agora terão que fazer coisas camera1.add( camera2 ); Quero dizer, isto é WTF quando eu olho para ele. Como o que? câmera na minha câmera? e se eu tiver dezenas de salas que precisam ser iluminadas individualmente? quantas câmeras eu preciso? e camadas ... não havia camadas ontem, certo, e agora eu tenho que l̲e̲a̲r̲n̲ sobre elas.

acabou, para não dizer que tenho a solução perfeita para isso. por exemplo, pessoas alternativa3d costumavam colocar luzes em coisas que estavam em caixas delimitadoras de luz. isso tinha a vantagem de ser quase zero para os usuários finais, mas estava caindo aos pedaços quando a fronteira entre as luzes tinha que estar inclinada. mas ainda assim, se eu tivesse que resolver esse problema em um projeto real agora, provavelmente resolveria raspando materiais padrão usados ​​em ShaderMaterial-se passando as luzes que desejo manualmente.

Camadas @makc são realmente super simples (e poderosas)!
A abordagem de @ Zob1 definitivamente não é a abordagem certa. Esperançosamente, não demorará muito até que as camadas também funcionem com as luzes.

Pessoal só para ter certeza de que estou seguindo corretamente; digamos que eu tenha uma única cena e uma fonte de luz "principal". É possível com essa técnica fazer com que certos materiais ignorem essa fonte de luz principal, enquanto também projetam sombras de uma fonte de luz diferente?

Bem, para isso também teremos que adicionar camadas de suporte aos materiais.

O que podemos fazer no momento é mostrar / ocultar objetos da câmera:

Digamos que você esteja fazendo um jogo e, no editor, use esferas para exibir os aceleradores. Essas esferas podem ser configuradas para a camada 1, o editor da câmera pode ter as camadas 0 e 1 habilitadas, mas a câmera do jogo pode ser configurada para a camada 0. Dessa forma, no seu editor você vê todos os manequins, mas no jogo eles ' se foi.

Acho que isso fará mais sentido sempre que eu adicionar a funcionalidade ao próprio editor. Provavelmente deveríamos fazer alguns exemplos também.

Direito! Então, basicamente o que eu quero fazer é ter personagens 2D no meu mundo Three JS. Esses personagens precisam de sombras "pontuais" para fazer com que pareçam fazer parte do ambiente. Atualmente estou conseguindo isso usando geometrias de círculo preto transparente colocadas em seus pés e algumas coisas bastante hacky para fazê-lo funcionar em ângulos. Mesmo assim, não funciona bem em superfícies complexas.

Minha ideia original era colocar geometrias de círculo invisíveis como "halos" acima de cada personagem e criar uma luz que está apontando diretamente para baixo, cobrindo toda a cena. Esses halos apenas projetariam sombras desta fonte de luz, enquanto tudo o mais na cena iria projetar sombras da fonte de luz "principal".

Acho que para essa ideia funcionar, precisamos de camadas, certo?

Esses halos apenas projetariam sombras desta fonte de luz, enquanto tudo o mais na cena iria projetar sombras da fonte de luz "principal".

Costumávamos ter uma opção shadowOnly , mas ela foi removida.

FWIW, existe essa abordagem para criar sombras ...

Ah, mas shadowOnly realmente não funcionaria porque então os halos projetariam sombras de ambas as fontes de luz, eu só quero que eles projetem sombras de uma.

Vou verificar esse exemplo no telefone agora, mas parece promissor.

Editar Hmm, mas se aquela esfera mudasse sua posição na cena e a malha do solo tivesse alturas variadas, sua sombra corresponderia aos normais da superfície do solo corretamente?

Não...

Sim, pensei assim. Precisa de camadas! Ele Ele

Olá @ rohan-deshpande,

Sim, para o seu caso de uso, você precisará de algum tipo de camada. Fui eu que implementei o recurso shadowmesh há um tempo. Eles foram feitos para serem usados ​​em uma cena contendo um piso ou solo plano, porque são sombras de um único plano. No entanto, se você precisar de sombras de plano único rápidas e baratas (mas corretas), elas são difíceis de superar em termos de desempenho. A razão pela qual adicionei isso foi porque mesmo para cenas de demonstração simples, os mapas de sombras diminuíram consideravelmente a minha taxa de quadros. Shadowmeshes, por outro lado, funcionam rápido até no meu telefone.

Você pode conferir meu jogo que os usa aqui:
https://github.com/erichlof/3dLightCycles

Estou renderizando a cena duas vezes por meio de 2 janelas de exibição diferentes e todos os objetos do jogo (ciclos e paredes de trilha) têm sombras corretas. Ele roda suavemente no meu smartphone, o que seria impossível com mapas de sombras para 2 renderizações de cena a cada quadro.

+1 aqui para camadas no futuro :)

O jogo

Ok, acho que vou esperar por camadas. Até então, minha solução hacky terá que ser suficiente.

Não, ainda não foi implementado. Você terá que esperar por camadas ou tentar uma das soluções listadas no ITT (cenas separadas, por exemplo).

+99999 novamente

Isso definitivamente seria muito útil. E agora temos camadas funcionando, e parece que é o que está segurando isso. Então, aqui está o solavanco amigável. ;-)

@manthrax verifique isso!

+99999 novamente

Eu adoraria por isso. Eu tenho uma situação em que cada avatar é iluminado apenas pela luz mais próxima, e posso ter milhares de luzes na cena, seria bom especificar uma única luz para cada avatar.

Oi!
Vou precisar desse recurso e pensei em implementá-lo, pois acho que localizei onde isso poderia ser feito ( initMaterial em WebGLRenderer ) e deve ser bastante simples de usar camadas existentes.

Estou pensando em criar uma máscara de bits específica de luz (como um objeto Layers ) para selecionar quais camadas são afetadas por um objeto de luz específico (independente da própria camada de objeto da luz) e, em seguida, filtrar luzes / mapas de sombras que são definidos como uniformes para cada objeto na função acima citada.

Isso seria relevante?

Vou tentar fazer isso e enviar uma solicitação pull assim que tiver conseguido, a menos que você me redirecione para algum outro método antes disso.

ATUALIZAR:

https://github.com/tiesselune/three.js/tree/selective-lighting

Estou chegando a algum lugar. Não tenho certeza de como isso pode afetar o desempenho ou como otimizar meu código para o desempenho, mas está funcionando nos poucos testes que fiz. Iluminação por camada! Yay!

Eu ainda tenho que testar mais alguns, porém, e fazer um exemplo relevante antes de enviar uma solicitação de pull.

ATUALIZAR:

Fiz mais alguns testes, e ter o mesmo material em dois objetos que estão em camadas diferentes (e têm configurações de iluminação diferentes) faz com que o renderizador atualize o material constantemente (via needsUpdate ) desde as configurações de iluminação nas mudanças materiais entre dois objetos, o que antes era impossível. Isso significa uma grande queda no desempenho e estranhezas visuais (já que o último material enviado vence no momento da renderização)

Claro, isso pode ser evitado criando uma nova instância de material em vez de usar exatamente o mesmo para dois objetos com configurações de iluminação diferentes. Mas eu duvido que cloná-lo para o usuário seja uma boa ideia, já que significaria observar o material original em busca de alterações para espelhá-lo no clone.

Aqui estão duas soluções que eu poderia usar:

  1. Eu poderia apenas exibir um aviso quando dois objetos em camadas diferentes com configurações de iluminação diferentes compartilham o mesmo material, para que o usuário possa criar e gerenciar um novo material clone sozinho.

  2. Eu poderia adicionar camadas em um nível de material em vez do nível do objeto (e criar um sistema de camadas paralelas para luzes) de forma que seja obrigatório usar diferentes materiais para obter diferentes configurações de iluminação. Isso significaria que haveria o sistema de camadas atual para visibilidade (em objetos e câmeras) e um diferente para iluminação (em materiais e luzes).

O que é que vocês acham?

Eu estava pensando sobre isso quando vi seu comentário. Acho que exibir um aviso não ajuda, pois muitas pessoas provavelmente não verão isso. Dos dois, definitivamente prefiro definir camadas de luz no material em vez de no objeto. É um pouco contra-intuitivo, mas ainda faz sentido.

Só para esclarecer, quando needsUpdate é setado, neste caso, ele apenas recalcula os valores uniformes, certo? Não deve ser necessário recompilar um sombreador porque os diferentes sombreadores devem ser armazenados em cache. Que tipo de impacto no desempenho você está vendo? Você usou um criador de perfil para ver exatamente onde a computação extra está acontecendo?

A propósito, filterAmbiantLights deve ser filterAmbientLights .

Você está certo sobre o erro ortográfico. Na verdade, eu tinha escrito tudo com "ambiant" antes de perceber que estava errado e esqueci uma ocorrência. 😇

Acho que vou mover as informações da camada no material então. Parece mais relevante e consistente com a forma como funciona.

A queda de desempenho veio (e ainda vem) de initMaterial (e então acquireProgram e getShaderParameter que é tremendamente lento por algum motivo) sendo chamado a cada quadro várias vezes porque o lightHash seria sempre diferente, definindo material.needsUpdate para true .

BTW, estou usando as ferramentas de criação de perfil do Chrome. (Cronogramas e perfilador).

Por mim, tudo bem, mas não sei por que acquireProgram deve estar em execução o tempo todo. Se o número de cada tipo de luz é adicionado aos parâmetros do programa, recompilar o sombreador todas as vezes não deve ser desnecessário?

Eu também não entendo;

Aqui está a pilha de chamadas (em cada quadro) e o terrível vazamento de memória que se segue, se você estiver familiarizado com isso, pode me ajudar a entender o que está errado. Parece que está criando novos WebGLProgram s cada quadro ...

threejscalltree

Talvez seja replaceLightNums que atualiza o código do sombreador de vértice / fragmento durante a criação do WebGLProgram, fazendo com que ele seja recompilado ou considerando que é um sombreador diferente ...?

EDIT: Enfim, usar camadas no nível do material resolve o problema conforme o esperado. Eu só tenho um vazamento de memória em algum lugar que devo investigar, mas, por outro lado, parece muito bom.

Provavelmente, é uma boa ideia entender por que isso está acontecendo apenas para ter certeza de que entendeu totalmente o código e não está introduzindo algum novo bug. Você pode percorrê-lo para ver por que o código do sombreador muda a cada quadro?

Não conheço WebGLPrograms bem o suficiente para dizer o que está acontecendo, mas parece que ele deveria estar armazenando em cache esses sombreadores para você.

É muito simples, na verdade:

  • saber se deve ou não chamar acquireProgram , initMaterial obtém o "código" do sombreador do cache (é mais um hash, na verdade, construído em getProgramCode ) e compara para o "código" do programa do material atual.
  • Uma vez que esta função cria o "código" a partir de parâmetros incluindo o número de cada tipo de luz, que é filtrado e embora diferente entre os objetos, o código pode ser diferente para um mesmo material (por assim dizer, o mesmo programa) de um objeto para o de outros.
  • Como esse processo é iterado para cada objeto, o "código" muda várias vezes por quadro, fazendo com que seja recompilado tantas vezes em um único quadro: o que causa a queda do perf.
  • Dito isso, uma vez que vários objetos têm o mesmo material, e portanto, o mesmo programa, o último objeto iterado impôs seus parâmetros ao programa, o que fez com que ambos os objetos fossem iluminados com a mesma configuração de luz, mas não necessariamente com os mesmos mapas de sombra (que pode ser calculado para objetos em uma ordem diferente, mas sofre o mesmo problema de "o último objeto ganha"), causando minhas estranhezas visuais.

Agora tudo funciona conforme o esperado (já que cada objeto com configurações de luz diferentes tem um material diferente e um programa diferente), exceto por uma otimização de memória que eu poderia fazer com meus próprios hashes de luz, que irei abordar em breve.

Poderia haver alguma melhoria se os números de luz fossem variáveis, de modo que cada material sejam apenas instâncias do mesmo programa, mas como esses números são inseridos no código do sombreador (em replaceLightNums ), parece incompatível com a forma como as coisas atualmente são (e sua otimização).

Espero que a explicação seja compreensível o suficiente

Gostaria de saber se podemos passar a máscara de camada para o shader (um uniforme por objeto e mais um uniforme por luz). Então poderíamos adicionar algo como isso em aqui .

Algo como...

for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {

    pointLight = pointLights[ i ];
    pointLight.distance *= float( object.mask & pointlight.mask > 0.0 );

    ...

}

Meh, eu não acho que podemos fazer operações bit a bit em glsl ...

Sim, parece que as operações bit a bit começam em GLSL 1.30 e que o WebGL padrão usa 1.00. 😕

Olá @mrdoob e @tiesselune ,

O Chrome 56 e o ​​Firefox 51 acabaram de chegar, o que significa que o WebGL 2.0 está habilitado por padrão (o WebGL2 segue as especificações do OpenGL ES 3.0). Isso significa que as operações de bits (e outras coisas legais como texturas 3D) agora estão disponíveis. Não sei se o Three está se preparando lentamente para a mudança para o WebGL 2.0, mas fiz algumas alterações obrigatórias em minha cópia do three84.js e habilitei o WebGL 2.0, e fiz uma pequena operação em um shader apenas para ter certeza. funcionou, e funcionou!
https://developers.google.com/web/updates/2017/01/nic56
https://developer.mozilla.org/en-US/Firefox/Releases/51

Só queria que você soubesse. 1 para a ideia de mascaramento :-)

Olá @erichlof ! Isso é uma ótima notícia para o WebGL2; isso significa que o renderizador WebGL2 provavelmente será capaz de abordar os problemas de mascaramento de uma maneira mais eficiente.

De qualquer forma, dado o uso muito limitado de navegadores com suporte para WebGL2 até agora, não acho que podemos descartar os esforços para fazê-lo funcionar no WebGL 1: leva muito tempo até que quase todos os navegadores possam executar aplicativos WebGL, então provavelmente será um um pouco mais até que o WebGL 2 seja realmente utilizável em grande escala ... 😕 Mas obrigado pela dica!

Oi de novo!

Nova atualização: fiz o que achei necessário para o gerenciamento de memória, mas a coleta de lixo de heap JS parece ter muito a ver com minha configuração de software (programas em execução, abas abertas, extensões) no momento em que executo perfis. Alguém com um pouco mais de experiência nisso pode confirmar que meu código não tem tanta fome de memória em comparação com a versão atual do threejs?

De qualquer forma, fiz um exemplo em examples / webgl_lights_selective_lighting.html . Acontece que obtive artefatos visuais relacionados ao mapa de sombras ao usar dois holofotes (nas mesmas camadas) simultaneamente nos objetos de pele da cena. Os objetos estáticos se comportam conforme o esperado. Eu executei testes e isso acontece no branch dev também, sem considerar as camadas de luz seletivas (na verdade, acabei de adicionar um holofote no exemplo do mapa de sombra, no branch dev). Alguém sabe de onde vem isso?

Aqui está uma captura de tela:
shadowmap

Deve ser possível ver o exemplo ao vivo aqui:

https://rawgit.com/tiesselune/three.js/selective-lighting/examples/webgl_lights_selective_lights.html

Porém, estou recebendo um erro:

Uncaught TypeError: Cannot read property 'set' of undefined
    at init (webgl_lights_selective_lights.html:117)
    at webgl_lights_selective_lights.html:67

@looeee : você terá que executar npm run build-uglify em um host local. Eu voluntariamente não incluí compilações em meus commits para fins de mesclagem ...

Ou devo?

EDITAR: aqui está um link de trabalho em um branch diferente para fins de teste: https://rawgit.com/tiesselune/three.js/selective-lights-test/examples/webgl_lights_selective_lights.html

Ei, +999999 de mim. Isso deve ser implementado (pelo menos com THREE.Layers )

$$('.comment-body').reduce((acc, el) => {
  let mat = el.textContent.match(/\+(\d+)/)
  let num = +(mat && mat[1] || 0)
  return acc + num
}, 0)
>> 1219997

🤔

@mrdoob ele calculou + Ns neste tópico

btw, +14570 para luzes seletivas

Isso será incrivelmente ótimo para ajustar como a iluminação funciona em uma abstração superior.

Por exemplo, na caneta a seguir, gostaria que a iluminação funcionasse de uma maneira para os elementos DOM em vez de outra maneira para a esfera para que a iluminação fosse mais realista:

https://codepen.io/trusktr/pen/RjzKJx

Certos efeitos que se parecem com um único ponto de luz podem ser obtidos combinando duas ou mais luzes que estão afetando seletivamente apenas certos elementos.

Por exemplo, no meu exemplo anterior, posso aumentar a intensidade da luz para obter uma sombra de boa aparência no "elemento DOM", mas a esfera ficará um pouco brilhante e brilhante. Se eu pudesse ter uma luz mais fraca para a esfera e uma luz mais brilhante para o "elemento DOM", então eu poderia conseguir algo mais realístico desta forma, onde pareceria para o visualizador que ainda há apenas uma luz. Então, esse tipo de coisa pode ser abstraído em uma API de nível superior que faz parecer que há apenas uma luz sendo manipulada quando atrás da cena duas luzes Three.js estão realmente em jogo.

@WestLangley

Como solução alternativa, você pode atingir a maioria dos seus requisitos tendo uma cena separada para cada sala (e suas luzes)?

Você tem um link para um exemplo de algo assim? Pode ter outros efeitos de renderização inesperados no resultado?

outros efeitos de renderização inesperados no resultado?

ordem de renderização de objetos transparentes, por exemplo - objetos transparentes na cena 1 serão renderizados antes dos objetos opacos na cena 2.

Você tem um link para um exemplo de algo assim?

aqui, fiz um só para você: https://jsfiddle.net/f2Lommf5/524/

ordem de renderização de objetos transparentes, por exemplo - objetos transparentes na cena 1 serão renderizados antes dos objetos opacos na cena 2.

Isso é o que eu estava pensando; isso torna a solução alternativa apenas uma solução alternativa para casos muito limitados. Ansioso pela solução real!

bem, você poderia argumentar que o problema só aconteceria se você pudesse ver os objetos opacos da cena2 da cena1 através dos referidos objetos transparentes. mas se for esse o caso, as luzes também deveriam passar, e não haveria razão para separar as cenas para começar. mas concordo que esse tipo de argumento não é realmente convincente.

@makc Aqui está um exemplo do problema que estou tentando resolver:

https://discourse.threejs.org/t/how-to-make-shadows-darker-on-transparent-objects/1389

Acho que a iluminação seletiva ajudaria muito nisso.

@trusktr Acho que você pode resolver isso alterando o material da sombra de mrdoob. mostra apenas a textura da sombra preto e branco, e você pode modificá-la para ser transparente conforme necessário

As máscaras no PlayCanvas parecem realmente fáceis de usar para iluminação seletiva: https://forum.playcanvas.com/t/set-certain-object-to-not-receive-light/785.

podemos obter isso mesclado? Acho que os problemas de sombra se deviam ao shader Lambert, nada a ver com a mudança no código. @tiesselune

@ErikBehar Na verdade, estava procurando algo para fazer esta tarde. Vou tentar atualizar o código para os últimos três js e enviar uma solicitação de pull, talvez? Na verdade, eu gostaria de saber que fiz uma contribuição real para um projeto tão grande. (E bom ter a confirmação de que esse bug não teve nada a ver com minhas alterações)

EDIT: acabei de descobrir que esta parte do código mudou muito. Acho que vai precisar de um pouco de tempo, já que os estados que eu estava usando anteriormente mudaram de WebGLRenderer para WebGLLights.

@tiesselune Eu meio que precisava colocar isso em um projeto, então fui em frente e transferi seu código para a v93, consulte: https://github.com/ErikBehar/three.js/tree/selectiveLights

Posso fazer uma RP, se vocês desejarem? @mrdoob

@ErikBehar Bem, parece mesmo o que eu queria, mas não tive tempo para fazer isso inteiramente. Acho que teria movido as funções de filtragem / hash do WebGLRenderer e adicionado-as ao objeto de estado WebGLLights. Eu sinto que eles pertencem lá agora, o sistema de camadas sendo uma parte do estado e não uma parte do renderizador.

@ErikBehar um PR seria ótimo!

@tiesselune Vou @mrdoob

Qual é o status disso? Eu mesclei o código r94dev de @ErikBehar em r94, em seguida, mesclei r97 nele, apenas alguns conflitos muito simples (mudança de versão, algumas variáveis ​​para iluminação seletiva e a criação de hash em renderizadores / WebGLRenderer.js; fique feliz em colocar um PR. @tiesselune se você puder me dar uma ideia de onde você pretendia que o estado de iluminação seletiva fosse, eu ficaria feliz em mudá-lo, testar e colocar um PR.

EDITAR:
Um pouco mais tarde: vejo que isso precisa de algum trabalho para funcionar, agora, com o novo lighthash.

@VaelynPhi Eu acho que, independentemente de eles estarem dispostos a aceitar o código de @ErikBehar ou não, é uma boa ideia enviar o PR, apenas para substituir o desatualizado no caso de outras pessoas quererem, como você fez

Desculpe deixar a bola cair sobre esse cara = / ...

Sem problemas; Eu entendo estar ocupado. Infelizmente, não consegui nem mesmo o branch que você tinha funcionando, @ErikBehar; Decidi ler o código para tentar decompô-lo para que pudesse mover o estado para o local apropriado e, com sorte, corrigir quaisquer bugs. Ainda não cheguei a um estado de porta funcional, mesmo na v94. Talvez eu possa limpá-lo e inserir o PR apenas para atualizá-lo como

adicionou um PR com base em:
https://github.com/ErikBehar/three.js/commit/ac0499b70b82bc7bb780100a8372fcdf318d1424#diff -5e43a0b5002eb2c419def3baf67d4e67
por @ErikBehar
alguém pode dar uma mão com alguma crítica e o exemplo?

https://github.com/mrdoob/three.js/pull/15223

Ei pessoal, qual é o status deste aqui? @tiesselune @ErikBehar Posso ajudar em algo? Seria bom implementá-lo finalmente após 4 anos 😄💯

@flyrell Acho que talvez possamos encerrar esse problema, já que parece estar mais perto de terminar em # 15223, talvez?

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