The Problem With Shaders

this is to my knowledge the simplest useable shader (that doesn’t simply replace what’s already there) that you can write in that game engine.

import bge 
own = bge.logic.getCurrentController().owner

VertexShader = """
    void main()
    {
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
        gl_TexCoord[0] = gl_MultiTexCoord0;
    }
"""
  
FragmentShader = """
uniform sampler2D texture;
 
    void main()
    {   
        vec4 colour = texture2D(texture, vec2(gl_TexCoord[0].x, gl_TexCoord[0].y));
        gl_FragColor = vec4(colour[0],colour[1],colour[2],colour[3]);
    }
"""
 
mesh = own.meshes[0]
for mat in mesh.materials:
    shader = mat.getShader()
    shader.setSource(VertexShader, FragmentShader, 1)
    shader.setSampler('texture', 0) 

it’s relatively simple, it does the usual gl pos calc, gets the pre existent texture and then “re-applies it”, this is fine for the overwhelming majority of purposes and will for the most part all you’ll ever need if that.

but what i want to know is how you get the rest of the information that’s typically found here


in the influence tab in the BGE using GLSL. any help would be greatly appreciated.

before you ask, my Blender version is 2.78a my game engine, openGL, and GLSL version are the ones that came with the default settings etc.

UPBGE +0.2x has:

import bge
self = bge.logic.getCurrentController()

self.owner.meshes["Mesh_Name"].materials["Material_Name"].textures["Texture_Name"]

Unfortunately BGE doesn’t I think… Could be wrong.

ehh yes and no, it’d look something closer to

import bge
self = bge.logic.getCurrentController()

print(self.owner.meshes[0].materials[0].getTextureBindcode(0));

more on that here:

but also this doesn’t exactly answer the question, I’m asking about how to retrieve geometry/diffuse/specular (influence) data etc in the vertex or fragment shader, while this could probably be worked around in BGE/BGL code i think it’d be really inefficient I do appreciate the answer though!

The uniforms from a blender material shader don’t transfer over a custom shader, so it’s not possible to retrieve any influence from a texture in the vertex or fragment shader. Also, the names of the uniforms of a blender material are generic, like unf25, and there are constants like cons82, which appears to be the Ambient, that could not be retrieved as they are not uniforms.
If you haven’t tried already, you can export the shader of a blender material, to see what I’m talking about. Here’s a script that exports the vertex and fragment shaders to textblocks, based on the example from the documentation.

import bpy
import gpu

materialName = "Material"

scene = bpy.data.scenes["Scene"]

material = bpy.data.materials[materialName]
shader = gpu.export_shader(scene,material)

vertexShader = bpy.data.texts.new(materialName+'.vs')
vertexShader.write(shader['vertex'].replace('\r','')) # remove carriage return

fragmentShader = bpy.data.texts.new(materialName+'.fs')
fragmentShader.write(shader['fragment'].replace('\r',''))

1 Like

I ran your code, and this is really cool, unfortunately I get this monstrosity
JustWhy.txt (216.1 KB)
which is completely useless if you don’t know where the fragment shader and the vertex shader begin and end, and this is just a basic diffuse shader that makes it yellow, and i’m personally not willing to search 4 thousand lines of code to find out, this is very interesting though!

That’s only the fragment shader, the vertex shader should be in a textblock with the extension ‘vs’.
It’s almost 4000 lines because it has every function needed to create every possible material, only the last 18 lines are the main function. There you can see the name of the uniforms, how, even if they could be used in a custom shader, you would have to figure out what is what.

You have to set those parameters as uniforms in the python end and treat them accordingly in the glsl(or just use them as literals). here is what the computer generated shader looks like with humanly readable names:
blenderShader.blend (1.2 MB)

i’m sorry, i had such a blond moment and just went ahead and read the code without reading the variable name. was wondering why there was basically no code prior to gl_FrontFacing.

Ultimate Passthrough shader for BGE 2.78a (630.2 KB)
I decided to come back and revisit this. It’s kinda funny that my solution was literally to reconstruct the model that is used in the BGE rather than passing through the data like I’d originally intended; but I digress the shader has some imperfections and isn’t as 1:1 as I was hoping to achieve. any help rectifying this as much as possible would of course be well appreciated. I also didn’t bother at all with the geometry metric as I don’t know how to obtain it from the material/texture/influence tab. I think what I do have is still impressive though.

did some experimentation and found that it may be possible to preset the data as a gameproperty from the bpy before the game starts. but that just seems… redundant to say the least. any way I could just straight up get the memory adress and access it that way?
it wouldn’t allow for stuff like animations though.

Going to comment to bump this since it’s been a few days now.