Hello, Everyone. I’m Hizard.
I always get a lot of help.
This time, it’s a request for help with the toon shader.
Idk anything about shaders and all I’ve written is following the code.
Therefore, I desperately need your help.
Code:
var MyToonShader = pc.createScript('myToonShader');
// initialize code called once per entity
MyToonShader.prototype.initialize = function() {
this.lightEntity = this.app.root.findByName('Light');
var toonShaderVert = this.app.assets.find('toonShader.vert').resource;
var toonShaderFrag = this.app.assets.find('toonShader.frag').resource;
const shader = pc.createShaderFromCode(this.app.graphicsDevice, toonShaderVert, toonShaderFrag, "myToon", {
aPosition: pc.SEMANTIC_POSITION,
aNormal: pc.SEMANTIC_NORMAL,
aUv: pc.SEMANTIC_TEXCOORD0,
});
const material = new pc.Material();
material.shader = shader;
let originalTexture = null;
var renders = this.entity.findComponents("render");
renders.forEach((render) => {
const meshInstances = render.meshInstances;
for (let i = 0; i < meshInstances.length; ++i) {
const meshInstance = meshInstances[i];
if(!originalTexture) {
const originalMaterial = meshInstance.material;
originalTexture = originalMaterial.diffuseMap;
}
meshInstance.material = material;
}
});
const lightPosArray = [
this.lightEntity.getPosition().x,
this.lightEntity.getPosition().y,
this.lightEntity.getPosition().z
]
material.setParameter('uLightPos', lightPosArray);
material.setParameter('uTexture', originalTexture);
material.update();
};
fragment
precision mediump float;
uniform sampler2D uTexture;
varying float vertOutTexCoord;
varying vec2 texCoord;
void main(void)
{
float v = vertOutTexCoord;
v = float(int(v * 6.0)) / 6.0;
//vec4 color = texture2D (uTexture, texCoord); // try this to use the diffuse color.
vec4 color = vec4(1.0, 1.0, 1.0, 1.0); // Change this line
gl_FragColor = color * vec4(v, v, v, 1.0);
}
vertex
// Attributes per vertex: position, normal and texture coordinates
attribute vec4 aPosition;
attribute vec3 aNormal;
attribute vec2 aUv;
uniform mat4 matrix_viewProjection;
uniform mat4 matrix_model;
uniform mat4 matrix_view;
uniform mat3 matrix_normal;
uniform vec3 uLightPos;
// Color to fragment program
varying float vertOutTexCoord;
varying vec2 texCoord;
void main(void)
{
mat4 modelView = matrix_view * matrix_model;
mat4 modelViewProj = matrix_viewProjection * matrix_model;
// Get surface normal in eye coordinates
vec3 eyeNormal = normalize(matrix_normal * aNormal);
// Get vertex position in eye coordinates
vec4 vertexPos = modelView * aPosition;
vec3 vertexEyePos = vertexPos.xyz / vertexPos.w;
// Get vector to light source
vec3 lightDir = normalize(uLightPos - vertexEyePos);
// Dot product gives us diffuse intensity. The diffuse intensity will be
// used as the 1D color texture coordinate to look for the color of the
// resulting fragment (see fragment shader).
vertOutTexCoord = max(0.0, dot(eyeNormal, lightDir));
texCoord = aUv;
// Transform the geometry
gl_Position = modelViewProj * aPosition;
}
Source: PlayCanvas Examples - shader-toon
Result:
- I’d like to keep the existing material and apply only toon shading.
- All of material in character is no texture file, only color value.
- I think I need to modify part
color
ofFragment
, right?
Update
…
- The coloring was successful.
Code:
var MyToonShader = pc.createScript('myToonShader');
MyToonShader.attributes.add('toonColor', { type: 'rgba', default: [0,0,0,1]});
MyToonShader.prototype.initialize = function() {
......
material.setParameter('toonColor', this.toonColor.data);
material.update();
};
fragment:
precision mediump float;
uniform sampler2D uTexture;
uniform vec4 toonColor;
varying float vertOutTexCoord;
varying vec2 texCoord;
void main(void)
{
float v = vertOutTexCoord;
v = float(int(v * 6.0)) / 6.0;
//vec4 color = texture2D (uTexture, texCoord); // try this to use the diffuse color.
vec4 color = toonColor;// vec4(1.0, 1.0, 1.0, 1.0);
gl_FragColor = color * vec4(v, v, v, 1.0);
}