Blending textures with vertex colors

@remorhaz hi again!



Sorry for long delay. I had some other issues…I tested your shader… And it works really differently as JME Lightting shader.



@nehon , @Momoko_Fan , can you check it out too? It seems sRGB and Linear RGB have really different lighting visuals. And I don’t know which is lighting system is better.



Screens:

http://www.mediafire.com/view/?e7lfodjddadw44p

http://www.mediafire.com/view/?1f278913gkrxowa

http://www.mediafire.com/view/?tp95b0mer0dbyca

http://www.mediafire.com/view/?bivykkac1jeigvc





It seems this is the magic of your shader:

[java]

float linearrgb_to_srgb(float c)

{

if(c < 0.0031308)

return (c < 0.0)? 0.0: c * 12.92;

else

return 1.055 * pow(c, 1.0/2.4) - 0.055;

}



void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)

{

col_to.r = srgb_to_linearrgb(col_from.r);

col_to.g = srgb_to_linearrgb(col_from.g);

col_to.b = srgb_to_linearrgb(col_from.b);

col_to.a = col_from.a;

}



void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)

{

col_to.r = linearrgb_to_srgb(col_from.r);

col_to.g = linearrgb_to_srgb(col_from.g);

col_to.b = linearrgb_to_srgb(col_from.b);

col_to.a = col_from.a;

}

[/java]

It seems JME Lighting shader has no Gamma Correction as it was mentioned here:

http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html

I can confirm we have no gamma correction at all in the lighting shader.



We have a gamma correction Filter though, contributed by @phate666 . I did not delve into gamma correction, and I’m not sure the Filter can be used without converting colors to srgb.



All i can say is that blender’s glsl render looks better than ours, not sure it’s only due to gamma correction but we should consider this at least as an option for the lighting shader.

Also take into account this:



“24.3.4 Two Wrongs Don’t Make a Right

The most common gamma mistake made in rendering is using nonlinear color textures for shading and then not applying gamma correction to the final image. …”



taken from here: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html



It means that every loaded texture should be converted too. As @remorhaz did in his shader.



Guys we really should to think about it.

@mifth said:
Also take into account this:

"24.3.4 Two Wrongs Don't Make a Right
The most common gamma mistake made in rendering is using nonlinear color textures for shading and then not applying gamma correction to the final image. ....."

Yes I read this article that why i said
@nehon said:
I'm not sure the Filter can be used without converting colors to srgb.
@mifth said:
It seems JME Lighting shader has no Gamma Correction as it was mentioned here:
http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html


There are two cases:
1. Your input diffuse texture is in linear color space, in this case you can optionally color grade (gamma correct) as a post process effect the final rendering result as the very last step.
2. the diffuse texture is in sRGB color space, in this case if you want to apply color management then you must set the texture type to SRGB (currently not supported by JME) or you must convert it to linear in the shader code and then apply the gamma correction in the post process pass.

An sRGB image is essentially just a gamma corrected image so the existing gamma correction filter can be used. But it makes only sense if all preceding shading steps were made in linear space.

@remorhaz Ok, i tested GammaCorrection filter. And it makes the texture more white. Actually, i like your corrected shader!





Code:

[java]



FilterPostProcessor fpp=new FilterPostProcessor(assetManager);

GammaCorrectionFilter gamma = new GammaCorrectionFilter(1.0f);

// gamma.setComputeLuma(true);

gamma.setGamma(1.7f);

viewPort.addProcessor(fpp);

fpp.addFilter(gamma);



[/java]



Screen:

http://i.imgur.com/pirxT.png

If i make:



[java]gamma.setGamma(1.0f);[/java]



So, the filter will not work…

The main point is that texture values has to be in linear space when doing shading of them, otherwise the itensities will come out wrong.



gamma(A) + gamma(B) != gamma(A + B)

Then this should be added to the GammaCorrectionFilter to convert image buffer to linear color:



[java]



float srgb_to_linearrgb(float c)

{

if(c < 0.04045)

return (c < 0.0)? 0.0: c * (1.0/12.92);

else

return pow((c + 0.055)*(1.0/1.055), 2.4);

}



void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)

{

col_to.r = srgb_to_linearrgb(col_from.r);

col_to.g = srgb_to_linearrgb(col_from.g);

col_to.b = srgb_to_linearrgb(col_from.b);

col_to.a = col_from.a;

}





main() {



vec4 converted_image; // converted buffer to linear

srgb_to_linearrgb(buffered_image, converted_image);





}



[/java]

@mifth said:
Then this should be added to the GammaCorrectionFilter to convert image buffer to linear color:

[java]

float srgb_to_linearrgb(float c)
{
if(c &lt; 0.04045)
return (c &lt; 0.0)? 0.0: c * (1.0/12.92);
else
return pow((c + 0.055)*(1.0/1.055), 2.4);
}

void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
{
col_to.r = srgb_to_linearrgb(col_from.r);
col_to.g = srgb_to_linearrgb(col_from.g);
col_to.b = srgb_to_linearrgb(col_from.b);
col_to.a = col_from.a;
}


main() {
...
vec4 converted_image; // converted buffer to linear
srgb_to_linearrgb(buffered_image, converted_image);

...
}

[/java]


Currently the shader I uploaded converts srgb to linear after reading the texture and converts it back to srgb after the lighting calculation. If you make a gamma correction post process pass then you make the correction two times. If you use the built in lighting shader then you will not shade in linear space so using the gamma filter will not do any good. What you need is to call srgb_to_linearrgb in the lighting shader (but not calling linearrgb_to _srgb at the end) and then adding a gamma correction post processor.

Wow… this looks really nice! If it’s ok, I’de like to play around with this in my versions of JME’s lighting shader.

@remorhaz you are right. If i convert all textures to “srgb_to_linearrgb” so, GammaCorrectionFilter will work correctly with Gamma = 2.0. But all other stuff assigned with ColorRGBA (like a color of background) will be more bright.



So, i decided to make gamma correction in Lighting shader. Because it does not make all other stuff more bright…



I have another question: should I convert “srgb_to_linearrgb” specularMap, NormalMap, ReflectionMap in my Lighting shader?



Thanks.



EDITED: and if i make some kind of color multiplication in my shader like:

[java]

vec3 color = vec4 (1.5,1.0,1.0,1.0);

diffusecolor *= color;

[/java]



should I convert “color” to the “srgb_to_linearrgb”?

@mifth said:
@remorhaz you are right. If i convert all textures to "srgb_to_linearrgb" so, GammaCorrectionFilter will work correctly with Gamma = 2.0. But all other stuff assigned with ColorRGBA (like a color of background) will be more bright.

So, i decided to make gamma correction in Lighting shader. Because it does not make all other stuff more bright...

I have another question: should I convert "srgb_to_linearrgb" specularMap, NormalMap, ReflectionMap in my Lighting shader?

Thanks.

EDITED: and if i make some kind of color multiplication in my shader like:
[java]
vec3 color = vec4 (1.5,1.0,1.0,1.0);
diffusecolor *= color;
[/java]

should I convert "color" to the "srgb_to_linearrgb"?


I'd love to see some rendered results from this. I did a quick conversion on the lighting shader and the end results were extremely bright (very hard to make out the shading). In the shader posted, a single conversion is done on the diffuse map only and then the final output is converted back... so I'm guess the answer to your question is no. Though, I'd love to know why the screens posted look different than what I am getting here.

Eh… worth mentioning, I only did a quick glance over the shader and didn’t see any noticeable difference in the lighting process (looked like JME’s at first glance)

i’m not sure about your “No”. Only @remorhaz knows right. As he knows how it works in blender shaders.

@mifth said:
i'm not sure about your "No". Only @remorhaz knows right. As he knows how it works in blender shaders.


This was in response to your first question... not the edit. He posted the blender shader here I thought.
@t0neg0d said:
This was in response to your first question... not the edit. He posted the blender shader here I thought.


there is no ReflectionMap in his shader either...

Do the conversion only on the diffuse map, other map types don’t contain color information.

@remorhaz said:
Do the conversion only on the diffuse map, other map types don't contain color information.


And if i want to make such an operation? :

[java]
vec4 diffusecolor = Texture2D(texture, texxCoord);
vec4 color = vec4 (1.5,1.0,1.0,1.0);
diffusecolor *= color;
[/java]

Should I convert color? Like "srgb_to_linearrgb(color, tempColor)" ?