Antes de dizer qualquer outra coisa: estou usando mapas de luz duplos, o que significa que preciso misturar um perto e um longe.
Então, eu estou trabalhando nisso há um tempo, tenho um ciclo dia / noite inteiro configurado para renderizadores e iluminação, e tudo está funcionando bem e não exige muitos processos.
O único problema que estou tendo é descobrir como combinar dois mapas de luz. Eu descobri como alternar mapas de luz, mas o problema é que parece meio abrupto e interrompe a experiência.
Eu fiz horas de pesquisa sobre isso, tentei todos os tipos de shaders, mistura de pixel por pixel e tudo o mais sem sucesso. A mistura de pixel por pixel em C # acabou sendo um pouco intensiva para o meu gosto, embora ainda esteja trabalhando para limpá-lo e fazê-lo funcionar de maneira mais suave. Os shaders pareciam promissores, mas não consegui encontrar um shader capaz de combinar adequadamente dois mapas de luz.
Alguém tem alguma pista sobre como eu poderia fazer isso? Eu só preciso de algum tipo de transição suave entre meu mapa de luz diurno e noturno. Talvez eu possa sobrepor as duas texturas e usar um canal alfa? Ou algo assim?
Graphics.Blit()
para renderizá-lo? Eu nunca fiz isso, mas olhando no manual, ele deve funcionar.Respostas:
Então, eu tentei recentemente e encontrei muitos dos mesmos problemas que vocês têm. A solução de textura de renderização é um pouco de um arenque vermelho. Consegui resolvê-lo usando a manipulação de pixels multithreading em um thread separado.
https://www.youtube.com/watch?v=T_zpFk1mdCI
Então, normalmente, alguém usaria
graphics.blit()
e passaria a textura de renderização para onde quer que fosse, mas os dados do lightmap não suportam texturas, eles exigem texture2ds. O próximo passo lógico seria copiar os dados para um texture2d e depois alimentá-los com os dados do lightmap. Essa técnica arruina as taxas de quadros porque está impedindo a GPU de enviar dados para a CPU, em vez de apenas uma referência aos dados.A solução é então não usar a GPU.
As transições do mapa de luz acontecem por um longo período de tempo, portanto, não é necessariamente importante atualizar o mapa de luz a cada quadro. Por uma questão de fato, os jogadores provavelmente não notariam se os mapas de luz eram atualizados apenas a cada 20-40 minutos no tempo do jogo.
Então, o que você faz é emitir a tarefa para a CPU em threads separados para cada mapa de luzes.
Normalmente, o Unity não suporta multithreading. Mas tudo bem, C # faz. Esse cara faz um trabalho fenomenal ao explicar multithreading no Unity, por isso, se você nunca ouviu falar ou nunca soube multithread no Unity, este é o vídeo:
https://www.youtube.com/watch?v=ja63QO1Imck
Tudo o que você precisa fazer é criar uma classe de encadeamento de trabalho que varie cópias dos dados de pixel do lightmap nas matrizes Color e criar uma função de mesclagem.
Um simples lerp de uma cor para a próxima serve.
Em seguida, crie o encadeamento, inicie-o e, quando todos os mapas de luz estiverem concluídos nos encadeamentos separados, você poderá copiar os dados de pixel de volta na textura de dados lightmap2d.
Publiquei um código de exemplo abaixo. Certamente não é a versão totalmente implementada, mas mostra os principais conceitos de criação da classe, criação do thread e configuração dos dados da luz.
As outras coisas que você teria que fazer é chamar uma função de vez em quando para acionar a atualização dos mapas de luz. Além disso, você deve copiar todos os dados de pixel na classe worker no início ou no tempo de compilação. Boa sorte para quem encontrar isso. Eu acho que a operação mudou sua vida, mas sei que outras pessoas com problemas semelhantes podem tropeçar nisso.
fonte
Existe um shader do skybox que combina entre dois conjuntos de texturas do skybox. Pense ciclo dia e noite!
Se você deseja criar ou animar a skybox a partir do script, use
skyboxmaterial.SetFloat("_Blend", yourBlend)
para alterar a mistura; também pode usarSetTexture
funções de material para configurar ou alterar as texturas.Tutorial em vídeo sobre o ciclo dia / noite: http://www.youtube.com/watch?v=FTfv9JhkmIA
O código de exemplo é o seguinte:
fonte
Se você sabe como alternar, por que não continuar criando vários mapas de luzes de transição no encadeamento em segundo plano e ativar as transições quando os mapas de luz estiverem prontos?
Você também pode dar uma olhada em um ativo interessante no AssetStore: https://www.assetstore.unity3d.com/en/#!/content/5674
Eu acho que inclui os mapas de luz que se misturam, embora eu não saiba como.
fonte