Je suis en train d'implémenter la diffusion atmosphérique d'une planète depuis l'espace. J'ai utilisé les shaders de Sean O'Neil de http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html comme point de départ.
J'ai à peu près le même problème lié à fCameraAngle sauf avec le shader SkyFromSpace par opposition au shader GroundFromSpace comme ici: http://www.gamedev.net/topic/621187-sean-oneils-atmospheric-scattering/
Je reçois des artefacts étranges avec le ciel du shader spatial lorsque je ne les utilise pas fCameraAngle = 1
dans la boucle intérieure. Quelle est la cause de ces artefacts? Les artefacts disparaissent lorsque fCameraAngle est limité à 1. Il me semble également ne pas avoir la teinte présente dans le bac à sable d'O'Neil ( http://sponeil.net/downloads.htm )
Position de la caméra X = 0, Y = 0, Z = 500. GroundFromSpace à gauche, SkyFromSpace à droite.
Position de la caméra X = 500, Y = 500, Z = 500. GroundFromSpace à gauche, SkyFromSpace à droite.
J'ai trouvé que l'angle de la caméra semble être géré très différemment selon la source:
Dans les shaders d'origine, l'angle de la caméra dans SkyFromSpaceShader est calculé comme suit:
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
Alors que dans le sol depuis l'espace shader, l'angle de la caméra est calculé comme suit:
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);
Cependant, diverses sources en ligne bricolent avec la négation du rayon. Pourquoi est-ce?
Voici un projet C # Windows.Forms qui illustre le problème et que j'ai utilisé pour générer les images: https://github.com/ollipekka/AtmosphericScatteringTest/
Mise à jour: J'ai découvert grâce au projet ScatterCPU trouvé sur le site d'O'Neil que le rayon de la caméra est annulé lorsque la caméra est au-dessus du point ombré afin que la diffusion soit calculée d'un point à la caméra.
La modification de la direction des rayons supprime en effet les artefacts, mais introduit d'autres problèmes comme illustré ici:
De plus, dans le projet ScatterCPU, O'Neil protège contre les situations où la profondeur optique de la lumière est inférieure à zéro:
float fLightDepth = Scale(fLightAngle, fScaleDepth);
if (fLightDepth < float.Epsilon)
{
continue;
}
Comme souligné dans les commentaires, avec ces nouveaux artefacts, cela laisse toujours la question, qu'est-ce qui ne va pas avec les images où la caméra est positionnée à 500, 500, 500? On dirait que le halo est concentré sur une partie complètement mauvaise de la planète. On pourrait s'attendre à ce que la lumière soit plus proche de l'endroit où le soleil devrait frapper la planète, plutôt que de l'endroit où elle change du jour à la nuit.
Le projet github a été mis à jour pour refléter les changements dans cette mise à jour.
la source
Réponses:
Je n'ai pas de code de travail en ce moment, car je fais la transition de mon moteur mais ce sont mes réglages de paramètres de travail:
C'était le shader:
Faites-moi savoir si cela fonctionne toujours. Si vous avez besoin d'aide, je vais essayer de fouiller mon code. Je pense que j'ai utilisé deux sphères pour faire le rendu: une pour la surface et une pour l'atmosphère.
la source
quelques pistes de réflexion: vérifiez la précision de vos flotteurs. aux échelles spatiales, la plupart du temps, float32 ne suffit pas. Vérifiez le tampon dpeth si vous avez un rendu primitif, comme une sphère sous votre shader de diffusion.
Ces artefacts peuvent également être trouvés dans le lancer de rayons, ce sont généralement des rayons secondaires qui se croisent avec la surface primaire tremblant à cause de problèmes de précision du flotteur.
EDIT: à 1000 (tous les entiers sont entièrement représentables jusqu'à 16 millions en représentation float32, grâce à la mantisse 24 bits), le nombre suivant pour un float32 est 1000.00006103, donc votre précision est toujours assez bonne dans cette plage.
cependant, si vous utilisiez des gammes de mètres, voir une planète à cette distance signifierait des valeurs de 100 000 000 et la suivante est de 100000008: 8 mètres de précision à 100 000 km.
cela provoquerait des sauts de caméra si vous essayiez de vous déplacer sur un satellite par exemple, et le rendu du satellite lui-même serait tout cassé si le zéro de votre monde était le centre de la planète. si c'est le centre du système stellaire, c'est encore pire.
recherchez flavien brebion (Ysaneya) et le jeu infinity quest for earth. Il a un journal de développement intéressant de gamedev et son forum où il explique comment les distances du système stellaire sont impossibles à gérer en utilisant des absolus.
Il mentionne également le problème du tampon de profondeur dans ce type de plages et est l'un des premiers, sinon le premier, à introduire des échelles z logarithmiques. http://www.gamedev.net/blog/73/entry-2006307-tip-of-the-day-logarithmic-zbuffer-artifacts-fix/ un beaucoup plus complet ici: http://outerra.blogspot.jp/ 2012/11 / maximizing-depth-buffer-range-and.html
Banc d'essai logiciel: bonne idée, c'est un excellent moyen de créer des shaders afin que vous puissiez déboguer ce qui se passe pas à pas. vérifiez simplement vos valeurs ligne par ligne, et si quelque chose vous semble bizarre, vous pouvez enquêter. Je n'ai pas vu dans le code que vous avez publié la partie où l'angle de la caméra est utilisé dans le shader, donc je suis un peu perplexe à propos de cette partie.
la source