• Create Account

### #ActualHodgman

Posted 03 December 2012 - 01:44 AM

Sometimes "gloss" terminology is a bit vague - some engines use it to mean the specular power, while others use it to mean the specular mask. In any case, it's good to fetch both the power and mask values from a texture to give your artists decent control over the materials.
In my engine, I call the specular-power texture the "roughness" texture.

You seem to be using the traditional Blinn-Phong specular function, and the code looks ok. In terms of style, I'd suggest a few more line breaks:
float NdotH = saturate(dot(halfvec, finalnormal)); //prefer saturate over max where able
float specPower = texture2D(gloss_texture, transformedTexcoord).r*99.0 + 1.0;
specular = pow(NdotH, specPower);

As for the "x*99+1" part, there is no right answer for this encoding/decoding function. Any positive value is valid for the specular power -- some materials might need "5" and others might need "50000"... This makes choosing a function that encodes this range into 8-bits particularly difficult.
If the materials in your game only need the values of 1-100, then your encoding is fine.

If you want to move more precision to the lower end, you can do something like:
float specPower = texture2D....
specPower = (specPower*specPower) * range + 1;
Or to move precision to higher values, something like:
float specPower = 1.0 - texture2D....
specPower = (1.0-(specPower*specPower)) * range + 1;
Some engines use the log function for a logarithmic distribution, but basically you've just got to choose a mapping that works for you.

Other engines might not even be using Blinn-Phong, so even if you use the same mapping, you'll get different appearances of "gloss" anyway.

### #1Hodgman

Posted 03 December 2012 - 01:41 AM

Sometimes "gloss" terminology is a bit vague - some engines use it to mean the specular power, while others use it to mean the specular mask. In any case, it's good to fetch both the power and mask values from a texture to give your artists decent control over the materials.
In my engine, I call the specular-power texture the "roughness" texture.

You seem to be using the traditional Blinn-Phong specular function, and the code looks ok. In terms of style, I'd suggest a few more line breaks:
float NdotH = saturate(dot(halfvec, finalnormal)); //prefer saturate over max where able
float specPower = texture2D(gloss_texture, transformedTexcoord).r*99.0 + 1.0;
specular = pow(NdotH, specPower);

As for the "x*99+1" part, there is no right answer for this encoding/decoding function. Any positive value is valid for the specular power -- some materials might need "5" and others might need "50000"... This makes choosing a function that encodes this range into 8-bits particularly difficult.
If the materials in your game only need the values of 1-100, then your encoding is fine.

If you want to move more precision to the lower end, you can do something like:
float specPower = texture2D....
specPower = (specPower*specPower) * range + 1;
Or to move precision to higher values, something like:
float specPower = 1.0 - texture2D....
specPower = (1.0-(specPower*specPower)) * range + 1;
Some engines use the log function for a logarithmic distribution, but basically you've just got to choose a mapping that works.

Other engines might not even be using Blinn-Phong, so even if you use the same mapping, you'll get different appearances of "gloss" anyway.

PARTNERS