Адаптировал для панды пример https://gamedev.ru/terms/PerPixelLighting
Код
from panda3d.core import Shader
from direct.showbase.ShowBase import ShowBase
def shader():
return Shader.make(Shader.SL_GLSL,
vertex="""
#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].xy = p3d_MultiTexCoord0;
v_FragmentPosition = p3d_Vertex.xyz;
v_FragmentNormal = p3d_Normal;
}
""",
fragment="""
#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.01, 0.01, 0.01, 0.01);
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):
ShowBase.__init__(self)
lihgt = NodePath("lihgt")
lihg_m = loader.load_model("models/icosphere")
lihg_m.reparent_to(lihgt)
lihgt.setPos(-5, 30, 15)
lihgt.reparent_to(render)
self.room = loader.load_model("models/abstractroom")
self.room.reparent_to(render)
self.room.set_shader(shader())
self.room.set_shader_input("pos_light", lihgt.getPos());
taskMgr.add(self.update, 'camera.update')
def update(self, task):
self.room.set_shader_input("pos_camera", camera.getPos());
return task.cont
demo = TestPointlight()
demo.run()