Développement et info sur l'avancée des projets par les développeurs

Alpha-Arts » Blog » Alpha Arts

Alpha Arts
1
Comme promis, voici la suite de mon article sur mon moteur d'éclairage 2.5D (si vous n'avez pas lu la partie une, c'est par ici).

On va voir aujourd'hui pour développer un zbuffer permettant de définir l'ordre d'affichage des pixels de nos sprites 3D afin de pouvoir les afficher dans l'ordre qu'on veut et de les faire s'intersecter en 3D.



On va[...]
Comme promis, voici la suite de mon article sur mon moteur d'éclairage 2.5D (si vous n'avez pas lu la partie une, c'est par ici).

On va voir aujourd'hui pour développer un zbuffer permettant de définir l'ordre d'affichage des pixels de nos sprites 3D afin de pouvoir les afficher dans l'ordre qu'on veut et de les faire s'intersecter en 3D.

http://www.holyspirit.fr/Autres/pixel_lighting/demo_zbuffer_2.png

On va utiliser la heightmap du sprite 3D pour connaitre la hauteur du pixel. Un pixel plus haut sera forcément plus proche de la caméra qu'un plus bas. Si vous ne me croyez pas, regardez ce shéma qui devrait vous en convaincre :

http://www.holyspirit.fr/Autres/pixel_lighting/shema2.jpg
P1 et P2 représentent le même pixel à l'écran, mais P2 est plus haut et donc plus proche de la caméra. Dès lors c'est P2 qui sera affiché et non P1.

Il nous suffira donc d'afficher le pixel uniquement si sa heightmap est plus clair que celui précédent. Pour ce faire, on travaillera avec deux écrans de rendus, l'un principal que l'utilisateur verra et l'autre permettant de stocker la hauteur des pixels dessinés à l'écran pour le moment, ainsi que leur niveau d'opacité (j'y reviendrai plus loin, c'est pour la gestion du blending et de l’anticrénelage).

Pour mettre tout ça en place, j'ai codé deux shaders, un qui est notre normal shader du précédent article auquel je rajoute une gestion de la profondeur. En gros je n'affiche le pixel que si sa heightmap est plus clair que l'actuel affiché à l'écran. L'autre shader permet de mettre à jour la heighmap, je dessine donc la heightmap de mon sprite avec ce shader sur l'écran virtuel contenant la heightmap actuelle de l'écran.

J'utilise uniquement la composante bleue des pixels pour stocker la hauteur de ceux-ci.


Voici le code de mon shader de heightmap :

uniform sampler2D diffuse;
uniform sampler2D heightmap;
uniform sampler2D heightmap_screen;
uniform vec2 screen_ratio;
uniform float height_factor;
uniform float z_pos;

void main()
{			
	gl_FragColor =  gl_Color * texture2D(heightmap, gl_TexCoord[0].xy);
	gl_FragColor[3] = 1.0;
	
	if( texture2D(heightmap, gl_TexCoord[0].xy)[3] > 0.2)
		gl_FragColor[2] /= texture2D(heightmap, gl_TexCoord[0].xy)[3];
	
	gl_FragColor[2] *=  height_factor/500.0;
	
	gl_FragColor[2] += z_pos/500.0;
	
	gl_FragColor[0] = texture2D(diffuse, gl_TexCoord[0].xy)[3];
	
	vec4 screen_color = texture2D(heightmap_screen, gl_FragCoord.xy*screen_ratio);
	
	if(gl_FragColor[2] <= screen_color[2])
	{
		gl_FragColor[2] = screen_color[2];
		gl_FragColor[0] = screen_color[0]
	}
}



Les trois textures passées en paramètre sont :
  • Diffuse : la color-map du sprite, permettant de récupérer le niveau d'opacité du pixel pour la gestion du blending.
  • Heightmap : la heightmap du sprite, permettant donc de récupérer la hauteur des pixels du sprite.
  • Heightmap-screen : la hauteur des pixels affichés à l'écran actuellement.


Je passe en outre comme paramètre screen_ratio, permettant d'inverser la normalisation de la position de mes pixels à l'écran afin de récupérer la couleur du pixel correspondant à l'écran via un : gl_FragCoord.xy*screen_ratio.

Enfin, les deux derniers paramètres me permettent de définir la position en z du sprite 3D (décalant vers le bleu plus clair la couleur des pixels de la heightmap) et son facteur de hauteur. Comme dans l'article précédent.

Au niveau du code, je mets à jour la composante bleu et rouge de l'écran uniquement si le nouveau pixel est plus bleu et donc plus haut. La composante rouge me permet de stocker l'opacité du pixel afin de gérer le blending par après dans le shader qui affiche le sprite à l'écran.

Remarquez le : "if( texture2D(heightmap, gl_TexCoord[0].xy)[3] > 0.2)
gl_FragColor[2] /= texture2D(heightmap, gl_TexCoord[0].xy)[3];"
C'est juste une petite correction du au fait que les logiciels 3D, quand ils font un rendu avec anticrénelage, affichent des pixels plus sombres en plus de plus transparents sur les côtés. Dès lors on divise par la transparence du pixel pour ré-obtenir la couleur d'origine et donc la hauteur d'origine. Mais on ne fait cela que pour des pixels avec un minimum de transparence (ici 1/5).


Attaquons nous justement à ce shader-ci maintenant !

Premier changement, pour définir la hauteur du pixel :
v.z += texture2D(heightmap, gl_TexCoord[0].xy)[2] * height_factor;

est devenu
if( texture2D(heightmap, gl_TexCoord[0].xy)[3] > 0.2)
	v.z += texture2D(heightmap, gl_TexCoord[0].xy)[2] * height_factor  / texture2D(heightmap, gl_TexCoord[0].xy)[3];
else
	v.z += texture2D(heightmap, gl_TexCoord[0].xy)[2] * height_factor;


C'est exactement comme on a fait juste au dessus.

Ensuite, si jamais le pixel du sprite est en dessous du pixel déjà affiché, on récupère l'opacité du pixel déjà affiché :
if(v.z/500.0 < texture2D(heightmap_screen, vec2(gl_FragCoord.xy*screen_ratio)).b)
	alpha_old = texture2D(heightmap_screen, vec2(gl_FragCoord.xy*screen_ratio)).r;


Avant de faire quoi que ce soit, on ajoute juste une petite condition : si l'opacité du pixel précédent est de 1, ça sert à rien d'afficher quoi que ce soit et des faire des calculs, donc on retourne un pixel transparent.

Ensuite on a tous nos calcul pour connaitre l'illumination et la couleur du pixel qu'on stocke dans un vec4 color.

Sauf que maintenant, avant de la retourner dans gl_FragColor, on ajoute une petite étape :
if(alpha_old != 0.0)
{
	color *= a * min(1.0,max(0.0,1.0 - alpha_old));
	color += texture2D(screen, vec2(gl_FragCoord*screen_ratio)) * alpha_old;
	color /= alpha_old + a * min(1.0,max(0.0,1.0 - alpha_old));
	color.a = alpha_old + a * min(1.0,max(0.0,1.0 - alpha_old));
}
else
	color.a = gl_Color.a * texture2D(diffuse, gl_TexCoord[0].xy).a;


Si l'opacité du pixel précédent est plus grande que 0 et s'il est au dessus (s'il était en dessous on aurait considéré qu'il avait une opacité de 0), alors on doit mixer les deux pixels, sinon on l'affiche avec sa transparence normale.
Pour mixer les pixels, on utilise la formule de mixage habituelle, celle de l'algorithme du peintre (plus d'infos ici) :
color_final = (color_a * alpha_a + color_b * alpha_b / (1 - alpha_a))/(alpha_a + alpha_b / (1 - alpha_a))

Où a est le pixel du dessus et b le pixel du dessous.

On sait que l'écran actuelle (écran des heightmap passé en paramètre sous le nom screen) contient déjà color_a et color contient color_b , on doit donc juste multiplié color par alpha_b * (1-alpha_a) et lui ajouter le pixel actuel de l'écran * alpha_old. On divise après le tout par l'alpha total afin d'obtenir le pixel final.

Et voilà ! On a notre z-buffer !

Revoici un aperçu de la bête (cliquez pour agrandir) :

http://www.holyspirit.fr/Autres/pixel_lighting/demo_zbuffer_2.png

Où on affiche d'abord l'arbre, puis une abbaye, puis l'herbe, puis l'autre abbaye. Chacune des abbaye est, bien évidemment, un seul sprite 3D.
Vous pouvez aussi remarquer les ombres qui feront l'objet d'un prochain billet.

C'est toujours la même adresse pour tester : ShadersTest_demo.rar

Par Gregouar - 08/04/2012

Ce weekend et début de semaine, nous avons travaillé sur un événement dans les catacombes.
Au moment où le joueur veut récupérer un objet de quête important, Johannes le Déchu apparait pour la lui prendre. Il s'enfuit alors avec et le joueur doit le poursuivre à travers les catacombes.

Abbé Hademar, de l'Abbaye de Saint Clodomir à propos de Hergahrt et Johannes :
Ce weekend et début de semaine, nous avons travaillé sur un événement dans les catacombes.
Au moment où le joueur veut récupérer un objet de quête important, Johannes le Déchu apparait pour la lui prendre. Il s'enfuit alors avec et le joueur doit le poursuivre à travers les catacombes.

Abbé Hademar, de l'Abbaye de Saint Clodomir à propos de Hergahrt et Johannes
Avec un prêtre d'une paroisse voisine nommé Johannes ils passaient leur temps à boire et à rire publiquement du fruit des confessions qu'ils recevaient. Sans parler de tout ce qu'on a pu entendre sur leurs écarts avec les femmes...


Le boucle de jeu se passe ainsi :
-Le joueur approche
-L'ennemi se téléporte dans une salle voisine
-Le joueur approche
-L'ennemi se téléporte derrière une barricade en invoquant des squelettes, narguant le joueur.
-...
-L'ennemi arrive dans un cul de sac et le joueur doit lui latter la face.

Ce moment de jeu comporte pas mal de problématiques :
-Comment forcer le joueur à poursuivre l'ennemi ?
-Comment l'empêcher de s'enfuir ?
-Que faire si le joueur meurt (il réapparait à la dernière potale activée...)
-Que faire s'il quitte le jeu ?

Nous avons décidé de faire sortir des os du sol, créant des barricades infranchissables afin d'empêcher le joueur d'aller visiter des salles annexes.
En outre, à chaque fois que le joueur entre dans une salle, des piques sortent du sol l'empêchant de s'enfuir et le forçant à se battre contre les méchants vilains.

Pour la mort et quand on quitte le jeu, après pas mal de réflexion, nous avons décidé que cela remet la quête à zéro, le joueur doit alors recommencer la course-poursuite entièrement.

Histoire de ne pas mettre que du blabla, voilà quand même quelques images.

Dans l'éditeur, préparation des salles qui où les squelettes seront invoqué.
http://img38.imageshack.us/img38/8536/editeur.png

La même salle en jeu :
http://img703.imageshack.us/img703/8989/screenshot2xe.png

Le combat contre Johannes :
http://img6.imageshack.us/img6/3166/screenshot5on.png

Par Gregouar - 22/03/2011

Alpha Arts
0
Il y a encore quelques années ce type de "site web" était prolifique, chez les adolescents en particulier. Qui n'as pas un copain, ou mieux une connaissance, avec un SkyBlog ?!
Outre cet aspect, les blogs restent de très bons outils de communication, notamment lors de la création d'un projet, ces derniers permettant de suivre très facilement l'avancement du dit projet. Pour[...]
Il y a encore quelques années ce type de "site web" était prolifique, chez les adolescents en particulier. Qui n'as pas un copain, ou mieux une connaissance, avec un SkyBlog ?!
Outre cet aspect, les blogs restent de très bons outils de communication, notamment lors de la création d'un projet, ces derniers permettant de suivre très facilement l'avancement du dit projet. Pour ma part, j'ai les Flux RSS de beaucoup de blogs dont Durian, le prochain court métrage de la Blender Fondation, 3D Ressources, un blog qui diffuse des objets 3D, ou encore un autre site qui traite lui d'actualité via des dessins "patates", à savoir l'excellent blog de Martin Vidberg : L'actu Patate.

Bref la "blogosphère" est aujourd'hui très remplie, il existe d'ailleurs de très grosses plateformes gratuites telles que Wordpress ou encore Dotclear qui sont les très gros monstres en la matière. On peut même citer Twitter qui reste une plateforme de microblogging, un dérivé de cette grande famille !

http://killpatate.site.free.fr/blog/zenphoto/cache/logo__Dotclear.png_w100_h100_cw73_ch73_cx0_cy0_thumb.png http://killpatate.site.free.fr/blog/zenphoto/cache/logo__Wordpress.jpg_w100_h100_cw480_ch480_cx0_cy0_thumb.jpg http://killpatate.site.free.fr/blog/zenphoto/cache/logo__Twitter.jpg_w100_h100_cw268_ch268_cx1_cy0_thumb.jpg
Logo des différentes plateformes de blogs : Dotclear - Wordpress - Twitter





L'équipe Alpha Arts ouvre donc son espace blog afin de mieux communiquer vers l'extérieur, notamment pour pouvoir parler plus facilement du développement de nos projets - entre autres Holyspirit - mais aussi pour aborder des thématiques liées au développement ou encore échanger des astuces utilisées sous nos logiciels préférés.

Prochainement quelque rubrique devrait voir le jour, dont entre autre "Tips", rubrique mensuel donnant des astuces sur nos logiciels ; quelques WIP dédié à la création numérique de nos ressources pour Holyspirit, ou tout simplement des articles pour approfondir le gameplay... en sommes beaucoup de chose à écrire !

http://killpatate.site.free.fr/blog/zenphoto/cache/bordel__ScanTripsAlpha-Reflexion.jpg_595.jpg


Toute l'équipe tiens donc à remercier Schnafon pour son travail accompli sur le site web, et ce malgré le nombre incroyable de coups de fouet reçu de lignes de code à gérer ! Bien évidement, la peinture est encore toute fraîche, il devrait néanmoins ne plus avoir de bug. De plus, nous ferons de notre mieux pour mettre en place toute les fonctions manquantes.

Bonne visite !

Par stilobique - 30/05/2010