Surface Shader 可替换的内置函数

Surface Shader 统一了着色流程,同时向用户提供了大量的自定义函数,大家可以根据自己的需求,利用宏机制,重写相关函数。

1、原理

Surface Shader 提供的自定义函数,在内部都有一个默认版本,并且在适合的时候被调用。可以参考 Surface Shader 执行流程了解详情。

这些函数通常以 Surfaces+Shader类型名+Modify+属性 方式全名,比如:

  • SurfacesVertexModifyLocalPos
  • SurfacesVertexModifyLocalNormal
  • SurfacesVertexModifyLocalTangent

所有函数可以在 internal/chunks/surfaces/default-functions/ 中查看。

如果你想替换某函数的实现,可以通过预定义该函数对应的宏来完成

比如,可以预先定义 CC_SURFACES_VERTEX_MODIFY_WORLD_POS 宏,让 Surface Shader 使用你定义的函数来计算世界坐标,示例代码如下:

#define CC_SURFACES_VERTEX_MODIFY_WORLD_POS
vec3 SurfacesVertexModifyWorldPos(in SurfacesStandardVertexIntermediate In)
{
  vec3 worldPos = In.worldPos;
  worldPos.x += sin(cc_time.x * worldPos.z);
  worldPos.y += cos(cc_time.x * worldPos.z);
  return worldPos;
}

如果对 Surface Shader 中的函数替换机制不熟悉,可以先参考 使用宏定义实现函数替换

用这种方式的好处是可以方便地扩展多种不同的材质数据结构、光照模型和渲染用途,并且不用对内置的 Surface Shader 流程进行修改。

2、VS 对应的常用函数列表

可用宏替换的 VS 内置函数定义在:internal/chunks/surfaces/default-functions/common-vs.chunk 文件中。

在 VS 中的内置函数参数均为 SurfacesStandardVertexIntermediate 结构体,存放的是 VS 输入输出的数据。用户无需关心具体的顶点输入输出流程处理,只需要聚焦到某个数据的修改即可。

预先定义宏 对应的函数定义 对应的材质模型 功能说明
CC_SURFACES_VERTEX_MODIFY_LOCAL_POS vec3 SurfacesVertexModifyLocalPos Common 返回修改后的模型空间坐标
CC_SURFACES_VERTEX_MODIFY_LOCAL_NORMAL vec3 SurfacesVertexModifyLocalNormal Common 返回修改后的模型空间法线
CC_SURFACES_VERTEX_MODIFY_LOCAL_TANGENT vec4 SurfacesVertexModifyLocalTangent Common 返回修改后的模型空间切线和镜像法线标记
CC_SURFACES_VERTEX_MODIFY_LOCAL_SHARED_DATA void SurfacesVertexModifyLocalSharedData Common 如果某些贴图和计算需要在多个材质节点中使用,可在此函数中进行,在世界变换前调用,直接修改 SurfaceStandardVertexIntermediate 结构体内的三个Local参数
CC_SURFACES_VERTEX_MODIFY_WORLD_POS vec3 SurfacesVertexModifyWorldPos Common 返回修改后的世界空间坐标(世界空间动画)
CC_SURFACES_VERTEX_MODIFY_CLIP_POS vec4 SurfacesVertexModifyClipPos Common 返回修改后的剪裁(NDC)空间坐标(通常用于修改深度)
CC_SURFACES_VERTEX_MODIFY_UV void SurfacesVertexModifyUV Common 修改结构体内的 UV0 和 UV1 (使用 tiling 等)
CC_SURFACES_VERTEX_MODIFY_WORLD_NORMAL vec3 SurfacesVertexModifyWorldNormal Common 返回修改后的世界空间法线(世界空间动画)
CCSURFACES_VERTEX_MODIFY SHARED_DATA void SurfacesVertexModify SharedData Common 如果某些贴图和计算需要在多个材质节点中使用,可在此函数中进行,直接修改 SurfaceStandardVertexIntermediate 结构体内的参数,减少性能耗费

3、FS 对应的常用函数列表

FS 由 PBR 和 Toon 两个部分组成,分别在下面两个文件中:

  • internal/chunks/surfaces/default-functions/standard-fs.chunk
  • internal/chunks/surfaces/default-functions/toon-vs.chunk

FS 中的函数,大部分为无参函数,用户需要结合 FS 输入值 来做处理。对于一些特殊用途的函数,也提供了对应的参数。具体属于哪种情况请参考函数定义。

预先定义宏 对应的函数定义 对应的材质模型 功能说明
CCSURFACES_FRAGMENT_MODIFY BASECOLOR_AND_TRANSPARENCY vec4 SurfacesFragmentModify BaseColorAndTransparency Common 返回修改后的基础色(rgb 通道)和透明值(a 通道)
CC_SURFACES_FRAGMENT_ALPHA_CLIP_ONLY vec4 SurfacesFragmentModify AlphaClipOnly Common 不需要获取颜色仅处理透贴的Pass中使用。如渲染到阴影图等,不重载此函数可能导致阴影没有透贴效果
CCSURFACES_FRAGMENT_MODIFY WORLD_NORMAL vec3 SurfacesFragmentModify WorldNormal Common 返回修改后的像素法线(通常是法线贴图)
CCSURFACES_FRAGMENT_MODIFY SHARED_DATA void SurfacesFragmentModify SharedData Common 若某些贴图和计算需要在多个材质节点中使用,可在此函数中进行,直接修改 Surface 结构体内的参数,减少性能耗费,类似legacy shader中的surf()函数。需要在定义函数前 include 必要的头文件
CCSURFACES_FRAGMENT_MODIFY WORLD_TANGENT_AND_BINORMAL void SurfacesFragmentModify WorldTangentAndBinormal Standard PBR 修改 Surface 结构体内的世界切空间向量
CCSURFACES_FRAGMENT_MODIFY EMISSIVE vec3 SurfacesFragmentModify Emissive Standard PBR 返回修改后的自发光颜色
CCSURFACES_FRAGMENT_MODIFY PBRPARAMS vec4 SurfacesFragmentModify PBRParams Standard PBR 返回修改后的 PBR 参数(ao, roughness, metallic, specularIntensity)
CCSURFACES_FRAGMENT_MODIFY ANISOTROPY_PARAMS vec4 SurfacesFragmentModify AnisotropyParams Standard PBR 返回修改后的各向异性参数(rotation, shape, unused, unused)
CCSURFACES_FRAGMENT_MODIFY BASECOLOR_AND_TOONSHADE void SurfacesFragmentModify BaseColorAndToonShade Toon 修改卡通渲染基础色
CCSURFACES_FRAGMENT_MODIFY TOON_STEP_AND_FEATHER vec4 SurfacesFragmentModify ToonStepAndFeather Toon 返回修改后的参数
CCSURFACES_FRAGMENT_MODIFY TOON_SHADOW_COVER vec4 SurfacesFragmentModify ToonShadowCover Toon 返回修改后的参数
CCSURFACES_FRAGMENT_MODIFY TOON_SPECULAR vec4 SurfacesFragmentModify ToonSpecular Toon 返回修改后的参数
CC_SURFACES_LIGHTING_MODIFY_FINAL_RESULT void SurfacesLightingModifyFinalResult Common 自定义光照模型,可以在之前计算的光照结果上再次修改,比如添加轮廓光等。需要在定义函数前 include 必要的头文件

条与 "" 相匹配的结果

    没有与 "" 匹配的结果