Page 1 sur 1

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

Publié : 28 Mars 2019 10:32
par bisonfoutu
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

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

Publié : 28 Mars 2019 10:37
par boubouk50
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.

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

Publié : 28 Mars 2019 11:24
par bisonfoutu
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"
}

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

Publié : 28 Mars 2019 11:47
par ReMix
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 ".

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

Publié : 28 Mars 2019 12:08
par bisonfoutu
Merci beaucoup !

Je vais essayer ça.

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

Publié : 28 Mars 2019 12:27
par bisonfoutu
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);
					
				}

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

Publié : 28 Mars 2019 14:18
par bisonfoutu
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