2025, Nov 13 03:00

Ursina/Panda3D GLSL shader warning: "does not contain a #version line" - fix by renaming to .vert and .frag

Seeing 'does not contain a #version line' in Ursina/Panda3D despite #version 150? The fix is file extensions: rename GLSL to .vert and .frag. Learn more.

GLSL shaders in Ursina (backed by Panda3D) can throw a confusing warning even when your shader files look perfectly valid. You hit run, and instead of a crisp shaded scene you get a message that your shader “does not contain a #version line,” despite starting the files with #version 150. The twist is that the issue isn’t inside your GLSL at all.

Symptom

:shader(warning): GLSL shader created-shader does not contain a #version line!

The vertex and fragment sources begin with #version 150, yet the warning persists.

Minimal setup that reproduces the warning

The following Ursina snippet loads GLSL from files that use the .glsl extension. The scene is ordinary: sky, light, two spheres, and a custom shader applied to both entities.

from ursina import *
import numpy as np

SCR_W, SCR_H = 1080, 600
game = Ursina(size=(SCR_W, SCR_H))

window.vsync = False
window.title = "BONDING POTENTIAL TEST"
window.borderless = False
window.fullscreen = False
window.fps_counter.enabled = True
window.exit_button.enabled = False
window.color = color.black

EditorCamera()
skybox = Sky()
pivot_node = Entity()
DirectionalLight(parent=pivot_node, y=1.5, z=3, shadows=True, rotation=(65, -15, 45))

use_alt_view = True

fx = Shader(Shader.GLSL, vertex="testVertexShader.glsl", fragment="testFragShader.glsl")

atom_a = Entity(
    model='sphere',
    scale=1.0,
    world_position=np.array([1, -10, 35]),
    color=color.red,
    shader=fx
)

atom_b = Entity(
    model='sphere',
    scale=1.0,
    world_position=np.array([34, -10, 15]),
    color=color.blue,
    shader=fx
)

What’s really going on

The warning is misleading in this situation. The root cause is the file naming convention. Panda3D requires the .vert and .frag extensions for GLSL shader sources and won’t accept .glsl. After duplicating and renaming the files accordingly, the warning disappears and the shader applies to the scene and camera.

Fix

Rename your shader sources to use .vert and .frag, then reference those exact filenames when creating the shader.

from ursina import *
import numpy as np

SCR_W, SCR_H = 1080, 600
game = Ursina(size=(SCR_W, SCR_H))

window.vsync = False
window.title = "BONDING POTENTIAL TEST"
window.borderless = False
window.fullscreen = False
window.fps_counter.enabled = True
window.exit_button.enabled = False
window.color = color.black

EditorCamera()
skybox = Sky()
pivot_node = Entity()
DirectionalLight(parent=pivot_node, y=1.5, z=3, shadows=True, rotation=(65, -15, 45))

use_alt_view = True

fx = Shader(Shader.GLSL, vertex="testVertexShader.vert", fragment="testFragShader.frag")

atom_a = Entity(
    model='sphere',
    scale=1.0,
    world_position=np.array([1, -10, 35]),
    color=color.red,
    shader=fx
)

atom_b = Entity(
    model='sphere',
    scale=1.0,
    world_position=np.array([34, -10, 15]),
    color=color.blue,
    shader=fx
)

That’s the entire change: keep your GLSL unchanged with #version 150 at the top, but ensure the filenames end in .vert and .frag.

Why this matters

File extensions drive how the engine treats shader sources. When the naming is off, you can end up chasing the wrong problem—editing your GLSL headers and re-checking versions—while the actual issue sits in plain sight on the filesystem. In this case there was no explicit output instructing to switch extensions; the only visible symptom was the version-line warning, which makes the misdirection especially costly in terms of debugging time.

I've seen errors like this when the shader file starts with invisible characters (things not visible in an editor) like a Windows BOM marker

It’s useful to keep in mind that similar warnings can also be triggered by seemingly innocuous file-level details.

Takeaways

If you’re wiring up GLSL in Ursina/Panda3D and see a “does not contain a #version line” warning despite having #version 150 at the top of your files, first validate the filenames. Use .vert for vertex shaders and .frag for fragment shaders. After renaming, the engine will stop complaining and your shader will bind as expected. Keep the GLSL header at the very start of the file, and stay attentive to how the engine discovers resources: a small naming convention can be the difference between a silent failure and a working pipeline.