J'ai été de travailler sur la zone d'éclairage de mise en œuvre de WebGL similaire à cette démo:
http://threejs.org/examples/webgldeferred_arealights.html
Ci-dessus la mise en œuvre de three.js a été porté à partir du travail de ArKano22 plus sur gamedev.net:
http://www.gamedev.net/topic/552315-glsl-area-light-implementation/
Bien que ces solutions sont très impressionnants, ils ont tous les deux un peu de limitations. Le principal problème avec ArKano22 origine de la mise en œuvre est que le calcul de la diffus terme ne prend pas en compte les normales de la surface.
J'ai été augmentant cette solution pour quelques semaines maintenant, en travaillant avec les améliorations apportées par redPlant pour remédier à ce problème. Actuellement, j'ai la normale calculs intégrés dans la solution, MAIS le résultat est aussi défectueuse.
Voici un petit aperçu de mon actuel de mise en œuvre:
Introduction
Les étapes de calcul de la diffus terme pour chaque fragment est comme suit:
- Projet le sommet sur le plan de l'éclairage de l'espace de siège, de sorte que la projection du vecteur coïncide avec la lumière normale/direction.
- Vérifiez que le sommet est sur le bon côté de l'éclairage de l'espace de l'avion par la comparaison de la projection du vecteur avec la lumière normale.
- Calculer la 2D décalage de ce point projeté sur le plan de la lumière du centre/de position.
- Pince 2D décalage vecteur de sorte qu'il se trouve à l'intérieur de la lumière de la zone (définie par sa largeur et sa hauteur).
- Tirer le monde de la 3D de la position de la projection et serré 2D point. C'est le point le plus proche sur la zone de lumière vers le sommet.
- Effectuer l'habitude diffuse les calculs que vous le feriez pour un point de lumière en prenant le produit scalaire entre le sommet-de-plus-proche-point du vecteur (normalisé) et le sommet de la normale.
Problème
Le problème avec cette solution est que l'éclairage calculs sont effectués à partir du point le plus proche et ne tiennent pas compte d'autres points sur les lumières de la surface qui pourrait être éclairant le fragment d'autant plus. Permettez-moi d'essayer d'expliquer pourquoi...
Considérons le schéma suivant:
La zone de lumière est à la fois perpendiculaire à la surface et croise. Chacun des fragments sur la surface toujours en revenir à un point plus proche sur la zone de lumière, lorsque la surface et la lumière se croisent. Depuis la normale à la surface et le sommet à la lumière des vecteurs sont toujours perpendiculaires, le produit scalaire entre eux est égal à zéro. Par la suite, le calcul de diffuser la contribution est égale à zéro malgré l'existence d'une vaste zone de lumière qui plane au-dessus de la surface.
Solution Potentielle
Je propose que, plutôt que de calculer la lumière à partir du point le plus proche sur la zone de lumière, nous calculons à partir d'un point sur la zone de la lumière qui donne le plus grand produit scalaire entre le vertex à la lumière de vecteur (normalisé) et le sommet de la normale. Dans le diagramme ci-dessus, ce serait le violet dot, plutôt que le point bleu.
À l'aide!
Et donc, c'est là que j'ai besoin de votre aide. Dans ma tête, j'ai une assez bonne idée de la façon dont ce point peut être dérivée, mais n'ont pas la compétence mathématique pour arriver à la solution.
Actuellement, j'ai les informations suivantes disponibles dans mon fragment shader:
- vertex position
- vertex normal (vecteur unitaire)
- la position de la lumière, de la largeur et de la hauteur
- la lumière normale (vecteur unitaire)
- la lumière (vecteur unitaire)
- la lumière (vecteur unitaire)
- projeté point à partir du sommet sur les lumières de l'avion (3D)
- projeté décalage du point de feux center (2D)
- serré offset (2D)
- mondiale de la position de cette serrées offset – le plus proche point (3D)
Pour mettre toutes ces informations dans un contexte visuel, j'ai créé ce schéma (j'espère que ça aide):
Pour tester ma proposition, j'ai besoin de la coulée point sur la zone de lumière représenté par les points rouges, afin que je puisse effectuer le produit scalaire entre le vertex-à-casting-point (normalisé) et le sommet de la normale. Là encore, le rendement maximum de la contribution possible de la valeur.
Mise à JOUR!!!
J'ai créé un interactif de dessin sur sur CodePen permettant de visualiser les mathématiques que j'ai actuellement mis en œuvre:
http://codepen.io/wagerfield/pen/ywqCp
Le relavent code que vous devez vous concentrer sur est ligne 318.
castingPoint.location
est une instance de l' THREE.Vector3
et est la pièce manquante du puzzle. Vous devez également remarquer qu'il y a 2 valeurs dans la partie inférieure gauche de l'esquisse – ces sont mis à jour dynamiquement pour afficher le produit scalaire entre les vecteurs.
J'imagine que la solution nécessiterait un autre pseudo avion qui s'aligne avec la direction de la normale de sommet ET qui est perpendiculaire à la lumière de l'avion, mais je peux me tromper!
De toute façon, j'espère que certains de compassion génie peut m'aider à résoudre ce!
Merci beaucoup d'avance :D