A problem with cel shading(toon shading)

I want to add the toon-edge on specific model
so using the CartoonEdgeFilter is not the way to solve this, whitch applies a cartoon-style edge detection filter to all objects in the scene.

I have found that using shader can reach my requirement of “add the toon-edge on specific model”
BUT, while shader in JME3 is based on Material, I can’t find a way to use both toon-shader and the texture attached with the j3o model

I use the AssestPack for my work, so I can only use j3o as model.
Is there a way to add toon-edge on a j3o model?

following is the the toon-edge shading code of the Technique part in j3md file I used:

Technique CartoonEdge {
    LightMode MultiPass

    VertexShader GLSL100:   ShaderBlow/Shaders/ToonBlow/ToonBlow_Edges.vert
    FragmentShader GLSL100: ShaderBlow/Shaders/ToonBlow/ToonBlow_Edges.frag


    WorldParameters {
        WorldViewProjectionMatrix
        NormalMatrix
        WorldViewMatrix
        ViewMatrix
        CameraPosition
        WorldMatrix
    }

    Defines {

        SPHERE_MAP : SphereMap
        FOG : FogColor
        FOG_SKY : FogSkyBox
        TOON_EDGES : EdgesColor
        FOG_EDGES : Fog_Edges
    }

    RenderState {
        FaceCull Front
        DepthTest On
        DepthWrite On
    }
}</blockquote>

Pardon my poor English whitch is not my first language.
Thanks for answering question~ :amused:

CartoonEdgeFilter is a post process effect that apply cartoon edges to the entire scene.
I think i remember @mifth having in heis shaderblow project something that was an option of his lighting shader to have cartoon edges on one model.
http://hub.jmonkeyengine.org/forum/topic/lightblow-shader/

Thank @nehon for giving the link, but I have read this before :smiley:

the code i just paste is the part of shaderBlowLib whitch @mifth mentioned

shaderblow project do have something to get cartoon edges on one model, but will replace the original texture of the j3o model.
do you know how to fix this?

No actually you have to use this lightBlow.j3md (is that the name?) definition instead of the lighting.j3md stock material definition.

actually the shaders provide toon edge are matCap.j3md and glass.j3md, and I choose matCap for my test

the following is my code, am i right using this?
[java]
// I add a j3o model with its texture
FloorItems cow = FloorItems.toPickable(app, (Node)assetManager.loadModel(“Models/cow.j3o”));
cow.setLocalScale(2f);
cow.move(new Vector3f(0, 50, 0));
rootNode.attachChild(cow);

// then I open the j3m file as Material, whitch can get cartoon edges on the cow model
Material mat_stl = assetManager.loadMaterial(“Materials/MatCap2.j3m”);

// attach material to the cow
cow.setMaterial(mat_stl);
[/java]

the effect is like this…
thie upper picture is the original model, then the lower one is the model with cartoon edge
but the original texture is replaced!!

here is the j3m file, it calls MatCap.j3md inside

Material My Material : ShaderBlow/MatDefs/MatCap/MatCap.j3md { MaterialParameters { DiffuseMap : Flip TestTextures/matcaps/met2.png Nor_Inv_Y : true Nor_Inv_X : false Nor_Inv_Z : false NormalMap : TestModels/LightBlow/jme_lightblow_nor.png FogSkyBox : Flip TestTextures/Water256.dds
    Toon : true
    EdgesColor : 1.0 0.0 0.0 1.0
    EdgeSize : 0.01
    Fog_Edges : true
 }
AdditionalRenderState {
}

}

mhh I’m surprised, @mifth, doesn’t your lighting shader supports the cartoon edges?

You can probably simulate this yourself with a simple vertex shader by pushing out the vertices in each normal direction and use front face culling.

@nehon said: mhh I'm surprised, @mifth, doesn't your lighting shader supports the cartoon edges?
Yes, the lightblow shder supports the edges. You are right.
@yaya741228 said: actually the shaders provide toon edge are matCap.j3md and glass.j3md, and I choose matCap for my test

Just check this example Google Code Archive - Long-term storage for Google Code Project Hosting.
You can use only color edges but without toon shading. Also, you can change the width of edges…

1 Like

@wezrule : is this what ToonBlow_Edges.vert and ToonBlow_Edges.frag have done? if so, the problem is still :cry:

thank @mifth for the link :amused:

but I still can’t solve my prolblem with this
in the file Toon_Base.j3m , it use texture by following

DiffuseMap : Flip ShaderBlow/Models/ToonBlow/toon.png
it's fine if using the obj or xml file for model with a png or jpg... file for texture BUT if I want to use the j3o file whitch have had its texture in it the Toon_Base Material will replace the texture of the j3o file

maybe there is some way to solve this:

  1. extract the texture from j3o file, so that I can use it as the toon Material’s DiffuseMap , is it possable?
  2. can I use 2 Material in one model? one for texture and one for toon edge? but useing 2 Material in one model seems impossable.
  3. is there other way for toon edge but not using Material?

@yaya741228 actueally i can’t get whatyour problem is. I gave you the link to the example which has Diffuse texture and toon edges. Just try this example and make your own material according mine.
Or you have an issue to assign new material to the model?
You can assign materials through JMP SDK. Just select Geometry and set a material at the properties panel.

<cite>@yaya741228 said:</cite> @wezrule : is this what ToonBlow_Edges.vert and ToonBlow_Edges.frag have done? if so, the problem is still :'(

no idea, haven’t used them :stuck_out_tongue: but that’s how I would do it for an individual model

maybe I should explain my problem shorter…

I need:

  1. open j3o file(with texture)
  2. add toon shading with that (no texture, only shading)
  3. display them

I dont want
1.open obj/xml/j3o file (WITHOUT texture)
2.add toon shading with that (WITH texture AND shading)
3. display them

the difference with them is where is the texture from (in the modle file or load form material)
And I don’t want to load a new texture (diffuse map) when making toon shading.
Is it possible?

thank for helping me, though I don’t have a good express of my question :smiley:
I had read and run all the link and example you gave me, and I’m still trying… Thanks again.

You can’t have several materials on a geometry.
You have to :

  1. open your j3o.
  2. remove the existing material and forget about it.
  3. create a new material with the lightBlow j3md definition
  4. set the texture to that material
  5. set the material on the model
  6. save your j3o.

tnanks @nehon
so I see, I can’t carry the old texture if I want to add a toon edge on a j3o model.
It means that I can’t use the assest pack as my modle.
I think I have to get another way to have some other models with separated texture.

@yaya741228 said: tnanks @nehon so I see, I can't carry the old texture if I want to add a toon edge on a j3o model. It means that I can't use the assest pack as my modle. I think I have to get another way to have some other models with separated texture.

You can… but when you set the new material you have to get the texture from the old one to set on the new material.

@pspeed can you tell me how to get the texture from the old j3o model?
I cant find a way to do so…

http://hub.jmonkeyengine.org/javadoc/
http://hub.jmonkeyengine.org/javadoc/com/jme3/material/Material.html
http://hub.jmonkeyengine.org/javadoc/com/jme3/material/Material.html#getTextureParam(java.lang.String)
http://hub.jmonkeyengine.org/javadoc/com/jme3/material/MatParamTexture.html
http://hub.jmonkeyengine.org/javadoc/com/jme3/material/MatParamTexture.html#getTextureValue()

but @pspeed, when I load a j3o file, it will become a Spatial like this…

Spatial model = assetManager.loadModel(“Model/ testModel.j3o”);

if I have a Material, I can get its texture surely
but now I only have the Spatial load by assetManager, I cant get its Material or even texture…
so that’s why I cant put a shading on a j3o model with its old texture.

@yaya741228 said: but @pspeed, when I load a j3o file, it will become a Spatial like this...

Spatial model = assetManager.loadModel(“Model/ testModel.j3o”);

if I have a Material, I can get its texture surely
but now I only have the Spatial load by assetManager, I cant get its Material or even texture…
so that’s why I cant put a shading on a j3o model with its old texture.

Sigh… I apologize. Sometimes I assume people know how to traverse the scene graph and stuff. This may be too hard for you.

[java] public Material makeToonishAndTransferOldTexture(Spatial spatial){
if (spatial instanceof Node){
Node n = (Node) spatial;
for (Spatial child : n.getChildren())
makeToonishAndTransferOldTexture(child);
}else if (spatial instanceof Geometry){
Geometry g = (Geometry) spatial;
Material m = g.getMaterial();

          if(m.getParam("DiffuseMap") != null){
        	  Texture dm = (Texture) m.getParam("DiffuseMap").getValue();
         
        	  Material mat = mainapp.assetpreloader.toon4.clone();
        	  mat.getParam("DiffuseMap").setValue(dm);
        	  g.setMaterial(mat);
        	  return mat;
          }
      }
      
      return null;
  }[/java] 

Try this method. It takes a model, applies a LightBlow material, and transfers the old DiffuseMap from the loaded model to the LightBlow material. This allows you to have a lightblow material while still having the old texture!

It works wonders for me :smiley: