iOS - GLES 2.0: transparence et tri

Questions à propos du scripting Shader.
Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6186
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

iOS - GLES 2.0: transparence et tri

Message par boubouk50 » 12 Déc 2016 17:52

Bonjour,

Comme d'habitude, iOS ne me fait que des misères. Ici, il s'agit d'un shader de feu que j'ai bidouillé pour gérer un peu mieux les volumes qu'un billboard.
Je suis parti d'un shader gratuit du store par Aubergine: Fire Shader.
J'ai modifié le shader pour appliquer un fresnel et ainsi modifier l'opacité par rapport à l'angle de vision, ce qui a pour effet de toujours visualiser au maximum le plan de feu en face et d'avoir les plans vus de coté disparaître.
Voilà le bouzin:

Code : Tout sélectionner

Shader "Aubergine/Object/BaseFX/Fire" {
	Properties {
		_NoiseTex("Noise Texture", 2D) = "white" { }
		_FireTex("Fire Texture", 2D) = "white" { }
		_AlphaTex("Alpha Texture", 2D) = "white" { }
		_Speed1("Speed1", Float) = 0.68753
		_Speed2("Speed2", Float) = 0.52000
		_Speed3("Speed3", Float) = 0.75340
		_Perturb1("Perturb1", Float) = 0.12300
		_Perturb2("Perturb2", Float) = 0.09100
		_Perturb3("Perturb3", Float) = 0.07230
		_UvOffset("UvOffset", Float) = 0.44000
		_UvMulti("UvMulti", Float) = 0.29000
	}

	SubShader {
		Tags { "RenderType" = "Transparent" "Queue" = "Transparent" "IgnoreProjector" = "True" }
		LOD 100

		Pass {
			Name "BASE"
			Tags { "LightMode" = "Always" }

			Fog { Mode off }
			ZWrite On //Normalement ZWrite Off pour pas trier
			Cull Off
			Blend SrcAlpha OneMinusSrcAlpha

			CGPROGRAM
			#pragma exclude_renderers xbox360 ps3 flash	//Apparemment, certaines plateformes ne gèrent pas tout
			//#pragma only_renderers gles glcore d3d9 d3d11
			#pragma vertex vert
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest
			
			#include "UnityCG.cginc"

			sampler2D _NoiseTex, _FireTex, _AlphaTex;
			fixed _Speed1, _Speed2, _Speed3, _Perturb1, _Perturb2, _Perturb3;
			fixed _UvOffset, _UvMulti;

			struct a2v {
				float4 vertex : POSITION;
				float4 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};

			struct v2f {
				float4 pos : SV_POSITION;
				float4 uv0 : TEXCOORD0;
				float4 uv1 : TEXCOORD1;
				float fresnel : FLOAT;
				float4 viewDir : TEXCOORD2;
			};

			v2f vert(a2v v) {
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv0.xy = v.texcoord.xy;
				o.uv0.z = v.texcoord.x;
				o.uv0.w = -v.texcoord.y + _Speed1 * _Time.y;
				o.uv1.x = v.texcoord.x;
				o.uv1.y = -v.texcoord.y + _Speed2 * _Time.y;
				o.uv1.z = v.texcoord.x;
				o.uv1.w = -v.texcoord.y + _Speed3 * _Time.y;
				o.viewDir.xyz = normalize (ObjSpaceViewDir (v.vertex));
				o.fresnel = saturate (abs (dot (v.normal, normalize (o.viewDir.xyz))) + abs(o.viewDir.y)); //abs(o.viewDir.y) permet de ne pas inclure les faces que l'on voit du dessus et dessous dans le fresnel (donc dans la disparition en fonction de l'angle de vision)
				return o;
			}

			fixed4 frag(v2f i) : COLOR {
				fixed n0 = tex2D(_NoiseTex, i.uv0.zw).r * 2.0 - 1.0;
				fixed n1 = tex2D(_NoiseTex, i.uv1.xy).r * 2.0 - 1.0;
				fixed n2 = tex2D(_NoiseTex, i.uv1.zw).r * 2.0 - 1.0;
				fixed2 n = n0 * _Perturb1 + n1 * _Perturb2 + n2 * _Perturb3;
				fixed2 uv = i.uv0.xy + n * (i.uv0.y * _UvOffset + _UvMulti);
				fixed3 base = tex2D(_FireTex, uv).rgb;
				fixed alpha = tex2D(_AlphaTex, uv).r;
				return fixed4 (base.rgb, alpha * i.fresnel * i.fresnel);
				//return fixed4 (i.fresnel, i.fresnel, i.fresnel, 1);  //A utiliser pour tester la valeur de fresnel
			}
			ENDCG
		}
	}

	FallBack Off
}
Ce shader fonctionne très bien sous Android, mais déjante sous iOS, n'ont pas que les calculs sont différents, mais l'affichage.
En effet, les plans qui possèdent ce shader disparaissent pratiquement (alpha proche de 0) si d'autres objets sont transparents dans la scène. (Je vous fait des captures d'écran pour illustrer).

EDIT - Ah oui, chose importante, ce n'est pas une question d'algorithme. Le code du shader fonctionne très bien, ce seraient plutôt les conditions à déboguer. ZWrite Off/On, ne change rien. Mon iPad Air ne prends pas en compte OpenGLES 3.0 ni metal.

Quelqu'un a une idée d'où viendrait le problème?
Merci
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6186
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: iOS - GLES 2.0: transparence et tri

Message par boubouk50 » 12 Déc 2016 18:10

Les screenshots en question:
Image
On voit nettement que les plans du feu sont rendus mais ils sont quasi-transparents.
Sous iOS, des fois (1 fois par secondes à peu près) un plan est correctement rendu puis disparaît de nouveau. Comme s'il arrivait à décider pour une fois qu'un plan avait le droit d'être rendu.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Moi 1971
Messages : 727
Inscription : 29 Sep 2015 13:38

Re: iOS - GLES 2.0: transparence et tri

Message par Moi 1971 » 12 Déc 2016 18:37

J'y connais rien, mais juste une idée.. est-ce que le temps de calcul ne serait pas trop long sur IOS et le Shader n’aurait pas le temps "d’être calculé" avant le temps d'affichage? .. J'ai lu un truc de ce genre dans le learn avec le lien : https://unity3d.com/fr/learn/tutorials/ ... nity-games.. mais ça n'a peut-être rien à voir..

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6186
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: iOS - GLES 2.0: transparence et tri

Message par boubouk50 » 13 Déc 2016 10:49

Bon, ça viendrait du fresnel, pas du calcul en lui même, mais du résultat qui varie en fonction de la position dans le tri ou un truc du genre... Une image pour mieux illustrer le propos:
Image
Comme vous pouvez le voir sur l'image de droite, tous les plans, quelle que soit leur orientation, ont la même couleur de fresnel, comme s'ils étaient tous orientés pareils.
Sur l'image de gauche, le plan possède la bonne couleur de fresnel, ce qui n'arrive pas souvent...

EDIT - le tag "DisableBatching" = "True", a l'air de corriger ce problème. J'ai encore quelques soucis de tri, mais le feu ne disparaît plus.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

zugsoft
Messages : 386
Inscription : 26 Juin 2014 23:43
Localisation : Swiss
Contact :

Re: iOS - GLES 2.0: transparence et tri

Message par zugsoft » 14 Déc 2016 00:01

Les shaders c'est encore quelque chose que je n'ai jamais trop regardé, les shaders de base Mobile me suffisent en general, je bidouille parfois juste les existant, sans trop comprendre ce que je fais , je ne pourrai pas t'aider a ce sujet.

Penses juste a prendre quelques Nurofen si jamais :mrgreen:
Moon RTS

Avatar de l’utilisateur
F@B
Messages : 1844
Inscription : 01 Août 2013 10:41
Contact :

Re: iOS - GLES 2.0: transparence et tri

Message par F@B » 14 Déc 2016 00:49

une idée comme ça...

une erreur de précision d'un Half au lieu d'un float sur le calcul du fresnel ? du genre un DOT entre la direction de la lumière et la normale qui serait arrondi a 1?

je balance ça comme ça mais dur a dire sur le débug le shader,a priori c'est sur cette ligne et il y a bien un DOT..

Code : Tout sélectionner

            o.fresnel = saturate (abs (dot (v.normal, normalize (o.viewDir.xyz))) + abs(o.viewDir.y));  
si tu force une valeur constante sur le résultat du DOT t'as toujours le problème ? un 0.5 par exemple ?
pour débug tu force unity en GLES ? ou t'as le probleme qu'une fois compilé sur le téléphone ??

je vois dans ton edit que tu regle le problème avec "DisableBatching" ? ça expliquerais peut être qu'avrec le batch la normale n'est pas bonne et que ton DOT se retrouve a 1 ?

désolé de réagir en retard boubouk j'avais zappé ton sujet !
ʕ·͡ᴥ·ʔ ==> Mon Portfolio <== ʕ·͡ᴥ·ʔ

Merci de lire et de prendre en considération la Nétiquette des Forums avant de poster un sujet !

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6186
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: iOS - GLES 2.0: transparence et tri

Message par boubouk50 » 14 Déc 2016 10:19

Je force en OpenGLES 2.0, j'y suis même contraint (Vuforia 5).
Le carré blanc, en fait, c'est le bon résultat. Mon dot ne se retrouve pas à 1, sinon tous mes plans seraient blancs. Ce que je pense qu'il se passe, c'est qu'avec le batching, le premier plan rendu est instancié et tout les autres prennent le même résultat, alors que le fresnel est dépendant de la normale de chacun.
Mon souci maintenant, est plutôt au niveau du tri. Pour le feu en soi, ce n’est pas trop problématique, vu que toutes les couleurs se mêlent. Mais mon feu peut se retrouver entre du verre, et là, il passe des fois devant ou derrière et visuellement, ça se voit...
J'ai découpé les vitres en plusieurs parties pour le tri. (pas mettre le feu au milieu d'un tube sinon il est à la fois devant et derrière donc le tri est mauvais) et jouer avec le ZWrite, mais sans réel résultat probant...
En tout cas, j'ai un feu visible maintenant, c'est déjà ça!
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
F@B
Messages : 1844
Inscription : 01 Août 2013 10:41
Contact :

Re: iOS - GLES 2.0: transparence et tri

Message par F@B » 14 Déc 2016 10:41

rhaa la semi transparence c'est le bordel, le Zwrite annule le tri si je dis pas de conneries

je sais pas si AlphaToMask marche en OpenGL ? ça m'a sauvé des galère mais ilfaut l'AA donc sur mobile c'est probablement mort.

Code : Tout sélectionner

			
			Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
			Zwrite Off
			AlphaToMask True 
			Blend SrcAlpha OneMinusSrcAlpha
pour le tri il te faut changer le RenderQueue, et attention quand tu changes le QUEUE dans le code du shader ! il faut réinitialiser le material sinon unity garde l'ancien !
donc a cause de ça t'a pu passer a coté du bon ;)

tu peux regarder le Transparent CutoutSoftEdge dans les legacy ou tu as deux passe,
une en Zwrite OFF qui s'occupe de la semi transparence
une en Zwrite qui clip le cutout mais du coup c'est du 0 ou 1 elle évite que le rendu se trouve globalement devant l'objet.
des problèmes néanmoins avec ça, la semi transparence disparait avec la skybox...

et sinon il te faut regarder les shaders de particules classique en additive voir comment la semi trans est gérée

Code : Tout sélectionner

Shader "Particles/Additive" {
Properties {
	_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
	_MainTex ("Particle Texture", 2D) = "white" {}
	_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
}

Category {
	Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
	Blend SrcAlpha One
	ColorMask RGB
	Cull Off Lighting Off ZWrite Off
	
	SubShader {
		Pass {
		
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_particles
			#pragma multi_compile_fog

			#include "UnityCG.cginc"

			sampler2D _MainTex;
			fixed4 _TintColor;
			
			struct appdata_t {
				float4 vertex : POSITION;
				fixed4 color : COLOR;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f {
				float4 vertex : SV_POSITION;
				fixed4 color : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				#ifdef SOFTPARTICLES_ON
				float4 projPos : TEXCOORD2;
				#endif
			};
			
			float4 _MainTex_ST;

			v2f vert (appdata_t v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				#ifdef SOFTPARTICLES_ON
				o.projPos = ComputeScreenPos (o.vertex);
				COMPUTE_EYEDEPTH(o.projPos.z);
				#endif
				o.color = v.color;
				o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}

			sampler2D_float _CameraDepthTexture;
			float _InvFade;
			
			fixed4 frag (v2f i) : SV_Target
			{
				#ifdef SOFTPARTICLES_ON
				float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
				float partZ = i.projPos.z;
				float fade = saturate (_InvFade * (sceneZ-partZ));
				i.color.a *= fade;
				#endif
				
				fixed4 col = 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
				UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); // fog towards black due to our blend mode
				return col;
			}
			ENDCG 
		}
	}	
}
}
ʕ·͡ᴥ·ʔ ==> Mon Portfolio <== ʕ·͡ᴥ·ʔ

Merci de lire et de prendre en considération la Nétiquette des Forums avant de poster un sujet !

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6186
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: iOS - GLES 2.0: transparence et tri

Message par boubouk50 » 14 Déc 2016 10:52

L'AA c'est mort, certaines tablettes rendent tout noir, d'autres rament comme pas possible.
Le RenderQueue, comme je peux tourner autour de l'objet, il faudrait le recalculer à chaque frame (distance caméra objet?) et avoir un matériau de verre différent par vitre. C'est faisable, à voir niveau performance ce que ça coûte de réinitialiser jusqu'à 4 matériaux par frame.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
F@B
Messages : 1844
Inscription : 01 Août 2013 10:41
Contact :

Re: iOS - GLES 2.0: transparence et tri

Message par F@B » 14 Déc 2016 11:04

non non le renderqueue c'est unity qui décide rien a faire de ton coté, juste lui dire dans quel ordre faire le rendu de ton objet.

en premier les skybox, opaque, transparent, ect

je schématise mais c'est souvent la le probleme quand tu as des trucs qui passe sur d'autres avec la transparence !

ça n'a aucun cout, c'est unity qui décide juste ou ranger le DC dans la pipeline
ʕ·͡ᴥ·ʔ ==> Mon Portfolio <== ʕ·͡ᴥ·ʔ

Merci de lire et de prendre en considération la Nétiquette des Forums avant de poster un sujet !

Répondre

Revenir vers « les Shaders »