[Problème] Couleur des lumières basée sur la distance

Modérateurs : Administrateurs Suppléants, Community Manager

bisonfoutu
Messages : 27
Inscription : 22 Juil 2015 15:44

[Problème] Couleur des lumières basée sur la distance

Message par bisonfoutu » 28 Mars 2019 10:32

Bonjour,

Je travail actuellement sur des surfaces shaders permettant d'afficher les objets en noir et blanc, sans dans un certain rayon autour de la caméra où les couleurs sont affichés. J'essaye d'intégrer cette logique dans tous les shaders que je vais devoir utiliser (terrain, particules, standard...). L'effet est actuellement implémenté et fonctionne sur le shader de terrain standard (ce qui me semble le plus complexe).

Je fais maintenant face à un problème plus complexe : la couleur des lumières modifie le rendu final, ce qui me contraint à n'utiliser que des lumières blanches (ce qui est problématique...).

Je cherche donc un moyen d'afficher la couleur de la lumière uniquement sur les zones colorés autour de la caméra, et rendre une lumière blanche sur les zones en noir et blanc. Le projet est en Deferred lighting.

J'ai déjà réalisé de nombreux test sans succès

Quelqu'un aurait-il une suggestion?

Merci d'avance

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 4907
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: [Problème] Couleur des lumières basée sur la distance

Message par boubouk50 » 28 Mars 2019 10:37

Peut-on avoir une image descriptive stp?
Tu as donc une zone colorisée et une autre N&B?
Dans le même principe, tu as donc une délimitation prédéfinie par la distance. Ne peux-tu pas l'utiliser pour décider de la couleur de la lumière en fonction de cela? Ou alors, la passe de N&B pourrait arriver après la passe d'illumination.
"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

bisonfoutu
Messages : 27
Inscription : 22 Juil 2015 15:44

Re: [Problème] Couleur des lumières basée sur la distance

Message par bisonfoutu » 28 Mars 2019 11:24

Voila une vidéo de l'effet en post process :
https://www.youtube.com/watch?v=KK3TEiI7HrQ

Pour être plus précis :

- Il existe plusieurs "points" émanant un aura coloré. L'environnement est donc noir et blanc sauf aux abord de ces points de couleur que je passe dans le shader avec un buffer.
- Cet effet a d'abord été réalisé avec un post process, mais celui ne fonctionne pas avec les particules car ils n'ont pas de ZWrite.

J'ai pour l'instant intégré cet effet sur le shader de terrain. Mais celui-ci est un peu complexe (j'ai commencé la programmation shader il y a peu de temps) et je n'arrive pas à modifier le lighting du shader.

Effectivement, réaliser l'effet sur une pass post lighting serait une bonne solution je pense, mais je ne sais pas comment le faire.

Voila le shader de terrain modifié, pour l'instant je n'ai mis que la camera comme "point de couleur", mais l'implémentation du buffer n'est pas un problème :

Code : Tout sélectionner

Shader "Nature/Terrain/Standard-custom" {
	Properties{
		// set by terrain engine
		[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
		[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}
		[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}
		[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}
		[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}
		[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
		[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
		[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
		[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
		[HideInInspector][Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
		[HideInInspector][Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
		[HideInInspector][Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
		[HideInInspector][Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
		[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 1.0
		[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 1.0
		[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 1.0
		[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 1.0

			// used in fallback on old cards & base map
			[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "white" {}
			[HideInInspector] _Color("Main Color", Color) = (1,1,1,1)
	}

		SubShader{
			Tags {
				"Queue" = "Geometry-100"
				"RenderType" = "Opaque"
			}

			CGPROGRAM
			#pragma surface surf Standard vertex:SplatmapVert finalcolor:SplatmapFinalColor finalgbuffer:SplatmapFinalGBuffer fullforwardshadows noinstancing
			#pragma multi_compile_fog
			#pragma target 3.0
				// needs more than 8 texcoords
				#pragma exclude_renderers gles psp2
				#include "UnityPBSLighting.cginc"

				#pragma multi_compile __ _TERRAIN_NORMAL_MAP

				#define TERRAIN_STANDARD_SHADER
				#define TERRAIN_SURFACE_OUTPUT SurfaceOutputStandard
				#include "Assets\_Project\Materials\Shaders\Builtin terrain\CustomTerrainSplatmapCommon.cginc"

				half _Metallic0;
				half _Metallic1;
				half _Metallic2;
				half _Metallic3;

				half _Smoothness0;
				half _Smoothness1;
				half _Smoothness2;
				half _Smoothness3;

				// Récupère un coeficient de distance entre la le pixel et la camera basé sur une distance maximum afin d'obtenir un dégradé
				float getCoef(float3 worldPos, float3 cameraPos, float maxDistance)
				{
					float dist = distance(worldPos, cameraPos);
					float coef = dist / maxDistance;
					float clampCoef = clamp(coef, 0, 1);
					return clampCoef;
				}
				void surf(Input IN, inout SurfaceOutputStandard o)
				{
					half4 splat_control;
					half weight;
					fixed4 mixedDiffuse;
					half4 defaultSmoothness = half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3);
					SplatmapMix(IN, defaultSmoothness, splat_control, weight, mixedDiffuse, o.Normal);
					o.Albedo = mixedDiffuse.rgb;

					// Calcul d'un coefficiant permettant de lerper entre la couleur de base et la couleur en grayscale
					float coef = getCoef(IN.worldPos, _WorldSpaceCameraPos, 20);
					float3 lum = Luminance(mixedDiffuse.rgb);
					float3 finalCol = lerp(o.Albedo, lum, coef); 
					// Output terrain color
					o.Albedo = finalCol;

					o.Alpha = weight;
					o.Smoothness = mixedDiffuse.a;
					o.Metallic = dot(splat_control, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3));
				}


ENDCG
			}

				Dependency "AddPassShader" = "Hidden/TerrainEngine/Splatmap/Standard-AddPass-custom"
	Dependency "BaseMapShader" = "Hidden/TerrainEngine/Splatmap/Standard-Base-custom"

	// Fallback "Nature/Terrain/Diffuse"
}

ReMix
Messages : 2
Inscription : 26 Oct 2018 15:57

Re: [Problème] Couleur des lumières basée sur la distance

Message par ReMix » 28 Mars 2019 11:47

Je pense qu'il y aurait un piste du coté de la fonction de FinalColor (voir l'exemple dans la doc : https://docs.unity3d.com/Manual/SL-Surf ... mples.html)
Là tu aurais simplement à désaturer la couleur, après éclairage.

Ca marchera facilement pour les objets, mais j'imagine que pour le terrain tu va devoir réimplémenter la fonction "finalcolor:SplatmapFinalColor ".

bisonfoutu
Messages : 27
Inscription : 22 Juil 2015 15:44

Re: [Problème] Couleur des lumières basée sur la distance

Message par bisonfoutu » 28 Mars 2019 12:08

Merci beaucoup !

Je vais essayer ça.

bisonfoutu
Messages : 27
Inscription : 22 Juil 2015 15:44

Re: [Problème] Couleur des lumières basée sur la distance

Message par bisonfoutu » 28 Mars 2019 12:27

J'ai réécrit la fonction FinalColor de SplatMap, mais cela ne change rien au rendu. Je ne suis pas sur de tout à fait comprendre les donnés que je manipule dedans. Ce code devrait modifier la couleur final du rendu il me semble.

Code : Tout sélectionner

#pragma surface surf Standard vertex:SplatmapVert finalcolor:FinalColor finalgbuffer:SplatmapFinalGBuffer fullforwardshadows noinstancing

void FinalColor(Input IN, TERRAIN_SURFACE_OUTPUT o, inout fixed4 color)
				{
					#ifdef TERRAIN_SPLAT_ADDPASS
					UNITY_APPLY_FOG_COLOR(IN.fogCoord, color, fixed4(1, 0, 0, 0));
					#else
					UNITY_APPLY_FOG(IN.fogCoord, color);
					#endif
					color *= o.Alpha;
					float coef = getCoef(IN.worldPos, _WorldSpaceCameraPos, 50);
					float4 lum = Luminance(color);
					o.Albedo = lerp(color, lum, coef);
					color = lerp(color, lum, coef);
					
				}

bisonfoutu
Messages : 27
Inscription : 22 Juil 2015 15:44

Re: [Problème] Couleur des lumières basée sur la distance

Message par bisonfoutu » 28 Mars 2019 14:18

j'ai réussi à faire fonctionner le shader en forward rendering, mais pas en deferred.

https://forum.unity.com/threads/deferre ... or.335875/

D'après ce forum, le modificateur "finalgbuffer" permet de faire la même chose que "finalcolor" en Deferred, mais cela ne fonctionne pas. J'ai en revanche réussi à le faire fonctionner en Light-Prepass.

Code : Tout sélectionner

#pragma surface surf Standard vertex:SplatmapVert finalgbuffer:FinalGBuffer  noinstancing exclude_path:forward
void FinalGBuffer(Input IN, TERRAIN_SURFACE_OUTPUT o, inout half4 outGBuffer0, inout half4 outGBuffer1, inout half4 outGBuffer2, inout half4 emission)
				{
					UnityStandardDataApplyWeightToGbuffer(outGBuffer0, outGBuffer1, outGBuffer2, o.Alpha);
					emission *= o.Alpha;
					float coef = getCoef(IN.worldPos, _WorldSpaceCameraPos, 20);
					float4 lum = Luminance(emission);
					//o.Albedo = lerp(emission, lum, coef);
					emission = lerp(emission, lum, coef);
				}
Je ne sais pas ce que je fait pas bien.

Merci pour votre aide

Répondre

Revenir vers « les Shaders »