- Home /
How to avoid Texture.Apply()
Hello!
I'm trying to create a dynamic background by painting a texture, pixel by pixel, at runtime in the update function. If I understand it correctly I have to call apply() after having SetPixels32() for Unity to actually pass along the new texture data to the GPU. This, it seems, is a costly process.
I thought to change the texture that the shader uses directly by setting the pixels of the MainTexture of the Material instead, hoping that the shader would pick up the change without having to call Apply(). No luck. I think I've misunderstood how shaders, materials and textures work together. I've looked into shader tutorials but I still don't understand how I can pass along texture data directly to the GPU, even with custom shaders.
So for my question: is it possible to send texture data directly to the GPU using Unity? If so, how do I do that?
This is what I have:
public class SkyCreator : MonoBehaviour {
private Texture2D _texture;
private MeshRenderer _renderer;
private int _screenWidth;
private int _screenHeight;
private float _pixelsPerUnit;
private Color32[] _pixels;
private Vector3 _lastPos;
// Use this for initialization
void Start () {
_screenWidth = Camera.main.pixelWidth;
_screenHeight = Camera.main.pixelHeight;
_pixels = new Color32[_screenWidth*_screenHeight];
_renderer = GetComponent<MeshRenderer>();
_texture = new Texture2D(_screenWidth,_screenHeight,TextureFormat.ARGB32, false);
for(int y = 0; y < _screenHeight; y++){
for(int x = 0; x < _screenWidth; x++){
_pixels[y*_screenWidth + x] = new Color(Random.Range(0f,1f),Random.Range(0f,1f),Random.Range(0f,1f));
}
}
_texture.SetPixels32(_pixels);
_texture.Apply();
_renderer.material.mainTexture = _texture;
//Create the mesh
var mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices = new Vector3[]{
new Vector3(0,0,0),
new Vector3(1,0,0),
new Vector3(1,-1,0),
new Vector3(0,-1,0)
};
mesh.triangles = new int[]{
0,1,2,0,2,3
};
mesh.uv = new Vector2[]{
new Vector2(0,0),
new Vector2(1,0),
new Vector2(1,1),
new Vector2(0,1)
};
mesh.Optimize();
mesh.RecalculateNormals();
}
}
Answer by Dave-Carlile · Jun 16, 2015 at 09:54 PM
You pass (updated) texture data long to the GPU by calling Texture.Apply.
As the documentation states, and you discovered, it can be an expensive operation.
What are you modifying in the texture? If it's a dynamic sky texture your best bet is going to be a shader that does all of the changes on the GPU.
Oh, I see! So the actual "drawing logic" needs to go into the shader. And yes, it's a dynamic sky. I was actually hoping to be able to make something a bit more general so that I could use it for different things. But I think I understand now. Thanks.
Your answer
Follow this Question
Related Questions
is there a way to make a gradient material, white to black, in Unity3D? 2 Answers
How to apply different textures to one model? 1 Answer
Assign Texture To Material Unity 4.6 1 Answer
Multiple materials on same object 0 Answers
Carpet in Shadergraph? 0 Answers