I discovered a strange behaviour while testing “software” points, if I try to send to the shader extra vertex data, the shader receive a constant random value.
Here is some code, if the point color is from p3d_Color, everything is fine, the points shade from green to red, if I uncomment the line for the extra data, the line is a solid color, red on my computer.
from panda3d.core import *
from math import pi, cos, sin
from direct.directbase import DirectStart
def shader():
return Shader.make(Shader.SL_GLSL,
vertex="""
#version 410
uniform mat4 p3d_ProjectionMatrix;
uniform mat4 p3d_ModelViewMatrix;
in vec4 p3d_Vertex;
in vec4 p3d_Color;
in vec4 extra;
out vec4 color;
void main() {
gl_Position = p3d_ProjectionMatrix * (p3d_ModelViewMatrix * p3d_Vertex);
//Uncomment to see the correct colors.
//color = p3d_Color;
//Uncomment to see the wrong color
color = extra;
}
""",
fragment="""
#version 410
in vec4 color;
out vec4 frag_color;
void main() {
frag_color = color;
}
""")
def make_geom(points, colors, size):
array = GeomVertexArrayFormat()
array.add_column(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint)
array.add_column(InternalName.make('color'), 4, Geom.NTFloat32, Geom.CColor)
array.add_column(InternalName.make('size'), 1, Geom.NTFloat32, Geom.COther)
array.add_column(InternalName.make('extra'), 4, Geom.NTFloat32, Geom.COther)
format = GeomVertexFormat()
format.addArray(array)
format = GeomVertexFormat.registerFormat(format)
vdata = GeomVertexData('vdata', format, Geom.UH_static)
vwriter = GeomVertexWriter(vdata, 'vertex')
colorwriter = GeomVertexWriter(vdata, 'color')
sizewriter = GeomVertexWriter(vdata, 'size')
extrawriter = GeomVertexWriter(vdata, 'extra')
geompoints = GeomPoints(Geom.UH_static)
for index, (point, color) in enumerate(zip(points, colors)):
vwriter.add_data3(point)
colorwriter.add_data4(color)
sizewriter.add_data1(size)
extrawriter.add_data4(color)
geompoints.add_vertex(index)
geom = Geom(vdata)
geom.add_primitive(geompoints)
return geom
size = 1000
points = []
colors = []
for i in range(size):
theta = pi * i / size
x = cos(theta)
y = sin(theta)
z = 0
points.append(LPoint3(x, y, z))
a = i / size
colors.append(LColor(1 - a, a, 0, 1))
geom = make_geom(points, colors, 4)
gnode = GeomNode('gnode')
gnode.add_geom(geom)
np = NodePath(gnode)
np.set_shader(shader())
np.reparent_to(render)
base.cam.set_pos(0, -1, 0)
base.run()