in 2.79, I could apply a shader to an object (this one below is intended to turn a plane red), use setSource() and just look at the result. But in 0.3, its complicated. The shader does not show up. This is my GLSL shader:
float red = 1;
float green = 0;
float blue = 0;
float alpha = 0.5;
uniform float time;
out vec4 fragColor;
void main(void) {
fragColor = vec4(abs(sin(time)),0,0,1);
}
I’m trying to make the plane (which has a bricks texture) pulsate from red to black via the shader, but I cannot get it to.
The console says this error, but I don’t see anything wrong with the script:
The time variable is supposed to be controlled by a Timer property. In the case of the red green blue alpha variables, they are supposed to be for controlling object alpha and colour through multiple game properties. My intent is to apply said shader to only 1 object in the scene, but not the entire scene like a 2D Filter does, like in 2.79, as this gave me a lot of control on what object could or could not have a shader.
Example:
Hook up a GLSL shader python script that just simply changes the object colour to a light grey or something else in 2.79 to an object (like the default Cube), and press P. You’ll see what I mean. No 2D filters required!
I checked the UPBGE online manual and setSource(), setUniform1f, etc are all depreciated, leaving only 2D filters as the option. The problem arises in which a 2D filter applies to the whole game view, not one object. So, is there any way to get a shader to be applied on an object in 0.3, or am I stuck with 2D filters forever? Many game designers want to place only one shader, or more onto an object, and not have it fill the entire screen, a good example might be a glass shader.
You can’t apply a custom GLSL material shader to objects in UPBGE 0.3 the same way it was done in previous versions, from BL_Shader:
BL_Shader is a class used to compile and use custom shaders scripts. This header set the #version directive, so the user must not define his own #version. Since 0.3.0, this class is only used with custom 2D filters.
It doesn’t apply to the plane, and instead, just shows up as a normal plane.
There is a vertex shader and a fragment shader in the code, and then I used the bind() to bind the two shaders and then a batch tries to draw the shader. But it never applies to the plane when I press P.
How can I make a shader batch apply in the UPBGE through a script?
you need to compile a shader only, then take it and swap the source of the bge object blender object to it
I asked GPT3
#To replace the shader source of an object in Blender using Python, you can follow these steps:
#Get a reference to the object and its material:
import bpy
# Get the object
obj = bpy.data.objects['MyObject']
# Get the object's material
mat = obj.active_material
#Find the shader node that you want to modify. If you are using a ShaderNodeCustomFunction node, you can find it using the following code:
# Find the Custom Function node
node = mat.node_tree.nodes.get("Custom Function")
#Modify the shader source code of the node by updating the custom_function property:
# Define the new shader source code
new_shader_src = """
void main() {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
"""
Update the shader source code node.custom_function = new_shader_src This will replace the shader source code of the Custom Function node with the new shader code. You can use similar steps to modify the shader source code of other types of shader nodes. Note that you will need to compile the shader after modifying the source code in order for the changes to take effect. You can use the bpy.ops.shader.custom_function_call() operator to compile the shader, as shown in the previous example.
AttributeError: 'str' object has no attribute 'custom_function_call'
And I cannot find a Custom Function node anywhere in the shader node editor menu. Do I have to build it myself? If so, I don’t know where to start.
All I can find is Script, but that has no inputs/outputs, therefore making it useless…
If I use any other node with the node_tree.get(), the console says:
AttributeError: 'NoneType' object has no attribute 'custom_function'
Which would be the result of the node, not the object having that kind of attribute. I’m getting really stumped here, and need help, as I have been trying to solve this for days, as it was so simple to apply to an object via a Python script back in 2.79, just use setSource() and bam! Instant shader, whereas now it’s almost impossible for some reason…
I am using UPBGE 0.3.5 Alpha (which is based on Blender 3.5)
what you need is to cobble together parts from bgl and video texture examples I think.
we get the texture slot from the material and override it’s source*
I asked youle for a example but did not get one back yet (its the holidays / everyone is busy)
So, the team is in the process of moving those bgl variables over?
Oh, and how would I “get the texture slot and override it’s source”? I tried it with VideoTexture, and it just returned as a black texture that was invalid, rather than a proper shader. Tried with bgl.glShaderSource and with videoTexture, and it just returned a solid red plane…
Why is my shader being invalidated? I am getting very frustrated!
Update: Due to M1’s GLSL shader compiling bug, the reason a plane on OSX with M1 will be black is because the GPU thinks the texture is bound to a variable, and doesnt see the texture as a proper texture. This does not happen with 2D filters, but happens if you try and map any GLSL shader onto an object via the VideoTexture module.
How do I bypass this bug on OSX and get a shader I code to look what its supposed to do? I also use ImageFFmpeg() to map the shader data onto the plane as a texture, and update it using the source.refresh() method. Nothing is wrong with the shaders I create. The GPU will not render it, and says:
UNSUPPORTED (log once): POSSIBLE ISSUE: Texture GLD_TEXTURE NUMBER (int) is bound to variable of type [insert example here like Float], texture is unloadable.
This bug does not affect other machines, only M1 Macs. I assume the GLSL shader compilation woes on MacOS will be fixed with the next version of UPBGE having full Metal support starting with 0.36. I am looking forward to this version that may finally fix that issue. Apple has also depreciated openGL, which could also be one of the reasons too.