Toon shader for Render Component

Hi, searching a working toon shader for playcanvas for render component
All my tries to adapt finding solutions for model component are failed.
Does somebody has a ready solution? Thanks

Hi @wazti,

This toon shader by @guzu is great, you just need to replace a couple of references from model to render component.

Here is my try on it:

https://playcanvas.com/editor/scene/1389397

//For questions, refer to https://github.com/guzuligo
//Version 0.1.1
var G2Toonshader = pc.createScript('g2Toonshader');
G2Toonshader.attributes.add("useThis",{title:"Initialize entity material",type:"boolean",default:true});
G2Toonshader.attributes.add("material",{type:"asset",assetType:"material",title:"Material",description:
"The material to convert to toonshaded. If left empty, a new material will be created and you'll have to"+
" assign this.material to your model to use it."});
G2Toonshader.attributes.add("smooths",{type:"number",title:"Smoothness",min:0,max:1.0,default:0,description:
"TTT"});
G2Toonshader.attributes.add("mixAlbedo",{type:"number",title:"Diffuse Mix",min:0,max:1.0,default:0});
G2Toonshader.attributes.add("uF0",{type:"json",title:"Colors",array:true,schema:[
    {name:"activation",title:"Density",type:"number",min:-0.01,max:1,default:.5},{name:"color",title:"Color",type:"rgb"}
]});

G2Toonshader.prototype.colors=0;
// initialize code called once per entity
G2Toonshader.statics={id:0};
G2Toonshader.prototype.initialize = function() {
    this.setup(this.material.resource);    
};

G2Toonshader.prototype.setup=function(mat,clone_){
    console.log("SETUP ",mat,clone_);
    var m;
    if (mat!==undefined){m=clone_?mat.clone():mat;}//TODO: to test
    else    
    if(!this.material){
        this.material=new pc.Asset("ToonMaterial"+(G2Toonshader.statics.id++),"material");
        
        m=this.material.resource=new pc.StandardMaterial();
    }else
        m=this.material.resource;
    
    this.m=m;//console.log("m=",m);
    //this.material.chunks={};
    this.reset();this.setParams();
    m.update();
    
    return this.m;
};

G2Toonshader.prototype.reset=function(){
    var m=this.m;
    
    var replace0="\n\t uniform float smooths;uniform float mixAlbedo;";
    var replace1="float v = max(max(dDiffuseLight.r,dDiffuseLight.g),dDiffuseLight.b);"+
        "\n\t vec3 color=vec3(0.);\n";//vec4 color;";
    this.colors=this.uF0.length;
    for (var i=0;i<this.uF0.length;i++){
        replace0+="\n\t uniform float  uF"+i+";";
        replace0+="\n\t uniform vec3   cF"+i+";";
        replace1+="\n\t color=(1.-smoothstep(uF"+(i)+"-smooths,uF"+(i)+",v))*color+(smoothstep(uF"+(i)+"-smooths,uF"+(i)+",v))*cF"+i+";";
    }
    replace1+="\n\t return mix(color,dAlbedo*color,mixAlbedo);";
    
    
    m.chunks.combineDiffuseSpecularPS=m.chunks.combineDiffuseSpecularNoReflPS=
        m.chunks.combineDiffusePS=m.chunks.combineDiffuseSpecularNoReflSeparateAmbientPS=
        replace0+"\n"+
        pc.shaderChunks.combineDiffusePS.replace("return dAlbedo * dDiffuseLight;",replace1);
    m.update();
};

G2Toonshader.prototype.setParams=function(){
    if(!this.m)return;
    var m=this.m;
    if(this.colors!=this.uF0.length)
        this.reset();
    m.setParameter('smooths', this.smooths);
    m.setParameter('mixAlbedo', this.mixAlbedo);
    for (var i=0;i<this.uF0.length;i++){
        var c=this.uF0[i].color;
        m.setParameter('uF'+i, this.uF0[i].activation);
        m.setParameter('cF'+i,[c.r,c.g,c.b]);
    }
    
};





// update code called every frame
G2Toonshader.prototype.update = function(dt) {
    this.setParams();
};
3 Likes

Thanks!

Hi, I’m not sure when but since the latest engine update this toon shader is now broken.
would @Leonidas or anyone be willing to share a solution to converting this shader?

Thanks for your time.

I think there have been several big changes in the shader chunks system and this requires a lot of updating right now. I may take a look at some point thought it may take some time :innocent:

2 Likes

if you end up taking a look at it I would greatly appreciate it

Thank you

1 Like

I think I fixed it .
I posted the updated project here : PlayCanvas 3D HTML5 Game Engine

3 Likes

Thanks for sharing!

Hey, I’m trying to get a toon shader working in Playcanvas and just found this.

Anyone know why it’s working when launched from this page: PlayCanvas 3D HTML5 Game Engine

But doesn’t work when launched from the editor?

When you launch it from the Editor, it uses the latest engine version, and the the project needs to be updated to work with it, as the engine has changed since the project was created. See this warning it prints:

When you launched prebuilt version, it was built with the engine version back then when the project was created and so it works - new engine releases make no effect here.

1 Like

Ah, OK. I haven’t used Playcanvas in about a year, so I’m a bit behind. I imagine a lot of my custom shader stuff I wrote before is probably defunct now.

Does it still operate in the same way as earlier versions where I can override a shader ‘chunk’ with my own code? Is there a list of all the chunks somewhere?

For example, I’m looking at this shader (https://github.com/playcanvas/engine/blob/02238de38b0ef46f985e761e6a94e475da4e34f3/src/scene/shader-lib/chunks/lit/frag/combine.js) as a possible place I could try to build a toon shader, but not sure how I would override that on a material.

Its still the same way:

material.chunks.combinePS= '...';
material.chunks.APIVersion = pc.CHUNKAPI_1_66;

More info on migrating:
https://developer.playcanvas.com/en/user-manual/graphics/shader-chunk-migrations/

1 Like