Low Poly是一种风格化渲染,其中的flat shading的效果有两种方式做到,第一种是拆分模型的顶点重计算法线,让拆分出的每个三角面三个顶点法线相同。
第二种方式可以在fragment shader中实现,在默认的情况下我们在fragment shader使用的法线都是经过三角形三个顶点的法线插值得到的,要达成flat shading的效果我们需要让整个三角形上的fragment的法线相同。于是我们可以使用ddx,ddy函数,其作用是求目标参数在屏幕X和Y方向的偏导。根据查到的信息,fragment总是在一个2x2的块中处理,使用ddx,ddy时当前fragment总能获得块中其他三个fragment的信息,因此将目标参数的插值返回即得到X和Y方向的偏导。
参考
于是在这里我们对传入fragment shader的世界坐标求偏导,就可以得到两个平面上的向量,再叉乘就能获得法线。由于三角形的世界坐标是线性变化的,每个像素得到的ddx和ddy都是相同的,于是所有fragment得到的法线都是其所在的三角形上的法线,即可得到flat shading的效果。
fixed4 frag(v2f i): SV_Target
{
float3 worldDx = ddx(i.worldPos);
float4 worldDy = ddy(i.worldPos);
float3 worldNormal = normalize(cross(worldDy, worldDx));
return fixed4(worldNormal * 0.5 + 0.5,0.0);
}
ddx和ddy还有别的很用途,例如如果对uv进行偏导,过大的偏导值代表了此处贴图的采样率低,于是我们就可以选择低等级的mipmap。
我们还能在Geometry shader中完成这个效果。