想尝试看懂表面着色器代码,虽然effect里的vs和fs写的简单,就几行include,但里面的嵌套也太深了,include的几个文件里又是include,有四五层,是不是函数功能分得有点太细了?
菜鸟实在是疑惑,表面着色器这么复杂的结构,大佬们真的能融会贯通全盘掌握吗?因为我看很多大佬分享的shader教程也还在用传统着色器。
我自己用起来也感觉传统着色器用着更顺手,渲染算法的加减乘除全在一起,一目了然。
菜鸟正入门呢,希望大佬们不吝赐教 
想尝试看懂表面着色器代码,虽然effect里的vs和fs写的简单,就几行include,但里面的嵌套也太深了,include的几个文件里又是include,有四五层,是不是函数功能分得有点太细了?
菜鸟实在是疑惑,表面着色器这么复杂的结构,大佬们真的能融会贯通全盘掌握吗?因为我看很多大佬分享的shader教程也还在用传统着色器。
我自己用起来也感觉传统着色器用着更顺手,渲染算法的加减乘除全在一起,一目了然。
菜鸟正入门呢,希望大佬们不吝赐教 
本来我就用传统着色器也没啥问题,但是表面着色器和传统着色器版本的toon着色器阴影效果不一样,所以想看懂表面着色器里的算法,在传统着色器里修改实现一下,结果代码实在难看懂。。。下图左边两个立方体用的是表面着色器的toon,右边两个用的是传统着色器的toon。麻烦大佬们有空指导一二,谢谢~

同步一下,用spectorjs查看两种着色器的translated fragment代码(因为原代码里宏定义和include非常多,很难判断哪些代码是有效的,spectorjs里展示的代码肯定是实际运行的代码),从最后的颜色计算部分往前逐一比较,终于发现了计算公式的差异,然后在传统着色器的CCToonShading函数(在legacy/shading-toon文件中)的基础上修改实现了新的shading-toon.chunk,最终实现了相同的阴影效果。
代码如下,注释的代码是原CCToonShading函数中的但现在无用的代码,新增代码有注释说明表面着色器中的来源函数。
只考虑了最简单的场景,没有考虑原代码中各种宏相关的高级渲染需求,仅供参考。
vec4 ToonShading (ToonSurface s) {
vec3 position;
HIGHP_VALUE_FROM_STRUCT_DEFINED(position, s.position);
vec3 V = normalize(cc_cameraPos.xyz - position);
vec3 N = normalize(s.normal);
vec3 L = normalize(-cc_mainLitDir.xyz);
float NL = 0.5 * dot(N, L) + 0.5;
float NH = 0.5 * dot(normalize(V + L), N) + 0.5;
// vec3 lightColor = cc_mainLitColor.rgb * cc_mainLitColor.w * s.baseStep;
vec3 diffuse = mix(s.shade1, s.shade2,
clamp(1.0 + (s.shadeStep - s.shadeFeather - NL) / s.shadeFeather, 0.0, 1.0));
diffuse = mix(s.baseColor.rgb, diffuse,
clamp(1.0 + (s.baseStep - s.baseFeather - NL) / s.baseFeather, 0.0, 1.0));
float specularWeight = 1.0 - pow(s.specular.a, 5.0);
float specularMask = step(specularWeight + EPSILON_LOWP, NH);
// vec3 specular = s.specular.rgb * specularMask;
// vec3 dirlightContrib = diffuse + specular;
// 表面着色器中没有shadowCover参数,实际效果相当于shadowCover=0.5
float shadow = 1.0;
#if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == CC_SHADOW_MAP
if(s.shadowCover < NL && cc_mainLitDir.w > 0.0) {
#if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_CASCADED
shadow = CCCSMFactorBase(position, N, s.shadowBias);
#endif
#if CC_DIR_LIGHT_SHADOW_TYPE == CC_DIR_LIGHT_SHADOW_UNIFORM
shadow = CCShadowFactorBase(CC_SHADOW_POSITION, N, s.shadowBias);
#endif
}
#endif
// dirlightContrib *= shadow;
// vec3 finalColor = lightColor * dirlightContrib;
// 以下为新增代码,分两阶段:CCSurfacesLighting和CCSurfacesShading
// CCSurfacesLighting阶段
// 设置参数
vec3 lightmapColor = vec3(0.0);
// 调用CCSurfacesLightingCalculateColorWithLighting
vec3 diffuseColorWithLighting = diffuse * s.baseStep;
// 调用CCSurfacesLightingCalculateDirect
vec3 irradiance = cc_mainLitColor.xyz * cc_mainLitColor.w;
vec3 directDiffuse = irradiance;
vec3 directSpecular = irradiance * specularMask;
// CCSurfacesShading阶段
// 设置参数
float lightmapCoef = 0.0;
// 设置lightingData.NoL=-1.0f后,调用CCSurfacesLightingCalculateColorWithLighting
vec3 backDiffuse = mix(s.shade1, s.shade2,
clamp(1.0 + (s.shadeStep - s.shadeFeather - 0.0) / s.shadeFeather, 0.0, 1.0));
backDiffuse = mix(s.shade1, backDiffuse,
clamp(1.0 + (s.baseStep - s.baseFeather - 0.0) / s.baseFeather, 0.0, 1.0));
vec3 backLightingDiffuse = backDiffuse * s.baseStep;
// 计算颜色
vec3 finalColor = mix(directDiffuse, lightmapColor, lightmapCoef) *
mix(backLightingDiffuse, diffuseColorWithLighting, shadow) +
directSpecular * diffuseColorWithLighting * shadow;
finalColor += s.emissive;
return vec4(finalColor, s.baseColor.a);
}