97Fermer99
bearbecueLe 01/05/2012 à 00:41
ouai, c'est normal, c'est parceque t'as un light-buffer en BGRA8, pas en floating-point.
bon entre chaque post ici jme souviens plus de quels formats t'as de dispo, mais si t'as que du 8-bits, c'est effectivement un probleme grin

en option il y a:

1- considerer le RGBA comme du RGBE (R, G, B, exposant), tu choisis un exposant qui se remappe entre deux valeurs arbitraires (genre tu fais real_scale = 1 + light_buffer.a * 100)
en gros:
quand t'ecris dans le light-buffer:

soit:
const float kScaleCoeff = 100.0f;
float scale = min(1.0f, length(irradiance.xyz));
outColor = float4(irradiance.xyz / scale, (scale - 1.0f) / kScaleCoeff);


soit:
const float kScaleCoeff = 100.0f;
float scale = min(1.0f, max(irradiance.x, max(irradiance.y, irradiance.z)));
outColor = float4(irradiance.xyz / scale, (scale - 1.0f) / kScaleCoeff);

(cette 2eme option utilisera mieux les bits dispos mais sera surement moins efficace, elle force un cassage de la vectorisation avec le max horizontal sur les 3 scalaires x, y, z, alors que le lenght() d'au dessus est cable en hardware et devrait etre plus rapide, meme si il necessite le calcul d'un dot product + racine carree)

quand tu lis le light-buffer:
float4 irradianceRGBE = light_buffer.sample(pixel_uv);
float3 irradiance = irradianceRGBE.xyz * (irradianceRGBE.w * 100.0f + 1.0f);


probleme: tu perds la possibilite de stocker ton spec dans l'alpha de ton light-buffer.

2- changer d'encodage. ne pas utiliser le RGB, mais le YUV.
ca a l'avantage de preserver la couleur. ca saturera l'intensite (Y) a 1, mais vu que U et V sont entre 0 et 1 par definition dans ce color-space, la chromaticite sera conservee.
par contre c'est ptet plus relou a blender. j'ai jamais teste ca, et j'ai pas trop d'image mentale de comment le YUV peut se blend, donc plutot que de te dire une connerie, va plutot faire 2/3 recherches google sur light-prepass et YUV grin j'ai vu passer quelques posts de gars qui experimentaient cette methode, ya ptet des trucs interessants a en tirer..

tiens, une idee qui me vient comme ca un peu a l'arrache en ecrivant:
si tu veux faire deux passes pour stocker les vraies couleurs de ton spec, tu peux faire une des passes en demi-resolution pour gagner en fill rate.
en gros, utiliser un principe comme le jpeg.
t'as deux rendertargets:

1- full-resol : irradiance.Y(0), irradiance.Y(1), specular.Y(0), specular.Y(1)
2- half-resol : irradiance.U, irradiance.V, specular.U, specular.V

dans la 1, tu peux utiliser 16 bits pour stocker les deux Y de l'irradiance et du spec, et avoir un range de valeurs plus important

bon apres vu que ca te fait quand meme deux passes, meme avec 4* moins de pixels sur la 2eme passe, jsais pas si ca vaut le coup par rapport au deffered classique.
mais ca peut etre un truc interessant a tester smile