[Bf-viewport] OpenGL low level shader API proposal

Brecht Van Lommel brechtvanlommel at pandora.be
Sat Dec 5 16:45:59 CET 2015


On Sat, Dec 5, 2015 at 10:50 AM, Antony Riakiotakis <kalast at gmail.com> wrote:
> * Transform is no different than a GPUShaderParam now. One can easily think
> of UI shaders where we just work with 2D coordinates

Indeed, a transformation can actually be stored in GPUShaderParams
under the hood, I'd just like to avoid users having to do that
manually each time.

> This can be achieved with a two layer system:
> We have a low level shader compilation, binding, etc system, and we have a
> use-case-specific shader interface which sits on top of it.

That's kind of what I'm proposing :).

But the design is different than yours. The funky shader example is a
use case specific shader interface.

* funky_shader_new() would compile the shader with GPU_shader_create()
* funky_material_params_finalize() would set uniforms with functions
like GPU_shader_uniform_vector()


> LightParams *lp = interface->getLightParams();
>
> lp->light_pos = pos;

What I'm missing here is the ability to reuse a set of shader
parameters. Consider for example the current GLSL node materials, if
you have multiple materials on an object then their shaders could
share the same per object GPUShaderParameters.

The other thing is that GPUShaderParams would be immutable once
created, so that per object GPUShaderParameters could be uploaded to
the GPU once and cached. With your interface the bind() call is
required to re-upload the data every time? I would like the parameters
to be validated and ready before that.

> GPUAttribute *p = interface->getPositionAttribute();
>
> GPU_bind_vertex_buffer(p, offset, stride, etc...);

I think we need a way to have both different types of meshes (cddm,
subsurf, metaballs, ..) and different types of shaders (GLSL, solid
lighting, matcaps, ..) working together.

So we need a general mechanism, where for all types of shaders you can
get the required attributes, for which I proposed using
GPUShaderVertexAttribs. It's not really clear to me if in this example
getPositionAttribute() is a function specific to one shader type or
available for all shader types?

> /* bind shader */
> shader->bind();
>
> /* sets attributes appropriately and effectively */
> interface->bind();
>
> /* draw */
> GPUdraw(numeElements, drawType)

I'm specifically trying to avoid binding and state, to avoid state
accidentally leaking, or having to deal with verbose and error prone
unbinding and unsetting of state. If there is only a small amount of
state then it's not as bad, I just prefer to pass it explicitly to the
draw function.


I can see that with my proposal it's not as clear which parameters and
attributes you need to pass. Having a data structure that has both a
pointer to the GPUShader and a set of GPUShaderParams would be simpler
to use. The funky shader example API could be like this:

GPUShaderParams *funky_light_params(FunkyLight light[], int num_lights);
GPUShaderInstance *funky_shader_instance(FunkMaterialParams *funky,
GPUShaderParams *shared_light_params);

And then you pass only that GPUShaderInstance* to the draw function.


Thanks for the feedback,
Brecht


More information about the Bf-viewport mailing list