- Home /
Notification of shader recompilation ?
Hi !
Is there a way to be notified a material's shader was recompiled ?
I mean, such an event would be the ideal place to setup shader constants that don't change across the entire shader and need to be uploaded only once. Instead, I have to upload these constants every frame, which kind of sucks...
That makes the user write 2 scenarios : one for debug mode where the shaders get recompiled often and another one for release mode where the shader gets compiled only once, too bad.
Answer by Owen-Reynolds · Oct 04, 2011 at 04:59 PM
You're talking about saving on things like renderer.material.SetFloat("_Shininess", shininess);
?
I thought constants needed to be sent every frame no matter what. Sure, the shader code is stored in the graphics card, but it doesn't have a spot where it stores the uniform variables (specSize = 12 ... .) Those are stored in the CPU, with the material. Since the specular shader, say, is used by lots of materials, remembering the most recent GPU setting for specSize wouldn't be useful.
The only way you should be able to set a GPU constant once is if whatever register happens to never get overridden by any other shader, like when materials are batched.
Answer by Patapom · Oct 04, 2011 at 09:05 PM
I was talking more about texture uploads, not simple parameters that change per-instance...
Imagine the case where a material uses a texture as a precomputated table : that texture never changes for any instance of the material and needs to be uploaded only once and stay in video memory.
Any decent driver has a cache that allows to keep textures in video memory without having to upload them everytime. I don't know how Unity processes the "material.SetTexture()" cases but I seriously hope that calling "SetTexture()" every frame doesn't upload my texture again everytime, although it didn't change from the last frame (hence my request to post the "SetTexture()" only once, when the shader gets recompiled)
Behind the scenes, I believe the $$anonymous$$aterial is requesting the Texture each frame. The request goes through the GPU driver, which checks whether the texture is already in the GPU, loading if needed.
Even if you have just changed the shader, the textures might be in memory anyway. Ex: first use of Diffuse with Bark, but Specular has used and loaded Bark for you. Likewise, you may have been using a shader for a while, but that texture got swapped out when you loaded a huge texture last frame.
I assume that SetTexture merely changes the value in the CPU-stored material, and takes almost no time by itself. Actually drawing the object triggers the GPU texture manager, which may or may not take a while.
Well, I surely hope that the Unity $$anonymous$$m knows what it's doing. ^^