i guess so.
Keep it up
Some recent issues regarding conditionals, and efficient use of ādiscardā have prompted some design rethinking. Also, after some real use in one of my projects, Iāve decided the workflow is poor, and will be fixing that too.
Conclusion: Iām doing some major design changes in the front end (the UI, loaders, libraries etc) to improve work flow, and shift to a more hierarchical and explicitly ordered structure. Iām not totally abandoning the GUI editor, but the main focus is being shifted a more traditional text based language thats roughly the equivalent of the graphical editor, except with explicit ordering. Iām also cleaning up/revising the node types system to hopefully make developing new node types much more straightforward.
Iām very busy with other stuff at the moment, so this will continue to be a slow process.
Iāve gotten the shader meta language to the point where Iām happy with it. It is working very well, and can quickly generate a wide variety of shaders from one configuration. The shaders can depend on what shader inputs are provided, what tags are set in the scene graph, the what vertex data columns are present, and to a limited (but extendable) extent, what render attributes are present. It supports extensions to the set of factors that can effect shaders, as well as arbitrary custom code generator nodes, and easy use of custom shader code.
With a bit of work, I think I could implement a port of pandaās autoshader in it now. All the features are there, and the workflow for implementing stuff is decent, but poorly documented currently.
There is a minimal example in the repo, but here is a more complex example. Iām not providing the library file which contains some snippets of shader code to back some of the nodes used here. Hopefully Iāll have a better example soon. This is from a closed source project, so I canāt really post everything needed to use it.
def fshader():
# get vertex color
vertexColor=Input("float4 l_color: COLOR")
# multiply vertex color with color from diffTex if there is one
diffTex=ConditionalInput("uniform sampler2D k_diffTex : TEXUNIT0")
diffTexColor=sampleTex(diffTex)
baseColor=Operator(False,"*",vertexColor,diffTexColor)
# discard if we have an alpha tag and alpha is below threshold
doDiscard=RequireTag("alpha")
discardColor=ConditionalPassThrough(doDiscard,baseColor)
alphaDiscard(discardColor)
#apply decal texture if present
decalTex=ConditionalInput("uniform sampler2D k_decalTex : TEXUNIT1")
decalTexColor=sampleTex(decalTex)
decaledColor=decal(baseColor,decalTexColor)
finalColor=FirstAvailable(decaledColor,baseColor)
# get color from material, or default if no material
hasMat=HasMaterial()
_rawMatColor=material()
rawMatColor=ConditionalPassThrough(hasMat,_rawMatColor)
defaultMatColor=Constant("float4","float4(0,0,0,0)")
baseMatColor=FirstAvailable(rawMatColor,defaultMatColor)
#get material buffer color, including matDecal if present
matDecalTex=ConditionalInput("uniform sampler2D k_matDecalTex : TEXUNIT2")
matDecalTexColor=sampleTex(matDecalTex)
matDecaledColor=decal(baseMatColor,matDecalTexColor)
matColor=FirstAvailable(matDecaledColor,baseMatColor)
# get normal using normal map, or basic vertex normal if no normal map
normTex=ConditionalInput("uniform sampler2D k_normalTex : TEXUNIT3")
normFromTex=texNorms(normTex)
normFromVert=Input("float3 l_normal : TEXCOORD1")
norms=FirstAvailable(normFromTex,normFromVert)
normColor=norm(norms)
# output colors
Output(finalColor,"float4 o_color: COLOR0")
Output(normColor,"float4 o_normal: COLOR1")
Output(matColor,"float4 o_misc: COLOR2")
def vshader():
attrColor=Input("uniform float4 attr_color")
vertColor=Input("float4 vtx_color : COLOR")
matColor=MatColor()
doVertColor=HasColumn("color")
doAttrColor=HasColorAttrib()
doMatColor=HasMaterial()
vertexColor=ConditionalPassThrough(doVertColor,vertColor)
materialColor=ConditionalPassThrough(doMatColor,matColor)
atributeColor=ConditionalPassThrough(doAttrColor,attrColor)
white=Constant("float4","float4(1,1,1,1)")
vColor=Operator(False,"*",atributeColor,vertexColor,materialColor)
finalColor=FirstAvailable(vColor,white)
Output(finalColor,"float4 l_color: COLOR")
modelvshader()
This is all very interesting, but Iām not sure what you mean by this:
Do you just mean example code?
I simple mean the particular example in my post requires a lot of other stuff (models, textures, custom loaders, my deferred shading setup etc) which Iām not releasing, so you canāt run that example. There are 2 functional examples you can run included in the repository, but they are somewhat less interesting.
Oh, thatās fine. If you donāt mean a custom shader by deferred shading setup, though.
Hey Craig, Iām replying here instead of the Feature Requests thread.
I donāt understand how to use your shader generator, Forgive me if theres a doc somewhere I missed.
I see these lines:
shaderManager=manager.getManager(["library"],"graph/lit.gen")
shaderManager.genShaders(render,"ShadersOut/debug")
From what I see shaderManager.genShaders() method takes a nodepath as the first argument, like nodepath.setShaderAuto(). Whatās the second argument? The shader which was generated by the getManager() call?
Other than that do we need to write the Cg shaders which the shader generator will use ourselves? Because Cg is beyond me, maybe I should wait a bit more until someone makes a collection of shaders which can be used with your shader generator.
Anyway, keep up the good work

Hey Craig, Iām replying here instead of the Feature Requests thread.
I donāt understand how to use your shader generator, Forgive me if theres a doc somewhere I missed.
I see these lines:shaderManager=manager.getManager(["library"],"graph/lit.gen") shaderManager.genShaders(render,"ShadersOut/debug")
From what I see shaderManager.genShaders() method takes a nodepath as the first argument, like nodepath.setShaderAuto(). Whatās the second argument? The shader which was generated by the getManager() call?
Other than that do we need to write the Cg shaders which the shader generator will use ourselves? Because Cg is beyond me, maybe I should wait a bit more until someone makes a collection of shaders which can be used with your shader generator.
Anyway, keep up the good work
It loads some content from a list of library folders (In this case just ālibraryā, look in there to see said content), then runs a script (In this case āgraph/lit.genā) that defines the shader builder. The second arg to genShaders is simply an optional path to dump debug files to so you can see what it generated.
The manager module (which I just added a few hours ago) provides a simplified API for this good for the case when you donāt want to make multiple different shader builders from different scripts using the same Library. In the Manager module, you will see the Manager class, its pretty simple really, it provides methods for getting shaders onto your nodePaths (genShaders) and making individual shaders (makeShader). Mostly the manager is there to hide the renderStateFactory from you so it wonāt confuse you (while its awesome, you really can ignore it unless you are adding custom node classes such as those in nodes.py)
To customize the shader generator to meet the needs of your project (say you wanted to add support for glow maps or something), you will need to edit the script file that defines the shader generator, and likley need some extra bits of CG code to splice in that you can provide by defining a new node in the library.
If you actually want to customize or extend the included scripts to create/edit new shader generator specifications, thats how you do it, but I recommend a very strong understanding of CG to try. With the current lack of good ways to debug issues, it can be a real challenge to figure out whats not working right. That said, if you just want to tweak some constant and equations (say swap in linear fog), such changes to the library and scripts are trivial.
I really need to draw out some sort of map of the project showing how all the different classes, files, and such relate. Its very strangely constructed (though not all that complicated).
Anyway, if you donāt want to dive into CG (I strongly recommend lots of CG coding, its great fun), you probably want to stay away from writing content for my shader generator. That said, if others provide the features you need, it should be very simple to use in your projects.
Ok, I guess I donāt hve the required knowledge to use it for my project yet.
I really need to draw out some sort of map of the project showing how all the different classes, files, and such relate. Its very strangely constructed (though not all that complicated).
Maybe Pydoc or Doxygen?
I strongly recommend lots of CG coding, its great fun
Iād love to learn Cg, but itās just too complicated. I donāt know how many attempts Iāve made already. I even have a printed version of the Cg Tutorial.

Iād love to learn Cg, but itās just too complicated. I donāt know how many attempts Iāve made already. I even have a printed version of the Cg Tutorial.
Some major improvements to the shader generator (its getting close to done aside from content). Along with the improvements, I updated my shader tutorial to include example usage of my shader generator: github.com/Craig-Macomber/Shader-Tut
Its not great, but it includes some basic custom shaders in panda with explanations, and some trivial use of the shader generator (with rather lacking explanations). CG really is a very simple language (much simpler than C), and Iād like to see more people comfortable using it. Hopefully this will help overcome some of the confusion about it.
Iād like feedback on the intelligibility and usefulness.
Iām really looking forward to this.
ā¦but to be honest it still looks hard to use. If thereās a artist friendy gui shader builder then there should be a way to save all thatās done to a file and then in code just point to a node and say āuse this shader from fileā it should take care of inputs, off screen buffers and all the stuff the shader needs to work.
Just like setShaderAuto() it should worke like a DoTheMagicIDontCareHowInFactImTooStupidToKnowAnyway(nodepath, āmy_shaderā) function.
Maybe itās too much to ask for, but Iāve got nothing to loste so Iām still asking for it.

Iām really looking forward to this.
ā¦but to be honest it still looks hard to use. If thereās a artist friendy gui shader builder then there should be a way to save all thatās done to a file and then in code just point to a node and say āuse this shader from fileā it should take care of inputs, off screen buffers and all the stuff the shader needs to work.
Just like setShaderAuto() it should worke like a DoTheMagicIDontCareHowInFactImTooStupidToKnowAnyway(nodepath, āmy_shaderā) function.
Maybe itās too much to ask for, but Iāve got nothing to loste so Iām still asking for it.
If you donāt want to write your own custom shader generator, its one line to load one, and one line to dump a node into it to have it generate shaders for every geom.
# load some predefined shader generator
shaderManager=shadergenerator.manager.getManager(["shadergenerator/library"],"shadergenerator/graph/basic.gen")
# use it on what ever nodes you want, just like the auto shader
shaderManager.genShaders(myNode)
Take a look at the usage tutorial: github.com/Craig-Macomber/Shade ⦠ain.py#L89
If you want to write your own custom shader generator (which is the only real part of the project that interests me.), of course its a bit more complex. Honestly, regardless of the GUI, letting artists optimize lighting equations is not going to work well (unless they can understand code, in which case editing code is fine, then they are also a coder). Script a new shader generator or use an existing shader generator, and feed it nodes on which the artist has setup the things the shader generator uses (tags, render attributes, shader inputs etc). What GUI you have for your artist to do this is a different issue.
I had some different plans initially, but they were not a good idea.
I updated the shader generator to have an option to output svg graphics of the graphs, some output from my game is dumped here: craig.p3dp.com/ShaderGraphs/
In the root direction there (linked), there are the generator graphs for two different shader generators (one for models, and one for lights). Those are generated from the script files. In the āoutputGraphsā folder are graphs representing the "ActiveGraph"s (which directly translate to shader source) produced for different renderStates. Those are produced from the generator graphs using the renderStates.
All the graph processing and outputting code is in the shaderBuilder module ( github.com/Craig-Macomber/Panda ⦠Builder.py )
There is still lots more debugging info Iād like to add to the graphs, but they are pretty informative as is. You can see that a wide variety of different shaders were generated from my model shader generator (it generated all the node⦠ones).
I think the next improvement would be to detect which ActiveNodes (those in the output graph) came from which generator nodes, and perhaps even include line numbers and/or script lines which resulted in those nodes in the ActiveGraph.