Comment obtenir une lumière qui change de couleur à mi-chemin?

11

J'ai pensé à créer des sources de lumière et des fenêtres colorées. Maintenant, les fenêtres sont semi-transparentes. Comment pourrais-je faire en sorte que lorsque la lumière (par exemple, un blanc pur) frappe le verre et continue à travers, mais change la couleur pour la même couleur que le verre qu'elle a traversé?

Je sais que l'effet décrit ici peut être truqué en utilisant des lumières de zone sur le côté "coloré" de la fenêtre, mais que se passe-t-il si je voulais juste avoir une lumière ponctuelle blanche?

manabreak
la source
Au lieu de changer la couleur de la lumière, pourriez-vous changer la couleur de base des objets illuminés de l'autre côté du verre? peut-être que ça ferait l'affaire?
HumanCatfood
La fenêtre transparente est rendue comme un deuxième passage, son ombrage modifie simplement l'équilibre des couleurs de chaque sortie de pixel. Cela ne fonctionnerait-il pas?
Patrick Hughes
Il me semble que cela est analogue au problème des ombres; si vous avez un bon algorithme pour les ombres projetées par des objets semi-transparents (je ne sais pas si c'est pratique), alors il vous suffit de l'exécuter pour trois canaux de couleurs parallèles.
Kevin Reid

Réponses:

14

Il existe un grand nombre de façons de procéder. Ceux-ci nécessiteront l'utilisation d'un shader et je suppose que vous faites déjà un éclairage par pixel. Voici quelques suggestions, mais trouver la technique qui vous convient peut nécessiter beaucoup plus de recherches.

Rapide et sale

Vous pouvez spécifier des boîtes englobantes qui définissent les zones intérieures. Si la lumière est en dehors des boîtes, mais que la géométrie (qui n'est pas dans l'ombre) est à l'intérieur de la boîte, alors la lumière doit avoir été affectée en passant par une fenêtre (ceci est également vrai si la géométrie est en dehors de la boîte et la lumière Est à l'intérieur). Le seul problème ici est de savoir comment transmettre les informations de la boîte au shader et comment exprimer l'effet sur la lumière.

Une autre option consiste à spécifier les fenêtres comme des objets se trouvant sur des plans. Testez d'abord pour voir si la géométrie et la lumière se trouvent sur les côtés opposés du plan, puis si le chemin entre eux coupe le plan en un point situé dans les limites de la fenêtre. Ce serait plus précis que la première méthode et il serait plus facile d'avoir des fenêtres dans les mêmes intérieurs avec différentes couleurs de verre.

Continuez à être plus détaillé avec la représentation géométrique des fenêtres et vous obtiendrez des résultats plus précis, mais le calcul deviendra également plus lourd.

Ces techniques fonctionneraient assez bien pour un tireur de couloir, mais pas aussi bien pour un monde dynamique ou ouvert car beaucoup de réglages seraient probablement nécessaires pour qu'il soit correct sans trop d'artefacts. De plus, ces techniques pourraient rapidement devenir un peu intenses, il serait donc conseillé de passer à un pipeline d'ombrage différé.

Cartes fantômes

Une autre option consiste à faire quelque chose de similaire au mappage d'ombres.

Dans la cartographie des ombres, vous générez une image bitmap du monde affecté par une lumière. Chaque pixel, bien que toujours une couleur, est en fait la distance de la pièce de géométrie non transparente la plus proche (vous utilisez les quatre octets pour 1 flottant au lieu de 4 couleurs). Si vous calculez la distance de la lumière à un morceau de géométrie et qu'elle est supérieure à la valeur correspondante dans la map d'ombre, alors votre morceau de géométrie est dans l'ombre (vous utilisez généralement le rayon entre la géométrie et la lumière pour indexer la map).

Si vous appliquez cette idée à votre problème, ce que vous feriez serait de stocker une carte de la distance de la lumière de la pièce de géométrie transparente la plus proche, puis de créer une deuxième carte de la couleur de la lumière après avoir traversé cette géométrie ( simplement la couleur de la géométrie si la lumière est blanche).

Si votre morceau de géométrie est plus éloigné que la distance sur cette carte, utilisez la couleur de la carte, sinon, utilisez la couleur claire d'origine.

La fonction de calcul de la couleur pour chaque pixel de la carte devrait être grossièrement; lightColor - inverséWindowColor. Donc, pour une lumière blanche pure et une fenêtre rouge pure qui n'absorbe aucun du spectre rouge que nous obtenons; (255.255.255) - (0,255.255) = (255,0,0). La couleur de la lumière de l'autre côté est donc du rouge pur. Pour un objet transparent plus complexe, tel qu'un vitrail, vous souhaiterez peut-être avoir une recherche de texture pour obtenir la couleur du matériau.

Si vous recherchez quelque chose de similaire, consultez les cartes d'ombres réfléchissantes .

Cette technique offre une grande fidélité et serait probablement la meilleure si vous souhaitez utiliser une géométrie transparente complexe telle que des vitraux.

Tenter une solution générale

Il est récemment devenu populaire de coder les informations d'éclairage dans une représentation voxel (elles ne sont pas uniquement destinées à la géométrie). Le dernier moteur crytek utilise ce type de stratagie pour un éclairage avancé ( volumes de propagation de la lumière ).

Voici l'idée générale:

  • Créez une carte de cubes régulièrement espacés qui englobe votre scène (pensez à utiliser des courbes d'ordre z ).
  • Trouvez un moyen de stocker les informations d'éclairage incident pour chaque voxel (les représentations harmoniques sphériques sont utiles ici).
  • Trouvez le voxel contenant une lumière et représentez cette lumière dans le voxel.
    • Propager la lumière vers l'extérieur à travers les voxels adjacents (un peu comme l'eau minecraft)
    • Calculer comment la géométrie de chaque voxel affectera la lumière qui le traverse (absorber, réfléchir, transmettre)
    • répéter jusqu'à ce que la lumière s'estompe

Il existe de nombreuses façons de créer ces informations de voxel, mais la liste ci-dessus donne une idée générale. Par exemple; vous pouvez commencer par générer des cartes / volumes d'ombre, puis projeter ces informations dans la carte voxel afin de créer rapidement la carte de l'éclairage direct. Ensuite, vous démarrez la propagation à partir des voxels le long du bord de la zone affectée. Gardez dans le mien que, dans ce cas, vous voudrez ignorer si la géométrie est transparente ou non lors de la génération de l'ombre / du volume.

Dans la dernière passe d'un rendu différé, lors du calcul de l'illumination d'un point de géométrie, vous utilisez simplement la position de la géométrie pour indexer votre carte de voxels pour découvrir à quoi ressemble l'éclairage incident à ce point de l'espace. Ensuite, vous pouvez créer une carte d'écran du côté du processeur d'éclairage incident, ou éventuellement le faire avec cuda.

OriginalDaemon
la source
Merci pour le long post! J'étudie actuellement si je ferai un rendu avant ou différé pour le projet actuel sur lequel je travaille. Pour le moment, cela va probablement être reporté. Comment feriez-vous lorsque la fenêtre est multicolore (disons, un vitrail dans une église)?
manabreak
@manabreak - J'utiliserais l'extension de la carte d'ombre car elle offrirait le meilleur niveau de fidélité pour ce cas. Je vais modifier le message pour expliquer cela.
OriginalDaemon
Hé Merci! Ce poste a vraiment fait ma journée, je n'ai probablement jamais vu autant d'efforts consacrés à un seul poste.
manabreak