Cartoon Edge Filter - insight needed

This question has been asked before - but not answered (at least not in a way I can understand).

I want to apply the cartoon edge filter to only some of the spatials in the scene.

How do I do this? Ideally I would like to be able to include / exclude a spatial by setting it’s material.

If there is no way to apply the edge filter to some objects and not others - can I at least have a different color outline for different objects?

You can’t. The CartoonEdgeFilter works on the entire scene, period.

You’ll have to use something different if you want to apply the effect on only one object.

@thetoucher made a RimLight shader

Maybe you could use this.

@chototsu did cool shader with cartoon edges. I included it into my library. Have a try.

It has a java class (cartoonedgeprocessor) and a shader. - have a look at an example with a fox character.

Looks promising, but I get this error when I try to use Materials/LightBlow/Shading_System/LightBlow_rim.j3m

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

com.jme3.asset.AssetLoadException: An exception has occured while loading asset: MatDefs/LightBlow/LightBlow.j3md

at com.jme3.asset.DesktopAssetManager.loadAsset(

at com.jme3.material.plugins.J3MLoader.loadFromRoot(

at com.jme3.material.plugins.J3MLoader.load(

at com.jme3.asset.DesktopAssetManager.loadAsset(

at com.jme3.asset.DesktopAssetManager.loadMaterial(

at mygame.Tank.loadMaterial(

at mygame.Tank.(

at mygame.WorldLoader.createTanks(

at mygame.GameConfig.parseSpawns(

at mygame.GameConfig.(

at mygame.Main.simpleInitApp(


at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(



Caused by: Vector4 value parameter must have 4 entries: Color

at com.jme3.material.plugins.J3MLoader.readValue(

at com.jme3.material.plugins.J3MLoader.readParam(

at com.jme3.material.plugins.J3MLoader.readMaterialParams(

at com.jme3.material.plugins.J3MLoader.loadFromRoot(

at com.jme3.material.plugins.J3MLoader.load(

at com.jme3.asset.DesktopAssetManager.loadAsset(

… 14 more

Am I doing something wrong?

Please, get latest mercurial version of a shaderBlow (hg clone ) and update your JMP(jMonkey Platform) with nightly builds.

I have forgotten to say that there is entire jmp project with examples. Have a try to test it. :slight_smile:

1 Like

Cool thanks, I finally got it working (actually had to go back to an older build of JME)

One question - with the ToonBlow shader - can I change the outline color to something other than black?

Yes you can. I thought about it too and i will implement it soon.

If you want it now… all you need is just set a Color parameter to ToonBlow_Edges.frag.

[java]gl_FragColor = vec4(0.0);[/java]

vec4(0.0) is an rgba color.


I want to change part of my graph’s edge which made by custom mesh, failed with exceptions, so I made one test in


public class CopyOfTestCustomMesh extends SimpleApplication {

public static void main(String[] args){

CopyOfTestCustomMesh app = new CopyOfTestCustomMesh();




public void simpleInitApp() {

viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));

Mesh m = new Mesh();

Vector3f [] vertices = new Vector3f[4];

vertices[0] =new Vector3f(1.1f,0,1.1f);

vertices[1] =new Vector3f(-1.1f,0,1.1f);

vertices[2] =new Vector3f(-1.1f,0,-1.1f);

vertices[3] =new Vector3f(1.1f,0,-1.1f);

Vector3f [] verticesO = new Vector3f[13];

verticesO[0] = new Vector3f(-2.7f,0,0).mult(1f);

verticesO[1] = new Vector3f(-2.7f,-3,0).mult(1f);

verticesO[2] = new Vector3f(0,-3,0).mult(1f);

verticesO[3] = new Vector3f(0,-4.6f,0).mult(1f);

verticesO[4] = new Vector3f(3.6f,-4.6f,0).mult(1f);

verticesO[5] = new Vector3f(3.6f,-1.3f,0).mult(1f);

verticesO[6] = new Vector3f(5.8f,-1.3f,0).mult(1f);

verticesO[7] = new Vector3f(5.8f,2.6f,0).mult(1f);

verticesO[8] = new Vector3f(4.3f,2.6f,0).mult(1f);

verticesO[9] = new Vector3f(4.3f,5.3f,0).mult(1f);

verticesO[10] = new Vector3f(-7f,5.3f,0).mult(1f);

verticesO[11] = new Vector3f(-7f,-0.5f,0).mult(1f);

verticesO[12] = new Vector3f(-2.7f,-0.5f,0).mult(1f);

Vector2f [] texCoord = new Vector2f[4];

texCoord[0] = new Vector2f(0,0);

texCoord[1] = new Vector2f(1,0);

texCoord[2] = new Vector2f(0,1);

texCoord[3] = new Vector2f(1,1);

int [] indexes = {0,1,2, 2,3,4, 4,5,6, 6,7,8, 8,9,10, 10,11,12, 2,4,5, 5,7,8, 5,8,10, 0,2,5, 0,10,12, 0,5,10,5,6,7};

m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(verticesO));

m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));

m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes));


Mesh wfMesh = m.clone();

Geometry wfGeom = new Geometry(“wireframeGeometry”, wfMesh);

//Material matWireframe = new Material(assetManager,“Common/MatDefs/Misc/Unshaded.j3md”);

//matWireframe.setColor(“Color”, ColorRGBA.Green);

//matWireframe.setTexture(“ColorMap”, assetManager.loadTexture(“Interface/Logo/Monkey.jpg”));


Material matWireframe = new Material(assetManager,“MatDefs/ToonBlow/ToonBlow.j3md”);



TangentBinormalGenerator.processTriangle(indexes, verticesO, texCoord);





Can not see anything in the JME window,(My environment is ok, can execute you code successfully), I don’t know what the problem is, can you take a look?

Many thanks.

Do you have a light source?