# Why (atten * 2) ?

Discussion in 'Shaders' started by Farfarer, Jun 28, 2011.

Not open for further replies.
1. ### Farfarer

Joined:
Aug 17, 2010
Posts:
2,249
Just curious as to why the surface shaders all multiply the result by (atten * 2) for shadows/light attenuation?

atten is already a 0-1 range, multiplying it by 2 just means that everything not in shadow gets twice as bright. Net result is that light brightness is only really useful up to 0.5 or stuff starts to get really bleached.

What's the logic there?

2. ### Jessy

Joined:
Jun 7, 2007
Posts:
7,327
Last edited: Jun 28, 2011
3. ### Farfarer

Joined:
Aug 17, 2010
Posts:
2,249
I see, so it is actually there to fake bleaching/overexposure.

Fair enough, I was just wondering

4. ### TheMetaMorphe

Joined:
Nov 9, 2012
Posts:
23
I thought this was for the converstion from gamma to linear light.

### Unity Technologies

Joined:
Aug 11, 2006
Posts:
3,331
No, this has nothing to do with linear lighting. It's just a multiplication by two so that a single light can actually brighten an object beyond its albedo colour. This factor predates the addition of light intensity (up to 8).

Linear lighting is achieved primarily by using gamma-correct reads and writes for source textures, frame and light buffers.

6. ### Farfarer

Joined:
Aug 17, 2010
Posts:
2,249
No, that'd be pow(color, gamma) then pow(color, 1/gamma)

### Unity Technologies

Joined:
Aug 11, 2006
Posts:
3,331
That's the function, yes, but it's built right into the hardware read/write operations. This is why it's called sRGB sampling, and why you don't have to write custom shaders.

8. ### TheMetaMorphe

Joined:
Nov 9, 2012
Posts:
23
Ok make sense, but it's not just a multiply by 2 :

float lengthSq = dot(i.lightDir, i.lightDir);
float atten = 1.0 / (1.0 + lengthSq * unity_LightAtten[0].z);

### Graphics PlumberUnity Technologies

Joined:
Nov 7, 2005
Posts:
4,526

Short answer to "why multiply by two?" - because in the EarlyDays, it was a cheap way to "fake" somewhat overbright light in fixed function shaders. And then it stuck, and it kind of dragged along.

We'd like to kill this concept. But that would mean breaking possibly a lot of existing shaders that all of you wrote (suddenly everything would become twice as bright). So yeah, a tough one... worth killing an old stupid concept or not?

Joined:
Jul 8, 2012
Posts:
354
worth

11. ### Farfarer

Joined:
Aug 17, 2010
Posts:
2,249
Yeah, I'd say go for it.

TheMetaMorph; That's the code for calculating the attenuation of a point light. The atten variable already has the light's attenuation in it, multiplied by the shadow value for that pixel.

12. ### McDev02

Joined:
Nov 22, 2010
Posts:
553
You mean it would become half as bright as I understand (removing *2 on attan)? Then do it, I hate this behaviour of overlit objects.
I don't understand the concept anyway, you can set light's intensity on 2 and get the same result.

13. ### Lulucifer

Joined:
Jul 8, 2012
Posts:
354
the situation just exist for shaders compiled for forward rendering path,not deferred lighting path,so ....

14. ### Farfarer

Joined:
Aug 17, 2010
Posts:
2,249
Uh, no, deferred has it too. Otherwise the render paths would look massively different...

15. ### Lulucifer

Joined:
Jul 8, 2012
Posts:
354
really.but i cant find any code related to atten that *2 in deferred related code,

### Graphics PlumberUnity Technologies

Joined:
Nov 7, 2005
Posts:
4,526
For deferred lighting we multiply *2 into the light color constant.

17. ### TheMetaMorphe

Joined:
Nov 9, 2012
Posts:
23
Yeah go for it please !

Farfarer : ok .

18. ### Noisecrime

Joined:
Apr 7, 2010
Posts:
1,482
For consistency I'd agree to kill it, but I fear this should have been done for a major Unity release (i.e. 4.0) doing so in a dot release may be a bit too annoying, unless it can be achieved easily, without overhead via some compile directive at build time?

On a similar note its always bugged me that on I think its gui textures, that either the rgb or alpha, or maybe both, has 'normal' level at (127,127,127,127), never did understand why.

19. ### duke

Joined:
Jan 10, 2007
Posts:
764
It's easy to fix in custom shaders, so yeah I'd say dooooooo itttttttt!

### Graphics PlumberUnity Technologies

Joined:
Nov 7, 2005
Posts:
4,526
"easy" is a very relative term. For someone who knows shaders, "everything two bright, remove *2 in your lighting code" -- they go, find *2 and remove it, done. For someone who has no clue what a shader is, but grabbed some shaders from friends/internet/assetstore, that might be more challenging.

Very similar reason, to be able to "overbright" the UI. Tint is put into a vertex color, which is clamped to 0..1 range. So by making 0.5 be the "neutral", you can overbright it.

21. ### Farfarer

Joined:
Aug 17, 2010
Posts:
2,249
Perhaps keep it for a milestone minor release (4.5?) or the next major release (5.0) then? Or if you've got any big graphical changes planned in this cycle, bundle it with those.

It's not a massive problem, but it'd be nice to see it go. However, I can see it causing issues for some folk if you suddenly ditch *2 mid cycle.

22. ### Noisecrime

Joined:
Apr 7, 2010
Posts:
1,482
Which is what I've never understood, why would anyone want to over-brighten their UI? Presumably i'm right in thinking this also loses 50% of the available range too if you don't want to over-brighten? I think (from memory) this also affects alpha, which is even worse, never want to lose half your range in alpha.

23. ### Farfarer

Joined:
Aug 17, 2010
Posts:
2,249
Yeah, but if that's removed and someone does want to overbrighten their UI, then they're screwed because it can't be done.

### Graphics PlumberUnity Technologies

Joined:
Nov 7, 2005
Posts:
4,526
Apparently some people do

You don't lose the possible range in the color tint, you just lose precision. I.e. you can't tint by 1/255 steps anymore, the steps are effectively by 2/255.

Joined:
Jun 2, 2015
Posts:
1

### Graphics PlumberUnity Technologies

Joined:
Nov 7, 2005
Posts:
4,526
Yes, that implicit "multiply by two" was removed in Unity 5.0.