Cartoon Render Effects?

I am playing with TestVertexProgramState which have a really cool cartoon render effect.I try to replace the torus  in TestVertexProgramState with a obj model(jmetest/data/model/maggie.obj).Everything seems fine,except that the model became gray.Black and white cartoon is cool,but ,is there a way to make the colors back?

I assume the reason is that the shader does not consider the material colors when shading the object. You could try editing the shader so that it uses gl_FrontColor and gl_FrontMaterial.diffuse colors.

Sorry for kicking this topic up but I'm very interested in the same thing. Seeing this topic is over an year old, I was wondering if someone already took the trouble in making a shader which considers the material colors.



If not, perhaps any tips before I dive into the amazing world of shaders? :slight_smile:



Thanks!

I’ve been playing with a toon shader lately myself here but use materials only to affect the overall tint of the characters, it is derived from a shader example linked in the thread above, there can be improvements to it…I would imagine…pretty much edited it by the seat of my pants, so stuff might be plain wrong, was told that normalmaps can be used to get better specularity, haven’t had the time of late to do much of anything on my project, so that’ll have to wait until have time to figure it out



hope that helps though

toon shader

frag


varying vec3 vNormal;
varying vec3 vVertex;
varying vec2 texCoord0;
varying vec2 texCoord1;

uniform sampler2D specularMap;
uniform sampler2D colorMap0;
uniform float diffuseMult;  
uniform float specMult;
uniform float silhouetteThreshold;
uniform float shininess;
uniform vec4 Material;


void main (void)
{
   vec3 L = normalize(gl_LightSource[0].position.xyz - vVertex);
   vec3 E = normalize(-vVertex);
   vec3 R = normalize(-reflect(L,vNormal));
  
   // Material Color:  
   vec4 base0 = texture2D(colorMap0, texCoord0);
   vec4 spec0 = texture2D(specularMap, texCoord1);
        
   // Silhouette Color:
   vec4 silhouetteColor = vec4(0.0, 0.0, 0.0, 1.0);
          
   // Lighting
   vec3 eyePos = normalize(-vVertex);
   vec3 lightPos = gl_LightSource[0].position.xyz;


   //vec3 Normal = vNormal; //normalize(vNormal);
   vec3 EyeVert = normalize(eyePos - vVertex);
   vec3 LightVert = normalize(lightPos - vVertex);
   vec3 EyeLight = normalize(LightVert+EyeVert);
  
  
   // Simple Silhouette
   float sil = max(dot(vNormal,EyeVert), 0.0);
   if( sil < silhouetteThreshold )
      gl_FragColor = silhouetteColor;
   else
   {
      gl_FragColor =  base0 *gl_FrontMaterial.diffuse*  gl_LightSource[0].diffuse;
  
      // Specular part
      float spec = pow(max(dot(vNormal,EyeLight),0.0), shininess);
  
      if( spec < 0.3 )
         gl_FragColor *= 0.80;
         //gl_FragColor *= 0.7;
      else
          gl_FragColor *= specMult*spec0 + gl_FrontMaterial.specular * gl_LightSource[0].specular;
          
        
  
        // Diffuse part
      float diffuse = max(dot(vNormal,LightVert),0.0);
      if( diffuse < 0.25 )
         //gl_FragColor *= 1.98 * gl_LightSource[0].ambient;
         gl_FragColor *=1.98 * gl_LightSource[0].diffuse;
      else
         //added multiplier to diffuse
         gl_FragColor *= (diffuseMult* base0 + gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse) * Material;
        
      }
}



vert


varying vec3 vNormal;
varying vec3 vVertex;
varying vec2 texCoord0;
varying vec2 texCoord1;
              
      
void main(void)
{
   gl_Position = ftransform();
   texCoord0 = gl_MultiTexCoord0.xy;
   texCoord1 = gl_MultiTexCoord1.xy;
   vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
   vNormal = normalize(gl_NormalMatrix * gl_Normal);
}


That looks amazing!  :-o

Thanks!



I was wondering though, does one need a powerful graphics card to use these kind of shaders? The reason why I'm interested in a cartoon shader is because having a cartoonish style can justify low-count poly models. It's all aimed towards performance.

forgot post a usage stuff "this can be done more elegantly I imagine but…



usage

setToonSpec(yourModelNode,1.0f,2.99f,0.25f,1.35f,0.315544f,0.812030f,0.800469f,0);




method


private void setToonSpec(Node model,float diffuseMult,float specMult, float sil, float shine, float r,float g,float b,float a)
    {
         GLSLShaderObjectsState glslshader = DisplaySystem.getDisplaySystem().getRenderer().createGLSLShaderObjectsState();
         glslshader.load(getClass().getResource("/data/shader/toontexturedspec.vert"),getClass().getResource("/data/shader/toontexturedspec.frag"));
         glslshader.setUniform("colorMap0", 0); // 0 being the  Diffuse Texture number from the TextureState you've connected to the model
         glslshader.setUniform("specularMap", 1); // 1 being the Specular Texture number from the TextureState you've connected to the model
         glslshader.setUniform("diffuseMult", diffuseMult);//diffuse color brightness influencer
         glslshader.setUniform("specMult", specMult);//specular color brightness influencer
         glslshader.setUniform("silhouetteThreshold", sil);// toon edge weight
         glslshader.setUniform("shininess", shine); // shine coverage
         glslshader.setUniform("Material",new ColorRGBA(r,g,b,a) );
         model.setRenderState(glslshader);
    }

Hi McBeth,



Finally had some time to check out your posted code. I was able to get it to work on my model and I can confirm it is more "shiny". However, the model still doesn't look cartoon-like. And with Cartoon-like I mean the black edges surrounding a model and the tone changing when rotating a model (like in TestVertexProgramState.java).



nin3render.jpg in your linked post, does show them. Did I perhaps set it up incorrectly?



Thanks!



EDIT: on second thought, the shader isn't showing at all. I'll try to mess arround with it some more.



EDIT #2:

Seems to have been a classpath error. Umm… err… Nevermind…

Darklord said:

EDIT #2:
Seems to have been a classpath error. Umm.. err... Nevermind...


no worries man, happens to me too :)

one thing u should know though, is that it doesn't always play nice with  large planar surfaces,use this portion of the shader code below adjusts that lower values makes the silhuette stuff cause objects like boxes and terrain to be almost completely black, except for regions where non-planar objects have the toon effects applied,...you'll get a kinda spot light effect. 1.98 works ok-ish if u are applying the rootNode, but it still looks kinda odd, looks good on characters and curvy surfaces though.
if( diffuse < 0.25 )
        //gl_FragColor *= 1.98 * gl_LightSource[0].ambient;
        gl_FragColor *=1.98 * gl_LightSource[0].diffuse;



I am no glsl expert, in fact, I still dont really know glsl  XD, so this thing probably tightened up plenty more


mcbeth said:

Darklord said:

EDIT #2:
Seems to have been a classpath error. Umm.. err... Nevermind...


no worries man, happens to me too :)

one thing u should know though, is that it doesn't always play nice with  large planar surfaces,use this portion of the shader code below adjusts that lower values makes the silhuette stuff cause objects like boxes and terrain to be almost completely black, except for regions where non-planar objects have the toon effects applied,...you'll get a kinda spot light effect. 1.98 works ok-ish if u are applying the rootNode, but it still looks kinda odd, looks good on characters and curvy surfaces though.
if( diffuse < 0.25 )
         //gl_FragColor *= 1.98 * gl_LightSource[0].ambient;
         gl_FragColor *=1.98 * gl_LightSource[0].diffuse;



I am no glsl expert, in fact, I still dont really know glsl  XD, so this thing probably tightened up plenty more



Thanks! I'll keep it in mind!

Right now im thrilled that I got it to work. It looks very sweet as you can see at the screenshot I attached. Most people that see it though, generally say that the non-cartoon one looks better. I blame that for not having a cartoonish scene which blends perfectly with the shader-style.

Anyways.. Thanks alot!