- Home /
Where can you store data in a shader, so that it's not computed for every fragment?
Please pardon me for being a n00b at GLSL. I haven't come across information about this yet, in my reading. I wrote this shader, which is kind of like a "terrain" shader, except the RGB channels are masks for colors, not textures. Take a gander first, I guess:
Properties { _MainTex ("RGB = Color Masks, A = Texture", 2D) = "" {} _RedColor ("Color for Red Texture Channel", Color) = (1,1,1) _GreenColor ("Color for Green Texture Channel", Color) = (1,1,1) _BlueColor ("Color for Blue Texture Channel", Color) = (1,1,1) }
SubShader {Pass { GLSLPROGRAM varying lowp vec2 uv;
#ifdef VERTEX
void main() {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
uv = gl_MultiTexCoord0.xy;
}
#endif
#ifdef FRAGMENT
uniform lowp sampler2D _MainTex;
uniform lowp vec3 _RedColor, _GreenColor, _BlueColor;
void main() {
lowp vec4 masks_texture = texture2D(_MainTex, uv);
gl_FragColor = vec4(
mat3(_RedColor, _GreenColor, _BlueColor)
* masks_texture.rgb * masks_texture.a,
1
);
}
#endif
ENDGLSL
}}
My concern is, that matrix of colors only needs to be created once per pass. I'm afraid that as it is, it will be created for every fragment. It's just plugging numbers in, with no calculations, so I doubt it's too big a deal, but I want to learn to write these to be as efficient as possible, and use good practice for future shaders.
Should I store the matrix as a variable outside the function? And if so, where? I don't know enough about GPUs or compilers yet; hopefully you do! ;-)
Answer by Statement · Mar 15, 2011 at 03:12 PM
You should be able to create a uniform matrix and set the matrix or vector4 on the shader through the material.
See Material.SetMatrix, Material.SetColor, Material.SetVector.
Basically you'd calculate the matrix/color/whathave you in update and update the value in the shader. That way you compute it once a frame. If you are dealing with multipass rendering I am not quite sure what callback you should hook up with, I haven't done so myself.
In other words: Basically you just create another property with a uniform variable just as you have done for the red, green and blue colors. Then you create a similar function to mat3 in C#/JS/Boo code and call that with the values of r/g/b. Then store the result in your computed color property.
I know you can do that. But the usability of that, for tweaking materials in the Editor, is nil, so I'm not interested. If there is no way to store data for an entire pass, ins$$anonymous$$d of for every pixel, then I'll leave the code as is. Or maybe I'll move the matrix to the vertex shader. Again, I'm new at this, so I don't know good practices.
Yeah, moving it to the vertex shader cuts down some computation although it would be neater to have it defined before the shader is used. Perhaps you can toy around with ExecuteInEdit$$anonymous$$ode and write a dedicated update script for this?
This would of course require to have an instance so it's not a very elegant solution. Hmm, let me take a look in the docs and see if I can find some better approach.
I have no desire to do anything outside of the shader. I'm going to be using colors on materials; life is going to be too much of a pain without that. This question is in no way limited to this particular shader. I just want to know if there's any place in a shader to define something once, or if that idea is just alien to programmable shader-writing practice.
Your answer
Follow this Question
Related Questions
How to prevent shader optimizations? 1 Answer
Shader problems! GLSL Questions! 0 Answers
Cg Language incompatibility Desktop VS GLSL Android 0 Answers
Decoding a video on the GPU 0 Answers
Grabpass refraction masking 0 Answers