- Home /
Changing shader based on graphics settings
I started with a seemingly simple aim: I have an outline shader that only looks good with 4x or 8x MSAA. The user can change their AA settings in the game, so I also want to automatically change the shader to only show outlines if decent antialiasing is turned on in the Unity quality settings.
Unfortunately I cannot find an elegant way to do this. Any ideas would be appreciated. Some bogus solutions:
Change a shader property.
I can easily change the outline width to zero or use a flag to disable them via a shader property. Unfortunately shader properties are only set via Materials, and can't be tweaked directly.
Change it through the materials then.
There's no way (that I know of) to get a list of all materials so I can find the ones using the appropriate shader and change the property. You can only get materials currently in a scene, but new materials can come into being in a scene at any time. I'd have to be constantly checking.
Have the shader read Unity's AA setting?
As far as I know, shaders can't read external values except through properties, and properties can only be set via materials.
So the only workable solution I can think of right now is to have a specific list of materials using the outline shader attached to an object so I can change them directly, but that means that any time a new material uses the outline shader, I have to remember to manually add it to the list. Or put any materials using that shader into the resources folder so I can access them that way.
Answer by reefwirrax · Nov 16, 2013 at 10:15 AM
the best way to get any information you can about the graphics settings Using unity itself, and use a unity code to change the shaders on the materials for the materials themselves on any object, or just to change the settings within the shaders. seeing as the shader would have to check with the processor, going backwards through the bus, you may as will just checked straight from the processor and send information forwards to shader, about graphics settings.'
instead of input keys here, you would use the graphics settings information
#pragma strict
var mytexture: Texture2D;
var mymaterial: Material;
function Start () {
mymaterial = Resources.Load("green tiles 1", typeof(Material)) as Material;
mytexture = Resources.Load("461223101") as Texture2D;
}
function Update () {
if (Input.GetKeyDown ("1")){renderer.sharedMaterial.shader = Shader.Find ("Custom/vertexoutlines");renderer.sharedMaterial.SetFloat( "select", 0.0);}
if (Input.GetKeyDown ("2")){renderer.sharedMaterial.shader = Shader.Find ("Custom/vertexoutlines");renderer.sharedMaterial.SetFloat( "select", 1.0);}
if (Input.GetKeyDown ("3")){renderer.sharedMaterial.shader = Shader.Find ("Custom/vertexoutlines");renderer.sharedMaterial.SetFloat( "select", 2.0);}
if (Input.GetKeyDown ("4")){renderer.sharedMaterial.shader = Shader.Find ("Custom/vertexoutlines");renderer.sharedMaterial.SetFloat( "select", 3.0);}
if (Input.GetKeyDown ("5")){renderer.sharedMaterial.shader = Shader.Find ("Custom/vertexoutlines");renderer.sharedMaterial.SetFloat( "select", 4.0);}
if (Input.GetKeyDown ("6")){renderer.sharedMaterial.shader = Shader.Find ("Diffuse");renderer.sharedMaterial.mainTexture = Resources.Load("461223117") as Texture2D;}
if (Input.GetKeyDown ("7")){renderer.sharedMaterial.shader = Shader.Find ("Diffuse");renderer.sharedMaterial.mainTexture = Resources.Load("461223127") as Texture2D;}
if (Input.GetKeyDown ("8")){renderer.sharedMaterial.shader = Shader.Find ("Diffuse");renderer.sharedMaterial.mainTexture = Resources.Load("461223132") as Texture2D;}
if (Input.GetKeyDown ("9")){renderer.sharedMaterial.shader = Shader.Find ("Diffuse");renderer.sharedMaterial.mainTexture = Resources.Load("461223148") as Texture2D;}
if (Input.GetKeyDown ("0")){renderer.sharedMaterial.shader = Shader.Find ("Diffuse");renderer.sharedMaterial.mainTexture = Resources.Load("461223166") as Texture2D;}
if (Input.GetKeyDown ("-")){renderer.sharedMaterial.shader = Shader.Find ("Diffuse");renderer.sharedMaterial.mainTexture = Resources.Load("461223169") as Texture2D;}
if (Input.GetKeyDown ("=")){renderer.sharedMaterial.shader = Shader.Find ("Diffuse");renderer.sharedMaterial.mainTexture = Resources.Load("461223155") as Texture2D;}
}
The problem with that approach is that it's not possible (as far as I know) to just retrieve a list of all materials. Your script will only update one material, but I was hoping to automatically update any instances of the outline shader. Other materials may be using it too, and I was hoping to not have to manually specify a list of them.