private static List<ShaderSnippet> AssembleFragmentSnippets(ShaderSnippet sceneFragmentShader,
            List<OptionalDataBuffer> buffers, List<Light> lights)
        {
            List<ShaderSnippet> fragmentSnippets = new List<ShaderSnippet>();
            //fragmentSnippets.reserve(1 + buffers.Count + lights.size());
            fragmentSnippets.Add(sceneFragmentShader);

            foreach (var buffer in buffers)
                fragmentSnippets.Add(buffer.GetFragmentShaderGLSL());

            if (lights.Count > 0) //only need one instance of light code
                fragmentSnippets.Add(lights[0].GetFragmentShaderGLSL());

            return fragmentSnippets;
        }
        public static ShaderProgram CreateProgram(InstancedModel model,
            ShaderSnippet sceneVertexShader, ShaderSnippet sceneFragmentShader, List<Light> lights)
        {
            Console.Write("Creating vertex and fragment shaders for Model with {0} light(s)... ", lights.Count);

            var buffers = model.GetOptionalDataBuffers();
            var vertexShaderStr = AssembleVertexShaderStr(buffers, sceneVertexShader, lights);
            var fragmentShaderStr = AssembleFragmentShaderStr(buffers, sceneFragmentShader, lights);

            Console.WriteLine("done.");
            return ShaderProgram.MakeProgram(
                Shader.MakeVertexShaderStr(vertexShaderStr),
                Shader.MakeFragmentShaderStr(fragmentShaderStr)
            );
        }
        private static string AssembleFragmentShaderStr(List<OptionalDataBuffer> buffers,
            ShaderSnippet sceneFragmentShader, List<Light> lights)
        {
            var fragmentSnippets = AssembleFragmentSnippets(sceneFragmentShader, buffers, lights);

            return BuildShader(
                AssembleFields(fragmentSnippets),
                AssembleMethods(fragmentSnippets),
                AssembleMainBodyCode(fragmentSnippets) + @"
                    //final fragment shader main body code from ShaderManager
                    if (colors.material == vec3(-1))
                        colors.material = vec3(1);

                    if (colors.lightBlend == vec3(-1))
                        colors.lightBlend = vec3(1);

                    vec3 lighting = ambientLight * colors.lightBlend;
                    vec3 color = colors.material * lighting;
                    gl_FragColor = vec4(color, 1);
                "
            );
        }
 private static string AssembleVertexShaderStr(List<OptionalDataBuffer> buffers,
     ShaderSnippet sceneVertexShader, List<Light> lights)
 {
     var vertexSnippets = AssembleVertexSnippets(sceneVertexShader, buffers, lights);
     return BuildShader(
         AssembleFields(vertexSnippets),
         AssembleMethods(vertexSnippets),
         AssembleMainBodyCode(vertexSnippets)
     );
 }