// Copyright (c) 2017-2022 Xiamen Yaji Software Co., Ltd. CCEffect %{ techniques: - passes: - switch: USE_OUTLINE_PASS vert: silhouette-edge-vs frag: silhouette-edge-fs rasterizerState: &r1 cullMode: front depthStencilState: &d1 depthFunc: less_equal depthTest: true depthWrite: true properties: lineWidth: { value: 10, target: outlineParams.x } depthBias: { value: 0, target: outlineParams.y } baseColor: { editor: { type: color } } baseColorMap: { value: grey } - vert: toon-vs frag: toon-fs properties: &props tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } mainColor: { value: [0.6, 0.6, 0.6, 1.0], target: baseColor, linear: true, editor: { displayName: BaseColor, type: color } } colorScale: { value: [1.0, 1.0, 1.0], target: colorScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } shadeColor1: { value: [0.4, 0.4, 0.4, 1.0], linear: true, editor: { type: color } } shadeColor2: { value: [0.2, 0.2, 0.2, 1.0], linear: true, editor: { type: color } } specular: { value: [1.0, 1.0, 1.0, 0.3], linear: true, editor: { type: color } } baseStep: { value: 0.8, target: shadeParams.x } baseFeather: { value: 0.001, target: shadeParams.y } shadeStep: { value: 0.5, target: shadeParams.z } shadeFeather: { value: 0.001, target: shadeParams.w } shadowCover: { value: 0.5, target: miscParams.x, editor: { slide: true, range: [0, 1.0], step: 0.001 } } emissive: { value: [0.0, 0.0, 0.0, 1.0], linear: true, editor: { type: color } } emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleAndStrenth.xyz } normalStrength: { value: 1.0, target: emissiveScaleAndStrenth.w, editor: { parent: USE_NORMAL_MAP }, slide: true, range: [0, 5.0], step: 0.001 } normalMap: { value: normal } mainTexture: { value: white, target: baseColorMap, editor: { displayName: BaseColorMap } } shadeMap1: { value: white } shadeMap2: { value: white } specularMap: { value: white } emissiveMap: { value: grey } - vert: toon-vs frag: toon-fs phase: forward-add propertyIndex: 1 embeddedMacros: { CC_FORWARD_ADD: true } depthStencilState: depthFunc: equal depthTest: true depthWrite: false blendState: targets: - blend: true blendSrc: one blendDst: one blendSrcAlpha: zero blendDstAlpha: one properties: *props - vert: shadow-caster-vs frag: shadow-caster-fs phase: shadow-caster propertyIndex: 1 rasterizerState: cullMode: front properties: tilingOffset: { value: [1.0, 1.0, 0.0, 0.0] } mainColor: { value: [0.6, 0.6, 0.6, 1.0], target: baseColor, editor: { displayName: BaseColor, type: color } } colorScale: { value: [1.0, 1.0, 1.0], target: colorScaleAndCutoff.xyz } alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } } shadeColor1: { value: [0.4, 0.4, 0.4, 1.0], editor: { type: color } } shadeColor2: { value: [0.2, 0.2, 0.2, 1.0], editor: { type: color } } specular: { value: [1.0, 1.0, 1.0, 0.3], editor: { type: color } } baseStep: { value: 0.8, target: shadeParams.x } baseFeather: { value: 0.001, target: shadeParams.y } shadeStep: { value: 0.5, target: shadeParams.z } shadeFeather: { value: 0.001, target: shadeParams.w } emissive: { value: [0.0, 0.0, 0.0, 1.0], editor: { type: color } } emissiveScale: { value: [1.0, 1.0, 1.0], target: emissiveScaleAndStrenth.xyz } normalStrenth: { value: 1.0, target: emissiveScaleAndStrenth.w, editor: { parent: USE_NORMAL_MAP } } mainTexture: { value: white, target: baseColorMap, editor: { displayName: BaseColorMap } } - &planar-shadow vert: planar-shadow-vs frag: planar-shadow-fs phase: planar-shadow propertyIndex: 0 depthStencilState: depthTest: true depthWrite: false stencilTestFront: true stencilFuncFront: not_equal stencilPassOpFront: replace stencilRef: 0x80 # only use the leftmost bit stencilReadMask: 0x80 stencilWriteMask: 0x80 blendState: targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha blendDstAlpha: one_minus_src_alpha - switch: USE_OUTLINE_PASS vert: silhouette-edge-vs frag: silhouette-edge-fs phase: deferred-forward rasterizerState: *r1 depthStencilState: *d1 propertyIndex: 0 - vert: toon-vs frag: toon-fs phase: deferred-forward propertyIndex: 1 }% CCProgram shared-ubos %{ uniform Constants { vec4 tilingOffset; vec4 baseColor; vec4 colorScaleAndCutoff; vec4 shadeColor1; vec4 shadeColor2; vec4 specular; // xyz: specular color, w: power vec4 shadeParams; vec4 miscParams; vec4 emissive; vec4 emissiveScaleAndStrenth; };}% CCProgram macro-remapping %{ // if enabled, shadowed area is very dark #pragma define-meta USE_COMPATIBLE_LIGHTING #define CC_SURFACES_USE_LEGACY_COMPATIBLE_LIGHTING USE_COMPATIBLE_LIGHTING #pragma define-meta USE_NORMAL_MAP #define CC_SURFACES_USE_TANGENT_SPACE USE_NORMAL_MAP }% CCProgram surface-vertex %{ #define CC_SURFACES_VERTEX_MODIFY_UV void SurfacesVertexModifyUV(inout SurfacesStandardVertexIntermediate In) { In.texCoord = In.texCoord * tilingOffset.xy + tilingOffset.zw; } }% CCProgram surface-fragment %{ #if USE_BASE_COLOR_MAP uniform sampler2D baseColorMap; #endif #if USE_NORMAL_MAP uniform sampler2D normalMap; #endif #if USE_1ST_SHADE_MAP uniform sampler2D shadeMap1; #endif #if USE_2ND_SHADE_MAP uniform sampler2D shadeMap2; #endif #if USE_SPECULAR_MAP uniform sampler2D specularMap; #endif #if USE_EMISSIVE_MAP uniform sampler2D emissiveMap; #endif #if USE_ALPHA_TEST #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b]) #endif #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TOONSHADE void SurfacesFragmentModifyBaseColorAndToonShade(out vec4 baseColorAndTransparency, out vec3 shade1, out vec3 shade2) { shade2 = shadeColor2.rgb * colorScaleAndCutoff.rgb; #if USE_2ND_SHADE_MAP shade2 *= SRGBToLinear(texture(shadeMap2, FSInput_texcoord).rgb); #endif shade1 = shadeColor1.rgb * colorScaleAndCutoff.rgb; #if USE_1ST_SHADE_MAP shade1 *= SRGBToLinear(texture(shadeMap1, FSInput_texcoord).rgb); #if SHADE_MAP_1_AS_SHADE_MAP_2 shade2 *= shade1.rgb; #endif #endif vec4 color = baseColor; #if USE_BASE_COLOR_MAP vec4 texColor = texture(baseColorMap, FSInput_texcoord); texColor.rgb = SRGBToLinear(texColor.rgb); color *= texColor; #if BASE_COLOR_MAP_AS_SHADE_MAP_1 shade1 *= texColor.rgb; #endif #if BASE_COLOR_MAP_AS_SHADE_MAP_2 shade2 *= texColor.rgb; #endif #endif baseColorAndTransparency = color; baseColorAndTransparency.rgb *= colorScaleAndCutoff.xyz; #if USE_ALPHA_TEST if (baseColorAndTransparency.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard; #endif } #define CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY void SurfacesFragmentAlphaClipOnly() { #if USE_ALPHA_TEST float alpha = baseColor.ALPHA_TEST_CHANNEL; #if USE_BASE_COLOR_MAP alpha = texture(baseColorMap, FSInput_texcoord).ALPHA_TEST_CHANNEL; #endif if (alpha < colorScaleAndCutoff.w) discard; #endif } #define CC_SURFACES_FRAGMENT_MODIFY_WORLD_NORMAL vec3 SurfacesFragmentModifyWorldNormal() { vec3 normal = FSInput_worldNormal; #if USE_NORMAL_MAP vec3 nmmp = texture(normalMap, FSInput_texcoord).xyz - vec3(0.5); normal = CalculateNormalFromTangentSpace(nmmp, emissiveScaleAndStrenth.w, normalize(normal.xyz), normalize(FSInput_worldTangent), FSInput_mirrorNormal); #endif return normalize(normal); } #define CC_SURFACES_FRAGMENT_MODIFY_EMISSIVE vec3 SurfacesFragmentModifyEmissive() { vec3 emissive = emissive.rgb * emissiveScaleAndStrenth.xyz; #if USE_EMISSIVE_MAP emissive *= SRGBToLinear(texture(emissiveMap, FSInput_texcoord).rgb); #endif return emissive; } #define CC_SURFACES_FRAGMENT_MODIFY_TOON_STEP_AND_FEATHER vec4 SurfacesFragmentModifyToonStepAndFeather() { return shadeParams; } #define CC_SURFACES_FRAGMENT_MODIFY_TOON_SHADOW_COVER float SurfacesFragmentModifyToonShadowCover() { return miscParams.x; } #define CC_SURFACES_FRAGMENT_MODIFY_TOON_SPECULAR vec4 SurfacesFragmentModifyToonSpecular() { vec4 specularParam = specular; #if USE_SPECULAR_MAP specularParam.rgb *= SRGBToLinear(texture(specularMap, FSInput_texcoord).rgb); #endif return specularParam; } }% CCProgram toon-vs %{ precision highp float; // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros #include #include // 2. common include with corresponding shader stage #include // 3. user surface functions that can use user (effect) parameters (ubo Constants) // see surfaces/default-functions/xxx.chunk #include #include // 4. surface include with corresponding shader stage and shading-model (optional) #include // 5. shader entry with corresponding shader stage and technique usage/type #include }% CCProgram shadow-caster-vs %{ precision highp float; #include #include #include #include #include #include }% CCProgram planar-shadow-vs %{ precision highp float; #include #include #include #include #include #include }% CCProgram toon-fs %{ // shading-model : toon // lighting-model : toon // shader stage : fs // technique usage/type : render-to-scene precision highp float; // 1. surface internal macros, for technique usage or remapping some user (material) macros to surface internal macros #include #include // 2. common include with corresponding shader stage #include // 3. user surface functions that can use user (effect) parameters (ubo Constants) // see surfaces/default-functions/xxx.chunk #include #include // 4. lighting-model (optional) #include // 5. surface include with corresponding shader stage and shading-model (optional) #include // 6. shader entry with corresponding shader stage and technique usage/type #include }% CCProgram shadow-caster-fs %{ precision highp float; #include #include #include #include #include #include }% CCProgram planar-shadow-fs %{ precision highp float; #include #include #include #include #include #include }% ////////////////////////////////////////////////silhouette-edge sample // how to write a simple surface material // change technique outline-vs/fs:vert/frag to silhouette-edge-vs/fs CCProgram surface-vertex-silhouette-edge %{ uniform OutlineVert { vec4 outlineParams; // x: line width, y: depth hack }; #define CC_SURFACES_VERTEX_MODIFY_LOCAL_POS vec3 SurfacesVertexModifyLocalPos(in SurfacesStandardVertexIntermediate In) { float width = outlineParams.x * 0.001; vec3 localPos = In.position.xyz; #if USE_POSITION_SCALING vec3 dir = normalize(localPos); float flip = dot(dir, normalize(In.normal)) < 0.0 ? -1.0 : 1.0; localPos += flip * dir * width * 2.0; #else localPos += normalize(In.normal) * width; #endif return localPos; } #define CC_SURFACES_VERTEX_MODIFY_CLIP_POS vec4 SurfacesVertexModifyClipPos(in SurfacesStandardVertexIntermediate In) { vec4 clipPos = In.clipPos; float scaleZ = cc_nearFar.z == 0.0 ? 0.5 : 1.0; clipPos.z -= outlineParams.y * 0.002 * scaleZ; return clipPos; } }% CCProgram surface-fragment-silhouette-edge %{ uniform OutlineFrag { vec4 baseColor; }; #if USE_BASE_COLOR_MAP uniform sampler2D baseColorMap; #endif // only for render-to-shadow-map or misc usage #define CC_SURFACES_FRAGMENT_MODIFY_BASECOLOR_AND_TRANSPARENCY vec4 SurfacesFragmentModifyBaseColorAndTransparency() { vec4 color = vec4(cc_mainLitColor.rgb, 1.0); color.rgb = SRGBToLinear(baseColor.rgb); #if USE_BASE_COLOR_MAP vec4 texColor = texture(baseColorMap, FSInput_texcoord); texColor.rgb = SRGBToLinear(texColor.rgb); color *= texColor; #endif return color; } }% CCProgram silhouette-edge-vs %{ precision highp float; #include #include #include #include }% CCProgram silhouette-edge-fs %{ precision highp float; #include #include #include #include }%