0
$\begingroup$

I am trying to export GLSL from Blender materials in a scene. This call appears to have been removed from module "gpu" in Blender's Python API as of 2.80. Is there any substitute? How should I proceed?

$\endgroup$
2
$\begingroup$

I, too, am dismayed that this function is no longer available. There doesn't seem to be any direct substitute, but, if you really want to look at the shaders, you could ...

  • Launch Blender from a command line with --debug-gpu-shaders
  • Blender will emit a few hundred lines of "Shader file written to disk: (path)"
  • Render your model, preferably alone in its own layer. Your cmd/shell window will show some more files written.
  • Filter the hundreds of generated files in (path) by searching in file contents for EEVEE_ENGINE. The others are probably UI related, just guessing. If you have many objects in your scene, this may also become overwhelming, but it will at least filter out the shaders used by blender itself rather than your models. The largest of these files is probably what you're looking for.

What you will find, however, is an absolute beast that you'll have no idea what to feed it. Search in the fragment shader for uniform - all those have to be supplied by you, do you know what they all mean? Now, if you want to go on an adventure, you could spend some time in the Python console doing

dir(gpu)
dir(gpu.shader)
dir(gpu.types)
dir(gpu.types.GPUShader)
dir(gpu.types.GPUBatch)

... and so forth. GPUShader seems to be completely opaque once its constructor is called with the shader source. GPUBatch encapsulates all the draw calls and data needed to render an object, but I haven't figured out how to get the data back out of it or determine what uniforms to bind where, etc.

Another option would be to export to something like glTF, which does have a material spec, but does not include shaders directly. Then use one of the available parsing/rendering libraries ( https://www.khronos.org/gltf/ ) with its own built in shaders that can emulate a lot of what the principled BSDF does to within an acceptable limit. Some of those are only parsers, not renderers, so check for that. Dynamically generated textures may be a problem though. For example, BabylonJS has many included shaders for various materials, and you can view their source at https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.js

The bottom line though, it seems, and I hate to say it, Blender's materials are for Blender's engine. If you're working in another game engine, it's best to create the geometry and rigging in Blender, and use the material system in your target engine to skin it.

The only way I can think to approach the problem if you're just writing your own simple engine in C++, for example, and you need the GL calls and data to draw what you see in Blender, would be to somehow hook the calls to GPUShader and GPUBatch constructors and dump the data as it's being created in Blender. You would also have to hook/dump those uniform values at draw time. Haven't tried that personally. Otherwise, just accept the limitations of your export format.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.