Passing vertex color to a shader


I am trying to pass vertex color to a shader but it doesn’t seem to work. I always get a float4(1.0, 1.0, 1.0, 1.0), whatever the object’s color is. I saw a similar thread in here, tried the workaround but no difference.

I have float4 vtx_color0 : COLOR0 as a parameter to my vertex shader, then pass it to the pixel shader after doing l_color0 = vtx_color0. Am I doing something wrong here?


We have just discovered a bug involving passing vertex color to a shader. The problem is that Cg doesn’t appear to support a vector parameter encoded as a series of four unsigned bytes, which is the normal way color is encoded.

One workaround is to convert the colors on any models you wish to use with this shader to floating-point. You can use the following function to do this:

def makeFloatColors(nodePath):
    colorName = InternalName.getColor()

    vdMap = {}

    # Get all the GeomVertexDatas at this NodePath and below.
    for gnp in nodePath.findAllMatches('**/+GeomNode').asList():
        gn = gnp.node()
        for i in range(gn.getNumGeoms()):
            geom = gn.modifyGeom(i)
            vd = geom.getVertexData()
            newVd = vdMap.get(vd, None)

            if newVd == None:
                # Check the format of this GeomVertexData.
                format = vd.getFormat()
                color = format.getColumn(colorName)
                if color and color.getNumericType == Geom.NTFloat32:
                    # This data already has a color column, and it's
                    # already a float type.  Great!

                    # We need to convert an existing column column to
                    # float, or add a new float color column.

                    newFormat = GeomVertexFormat(format)

                    colorArray = GeomVertexArrayFormat(colorName, 4, Geom.NTFloat32, Geom.CColor)
                    newFormat = GeomVertexFormat.registerFormat(newFormat)

                    newVd = vd.convertTo(newFormat)
                    vdMap[vd] = newVd

            if newVd != None:

Just call makeFloatColors(model), where model is the NodePath at the root of the model you have loaded.

We are working on a better workaround.


Thanks David, that helped.