… or any game for that matter? I’ve tried googling these forums and the internet in general for some information on the topic, but I haven’t found anything conclusive. I’ve seen people mention that you have to handle it for your game specifically and through image effects. Unity doesn’t ship with anything suited for the job? Is there any de facto standard assets on the asset store for this purpose?
I wanted to see how other games did it and here’s what I found in a random selection of games I currently have installed on Steam:
Witcher 3
Gamma slider. Not available in windowed mode or borderless windowed mode, only fullscreen. Not sure why. I’m guessing it’s a technical limitation with the way they’ve implemented it.
Crysis
Separate sliders for brightness, contrast and gamma. Changing these affects everything on the desktop outside the game as well. Really odd. Is this some universal Windows/Nvidia approach? Why else would it affect things outside of the game on both my monitors?
Serious Sam 3
Separate sliders for brightness, contrast, gamma and saturation. Can even make your game grayscale if you want. Behaves very much like adjustment layers in Photoshop so I’m guessing it’s like a color correction image effect in Unity.
Dying Light
Gamma slider.
Portal 2 & Counter-Strike Global Offensive
Brightness slider. But it seems to behave differently in each game. But it behaves like a gamma slider in both games I guess, and not like a brightness slider.
The only Unity games I have installed are early access games and none of them have any such options.
I don’t want a hack like changing the ambient light or anything like that. It has to be solid. I’ve found that I can increase/decrease the exposure on my tone mapping image effect. It makes my bloom overexposed as well, which I don’t want, but it’s the best out of the box option I’ve found so far.
I realize I don’t really know what gamma does technically as a graphics setting, but I find changing gamma a lot more pleasing than changing brightness. I guess it increases/decreases the brightness of mid tones or something without affecting the already bright areas as much whereas brightness just brightens the whole image.
I just made my first image effect and I think I managed to create a brightness slider by just doing this return tex2D(_MainTex, i.uv) * _Brightness; in my image effect.
Obviously not gamma, but it seems to work well as a general brightness slider. Better than changing the exposure value of the tone mapper for sure.
Still seems odd to me how little information there is about this. Seems like something every Unity game (3d at least) should have.
For anyone else stumbling upon this I implemented the above code snippet in my extended Stealth tutorial project available here:
Below is the entire code. Just apply to a camera like any other image effect and hook it up to a GUI slider if you want it as a menu setting.
The reason my variable is called shaderDerp and not shader is because of a problem I reported here:
Would love it if anyone knew anything about that.
I will look at how you implement a proper gamma slider later on, but for now this suited me well no matter how wrong or hacky it may turn out to be.
Brightness.cs
using System;
using UnityEngine;
[ExecuteInEditMode]
[AddComponentMenu("Image Effects/Color Adjustments/Brightness")]
public class Brightness : MonoBehaviour {
/// Provides a shader property that is set in the inspector
/// and a material instantiated from the shader
public Shader shaderDerp;
Material m_Material;
[Range(0.5f, 2f)]
public float brightness = 1f;
void Start() {
// Disable if we don't support image effects
if (!SystemInfo.supportsImageEffects) {
enabled = false;
return;
}
// Disable the image effect if the shader can't
// run on the users graphics card
if (!shaderDerp || !shaderDerp.isSupported)
enabled = false;
}
Material material {
get {
if (m_Material == null) {
m_Material = new Material(shaderDerp);
m_Material.hideFlags = HideFlags.HideAndDontSave;
}
return m_Material;
}
}
void OnDisable() {
if (m_Material) {
DestroyImmediate(m_Material);
}
}
void OnRenderImage(RenderTexture source, RenderTexture destination) {
material.SetFloat("_Brightness", brightness);
Graphics.Blit(source, destination, material);
}
}