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

1 Like

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

Hi! Was looking for a toon shader and stumbled upon this thread. Last post, you mentioned you fixed it, but perhaps it broke again because this is not how itā€™s supposed to look right?

image

Regards

  • Bjƶrn

I think I fixed it ā€¦ again ā€¦ you had to change dalbedo to albedo in the shader chunk replacement code.
cell shading look

Once again I posted the updated project here : PlayCanvas 3D HTML5 Game Engine

1 Like

in my previous post I took a screenshot showing the shader working correctly but when I published it the published version does not seem to work. Would @mvaligursky , @LeXXik or @Leonidas know why this might be happening?

Thanks

thatā€™s odd, thanks for looking into it again though.

My only observation so far, is that if I use Launch within the editor, it looks fine, but sparks this message in the console:

If I publish - or Launch but deselect ā€œDebugā€ It no longer looks like cel shader. Message is also gone by then.

The messages like this get only logged in the debug mode, but indicate an issue that should be fixed, as the shader chunk API has changed and the chunk you use might no longer be compatible.

I believe i fixed it for the launcher with debug disabled and the Published versions.

Check it out here PlayCanvas 3D HTML5 Game Engine

On github in the src/scene/shader-lib/chunks/lit/frag/combine.js file youā€™ll find this code

vec3 combineColor(vec3 albedo, vec3 sheenSpecularity, float clearcoatSpecularity) {
	vec3 ret = vec3(0);
#ifdef LIT_OLD_AMBIENT
	ret += (dDiffuseLight - light_globalAmbient) * albedo + material_ambient * light_globalAmbient;
#else
	ret += albedo * dDiffuseLight;
#endif

It seems that when debug is enabled it triggers the ā€œ#ifdef LIT_OLD_AMBIENTā€ case. But when debug is disabled it triggers the ā€œ#elseā€ case. Previously I was only modifying the ā€œ#ifdef LIT_OLD_AMBIENTā€ case but now Iā€™m modifying both and it seems to work.

Iā€™m curious why it triggers a different case depending on if debug is enabled though. Would you know why this might be the case @mvaligursky?

Also it seems that if you dont specify a shader chunk api version it will always assume that the API version is 1.62 because when I set "material.chunks.APIVersion = pc.CHUNKAPI_1_70; " I dont get the warning that it is 1.62 in the debug console.

Maybe someone could confirm whether this is correct as well.

Thanks for your time.

1 Like

I would not expect the debug mode to change which branch is taken, so no idea whatā€™s happening but likely something else.

Yes, to kill the warning you need to set the API version, as that is what is used in the debug mode for checks, all good here.

Glad you got it going!