I also did some experiments with shaders in FreeCAD some time ago. My original goal was to implement MatCaps and Ambient Occlusion, but never had the time to achieve anything substantial.

This might be useful to you:

Vertex shader (vshader.glsl):

Code: Select all

```
varying vec4 eposition;
varying vec3 normal;
varying vec3 diffuseColor;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
eposition = gl_ModelViewMatrix * gl_Vertex;
normal = gl_NormalMatrix * gl_Normal;
}
```

Fragment shader (fshader.glsl):

Code: Select all

```
varying vec4 eposition;
varying vec3 normal;
varying vec3 diffuseColor;
void main(void)
{
const vec3 lightColor = vec3(1, 1, 1);
//vec3 eye = -normalize(eposition);
float nDotVP = max(0.0, dot(normalize(normal), normalize(lightColor)));
gl_FragColor.xyz = vec3(1,1,1) * nDotVP;
gl_FragColor.w = 1.0;
}
```

Python Code:

Code: Select all

```
from pivy.coin import *
shaderSearchDir = "/path_to_freecad_projects/FreeCAD_Shading_Experiments/"
def createShader():
vertexShader = SoVertexShader()
vertexShader.sourceProgram.setValue(shaderSearchDir + 'vshader.glsl')
fragmentShader = SoFragmentShader()
fragmentShader.sourceProgram.setValue(shaderSearchDir + 'fshader.glsl')
shaderProgram = SoShaderProgram()
shaderProgram.shaderObject.set1Value(0, vertexShader);
shaderProgram.shaderObject.set1Value(1, fragmentShader);
return shaderProgram
def createDirLight():
light = SoDirectionalLight()
light.direction.setValue(SbVec3f(0, 0, -1))
light.color.setValue(SbColor(0, 0, 1))
return light
def createSphere():
s = SoSphere()
return s
def printSceneGraph(root, level):
indent = ' ' * level
print('{0} name:"{1}" type:{2} id:{3} : {4}'.format(indent, root.getName(), root.getNodeType(), root.getNodeId(), type(root)))
if isinstance(root, SoGroup):
num = root.getNumChildren()
for i in range(num):
c = root.getChild(i)
printSceneGraph(c, level + 1)
def addCustomShadedSphere(root, shader):
sep1 = SoSeparator()
ssep = SoSeparator()
sph = createSphere()
ssep.addChild(sph)
sep1.addChild(shader)
sep1.addChild(ssep)
root.addChild(sep1)
printSceneGraph(sep1, 0)
view = Gui.ActiveDocument.ActiveView
root = view.getSceneGraph()
#dir(graphRoot)
printSceneGraph(root, 0)
shader = createShader()
addCustomShadedSphere(root, shader)
# root.addChild(shader)
#light = createDirLight()
#graphRoot.insertChild(shader, 0)
#graphRoot.insertChild(light, 0)
```