segunda-feira, 25 de outubro de 2010

3D LOD Subdivision - Tutorial


LOD para aqueles que não conhecem o termo significa level of details, traduzindo o que isso quer dizer em palavras simples, é que quanto mais distante da câmera mais simplificada a geometria ficará.
No nosso caso a proposta é ter um LOD Subdivision, então podemos concluir que quanto mais distante da câmera menor será a subdivisão aplicada à geometria. A vantagem de se usar isso é tornar a cena mais leve para o render otimizando o número de polígonos a se usar.
As aplicações podem variar, mas em geral creio que a melhor aplicação para essa técnica é para terrenos irregulares e detalhados, desertos com dunas e oceanos. Formas as quais podem ser compostas usando modificadores como o displace.
Eu desenvolvi essa técnica por pura necessidade para fazer um oceano. Eu tinha uma vasta extensão de água animada e que precisava de ondas, mas máquinas fracas para agüentarem o processamento de muitos polígonos.
Então, creio que assim como eu outros podem ter necessidades específicas e encontrarem novas aplicações para essa técnica, diferente das que eu citei acima.

Para explicar a aplicação e o funcionamento dessa técnica, vamos usar um "Plane" com 10x10 segmentos como base.

A etapa seguinte é criarmos um controlador. Ele terá 2 funções, a primeira vai ser indicar a área que vai ser selecionada, e a segunda é possibilitar fazer um link entre a subdivisão e a câmera.

Esse controlador deverá ser uma geometria, ele não pode ser um helper, pois helpers são objetos nulos. Para o nosso exemplo vou usar uma esfera, mas pode ser qualquer outro objeto.

Agora vem a primeira parte do segredo do funcionamento da técnica. Como a nossa subdivisão vai ser seletiva e móvel, pois caso a câmera seja animada, e desejemos ter subdivisão apenas onde a câmera está então essa subdivisão deve seguir a câmera onde ela for.
Usaremos o modificador "Vol. Select" para fazer a seleção da área, e essa seleção será feita com referência no nosso controlador.

Atentem para as configurações usadas no modificador. Em "Stack Selection Levels" usaremos a seleção de vértices, o método de seleção (selection Method) dever ser por adição (mais a frente explico o motivo) e finalmente em "Select By" usaremos a opção de "Mesh Objetct", e selecionamos agora o nosso controlador, então poderemos ver dentro do volume do controlador os vértices selecionados no caso da imagem de exemplo temos apenas 1 vértice.
A próxima etapa é ajustar a área total que será afetada pelo primeiro nível de subdivisão. Isso deve ser feito no menu "Soft Selection ainda no modificador "Vol. Select".

Os valores usados para configurar o "Falloff" e o "Pinch" podem variar de acordo com as dimensões da cena, a escala e a sua própria necessidade.
Feitas as configurações no "Vol. Select" vamos aplicar o modificador "MeshSmooth" em cima, assim ele vai atuar apenas na região que esta selecionada. É importante avisar que com o modificador "TurboSmooth" não funciona.

Outro detalhe importante é desmarcar a opção "Apply To Whole Mesh" para que a subdivisão seja aplicada apenas na nossa seleção.
Agora temos o primeiro nível da subdivisão pronto, mas precisamos de mais níveis para que o efeito funcione melhor, então vamos replicar o que já foi feito. Para sermos mais práticos vamos apenas selecionar os 2 modificadores copiar e colar.

Feito isso precisamos ajustar o "Soft Selection" do novo "Vol. Select" para expandir a sua área de seleção.
Novamente esses ajustes deverão ser feitos de acordo com as necessidades das suas cenas.

Agora fica claro o por que selecionamos o metodo de Adição (Add) no "Vol. Seletion", pois caso contrario a seleção do segundo não se somaria a do primeiro, assim o efeito não funcionaria.
Notem agora que temos 2 níveis de subdivisão diferentes. O primeiro nível, mais ao centro esta com 2 subdivisões, a do primeiro modificador "MeshSmooth" mais a do segundo.
Agora podemos repetir esse processo quantas vezes forem necessárias até atingir o nível de subdivisão que for preciso.

Agora experimentem selecionar o controlador (a esfera) e movê-lo sobre o "Plane" para ver como ficou a subdivisão.

Agora para completar a ferramenta, vamos fazer um link do nosso controlador à nossa câmera, mas antes deixe o controlador próximo à câmera o quanto for preciso para que a área mais subdividida seja o foco da atenção.

Ajustada a cena faremos o link (aqui estou usando a ferramenta "Select and Link") para que o controlador siga sempre a câmera.

Esse "link" pode ser feito de outras maneiras, via "Constraints" ou "Wire Parameters" para limitar os eixos que o controlador irá se mover ou poder animar o link do controlador de uma câmera para outra.
Outro detalhe importante e que não pode ser esquecido é entrar nas propriedades do nosso controlador e desabilitar a opção que o deixa renderizável ("Renderable"), assim ele não aparecerá no render e nem influenciara na nossa cena.

Agora para testarmos a aplicação dessa técnica adicione um modificador "Noise" no "Plane".

Notem que o "Noise" esta atuando somente na área que esta selecionada, dependendo da situação isso pode ou não ser desejável. Caso não seja desejável, caso precisemos que seja aplicado no todo do nosso "Plane" basta aplicar antes do "Noise" o modificador "Poly Select" sem alterar nenhum de seus parâmetros, isso irá limpar as nossas seleções para o que estiver acima dele fazendo assim o "Noise" afetar todo o nosso "Plane".

Caso o nível de subdivisão no primeiro ou nos demais níveis não tenha ficado suficiente, podemos voltar aos modificadores "MeshSmoth" e aumentar o valor do "Iterations", mas atenção! Isso deve ser feito com cautela, sempre salve a cena antes de fazer isso, e tenha cópias de segurança, pois subdivisões muito altas podem vir a travar a máquina, principalmente máquinas com pouca memória RAM (o mínimo recomendado pela Autodesk para o 3Ds Max é de 4gb de RAM).
Uma outra alternativa bem viável é adicionar acima do "Poly Select" um "TurboSmooth" ou mesmo um "MeshSmoth" e usar o "Render Iterations" (Render Iters.), pode-se jogar com os valores do” Iterations" x "Render Iterations", tudo pode variar de acordo com a necessidade da cena.

Notem que o nível de subdivisão do centro é bem maior que nas extremidades.
Aqui um exemplo sem o "Poly Select":

 Assim como expliquei, o "Noise" vai atuar apenas na área da seleção dos nossos "Vol. Selection". Já o "TurboSmooth" como expliquei antes não funciona com seleção. Mas se ao invés do "TurboSmooth" você tiver usado um "MeshSmoth" então diferente de antes precisaremos deixar a opção "Apply To Whole Mesh" ligada para que ele não atue apenas na seleção.
E agora a nossa ferramenta está completa, experimentem mover a câmera e ver como vai ficar o resultado.

Só o que fizemos até aqui já é o suficiente para otimizar em muito a nossa cena, mas ainda podemos fazer mais. Temos toda uma geometria que não aparece em cena e que fica na parte de traz da câmera, em casos mais específicos podemos precisar dessa parte (para reflexos ou outras necessidades específicas) então basta ignorar essa última etapa, essa geometria oculta pode ser removida da cena para deixar nosso projeto mais leve ainda, então vamos ver como fazer isso.
Adicione o modificador “Slice” abaixo do modificador "Poly Select" e marque a opção “Remove Top”.

Em seguida clique no símbolo de “+” ao lado do “Slice” para acessarmos as sub-propriedades do modificador e selecione a opção “Slice Plane”. Feito isso vamos usar a ferramenta “Align” Para alinharmos o “Slice” com a nossa câmera, então após ativar o “Align” clique sobre a câmera e faça o alinhamento da posição e da orientação usando o “Pivot Point” como base.

Agora já estamos removendo a parte da geometria que fica atrás da nossa câmera, porém ainda precisamos fazer com que o “Slice” acompanhe a câmera quando ela se mover ou rotacionar, para isso vamos usar o “Wire Parameter”.
Para acessar o “Wire Parameter” clique com o segundo botão do mouse sobre o objeto para abrir o menu flutuante, em seguida clique sobre a opção “Wire Parameter”. No novo menu que irá abrir siga as etapas como mostra na imagem abaixo.

Após selecionar o “X Position” você deve clicar sobre a sua câmera para fazermos a ligação das informações do “Slice” às da câmera.

Feito isso a janela de configurações do “Wire Parameter” vai abrir. Aqui vamos indicar quem vai controlar quem usando as setas de direção que ficam no meio da janela.
Vamos fazer esse controle para os eixos X e Y, pois não temos interesse que o “Slice” se mova no eixo Z.
Selecione o “X Position” da câmera e o “X Position” do “Slice”, ligue a seta de posição de modo que a câmera seja o “Master”, e no campo “Expression” vamos fazer uma expressão matemática simples para mover o “Slice” um pouco mais para trás da câmera, digite apenas “-25” logo depois de “X Position” (ou o valor que se adaptar melhor a sua cena, pois como já falei os valores podem variar de acordo com a escala e as proporções da cena) e clique em “Connect”. Faça o mesmo para o eixo Y, lembre-se devemos ligar cada eixo com seu par, portanto Y com Y.

Agora o “Slice” já esta se movendo com a câmera, mas precisamos também que ele gire com ela, para isso vamos conectar o “Rotation” dos 3 eixos, mas dessa vez não precisamos usar expressão.

Agora o “Slice” já esta seguindo a mesma orientação da câmera, experimente girar a câmera para verificar o resultado.

Com essa última etapa nossa ferramenta fica realmente completa e pronta para usar. Espero que tenham gostado e que essa técnica venha a ser útil. Em breve pretendo tentar transformar isso em um script para facilitar a aplicação.

Clique aqui para baixar o arquivo da cena de estudo (3Ds Max 2010)

9 comentários:

wmiler disse...

Opa Tiago Medeiros, muito bom o tuto. Esta técnica abre um leque de opções q podemos fazer.
Obrigado...

Anônimo disse...

muito bom tiago...
realmente abre um monte de possibilidades...!!!

Danilo disse...

Parabéns mestre Thiago, cada técnica sua é melhor do que a outra. Vc é um gênio cara, pode ter certeza. Quando fazia cenas complexas que tinha oceano, eu sofria as vezes quando tinha uma malha pesada e extensa, no caso um oceano. Mas agora com essa sua técnica, a gente pode limitar a área do oceano em que ficará densa com o uso de um helper do 3ds Max, o que fica legal é que é só colocar o helper próximo a lente da câmera e mandar renderizar, somente a área que será melhor mostrada pela câmera, será a que será mais subdividida. Parabéns, excelente tutorial.
Abraços e sucesso!!
danilo_icf (www.3d1.com.br)

Peh disse...

poxa vida sensacional thiago.. soh vendo coisas assim pra ver o poder q o max tem e as ferramentas sensacionais dele... isso aqui é incrivel meu velho.. ta de parabens e obrigado pela contribuição.

Anônimo disse...

parabens cara, muito bom esse tutorial mesmo.
nunca tinha reparado essa opçao do meshsmooth de apply whole mesh, e uma coisa legal q eu descobri tb eh q vc pode criar uma mapa e usar no vol.select, assim quando vc criar um mapa de displace vc tb pode pintar um mapa dizendo aonde ele será mais detalhado

tiagodmed disse...

E ai pessoal, que bom que ta todo mundo curtindo o material :D valeu pelo apoio de todos ;)
Quanto a usar mascaras de bitmap para marcar áreas, esse vai ser um tutorial que pretendo fazer mais pra frente quando sobrar um tempo.
A ferramenta que estou pretendendo criar tb vai ter esse recurso ;)

Djodi disse...

Eu sempre digo para meus alunos para não fazerem um tutorial pelo resultado final do mesmo, mas sim pelas ferramentas utilizadas.

Eu costumo fazer gramados espalhando algumas folhas de grama com o particle flow, mas isso sempre me dava o problema de apagar as faces do objeto emissor que não estavam aparecendo na camera para não desperdiçar recursos. Uma mudança de camera e já era...

Vendo seu tuto já pensei que se eu tivesse uma geometria que copiasse o FOV da camera eu poderia utilizá-la no Vol. Select para selecionar apenas as faces que aparecessem no meu emissor e então distribuir apenas nessas faces.

Rumei direto para o scriptspot.com e voilà: http://www.scriptspot.com/3ds-max/scripts/cameracone . Este script cria uma piramide com as mesmas dimensões do FOV da camera, e se atualiza com ela. Dessa forma, posso conectá-la ao Vol. Select e ter partículas apenas onde a camera vê.

Com tudo isso quero dizer,

muito obrigado Tiago!

tiagodmed disse...

Nossa Djodi, perfeito isso! É uma ótima sacada!
Vou até documentar isso e colocar aqui como um complemento a esse material, se vc ver esse meu comentário me envia um email com seu nome completo para mim poder dar os créditos pela idéia :D assim tb já fico com o seu contato (vc pode enviar usando a barra de contato na lateral do blog ;) )

renatopolimeno disse...

Tiago,
abaixo o link para script que fiz baseado no seu tutorial:

http://renatopolimeno.com/wp-content/uploads/rp_TiagoMedeiros_LOD.zip

(arquivo .zip ~12MB com video-demo + script .ms aberto para interessados em estudar as linhas e execução do código)

Espero que seja util pra você e pra galera aí. ;)

Abraços

Postar um comentário