使用的是 基于Kajiya-Kay模型的毛发渲染 ,网上也有很多这样的教程,下面的教程个人角色还可以的,
这样就不重复写了,直接看上面的教程就好了
网上也有很多类似的教程和demo,也比较杂,这里就列出一个个人角色比较好的演示工程,工程里面只有材质,不过也够用了
#
守望先锋2的人物的头发有这几张贴图,了解过 Kajiya-Kay 的话,都大概能知道这几张图的作用,这里就不细说了,最主要是的最后一张 红绿色的的 方向图
方向图在这里控制 高光的流动方向,在shader中大概的使用就是例如
// --- Vertex Shader ---
// Pass TBN matrix to fragment shader
out VS_OUT {
vec3 normal;
vec3 tangent;
vec3 bitangent;
vec2 uv;
} vs_out;
void main() {
// Calculate TBN matrix
vec3 T = normalize(vec3(model * vec4(tangent, 0.0)));
vec3 N = normalize(vec3(model * vec4(normal, 0.0)));
T = normalize(T - dot(T, N) * N); // Orthogonalize
vec3 B = cross(N, T);
vs_out.tangent = T;
vs_out.bitangent = B;
vs_out.normal = N;
vs_out.uv = uv;
}
// --- Fragment Shader ---
uniform sampler2D directionMap; // RGB = flow direction (tangent space)
void main() {
// 1. Sample direction map
vec3 flowDir = texture(directionMap, uv).xyz;
flowDir = normalize(flowDir * 2.0 - 1.0); // [0,1] -> [-1,1]
// 2. Construct TBN matrix
mat3 TBN = mat3(vs_out.tangent, vs_out.bitangent, vs_out.normal);
// 3. Transform flow direction to world space
vec3 worldFlowDir = TBN * flowDir;
// 4. Anisotropic highlight calculation (Kajiya-Kay model)
vec3 viewDir = normalize(cameraPos - worldPos);
vec3 tangentDir = normalize(worldFlowDir);
float sinTheta = sqrt(1.0 - pow(dot(tangentDir, viewDir), 2));
float anisotropy = 0.5; // Control highlight spread
float spec = exp(-(sinTheta / anisotropy));
// 5. Combine with base color
vec3 finalColor = baseColor + spec * specularColor;
}
最主要的,方向图要通过 TBN矩阵来变换,不然就会有问题