How to set a texture in an image effect material?

I’m trying to set the texture via code on a material used in a post-process image effect. I’m calling SetTexture() on a reference to the material, but it’s not having any effect.

In this example, myMaterial has a shader that has a texture property. Just for this test, the shader simply overwrites the output with whatever color is in the texture.

[ExecuteInEditMode]
public class MyImageEffect : MonoBehaviour
{
    public Material myMat;
    public Texture myTexture;

    void Start()
    {
        myMat.SetTexture(0, myTexture);
    }

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source, destination, myMat);
    }
}

This all works fine if I drag a texture into the material’s texture property before running. However, if I try to assign the texture at runtime, it does not work.

For non-image-effect materials, you can change the texture on a material by grabbing the material from an object’s renderer:

	void Start () 
	{
        thisRenderer = GetComponent<MeshRenderer>();
        thisRenderer.sharedMaterial.SetTexture(0, myTex);
    }

In the case of a material used in a image effect, there is no renderer to grab the material off, so I’ not sure if I’m accessing it the correct way.
Any help would be appreciated.

However, if I try to assign the texture at runtime, it does not work.

Maybe because you set the texture only once at Start(), try to do it before the Blit like so:

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
             myMat.SetTexture(0, myTexture);
             Graphics.Blit(source, destination, myMat);
    }

Also are you sure your texture ID is 0 ? I would use the property string directly if I have troubles, guessing the sampler2D is called “_MainTex” in the shader:

myMat.SetTexture("_MainTex", myTexture);

If you really want to use an int (which is faster for repetitive calls) check Shader.PropertyToID, it should be much safer than hardcoded ID.

Edit: in Edit mode you might have to manually refresh the game view to see changes, this redraws all views:

UnityEditorInternal.InternalEditorUtility.RepaintAllViews()