Avant de dire autre chose: j'utilise des cartes lumineuses doubles, ce qui signifie que je dois mélanger à la fois un proche et un lointain.
Donc, je travaille sur cela depuis un certain temps maintenant, j'ai un cycle jour / nuit complet configuré pour les rendus et l'éclairage, et tout fonctionne bien et ne demande pas beaucoup de processus.
Le seul problème que j'ai est de trouver comment mélanger deux lightmaps ensemble, j'ai compris comment changer de lightmaps, mais le problème est que ça a l'air plutôt brutal et interrompt l'expérience.
J'ai fait des heures de recherche à ce sujet, essayé toutes sortes de shaders, mélange pixel par pixel, et tout le reste en vain. Le mélange pixel par pixel en C # s'est avéré être un peu intensif en processus à mon goût, bien que je travaille toujours à le nettoyer et à le faire fonctionner plus facilement. Les shaders avaient l'air prometteurs, mais je n'ai pas pu trouver un shader capable de mélanger correctement deux lightmaps.
Quelqu'un at-il des pistes sur la façon dont je pourrais y parvenir? J'ai juste besoin d'une sorte de transition en douceur entre mon lightmap diurne et nocturne. Peut-être que je pourrais superposer les deux textures et utiliser un canal alpha? Ou quelque chose comme ça?
Graphics.Blit()
pour le rendre? Je n'ai jamais fait ça, mais en regardant dans le manuel, ça devrait marcher.Réponses:
J'ai donc récemment essayé cela et j'ai rencontré beaucoup des mêmes problèmes que vous. La solution de texture de rendu est un peu un hareng rouge. J'ai pu le résoudre en utilisant la manipulation de pixels multithreads sur un thread séparé.
https://www.youtube.com/watch?v=T_zpFk1mdCI
Donc, normalement, on utilise
graphics.blit()
et transmet la texture de rendu là où elle doit aller, mais les données lightmap ne prennent pas en charge les textures, elles nécessitent texture2ds. La prochaine étape logique serait de copier les données dans un texture2d, puis de les alimenter dans les données lightmap. Cette technique ruine les fréquences d'images car elle bloque le GPU pour envoyer des données au CPU, plutôt qu'une simple référence aux données.La solution est alors de ne pas utiliser le GPU.
Les transitions de la carte de lumière se produisent sur une longue période de temps, il n'est donc pas nécessairement important de mettre à jour la carte de lumière à chaque image. En fait, les joueurs ne remarqueraient probablement pas si les cartes lumineuses n'étaient mises à jour que toutes les 20 à 40 minutes en temps de jeu.
Donc, ce que vous faites, vous lancez la tâche vers le CPU sur des threads séparés pour chaque carte de lumière.
Ordinairement, Unity ne prend pas en charge le multithreading. Mais ça va, C # le fait. Ce gars fait un travail phénoménal pour expliquer le multithreading dans Unity, donc si vous n'en avez jamais entendu parler, ou si vous n'avez jamais su comment multithread dans Unity, voici la vidéo:
https://www.youtube.com/watch?v=ja63QO1Imck
Tout ce que vous devez faire est de créer une classe de threads de travail qui varie les copies des données de pixels du plan optique dans les tableaux de couleurs, puis de créer une fonction de fusion.
Un simple lerp d'une couleur à l'autre fera l'affaire.
Créez ensuite le fil, démarrez-le, et lorsque toutes les lightmaps sont terminées dans les threads séparés, vous pouvez recopier les données de pixels dans la texture de données lightmap2d.
J'ai posté un exemple de code ci-dessous. Ce n'est certainement pas la version entièrement implémentée, mais elle vous montre les principaux concepts de création de la classe, de création du thread, puis de définition des données de lumière.
Les autres choses que vous devriez faire sont d'appeler une fonction de temps en temps pour déclencher la mise à jour des lightmaps. Vous devez également copier toutes les données de pixels dans la classe de travail au démarrage ou au moment de la compilation. Bonne chance à tous ceux qui trouveront ça. Je suppose que l'op a changé sa vie, mais je sais que d'autres personnes ayant des problèmes similaires pourraient tomber dessus.
la source
Il existe un shader skybox qui se fond entre deux ensembles de textures skybox. Pensez au cycle jour et nuit!
Si vous souhaitez créer ou animer la skybox à partir d'un script, utilisez
skyboxmaterial.SetFloat("_Blend", yourBlend)
pour modifier le mélange; peut également utiliserSetTexture
des fonctions matérielles pour configurer ou modifier les textures.Tutoriel vidéo sur le cycle jour / nuit: http://www.youtube.com/watch?v=FTfv9JhkmIA
L'exemple de code se présente comme suit:
la source
Si vous savez comment changer, pourquoi ne pas continuer à créer un certain nombre de lightmaps de transition sur le thread d'arrière-plan, puis activer les transitions lorsque les lightmaps sont prêtes?
Vous pouvez également consulter un actif intéressant sur AssetStore: https://www.assetstore.unity3d.com/en/#!/content/5674
Je suppose que cela inclut le mélange des lightmaps, bien que je ne sache pas comment.
la source