Error if you replace gl_MultiTexCoord0 on p3d_MultiTexCoord0

I started studying shaders in Panda, first of all I decided to implement pixel lighting, I found the code for OpenGL and sort of successfully adapted it.

from panda3d.core import CardMaker, Shader
from direct.showbase.ShowBase import ShowBase

def shader():
    return Shader.make(Shader.SL_GLSL,
#version 120

varying vec3 v_FragmentPosition;
varying vec3 v_FragmentNormal;

attribute vec2 p3d_MultiTexCoord0;
attribute vec4 p3d_Vertex;
attribute vec3 p3d_Normal;

uniform mat4 p3d_ModelViewProjectionMatrix;

void main( void )
    gl_Position    = p3d_ModelViewProjectionMatrix * p3d_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    v_FragmentPosition  =;
    v_FragmentNormal  = p3d_Normal;


#version 120

uniform sampler2D p3d_Texture0;
uniform vec3 pos_light;
uniform vec3 pos_camera;

varying vec3 v_FragmentPosition;
varying vec3 v_FragmentNormal;

const vec4  k_LightColor = vec4(1.0, 0.6, 0.3, 1.0);
const float k_Shininess = 64.0;

const float k_ConstAttenuation = 0.5;
const float k_LinearAttenuation = 0.05;
const float k_QuadricAttenuation = 0.001;

void main( void )
    vec3  L = pos_light - v_FragmentPosition;

    // ** Used in the calculation of light extinction
    float distance = length( L );

    L = normalize( L );
    vec3  N = normalize( v_FragmentNormal );

    // ** The H vector is used to calculate the gloss (specularity) of a fragment
    vec3  E = normalize( pos_camera - v_FragmentPosition );
    vec3  H = normalize( L + E ); // ** Half-vector

    // ** The calculation coefficient. attenuations
    float attenuation = 1.0 / ( k_ConstAttenuation + k_LinearAttenuation * distance + k_QuadricAttenuation * distance * distance );

    float diffuse = clamp( dot( L, N ), 0.0, 1.0 );
    float specular  = pow( clamp( dot( N, H ), 0.0, 1.0 ), k_Shininess );
    if( diffuse <= 0.0 ){
        specular = 0.0; 
    vec4 diffuseColor  = diffuse * k_LightColor * attenuation;
    vec4 specularColor = specular * k_LightColor * attenuation;
    vec4 ambientColor = vec4(0.02, 0.02, 0.02, 0.02);
    vec4 emissionColor = vec4(0.0, 0.0, 0.0, 0.0);

    gl_FragColor = ( diffuseColor + specularColor + ambientColor + emissionColor) * texture2D(p3d_Texture0, gl_TexCoord[0].xy );

from direct.showbase.ShowBase import ShowBase
from panda3d.core import NodePath

class TestPointlight(ShowBase):

    def __init__(self):
        lihgt = NodePath("lihgt")
        lihg_m = loader.load_model("../models/icosphere")
        lihgt.setPos(-5, 30, 15)
        room = loader.load_model("../models/abstractroom")
        room.set_shader_input("pos_light", lihgt.getPos());
        room.set_shader_input("pos_camera", camera.getPos());
demo = TestPointlight()

However, I can’t replace gl_MultiTexCoord0 with p3d_MultiTexCoord0, this causes an error:

:display:gsg:glgsg(error): An error occurred while compiling GLSL vertex shader created-shader:
created-shader(16) : error C1035: assignment of incompatible types

The second problem is an artifact with lighting.

I think this is a consequence of the fact that I use input from OpenGL.

I think gl_TexCoord is a vec4, or possibly a vec3, but you are assigning a vec2 to it. You could instead do gl_TexCoord[0].xy = p3d_MultiTexCoord0;

The use of gl_TexCoord is generally not necessary any more, I think you should instead use a custom varying variable for passing inputs to the fragment shader.

This worked, but the artifacts in the form of straight illuminated lines remained.

It looks like the problem was the wrong mirror color.
Oh Yes, the camera position should be updated in every frame.

You don’t need to manually pass in the camera and light position if you make use of the built-in shader inputs:

See this codebase for an example GLSL 120 shader that implements lighting using the built-in inputs:

The problem is that I will depend on different classes of light, materials that are part of the Panda and are not always convenient. I have come to the conclusion that it is easier to write the necessary classes myself. For example, the light source, material, and so on. This is probably the only camera class that I can use in shaders without changes.