disney BRDF代码解释

本文介绍了一种基于BRDF的光照模型计算方法,详细解释了如何使用GLSL着色语言来实现各种光照效果,包括漫反射、高光反射、菲涅尔效应等,并讨论了不同粗糙度和各向异性对光照的影响。

图片稍后补上..

vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y )
{
//计算有用的变量
float NdotL = dot(N,L);
float NdotV = dot(N,V);
//简单的背面判断
if (NdotL < 0 || NdotV < 0) return vec3(0);

vec3 H = normalize(L+V);
float NdotH = dot(N,H);
float LdotH = dot(L,H);

//gamma 修正
vec3 Cdlin = mon2lin(baseColor);
//亮度 =>通过rgb计算灰度
float Cdlum = .3*Cdlin[0] + .6*Cdlin[1] + .1*Cdlin[2]; // luminance approx.
//归一化(分离色相,饱和度)??
vec3 Ctint = Cdlum > 0 ? Cdlin/Cdlum : vec3(1); // normalize lum. to isolate hue+sat
//??
vec3 Cspec0 = mix(specular*.08*mix(vec3(1), Ctint, specularTint), Cdlin, metallic);
//??
vec3 Csheen = mix(vec3(1), Ctint, sheenTint);

// Diffuse fresnel - go from 1 at normal incidence to .5 at grazing

// and mix in diffuse retro-reflection based on roughness

//FL = (1-NdotL)^5 = (1-cosL)^5
float FL = SchlickFresnel(NdotL), FV = SchlickFresnel(NdotV);
float Fd90 = 0.5 + 2 * LdotH*LdotH * roughness;
//mix(a,b,c) = (a+(b-a) * c)
//mix(1, Fd90, FL) = (1+(Fd90-1)*FL)
float Fd = mix(1, Fd90, FL) * mix(1, Fd90, FV);

// Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
// 1.25 scale is used to (roughly) preserve albedo
// Fss90 used to “flatten” retroreflection based on roughness
//次表面参数
float Fss90 = LdotH*LdotH*roughness;
float Fss = mix(1, Fss90, FL) * mix(1, Fss90, FV);
float ss = 1.25 * (Fss * (1 / (NdotL + NdotV) - .5) + .5);

// specular
float aspect = sqrt(1-anisotropic*.9);
float ax = max(.001, sqr(roughness)/aspect);

float ay = max(.001, sqr(roughness)*aspect);
//GGX分布函数
//此处是各项异性

float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay);

//Specular 菲涅尔
//mix(a,b,c) = (a+(b-a) * c)

//F0 = Cspec0
float FH = SchlickFresnel(LdotH);
vec3 Fs = mix(Cspec0, vec3(1), FH);

//smithG GGX

float roughg = sqr(roughness*.5+.5);
float Gs = smithG_GGX(NdotL, roughg) * smithG_GGX(NdotV, roughg);

// sheen
vec3 Fsheen = FH * sheen * Csheen;

//处理透明层:

// clearcoat (ior = 1.5 -> F0 = 0.04)
//GTR1:
float Dr = GTR1(NdotH, mix(.1,.001,clearcoatGloss));

//mix(a,b,c) = (a+(b-a) * c)

//F0 = 0.04(ior = 1.5 -> F0 = 0.04)
float Fr = mix(.04, 1, FH);

//透明层的固定粗糙度为0.25

float Gr = smithG_GGX(NdotL, .25) * smithG_GGX(NdotV, .25);








return ((1/PI) * mix(Fd, ss, subsurface)*Cdlin + Fsheen) * (1-metallic)
    + Gs*Fs*Ds + .25*clearcoat*Gr*Fr*Dr;

}

float SchlickFresnel(float u)
{
float m = clamp(1-u, 0, 1);
float m2 = m*m;
return m2*m2*m; // pow(m,5)
}

float GTR1(float NdotH, float a)
{
if (a >= 1) return 1/PI;
float a2 = a*a;
float t = 1 + (a2-1)*NdotH*NdotH;
return (a2-1) / (PI*log(a2)*t);
}

float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay)
{
return 1 / ( PI * ax*ay * sqr( sqr(HdotX/ax) + sqr(HdotY/ay) + NdotH*NdotH ));
}

float smithG_GGX(float Ndotv, float alphaG)
{
float a = alphaG*alphaG;
float b = Ndotv*Ndotv;
return 1/(Ndotv + sqrt(a + b - a*b));
}

### Unity URP 中 BRDF 和 PBR 的实现与配置 在 Unity Universal Render Pipeline (URP) 下,基于物理的渲染(Physically Based Rendering, PBR)是一种广泛使用的渲染技术。它通过模拟真实世界的光照行为来创建更逼真的视觉效果。以下是关于 URP 中 BRDF 和 PBR 实现及配置的关键点: #### 1. **BRDF 定义及其作用** BRDF(Bidirectional Reflectance Distribution Function)是一个描述表面反射特性的函数,在 PBR 渲染管线中起着核心作用。URP 使用的是 Disney BRDF 模型[^1],该模型简化了许多复杂的光学计算,并提供了更好的艺术控制能力。 - Disney BRDF 将漫反射和镜面反射分开处理,其中漫反射采用 Lambertian 反射模型[^3]。 - 镜面反射部分则利用 GGX 微平面分布函数以及 Smith 衰减模型来进行精确建模[^2]。 这些理论基础被封装进了 Shader 文件内部,开发者通常不需要手动修改它们的具体实现细节。 #### 2. **URP 内置 Lit 材质分析** Unity 提供了一个名为 `Universal Render Pipeline/Lit` 的默认材质类型用于支持 PBR 效果。此材质包含了完整的金属粗糙度工作流所需的所有参数设置选项。 - **Metallic Workflow**: 这种方法允许艺术家定义物体表面上哪些区域表现为导体(metal),而其他地方则是绝缘体(dielectric)。这种区分直接影响最终颜色表现形式——对于纯金属性材料来说,其Albedo Map实际上代表了F0 Fresnel Term的颜色;而非金属对象,则会按照传统方式解释成Diffuse Color加上Specular Highlight叠加而成的效果。 - **Roughness Parameterization**: 表面粗糙程度决定了高光范围大小以及整体光泽感强弱。较低数值对应平滑干净外观,反之亦然。 #### 3. **自定义 PBR Shader 开发指南** 如果标准Lit Material无法满足特定需求时,可以考虑编写自己的Shader脚本来自由调整各项特性。下面给出一段简单的HLSL代码片段作为参考起点: ```hlsl // HLSL snippet demonstrating basic structure of custom lit pass. half4 LightingCustom(SurfaceOutputStandard s, half3 viewDir, UnityGI gi) { // Diffuse term calculation using Burley model. float NdotV = saturate(dot(s.Normal, viewDir)); // Specular term with GGX distribution and Schlick-Fresnel approximation. float3 F = FresnelSchlick(NdotV, _F0); float D = DistributionGGX(NdotV, roughness); float G = GeometrySmith(...); return ...; // Combine diffuse & specular terms appropriately here. } ``` 上述伪代码展示了如何组合不同的数学表达式以构建一个全新的Lighting Model实例. #### 4. **解决常见问题** 当尝试迁移旧版Build-In Engine中的资产至新Pipeline时可能会遇到一些挑战。例如,《无主之地3》风格的角色渲染案例提到过两个主要障碍:一是边缘检测算法可能导致某些角度下线条断裂不连续的现象发生;二是希望达成混合画风目标即人物肌肤呈现卡通化倾向的同时保持服饰装备遵循真实的物理学规律变化趋势. 对于前者可通过改进抗锯齿策略或者引入后期特效手段加以缓解改善;至于后者则需精心设计Material Graph节点布局从而平衡两者之间的差异冲突关系. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值