À la recherche d'ombres prometteuses pour roguelike



Chers Khabrovchans, je présente à votre attention la poursuite des recherches sur le thème de la recherche d'ombres appropriées pour un bagel 2D.

Ce billet est une suite de la publication , une sorte de travail sur les erreurs et le développement de l'idée.

Dans leurs commentaires, des critiques respectés ont noté à juste titre que dans les espaces clos, les ombres se sont révélées anguleuses et quelque peu contre nature. Plusieurs solutions ont été proposées, j'ai aimé la proposition d'utiliser le lancer de rayons pour calculer l'ombre.



Je précise, je ne travaille pas avec la carte vidéo (je ne travaille pas encore), tous les résultats sont modélisés sur le CPU.

Dans ce travail sur le reykasting, nous comprenons la méthode de construction d'une image en projetant des rayons d'un observateur dans l'espace jusqu'à ce qu'il croise un obstacle (limites de l'écran) et met en évidence le lieu de leur collision.

Ici, nous utiliserons une version simplifiée du rakecasting basée sur l'intersection d'une tuile avec un rayon. Cette méthode a été largement utilisée dans les jeux pseudo-tridimensionnels du passé (par exemple, Wolfenstein_3D , par rapport à ceux qui sont dans le sujet), nous l'adaptons pour un espace bidimensionnel.



L'algorithme est assez simple pour la compréhension et la réalisation. J'apporterai ma propre implémentation:

Pascal
// i,j -  ,  -  // X,Y -    // r -     //   if cos(a)<0 then begin di :=-1; ddi:= 0; end else begin di := 1; ddi:= 1; end; if sin(a)<0 then begin dj :=-1; ddj:= 0; end else begin dj := 1; ddj:= 1; end; //        Y x1 := (i+ddi) * tile_size; y1 := y+ (x1-x) * tan(a); Dx := len(x,y,x1,y1); y1 := (j+ddj) * tile_size; x1 := x+ (y1-y) * cotan(a); Dy := len(x,y,x1,y1); sum_lenX := 0; sum_lenY := 0; //    X  Y   a rX := abs(tile_size / cos(a)); rY := abs(tile_size / sin(a)); //    repeat if sum_lenX+DX < sum_lenY+DY then begin x1 := (i+ddi) * tile_size; y1 := y+ (x1-x) * tan(a); i := i+di; //         key := is_wall(i,j); sum_lenX := sum_lenX + DX; if DX<>rX then DX:=rX; //       if r<sum_lenX then Break; end else begin y1 := (j+ddj) * tile_size; x1 := x+ (y1-y) * cotan(a); j := j+dj; //         key := is_wall(i,j); sum_lenY := sum_lenY + DY; if DY<>rY then DY:=rY; //       if r<sum_lenY then Break; end; until (      ); // x1,y1   

Étant donné que la poutre traverse les cellules sur chaque axe à la même distance, vous pouvez économiser sur les calculs et vérifier uniquement s'il y a des murs dans la tuile. Nous avons besoin d'une intersection avec un obstacle et rappelons-nous ses coordonnées.

Dans mon implémentation, j'ai mis toutes les trigonométrie et divisions dans un tableau séparé pour chaque angle, ce qui a considérablement accéléré l'algorithme.

Après avoir lancé les rayons dans toutes les directions avec l'étape souhaitée, nous obtenons approximativement l'image suivante:



Augmenter le nombre de rayons à plusieurs milliers et obtenir le polyèdre souhaité de la lunette. Il est bien sûr possible de projeter des rayons pour chaque pixel de l'image, comme sur les accélérateurs 3D, mais vous ne pouvez pas vous passer d'une carte vidéo ici.



Le travail avec les couches commence.

Portée Par la suite, les rayons passent un peu dans les profondeurs des objets. Une telle convention de jeu crée un environnement unique caractéristique des jeux 2D.



Génération de cartes d'éclairage. Nous générons à l'avance des sources de lumière statiques et des caches pour améliorer les performances, nous appliquons des sources dynamiques en cours d'affichage à l'écran.



Tout rassembler. Il ne manque que de terribles monstres et trésors ... de nombreux trésors.



Les murs avec une courbure variable de la pénétration de la lumière ne me sont pas allés, mais c'est peut-être un amateur.



Dans le processus de création du prototype, j'ai essayé de nombreuses variantes du modèle, certaines d'entre elles sont mieux adaptées à l' horreur :



J'ai particulièrement aimé l'effet de multiples réflexions de rayons sur les murs, mais même sa mise en œuvre naïve était si lente que je l'ai laissé pour l'avenir lorsque je suis devenu ami avec la carte vidéo.

Merci de votre attention.

Lien pour jouer (exe pour windows)

Partie 1 , partie 3

Source: https://habr.com/ru/post/fr431304/


All Articles