Billboards transparent avec ombres tramées selon l'alpha

Questions à propos du scripting Shader.
Avatar de l’utilisateur
F@B
Messages : 1844
Inscription : 01 Août 2013 10:41
Contact :

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par F@B » 09 Mars 2016 15:50

Alesk a écrit :C'est bien le cas, j'ai pour le moment supprimé la réception d'ombres sur les billboards car ça me faisait n'importe quoi :p
Je m'attaquerais à ce problème dans un second temps ^_^
et oui! je viens de reprendre un peu mon shader et c'est bien ça le problème....

soit je suis en RenderQueue Transparent et pas d'ombre receiver.... ce qui m’ennuie beaucoup
soit je suis en RenderQueue alphaTest, et la PAF! les ombres sont ok mais la semitransparence passe derrière la skybox ! :grr: :pleur4: X( :/ :snif:

Autre astuce importante quand change un renderQueue dans le Tag, pensez a bien reset le material sinon ce dernier garde en mémoire l'ancien RenderQueue... ça m'a rendu fou ça, avant que je trouve!
ʕ·͡ᴥ·ʔ ==> 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
Titan
Messages : 582
Inscription : 12 Sep 2011 13:54
Contact :

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par Titan » 09 Mars 2016 18:34

Alesk a écrit :Qu'est-ce que tu entends par "référentiel global" ?
le worldPosition que tu a dans ton vertex shader, tu peut le passer à ton fragment shader et t'en servir comme seed sur ton rand.
Désolé j'essayai de limité le franglais :-D
____________________________________________
Hop Boy

Avatar de l’utilisateur
Alesk
Messages : 2303
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par Alesk » 10 Mars 2016 11:15

F@B a écrit : soit je suis en RenderQueue Transparent et pas d'ombre receiver.... ce qui m’ennuie beaucoup
soit je suis en RenderQueue alphaTest, et la PAF! les ombres sont ok mais la semitransparence passe derrière la skybox ! :grr: :pleur4: X( :/ :snif:
Je vais y réfléchir (mais dès que tu peux, pense au package de test, car je ne parviens toujours pas à reproduire ton souci avec la skybox)
F@B a écrit :Autre astuce importante quand change un renderQueue dans le Tag, pensez a bien reset le material sinon ce dernier garde en mémoire l'ancien RenderQueue... ça m'a rendu fou ça, avant que je trouve!
Ok merci pour l'info !
Titan a écrit :
Alesk a écrit :Qu'est-ce que tu entends par "référentiel global" ?
le worldPosition que tu a dans ton vertex shader, tu peut le passer à ton fragment shader et t'en servir comme seed sur ton rand.
Désolé j'essayai de limité le franglais :-D
Haaaaaaaaaaaa ok, ben c'est plus clair en franglais ! ;)
Bon sinon, j'avais fini par comprendre... Mais ça ne convient pas, du moins pas seulement comme ça car ma fonction rand n'est pas tip top et il faut lui balancer à chaque fois une valeur différente pour chaque.
Sinon j'ai essayé tout simplement avec une texture de noise... et ça me pose le même souci :/

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

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par F@B » 10 Mars 2016 11:25

Tiens j'ai modifié ton shader pour obtenir la même chose ;)

http://starting-lab.com/shader/Alesk.unitypackage
ʕ·͡ᴥ·ʔ ==> 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
Alesk
Messages : 2303
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par Alesk » 10 Mars 2016 13:55

Ok, ben ça déconne parce que tu as mis "Queue"="AlphaTest", avec Transparent, ça s'affiche correctement.
Donc as-tu vraiment besoin d'utiliser AlphaTest ?

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

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par F@B » 10 Mars 2016 14:04

et oui sinon pas d'ombres reçues !

j'ai trouvé une parade avec AlphaToMask True du coup.
soit je suis en RenderQueue Transparent et pas d'ombre receiver.... ce qui m’ennuie beaucoup
soit je suis en RenderQueue alphaTest, et la PAF! les ombres sont ok mais la semitransparence passe derrière la skybox ! :grr: :pleur4: X( :/ :snif:
ou alors y'a un truc qui m'échappe !
ʕ·͡ᴥ·ʔ ==> 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
Alesk
Messages : 2303
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par Alesk » 10 Mars 2016 15:03

Ok, je le note... et je vais étudier ça en détails.

En attendant mieux, voici ma version actuelle du shader. J'ai essayé de piocher d'autres valeurs pour générer le bruit aléatoire en faisant un mix à partir de la worldposition du centre de chaque billboard (et non des vertices) ainsi que l'index de chaque billboard.
ça fourmille toujours, mais là je ne vois pas comment obtenir mieux avec cette méthode.

Code : Tout sélectionner


Shader "Custom/BillboardsWithShadows2"
{
	Properties
	{
		_Color ("Main Color", Color) = (1,1,1,1)
		_MainTex ("Alpha", 2D) = "white" {}
		_Size ("Particle Size", Range(0.01,2)) = 1

		_MaxCameraDistance ("Max Camera Distance", float) = 250
		_Transition ("Transition", float) = 30
		_RandomDithering("Random Dithering", Range(0,10)) = 1
	}

	SubShader
	{
		Tags { "Queue" = "Transparent" "RenderType"="Transparent" }

		// base pass
		Pass
		{
			Tags { "LightMode" = "ForwardBase"}
            Blend SrcAlpha OneMinusSrcAlpha
            Cull Off
	   		Lighting Off
	   		ZWrite Off

			CGPROGRAM
				#pragma vertex vertexShader
				#pragma fragment fragmentShader
				#pragma geometry geometryShader

				#pragma multi_compile_fwdbase
				#pragma multi_compile_fog

				#pragma fragmentoption ARB_precision_hint_fastest

				#include "UnityCG.cginc"
				#include "AutoLight.cginc"

				struct VS_INPUT
				{
					float4 position : POSITION;
					float4 uv_Noise : TEXCOORD0;
					fixed sizeFactor : TEXCOORD1;
					float4 color: COLOR;

				};

				struct GS_INPUT
				{
					float4 worldPosition : TEXCOORD0;
					float4 color: COLOR;

				};

				struct FS_INPUT
				{
					float4 pos	: SV_POSITION;		// has to be called this way because of unity MACRO for light
					float2 uv_MainTexture : TEXCOORD0;
					float4 tint : COLOR0;

					LIGHTING_COORDS(1,2)
					UNITY_FOG_COORDS(3)
				};

				uniform fixed4  _Color;
				uniform sampler2D _MainTex;

				// for billboard
				uniform float _Size;
				uniform float _MaxCameraDistance;
				uniform float _Transition;

				uniform float4 _LightColor0;


				// Vertex Shader ------------------------------------------------
				GS_INPUT vertexShader(VS_INPUT vIn)
				{
					GS_INPUT vOut;

					// set output values
					vOut.worldPosition =  mul(_Object2World, vIn.position);
					vOut.color = vIn.color;

					return vOut;
				}


				// Geometry Shader -----------------------------------------------------
				[maxvertexcount(4)]
				void geometryShader(point GS_INPUT p[1], inout TriangleStream<FS_INPUT> triStream)
				{
					// cutout trough a transition area
					float cameraDistance = length(_WorldSpaceCameraPos - p[0].worldPosition);

					// discard billboards that are too far away
					if (cameraDistance > _MaxCameraDistance)
						return;

					float t = (cameraDistance - (_MaxCameraDistance - _Transition)) / _Transition;
					float alpha = clamp (1, 0, lerp (1.0, 0.0, t));

					float3 viewDirection = UNITY_MATRIX_V[2].xyz;
					float3 up = UNITY_MATRIX_V[1].xyz;
					float3 right = cross(up, viewDirection);

					// billboard's size and color
					float halfSize = 0.5f * _Size;

					float4 tint = p[0].color;

					tint.a = alpha * p[0].color.a;

					tint *= _Color;

					// create billboard
					float4 v[4];
					v[0] = float4(p[0].worldPosition + halfSize * right - halfSize * up, 1.0f);
					v[1] = float4(p[0].worldPosition + halfSize * right + halfSize * up, 1.0f);
					v[2] = float4(p[0].worldPosition - halfSize * right - halfSize * up, 1.0f);
					v[3] = float4(p[0].worldPosition - halfSize * right + halfSize * up, 1.0f);

					// matrix to transfer vertices from world to screen space
					float4x4 vpMatrix = mul(UNITY_MATRIX_MVP, _World2Object);

					FS_INPUT fIn;

					fIn.pos = mul(vpMatrix, v[0]);
					fIn.uv_MainTexture = float2(1.0f, 0.0f);
					fIn.tint = tint;
					TRANSFER_VERTEX_TO_FRAGMENT(fIn);
					UNITY_TRANSFER_FOG(fIn,fIn.pos);

					triStream.Append(fIn);

					fIn.pos =  mul(vpMatrix, v[1]);
					fIn.uv_MainTexture = float2(1.0f, 1.0f);
					fIn.tint = tint;
					TRANSFER_VERTEX_TO_FRAGMENT(fIn);
					UNITY_TRANSFER_FOG(fIn,fIn.pos);

					triStream.Append(fIn);

					fIn.pos =  mul(vpMatrix, v[2]);
					fIn.uv_MainTexture = float2(0.0f, 0.0f);
					fIn.tint = tint;
					TRANSFER_VERTEX_TO_FRAGMENT(fIn);
					UNITY_TRANSFER_FOG(fIn,fIn.pos);

					triStream.Append(fIn);

					fIn.pos =  mul(vpMatrix, v[3]);
					fIn.uv_MainTexture = float2(0.0f, 1.0f);
					fIn.tint = tint;
					TRANSFER_VERTEX_TO_FRAGMENT(fIn);
					UNITY_TRANSFER_FOG(fIn,fIn.pos);

					triStream.Append(fIn);
				}


				// Fragment Shader -----------------------------------------------
				float4 fragmentShader(FS_INPUT fIn) : COLOR
				{
					fixed4 color = tex2D(_MainTex, fIn.uv_MainTexture) * fIn.tint;
					if (color.a < 0.01) discard;

					float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
					float atten = LIGHT_ATTENUATION(fIn);

					float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
					float3 normal = float3(0,1,0);
					float3 lambert = float(max(0.0,dot(normal,lightDirection)));
					float3 lighting = (ambient + lambert * atten) * _LightColor0.rgb;

					color = fixed4 (color.rgb * lighting, color.a);

					UNITY_APPLY_FOG(fIn.fogCoord, color);
					return color;
				}

			ENDCG
		}

		// shadow caster
		Pass
		{
			//Name "ShadowCaster"
			Tags { "LightMode" = "ShadowCaster" }

			Fog { Mode Off }
			ZWrite On
			ZTest LEqual

			CGPROGRAM

			#pragma vertex	vertexShader
			#pragma geometry geometryShader
			#pragma fragment fragmentShader

			#pragma multi_compile_shadowcaster
			//#pragma only_renderers d3d11
			#define SHADOW_CASTER_PASS

			#include "UnityCG.cginc"
			#include "HLSLSupport.cginc"

			struct VS_INPUT
			{
				float4 position : POSITION;
				float4 uv_Noise : TEXCOORD0;
				fixed sizeFactor : TEXCOORD1;
				uint vid : SV_VertexID;
			};

			struct SHADOW_VERTEX
			{
				float4 vertex : POSITION; // has to be called this way because of unity macro

			};

			struct GS_INPUT
			{
				float4 worldPosition : TEXCOORD0;
			};

			struct FS_INPUT
			{
				float4 uv_MainTexture : TEXCOORD0;
				V2F_SHADOW_CASTER;
			};
			uniform fixed4  _Color;
			uniform sampler2D _MainTex;

			// for billboard
			uniform float _Size;
			uniform float _RandomDithering;

			uniform float _Transition;
			uniform float _MaxCameraDistance;

		   GS_INPUT vertexShader (VS_INPUT v)
		   {
				GS_INPUT vOut;
				// set output values
				vOut.worldPosition =  mul(_Object2World, v.position);
				vOut.worldPosition.w = v.vid; // unique index of the vertex
				return vOut;
		   }

		   // Geometry Shader
		   [maxvertexcount(4)]
		   void geometryShader(point GS_INPUT p[1], inout TriangleStream<FS_INPUT> triStream )
		   {
				// cutout trough a transition area
				float cameraDistance = length(_WorldSpaceCameraPos - p[0].worldPosition);

				// discard billboards that are too far away
				if (cameraDistance > _MaxCameraDistance)
					return;

				float t = (cameraDistance - (_MaxCameraDistance - _Transition)) / _Transition;
				float alpha = clamp (1, 0, lerp (1.0, 0.0, t));

				float3 viewDirection = UNITY_MATRIX_V[2].xyz;
				float3 up = UNITY_MATRIX_V[1].xyz;
				float3 right = cross(up, viewDirection);

				// size of billboard
				float halfSize = 0.5f * _Size;

				// create billboard
				float4 vertices[4];
				vertices[0] = float4(p[0].worldPosition.xyz + halfSize * right - halfSize * up, 1.0f);
				vertices[1] = float4(p[0].worldPosition.xyz + halfSize * right + halfSize * up, 1.0f);
				vertices[2] = float4(p[0].worldPosition.xyz - halfSize * right - halfSize * up, 1.0f);
				vertices[3] = float4(p[0].worldPosition.xyz - halfSize * right + halfSize * up, 1.0f);

				FS_INPUT fIn;

				SHADOW_VERTEX v;
				v.vertex = mul (_World2Object, vertices[0]);
				fIn.uv_MainTexture = float4(1.0f, 0.0f,p[0].worldPosition.xw*0.1);
				TRANSFER_SHADOW_CASTER(fIn)		// uses "v.vertex" for vertex position

				triStream.Append(fIn);

				v.vertex = mul (_World2Object, vertices[1]);
				fIn.uv_MainTexture = float4(1.0f, 1.0f,p[0].worldPosition.yw*0.1);
				TRANSFER_SHADOW_CASTER(fIn)

				triStream.Append(fIn);

				v.vertex = mul (_World2Object, vertices[2]);
				fIn.uv_MainTexture = float4(0.0f, 0.0f,p[0].worldPosition.zw*0.1);
				TRANSFER_SHADOW_CASTER(fIn)

				triStream.Append(fIn);

				v.vertex = mul (_World2Object, vertices[3]);
				fIn.uv_MainTexture = float4(0.0f, 1.0f,p[0].worldPosition.w*0.3,p[0].worldPosition.w*0.1);
				TRANSFER_SHADOW_CASTER(fIn)

				triStream.Append(fIn);
			}

			float rand(float3 co){
				return frac(sin(dot(co.xyz,float3(12.9898,78.233,45.5432)))*43758.5453);
			}

			fixed4 fragmentShader (FS_INPUT fIn) : COLOR
			{
				fixed clipme = tex2D(_MainTex, fIn.uv_MainTexture.xy).a * _Color.a - 0.005;

				// random dithering
				clipme -= rand(fIn.uv_MainTexture.xzw)*_RandomDithering*_RandomDithering;
				clip(clipme);

				// better stability with QualitySettings/Shadow Projection = Close fit
				fIn.pos.xy = floor(fIn.pos.xy) * 0.25;
				clipme -= frac(fIn.pos.xy.x + fIn.pos.xy.y);
	           	clip(clipme);

	           	SHADOW_CASTER_FRAGMENT(fIn);
			}

			ENDCG
		}
	}

	FallBack "Diffuse"
}

Prochaine étape : réception des ombres sur les particules ;)

Avatar de l’utilisateur
Titan
Messages : 582
Inscription : 12 Sep 2011 13:54
Contact :

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par Titan » 10 Mars 2016 17:15

Titan a écrit :
Alesk a écrit :Qu'est-ce que tu entends par "référentiel global" ?
le worldPosition que tu a dans ton vertex shader, tu peut le passer à ton fragment shader et t'en servir comme seed sur ton rand.
Désolé j'essayai de limité le franglais :-D
Haaaaaaaaaaaa ok, ben c'est plus clair en franglais ! ;)
Bon sinon, j'avais fini par comprendre... Mais ça ne convient pas, du moins pas seulement comme ça car ma fonction rand n'est pas tip top et il faut lui balancer à chaque fois une valeur différente pour chaque.
Sinon j'ai essayé tout simplement avec une texture de noise... et ça me pose le même souci :/[/quote]
En fait tu pourrais même arrêté de générer du bruit, tu applique une texture avec du tri-planar mapping. Tu met ça et c'est réglé: Image
Tu dit que tu a déjà essayé, c'était quoi le probléme avec le résultat ?
____________________________________________
Hop Boy

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

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par F@B » 10 Mars 2016 17:35

Alesk a écrit : Prochaine étape : réception des ombres sur les particules ;)
Tiens moi au jus si tu trouve une solution au problème, car tu vas t'y frotter je pense ;)
ʕ·͡ᴥ·ʔ ==> 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
Alesk
Messages : 2303
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: Billboards transparent avec ombres tramées selon l'alpha

Message par Alesk » 10 Mars 2016 19:02

Titan a écrit :En fait tu pourrais même arrêté de générer du bruit, tu applique une texture avec du tri-planar mapping. Tu met ça et c'est réglé: Image
Tu dit que tu a déjà essayé, c'était quoi le probléme avec le résultat ?
Le fourmillement ne cesse que lorsque l'on a la caméra avec nez collé sur l'ombre, dès que l'on s'éloigne un peu et/ou que l'on utilise les cascades sur les ombres, le problème revient :/
Et après quelques tests, il s'avère que ma fonction rand n'est pas si gourmande que ça, c'est juste la surface occupée à l'écran qui fait varier le framerate, quand on a la qualité à donf.
F@B a écrit :
Alesk a écrit : Prochaine étape : réception des ombres sur les particules ;)
Tiens moi au jus si tu trouve une solution au problème, car tu vas t'y frotter je pense ;)
Même pas peur, et je crois que j'ai déjà un début de solution dans un autre test :p
Dernière édition par Alesk le 11 Mars 2016 10:36, édité 1 fois.

Répondre

Revenir vers « les Shaders »