Advertisement Jump to content
Sign in to follow this  

Specular questions (with pics)

This topic is 1702 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts


I'm redoing my specular highlight implementation in my shaders, and with this I have a few short questions. Also after refreshing my knowledge reading some articles. This is my calculation in pseudo:


** viewdir = normalize(camerapos - vtx wpos)

** half vector = normalize(viewdir + -lightdir

** specular term = pow(saturate(dot(half, normal)), power) * lightcolor/intensity 


My specular material properties I retrieve like this (from 3ds max):

- specular level RGB, i.e. 1.0 / 1.0 / 1.0 is full bright white

- specular power is glossiness from max (50 in max = 50, 100 in max = 100 power)


My questions:

- would you agree that I could use either lightcolor/intensity or specular material level (/color)? Where the 1st makes the specular highlights in the color of the light, and the 2nd makes them the color of the specular properties of the material?

- in the past I had 2 different approaches to getting the lightdir for the half vector equation:


1. lightdir = -lightdir (most logical)

2. lightdir = normalize(-lightdir  - vtx wpos)


Both work, bot from all theory I know the 1st one seems most realistic/best. What would you say?


- is it correct that a specular highlight on for example a glass material, gets bigger the further the camera is away?

Here's an example from further and nearer to a glass material:





Edited by cozzie

Share this post

Link to post
Share on other sites

The specular material property is a mask describing how much red, green and blue light the surface reflects - its a ratio of the light intensity, so you should be using both.

Share this post

Link to post
Share on other sites
Thanks, that means I would need to multiply with both the specular material level/color and the light color/intensity (both vectors).

I'm actually not sure how it works in real life, I believe for metals the specular highlight is more or less the color of the materials specular reflection, and for none metals it's more or less the color of the light.

What I can't figure out is why I need to multiply my specular power enormously to get a nice highlight. For example the power of my glass material is 75 (from max exported), but only when I multiply/ change it to become around 8000, the highlight looks ok. Is there a logical/ mathematical reason for this? (couldn't find it in the articles I looked up)

Share this post

Link to post
Share on other sites

That depends if you're trying to be "physically based" with your shading.

In real life every material has a characteristic Fresnel Reflectance which is measured at normal incidence angle. That would be your SpecularColor or SpecularIntensity.

You can think of it as the minimum intensity of its reflectivity because it will always reach a maximum reflectivity of 1 (=solid white) depending on the viewing angle. Most materials have indeed very low fresnel reflectance (~0.02) whereas metals already start at ~0.7-0.8 (which is why they seem so shiny smile.png ).

The reason your specular highlight changes with increasing distance might be because of mipmapping and filtering of the normal map.


@op calculating the light direction depends on what kind of light it is. For a directional light you just use the light direction (negated because we shade from the view of the pixel/surface) but for example point light you'd need to calculate the light direction as a function of the light's position and the object's position (kind of like you did in the second example).

And like digitalfragment said you have to multiply by both the light's color and the materials specular color.

I'm not familiar with the settings for blinn-phong in 3ds max but if it's a value from 0 - 100 then they probably map it differently.

One mapping that I like is this one which ranges from 2-2048:

SpecularPower = exp2(10 * gloss + 1)

gloss = value from 0 to 1 (for example what you'd read in your shader from a gloss map)


If you're interested in physically-based-shading I'd recommend reading this: (Background: Physics and Math of Shading slides)

Edited by lipsryme

Share this post

Link to post
Share on other sites


Thanks for the information, I've been playing around and stupidly the material I was testing with had a very low shininess in max, so raising that closer to 100 solved it without actualy 'rescaling' the specular power (I now just adapt the value from max).


The formula you gave though can be very useful when I start working with gloss maps (probably a while from now, but never the less :))


My shader(s) now take both the lightcolor as the diffuse material component into account, here's a snippet of the shader:

// directional light, specular term

			float3 h = normalize(-DirLightDir[i] + input.ViewDir);	
			float specular = max(dot(h, normalMap), 0.0f);
			specularAcc = pow(specular, MatSpecPower) * DirLightColInt[i] + specularAcc;

// the final addition/ calculation returning the end color

	float3 cd = (MatDiff * diffuseAcc + hemiAmb); 
	float3 ci = (MatSpec * specularAcc + MatEmi);
	float3 final = textureColor.rgb * cd + ci; 
	return float4(final, textureColor.a);

Some more tests also showed I should be fine for now, below 2 screenshots.

Regarding physical based shading, I didn't get into it yet, too much to do on my engine in too little time (day job takes so much time :))





Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!