Jump to content

Shader Cel-shading


Dad72
 Share

Recommended Posts

I found a shader for make a materials Cel-Shading (Toon). but I do not know how to separate the code in vertex.fx and fragment.fx.
 
I don't know anything with shaders.
 
 I want to adapt to Babylon. How do I?
 

The Shader :

float4x4 World : World < string UIWidget="None"; >;float4x4 View : View < string UIWidget="None"; >;float4x4 Projection : Projection < string UIWidget="None"; >;texture colorTexture : DIFFUSE < string UIName =  "Diffuse Texture"; string ResourceType = "2D"; >;float3 DiffuseLightDirection = float3(1, 0, 0);float4 DiffuseLightColor = float4(1, 1, 1, 1);float DiffuseIntensity = 1.0;float ToonThresholds[4] = {0.95,0.5, 0.2, 0.03 };float ToonBrightnessLevels[5] = { 1.0, 0.8, 0.6, 0.35, 0.01 }; sampler2D colorSampler = sampler_state {    Texture = <colorTexture>;    FILTER = MIN_MAG_MIP_LINEAR;    AddressU = Wrap;    AddressV = Wrap;}; struct VertexShaderInput {    float4 position : POSITION0;    float3 normal :NORMAL0;    float2 uv : TEXCOORD0;};struct VertexShaderOutput {    float4 position : POSITION0;    float3 normal   : TEXCOORD1;    float2 uv : TEXCOORD0;};VertexShaderOutput std_VS(VertexShaderInput input) {    VertexShaderOutput output;    float4 worldPosition = mul(input.position, World);    float4 viewPosition = mul(worldPosition, View);    output.position = mul(viewPosition, Projection);    output.normal = normalize(mul(input.normal, World));    output.uv = input.uv;    return output;}float4 std_PS(VertexShaderOutput input) : COLOR0 {    float lightIntensity = dot(normalize(DiffuseLightDirection), input.normal);    if(lightIntensity < 0) lightIntensity = 0;    float4 color = tex2D(colorSampler, input.uv) * DiffuseLightColor * DiffuseIntensity;    color.a = 1;    if (lightIntensity > ToonThresholds[0]) color *= ToonBrightnessLevels[0];    else if ( lightIntensity > ToonThresholds[1]) color *= ToonBrightnessLevels[1];    else if ( lightIntensity > ToonThresholds[2]) color *= ToonBrightnessLevels[2];    else if ( lightIntensity > ToonThresholds[3]) color *= ToonBrightnessLevels[3];    else color *= ToonBrightnessLevels[4];    return color;}technique Toon {    pass p0 {        VertexShader = compile vs_2_0 std_VS();        PixelShader = compile ps_2_0 std_PS();    }}

Thanks for help

Link to comment
Share on other sites

Hum, we discussed offline of this kind of ask. The forum is for helping and *NOT* delegating your work to others.

 

BTW, I did what you ask:

cellshading.jpg

 

You need to use the latest version of babylon.js on the repo.

 

Then:

cellShading.vertex.fx:

#ifdef GL_ESprecision mediump float;#endif// Attributesattribute vec3 position;attribute vec3 normal;attribute vec2 uv;// Uniformsuniform mat4 world;uniform mat4 worldViewProjection;// Normalvarying vec3 vPositionW;varying vec3 vNormalW;varying vec2 vUV;void main(void) {	vec4 outPosition = worldViewProjection * vec4(position, 1.0);	gl_Position = outPosition;		vPositionW = vec3(world * vec4(position, 1.0));	vNormalW = normalize(vec3(world * vec4(normal, 0.0)));	vUV = uv;}

cellShading.fragment.fx:

#ifdef GL_ESprecision mediump float;#endif// Lightsvarying vec3 vPositionW;varying vec3 vNormalW;varying vec2 vUV;// Refsuniform float ToonThresholds[4];uniform float ToonBrightnessLevels[5];uniform vec3 vLightPosition;uniform vec3 vLightColor;uniform sampler2D textureSampler;void main(void) {	// Light	vec3 lightVectorW = normalize(vLightPosition - vPositionW);	// diffuse	float ndl = max(0., dot(vNormalW, lightVectorW));	vec3 color = texture2D(textureSampler, vUV).rgb * vLightColor;	if (ndl > ToonThresholds[0])	{		color *= ToonBrightnessLevels[0];	} 	else if (ndl > ToonThresholds[1])	{		color *= ToonBrightnessLevels[1];	}	else if (ndl > ToonThresholds[2])	{		color *= ToonBrightnessLevels[2];	}	else if (ndl > ToonThresholds[3])	{		color *= ToonBrightnessLevels[3];	}	else	{		color *= ToonBrightnessLevels[4];	}		gl_FragColor = vec4(color, 1.);}

And finally the material and a small code to test:

var CreateCellShadingScene = function (engine) {        var CellShadingMaterial = function (name, scene, light) {        this.name = name;        this.id = name;        this.light = light;        this._scene = scene;        scene.materials.push(this);        this.texture = null;        this.toonThresholds = [0.95, 0.5, 0.2, 0.03];        this.toonBrightnessLevels = [1.0, 0.8, 0.6, 0.35, 0.01];    };    CellShadingMaterial.prototype = Object.create(BABYLON.Material.prototype);    // Properties       CellShadingMaterial.prototype.needAlphaBlending = function () {        return false;    };    CellShadingMaterial.prototype.needAlphaTesting = function () {        return false;    };    // Methods       CellShadingMaterial.prototype.isReady = function (mesh) {        var engine = this._scene.getEngine();        if (this.texture && !this.texture.isReady) {            return false;        }        this._effect = engine.createEffect("./Scenes/Customs/shaders/cellShading",            ["position", "normal", "uv"],            ["worldViewProjection", "world", "view", "vLightPosition", "vLightColor", "ToonBrightnessLevels", "ToonThresholds"],            ["textureSampler"],            "");        if (!this._effect.isReady()) {            return false;        }        return true;    };    CellShadingMaterial.prototype.bind = function (world, mesh) {        this._effect.setMatrix("world", world);        this._effect.setMatrix("worldViewProjection", world.multiply(this._scene.getTransformMatrix()));        this._effect.setVector3("vLightPosition", this.light.position);        this._effect.setColor3("vLightColor", this.light.diffuse);        this._effect.setArray("ToonThresholds", this.toonThresholds);        this._effect.setArray("ToonBrightnessLevels", this.toonBrightnessLevels);        // Textures                this._effect.setTexture("textureSampler", this.texture);    };    CellShadingMaterial.prototype.dispose = function () {        if (this.texture) {            this.texture.dispose();        }        this.baseDispose();    };    var scene = new BABYLON.Scene(engine);    var camera = new BABYLON.ArcRotateCamera("Camera", 0, Math.PI / 4, 40, BABYLON.Vector3.Zero(), scene);    var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 100, 2), scene);    var sphere = BABYLON.Mesh.CreateSphere("Sphere0", 32, 3, scene);    var cylinder = BABYLON.Mesh.CreateCylinder("Sphere1", 5, 3, 2, 32, scene);    var torus = BABYLON.Mesh.CreateTorus("Sphere2", 3, 1, 32, scene);    var cellShadingMaterial = new CellShadingMaterial("mat0", scene, light);    cellShadingMaterial.texture = new BABYLON.Texture("Scenes/Customs/Ground.jpg", scene);        sphere.material = cellShadingMaterial;    sphere.position = new BABYLON.Vector3(-10, 0, 0);    cylinder.material = cellShadingMaterial;    torus.material = cellShadingMaterial;    torus.position = new BABYLON.Vector3(10, 0, 0);        // Animations    var alpha = 0;    scene.registerBeforeRender(function () {        sphere.rotation.y = alpha;        sphere.rotation.x = alpha;        cylinder.rotation.y = alpha;        cylinder.rotation.x = alpha;        torus.rotation.y = alpha;        torus.rotation.x = alpha;        alpha += 0.05;    });        return scene;};
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...