x


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! ;-)

more ▼

asked Mar 15 '11 at 03:02 PM

Jessy gravatar image

Jessy
15.7k 72 95 198

(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

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.

more ▼

answered Mar 15 '11 at 03:12 PM

Statement gravatar image

Statement ♦♦
20.2k 35 71 176

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, instead 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.

Mar 15 '11 at 03:37 PM Jessy

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 ExecuteInEditMode and write a dedicated update script for this?

Mar 15 '11 at 05:16 PM Statement ♦♦

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.

Mar 15 '11 at 05:18 PM Statement ♦♦

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.

Mar 15 '11 at 06:03 PM Jessy
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1744
x47
x46

asked: Mar 15 '11 at 03:02 PM

Seen: 1385 times

Last Updated: Mar 15 '11 at 03:02 PM