真实感人物渲染--布料
在网上找到的一些资源介绍了一些布料的光照模型(可以不看直接看后面的实现)
不同布料的光照模型
| 布料类型 | 推荐模型 | 原因说明 | 实现细节 |
|---|---|---|---|
| 丝绸 | Cook-Torrance + Ashikhmin-Shirley各向异性 | 丝绸有强烈各向异性高光和虹彩效应 | 使用各向异性NDF,添加菲涅尔色彩变化 |
| 棉布 | Oren-Nayar + 弱Cook-Torrance | 棉布有微观纤维结构,微弱高光 | 粗糙度0.7-0.9,高光强度0.1-0.3 |
| 羊毛 | Oren-Nayar + 次表面散射 | 羊毛完全哑光,强次表面散射 | 粗糙度>0.8,关闭高光,添加SSS |
| 皮革 | Cook-Torrance + 双层模型 | 皮革有清漆层和基底层的复合反射 | 双层粗糙度,清漆层高光 |
| 合成纤维 | Cook-Torrance + Sheen | 合成纤维有均匀高光和斜射光泽 | 中等粗糙度,添加Sheen项 |
| 牛仔布 | Oren-Nayar + 法线细节 | 牛仔布粗糙,有编织纹理 | 高粗糙度,强法线贴图 |
| 天鹅绒 | Cook-Torrance + 背向散射 | 天鹅绒顺光暗,逆光亮 | 特殊的背向散射模型 |
分析布料
布料表面分析 → 选择光照模型
├── 光滑有光泽 (粗糙度 < 0.4)
│ ├── 各向异性明显 → Cook-Torrance + 各向异性NDF
│ └── 各向同性 → Cook-Torrance (GGX)
├── 粗糙无光泽 (粗糙度 > 0.6)
│ ├── 有明显纤维结构 → Oren-Nayar
│ └── 均匀粗糙 → Lambert
└── 中等粗糙 (0.4 ≤ 粗糙度 ≤ 0.6)
├── 有微高光 → Cook-Torrance + Oren-Nayar混合
└── 无高光 → Oren-Nayar
不同光照模型

Lambert(朗伯)漫反射模型



// Lambert实现
float3 LambertDiffuse(float3 albedo, float3 normal, float3 lightDir)
{
float NdotL = max(dot(normal, lightDir), 0.0);
return albedo * NdotL;
}
// 适合:合成纤维、涤纶、光滑棉布
// 参数范围:粗糙度 > 0.7,无微观结构
Oren-Nayar 模型




// Oren-Nayar实现
float OrenNayarDiffuse(float3 normal, float3 lightDir, float3 viewDir, float roughness)
{
float sigma = roughness * PI / 2.0; // 粗糙度转换为弧度
float sigma2 = sigma * sigma;
float A = 1.0 - 0.5 * sigma2 / (sigma2 + 0.33);
float B = 0.45 * sigma2 / (sigma2 + 0.09);
float NdotL = dot(normal, lightDir);
float NdotV = dot(normal, viewDir);
float theta_r = acos(NdotV);
float theta_i = acos(NdotL);
float alpha = max(theta_r, theta_i);
float beta = min(theta_r, theta_i);
// 计算方位角差
float3 Lproj = normalize(lightDir - normal * NdotL);
float3 Vproj = normalize(viewDir - normal * NdotV);
float cosPhi = dot(Lproj, Vproj);
float C = sin(alpha) * tan(beta);
return max(0.0, NdotL) * (A + B * max(0.0, cosPhi) * C);
}
// 适合:棉布、羊毛、粗麻布、牛仔布
// 参数范围:粗糙度 0.5-1.0,有明显纤维结构
Cook-Torrance BRDF模型


// Cook-Torrance完整实现
float3 CookTorranceBRDF(float3 normal, float3 viewDir, float3 lightDir,
float roughness, float metallic, float3 F0)
{
float3 halfVec = normalize(lightDir + viewDir);
float NdotL = max(dot(normal, lightDir), 0.0);
float NdotV = max(dot(normal, viewDir), 0.0);
float NdotH = max(dot(normal, halfVec), 0.0);
float VdotH = max(dot(viewDir, halfVec), 0.0);
// 法线分布函数 (GGX/Trowbridge-Reitz)
float a = roughness * roughness;
float a2 = a * a;
float NdotH2 = NdotH * NdotH;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
float D = a2 / (PI * denom * denom);
// 几何遮蔽函数 (Smith-Schlick GGX)
float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
float G_l = NdotL / (NdotL * (1.0 - k) + k);
float G_v = NdotV / (NdotV * (1.0 - k) + k);
float G = G_l * G_v;
// 菲涅尔项 (Schlick近似)
float3 F = F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);
// 漫反射项 (能量守恒)
float3 kD = (1.0 - F) * (1.0 - metallic);
return (kD * albedo / PI + (D * F * G) / max(4.0 * NdotL * NdotV, 0.001));
}
// 适合:丝绸、皮革、合成纤维、有光泽的布料
// 参数范围:粗糙度 0.1-0.6,有明显高光反射
高光
| 布料类型 | 高光特征 | 视觉表现 | 物理原理 |
|---|---|---|---|
| 丝绸 | 强烈各向异性 | 方向性光泽,虹彩效应 | 纤维规则排列,薄膜干涉 |
| 棉布 | 微弱漫反射高光 | 柔和漫反射,几乎无镜面 | 不规则纤维散射 |
| 皮革 | 双层反射(清漆层) | 表层光泽+基底漫反射 | 表面涂层+基底层 |
| 羊毛 | 无镜面高光 | 完全哑光,有绒毛光泽 | 纤维散射完全随机 |
| 天鹅绒 | 背向散射 | 逆光时发亮 | 纤维导向性反射 |
| 合成纤维 | 均匀高光+斜射光泽 | 均匀光泽,斜角有光晕 | 人造纤维规则结构 |
丝绸 - 各向异性高光模型

物理原理:
丝绸的高光来自纤维的规则排列,形成方向性镜面反射。由于纤维表面的薄膜干涉,还会产生虹彩效应。
// 丝绸完整高光模型
float3 SilkSpecular(float3 normal, float3 tangent, float3 bitangent,
float3 viewDir, float3 lightDir,
float roughnessU, float roughnessV,
float3 baseColor, float iridescence)
{
// ========== 1. 各向异性NDF (Ward模型) ==========
float3 halfVec = normalize(lightDir + viewDir);
float NdotH = dot(normal, halfVec);
float TdotH = dot(tangent, halfVec);
float BdotH = dot(bitangent, halfVec);
float NdotL = dot(normal, lightDir);
float NdotV = dot(normal, viewDir);
// Ward各向异性分布函数
float exponent = (TdotH * TdotH) / (roughnessU * roughnessU) +
(BdotH * BdotH) / (roughnessV * roughnessV);
exponent = exponent / (1.0 - NdotH * NdotH);
float D = 1.0 / (4.0 * PI * roughnessU * roughnessV) *
exp(-exponent) / sqrt(NdotL * NdotV);
// ========== 2. 丝绸菲涅尔 (带色彩变化) ==========
float3 F0 = float3(0.04, 0.04, 0.04);
// 丝绸有更高的菲涅尔反射率
F0 = lerp(F0, float3(0.08, 0.08, 0.08), 0.5);
float LdotH = dot(lightDir, halfVec);
float3 F = F0 + (1.0 - F0) * pow(1.0 - LdotH, 5.0);
// 虹彩效应(薄膜干涉)
if (iridescence > 0.0)
{
float3 iridescentColor = CalculateIridescence(viewDir, normal, 1.5);
F = lerp(F, F * iridescentColor, iridescence);
}
// ========== 3. 丝绸特有的几何项 ==========
// 丝绸表面更光滑,遮蔽较少
float G = 1.0 / (LdotH * LdotH);
// ========== 4. 最终高光 ==========
float3 specular = (D * F * G) / (4.0 * NdotL * NdotV + 0.0001);
// ========== 5. 二次高光(丝绸特有的微高光) ==========
float secondarySpec = pow(NdotH, 50.0) * 0.1;
specular += secondarySpec * F;
return specular;
}
// 虹彩效应计算
float3 CalculateIridescence(float3 viewDir, float3 normal, float ior)
{
float cosTheta = dot(viewDir, normal);
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
// 薄膜干涉公式:光程差 = 2 * n * d * cosθ'
// 简化:使用视角作为参数
float angle = 1.0 - cosTheta; // 掠射角
// 不同波长的相位差
float phaseR = angle * 100.0;
float phaseG = angle * 120.0;
float phaseB = angle * 140.0;
// 干涉条纹
float3 rainbow;
rainbow.r = 0.5 + 0.5 * cos(phaseR);
rainbow.g = 0.5 + 0.5 * cos(phaseG + 2.0 * PI / 3.0);
rainbow.b = 0.5 + 0.5 * cos(phaseB + 4.0 * PI / 3.0);
return rainbow;
}
棉布 - 微表面高光模型

物理原理:
棉布的高光是漫反射主导的微弱高光,来自纤维表面的微表面散射。
// 棉布高光模型(几乎无镜面,主要是漫反射)
float3 CottonSpecular(float3 normal, float3 viewDir, float3 lightDir,
float roughness, float3 albedo)
{
// 棉布几乎没有镜面反射
// 使用非常微弱的微表面散射高光
float3 halfVec = normalize(lightDir + viewDir);
float NdotH = dot(normal, halfVec);
float NdotL = dot(normal, lightDir);
float NdotV = dot(normal, viewDir);
if (NdotL <= 0.0 || NdotV <= 0.0)
return 0.0;
// ========== 1. 棉布特有的微高光分布 ==========
// 棉布高光非常宽泛模糊
float alpha = roughness * roughness;
// 使用更宽的分布(类似Beckmann但更模糊)
float NdotH2 = NdotH * NdotH;
float denom = NdotH2 * alpha + (1.0 - NdotH2);
float D = exp(-(1.0 - NdotH2) / (denom * 0.1)) / (PI * alpha * NdotH2 + 0.0001);
// ========== 2. 棉布菲涅尔(非常弱) ==========
float LdotH = dot(lightDir, halfVec);
float3 F0 = float3(0.02, 0.02, 0.02); // 非常低的菲涅尔反射率
float3 F = F0 + (1.0 - F0) * pow(1.0 - LdotH, 5.0);
// ========== 3. 几何项(强遮蔽) ==========
// 棉布表面粗糙,遮蔽严重
float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
float G = NdotL * NdotV / ((NdotL * (1.0 - k) + k) * (NdotV * (1.0 - k) + k));
// ========== 4. 漫反射主导的高光混合 ==========
// 棉布高光有色(与漫反射相关)
float3 specularColor = albedo * 0.3;
float3 specular = (D * F * G) / (4.0 * NdotL * NdotV + 0.0001);
return specular * specularColor * 0.1; // 非常弱的高光
}
// 棉布完整的BRDF(漫反射主导)
float3 CottonBRDF(float3 normal, float3 viewDir, float3 lightDir,
float3 albedo, float roughness)
{
// 主要使用Oren-Nayar漫反射
float3 diffuse = OrenNayarDiffuse(normal, lightDir, viewDir, roughness, albedo);
// 非常微弱的高光
float3 specular = CottonSpecular(normal, viewDir, lightDir, roughness, albedo);
return diffuse + specular;
}
皮革 - 双层高光模型

物理原理:
皮革有清漆层(coating) 和基底层。清漆层提供锐利高光,基底层提供柔和高光。
// 皮革双层高光模型
struct LeatherLayer
{
float roughness;
float strength;
float3 F0;
float thickness; // 用于干涉效应
};
float3 LeatherDualLayerSpecular(float3 normal, float3 viewDir, float3 lightDir,
LeatherLayer baseLayer, LeatherLayer coatingLayer)
{
float3 halfVec = normalize(lightDir + viewDir);
float NdotH = dot(normal, halfVec);
float NdotL = dot(normal, lightDir);
float NdotV = dot(normal, viewDir);
float LdotH = dot(lightDir, halfVec);
// ========== 1. 基底层高光 ==========
// 基底较粗糙
float alphaBase = baseLayer.roughness * baseLayer.roughness;
float D_base = D_GGX(NdotH, alphaBase);
float3 F_base = FresnelSchlick(LdotH, baseLayer.F0);
float G_base = GeometrySmith(NdotL, NdotV, baseLayer.roughness);
float3 specularBase = (D_base * F_base * G_base) / (4.0 * NdotL * NdotV + 0.0001);
// ========== 2. 清漆层高光 ==========
// 清漆层较光滑
float alphaCoating = coatingLayer.roughness * coatingLayer.roughness;
float D_coating = D_GGX(NdotH, alphaCoating);
// 清漆层有更高的菲涅尔反射率
float3 F_coating = FresnelSchlick(LdotH, coatingLayer.F0);
float G_coating = GeometrySmith(NdotL, NdotV, coatingLayer.roughness);
float3 specularCoating = (D_coating * F_coating * G_coating) / (4.0 * NdotL * NdotV + 0.0001);
// ========== 3. 层间干涉 ==========
// 清漆层与基底层之间的干涉
float interference = 0.0;
if (coatingLayer.thickness > 0.0)
{
// 简化干涉模型
float phase = coatingLayer.thickness * 100.0 * (1.0 - LdotH);
interference = 0.5 + 0.5 * cos(phase);
}
// ========== 4. 能量守恒混合 ==========
// 清漆层会遮挡基底层
float coatingTransmission = 1.0 - F_coating.r; // 近似透射率
float3 finalSpecular = specularBase * coatingTransmission * baseLayer.strength +
specularCoating * coatingLayer.strength * (1.0 + interference * 0.2);
return finalSpecular;
}
// 皮革老化效果(随时间变化)
float3 LeatherAging(float3 specular, float age, float3 positionWS)
{
// 模拟皮革老化:高光变暗、变粗糙
float ageDarkening = exp(-age * 0.5);
float ageRoughening = saturate(age * 0.3);
// 磨损区域(如边缘、褶皱处)
float3 worldNormal = normalize(cross(ddx(positionWS), ddy(positionWS)));
float wear = 1.0 - saturate(dot(worldNormal, float3(0, 1, 0)));
wear = pow(wear, 2.0);
// 磨损导致高光减弱
specular *= ageDarkening * (1.0 - wear * 0.7);
// 添加划痕微高光
float scratchNoise = fbm(positionWS * 10.0);
float scratches = step(0.95, scratchNoise) * 0.1;
specular += scratches * age;
return specular;
}
羊毛 - 绒毛高光模型

物理原理:
羊毛没有镜面高光,但有绒毛光泽(fuzz sheen),来自纤维末端的背向散射。
// 羊毛绒毛高光模型(实际上几乎没有镜面高光)
float3 WoolSheen(float3 normal, float3 viewDir, float3 lightDir,
float fuzzAmount, float fiberLength)
{
// 羊毛的高光主要来自绒毛的微反射
// ========== 1. 绒毛法线扰动 ==========
// 绒毛使表面法线随机化
float3 fuzzNormal = normal;
// 添加随机扰动(基于位置)
float3 positionWS = GetPositionWS();
float3 randomOffset = float3(
fbm(positionWS * 5.0),
fbm(positionWS * 5.0 + float3(100, 0, 0)),
fbm(positionWS * 5.0 + float3(0, 100, 0))
) * 2.0 - 1.0;
fuzzNormal += randomOffset * fuzzAmount * fiberLength;
fuzzNormal = normalize(fuzzNormal);
// ========== 2. 背向散射光泽 ==========
// 当光线从背面照射时,绒毛会发光
float NdotL = dot(fuzzNormal, lightDir);
float VdotN = dot(viewDir, normal);
// 背向散射项(当光线和视线在法线两侧时)
float backScatter = saturate(-NdotL * 0.5 + 0.5);
backScatter = pow(backScatter, 2.0) * fuzzAmount;
// ========== 3. 边缘光泽 ==========
// 边缘处的绒毛更明显
float edgeFactor = 1.0 - saturate(VdotN);
edgeFactor = pow(edgeFactor, 3.0) * 2.0;
// ========== 4. 绒毛微高光 ==========
// 单个纤维末端的微弱高光
float3 halfVec = normalize(lightDir + viewDir);
float NdotH = dot(fuzzNormal, halfVec);
// 非常宽泛的高光
float fiberSpec = pow(saturate(NdotH), 10.0) * 0.01 * fuzzAmount;
// ========== 5. 组合 ==========
float3 sheen = (backScatter + edgeFactor + fiberSpec) * fuzzAmount;
// 羊毛高光是单色的,类似白色/米色
return sheen * float3(1.0, 0.98, 0.95);
}
// 完整羊毛BRDF(无镜面高光)
float3 WoolBRDF(float3 normal, float3 viewDir, float3 lightDir,
float3 albedo, float roughness, float fuzzAmount, float thickness)
{
// 漫反射(使用次表面散射增强)
float NdotL = dot(normal, lightDir);
float3 diffuse = LambertDiffuse(albedo, NdotL);
// 次表面散射
float3 subsurface = SubsurfaceScattering(normal, viewDir, lightDir, thickness);
diffuse += subsurface * 0.5;
// 绒毛光泽(替代传统高光)
float3 sheen = WoolSheen(normal, viewDir, lightDir, fuzzAmount, 0.5);
return diffuse * albedo + sheen;
}
天鹅绒 - 背向散射高光模型

物理原理:
天鹅绒有特殊的方向性纤维,导致逆光时更亮(backward scattering)。
// 天鹅绒背向散射模型
float3 VelvetBackscattering(float3 normal, float3 viewDir, float3 lightDir,
float roughness, float pileLength, float3 albedo)
{
// 天鹅绒纤维方向(通常垂直于表面)
float3 fiberDirection = normal;
// ========== 1. 背向散射核心 ==========
// 当光线方向与视图方向在法线同侧时,发生背向散射
float NdotL = dot(normal, lightDir);
float NdotV = dot(normal, viewDir);
// 背向散射强度:当NdotL和NdotV都小(掠射角)时最强
float backScatter = (1.0 - abs(NdotL)) * (1.0 - abs(NdotV));
backScatter = pow(backScatter, 2.0);
// ========== 2. 纤维方向性 ==========
// 纤维导致的各向异性背向散射
float LdotFiber = dot(lightDir, fiberDirection);
float VdotFiber = dot(viewDir, fiberDirection);
// 当光线和视线都与纤维方向接近垂直时,背向散射最强
float fiberEffect = (1.0 - abs(LdotFiber)) * (1.0 - abs(VdotFiber));
fiberEffect = pow(fiberEffect, 3.0);
// ========== 3. 颜色效果 ==========
// 天鹅绒背向散射有颜色偏移(向红色偏移)
float3 backscatterColor = albedo;
backscatterColor.r *= 1.2; // 增强红色
backscatterColor.b *= 0.8; // 减弱蓝色
// ========== 4. 纤维密度影响 ==========
// 纤维越密,背向散射越强
float densityEffect = saturate(pileLength * 2.0);
// ========== 5. 最终背向散射 ==========
float3 backscattering = backScatter * fiberEffect * densityEffect * backscatterColor;
return backscattering * 2.0; // 天鹅绒背向散射很强
}
// 天鹅绒镜面高光(非常微弱)
float3 VelvetSpecular(float3 normal, float3 viewDir, float3 lightDir,
float roughness, float pileLength)
{
// 天鹅绒几乎没有镜面高光
// 只有非常微弱的纤维末端反射
float3 halfVec = normalize(lightDir + viewDir);
float NdotH = dot(normal, halfVec);
float NdotL = dot(normal, lightDir);
float NdotV = dot(normal, viewDir);
if (NdotL <= 0.0 || NdotV <= 0.0)
return 0.0;
// 非常粗糙的分布
float alpha = roughness * roughness;
float alpha2 = alpha * alpha;
float NdotH2 = NdotH * NdotH;
float denom = NdotH2 * (alpha2 - 1.0) + 1.0;
float D = alpha2 / (PI * denom * denom);
// 弱菲涅尔
float LdotH = dot(lightDir, halfVec);
float3 F0 = float3(0.02, 0.02, 0.02);
float3 F = F0 + (1.0 - F0) * pow(1.0 - LdotH, 5.0);
// 几何项
float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
float G = NdotL * NdotV / ((NdotL * (1.0 - k) + k) * (NdotV * (1.0 - k) + k));
// 非常微弱的高光
float3 specular = (D * F * G) / (4.0 * NdotL * NdotV + 0.0001);
return specular * 0.05; // 强度非常低
}
// 完整天鹅绒BRDF
float3 VelvetBRDF(float3 normal, float3 viewDir, float3 lightDir,
float3 albedo, float roughness, float pileLength)
{
// 漫反射(天鹅绒漫反射也很弱)
float NdotL = dot(normal, lightDir);
float3 diffuse = LambertDiffuse(albedo, NdotL) * 0.5; // 较暗
// 背向散射(主要视觉效果)
float3 backscattering = VelvetBackscattering(normal, viewDir, lightDir,
roughness, pileLength, albedo);
// 微弱镜面高光
float3 specular = VelvetSpecular(normal, viewDir, lightDir, roughness, pileLength);
return diffuse + backscattering + specular;
}
合成纤维 - 均匀高光+斜射光泽

物理原理:
合成纤维有均匀的规则结构,产生均匀高光,加上斜射时的额外光泽(sheen)。
// 合成纤维高光模型
float3 SyntheticFiberSpecular(float3 normal, float3 viewDir, float3 lightDir,
float roughness, float sheenStrength, float uniformity)
{
float3 halfVec = normalize(lightDir + viewDir);
float NdotH = dot(normal, halfVec);
float NdotL = dot(normal, lightDir);
float NdotV = dot(normal, viewDir);
float LdotH = dot(lightDir, halfVec);
// ========== 1. 基础镜面高光 ==========
// 合成纤维有均匀的镜面高光
float alpha = roughness * roughness;
float alpha2 = alpha * alpha;
float NdotH2 = NdotH * NdotH;
float denom = NdotH2 * (alpha2 - 1.0) + 1.0;
float D = alpha2 / (PI * denom * denom);
// 合成纤维菲涅尔(比天然纤维强)
float3 F0 = float3(0.05, 0.05, 0.05);
float3 F = F0 + (1.0 - F0) * pow(1.0 - LdotH, 5.0);
// 几何项
float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
float G = NdotL * NdotV / ((NdotL * (1.0 - k) + k) * (NdotV * (1.0 - k) + k));
float3 specularBase = (D * F * G) / (4.0 * NdotL * NdotV + 0.0001);
// ========== 2. 斜射光泽 (Sheen) ==========
// 合成纤维在掠射角有额外光泽
float sheen = 0.0;
if (sheenStrength > 0.0)
{
// 使用Charlie分布模拟sheen
float charlieAlpha = roughness * 2.0; // sheen更宽
float charlieD = (2.0 + 1.0 / charlieAlpha) *
pow(1.0 - NdotH * NdotH, 1.0 / (2.0 * charlieAlpha)) /
(2.0 * PI);
// Sheen的菲涅尔不同
float3 sheenF = F0 + (float3(0.3, 0.3, 0.3) - F0) * pow(1.0 - LdotH, 3.0);
sheen = charlieD * sheenF.r * sheenStrength;
}
// ========== 3. 均匀性处理 ==========
// 合成纤维高光非常均匀
float uniformFactor = uniformity;
specularBase = lerp(specularBase, specularBase * 0.8 + 0.2, uniformFactor);
// ========== 4. 组合 ==========
return specularBase + sheen;
}
二.实现

1.布料漫反射 - Oren-Nayar

原理:
Oren-Nayar模型准确地模拟了布料微表面材质的光线散射行为。考虑了表面粗糙度对漫反射的影响。
float3 ClothDiffuse(float3 albedo, float3 normal, float3 lightDir,
float3 viewDir, float roughness)
{
// 计算表面粗糙度参数
float sigma = roughness * PI / 2.0;
float sigma2 = sigma * sigma;
float A = 1.0 - 0.5 * sigma2 / (sigma2 + 0.33);
float B = 0.45 * sigma2 / (sigma2 + 0.09);
float NdotL = max(dot(normal, lightDir), 0.001);
float NdotV = max(dot(normal, viewDir), 0.001);
float3 Lproj = normalize(lightDir - normal * NdotL);
float3 Vproj = normalize(viewDir - normal * NdotV);
float cosPhi = dot(Lproj, Vproj);
float diffuse = NdotL * (A + B * max(0.0, cosPhi) * sqrt(1.0 - NdotL * NdotL));
return albedo * diffuse;
}
2. 布料高光模型 - Charlie NDF

原理:
Charlie NDF(正态分布函数)专门用于模拟布料和织物表面的微表面分布。相比传统的GGX或Beckmann模型,Charlie NDF能产生更柔和、更符合布料特性的高光。
float Charlie(float NdotH, float roughness)
{
roughness = max(roughness, 0.001);
float invRoughness = 1.0 / roughness;
float sin2Theta = 1.0 - NdotH * NdotH;
float exponent = (2.0 + invRoughness) * 0.5;
return (2.0 + invRoughness) * pow(sin2Theta, exponent * 0.5) / (2.0 * PI);
}
3. 镭射效果

原理:
基于视角相关的颜色映射,通过Ramp贴图实现动态色彩变化。使用NdotV(法线与视线点积)控制颜色变化。
Ramp贴图

float3 CalculateEnhancedFoilEffect(float NdotV, float foilMask,
float3 normalWS, float3 viewDirWS)
{
float foilUVX = saturate(NdotV * 0.5 + 0.5);
foilUVX = lerp(foilUVX, 0.5, _FoilRoughness * 0.2);
float3 rampColor = SAMPLE_TEXTURE2D(_RampMap, sampler_BaseMap, float2(foilUVX, 0.5)).rgb;
rampColor = ProcessColor(rampColor);
float edgeFactor = 1.0 - pow(1.0 - NdotV, 2.0) * 0.5 + 1.0;
return rampColor * _FoilIntensity * foilMask * edgeFactor;
}
4.绒毛效果(Fuzz)

原理:
模拟布料表面的微小纤维产生的背向散射效果。添加法线扰动和背向散射使用负法线点积的光照
float3 CalculateFuzz(float3 normal, float3 viewDir, float3 lightDir, float fuzzAmount)
{
// 绒毛法线扰动
float3 randomOffset = float3(
sin(_Time.y * 2.0 + normal.x * 10.0) * 0.1,
cos(_Time.y * 1.5 + normal.y * 10.0) * 0.1,
0
);
float3 fuzzNormal = normalize(normal + randomOffset * fuzzAmount);
// 背向散射计算
float NdotL = dot(fuzzNormal, lightDir);
float backScatter = saturate(-NdotL * 0.5 + 0.5);
backScatter = pow(backScatter, 2.0);
return backScatter * fuzzAmount * 0.3;
}
参考资料
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)