unity urp 棉麻织物渲染

在这里插入图片描述
我在前一篇写了对于衣服和硬表面材质的区别。这一篇来实现一下正常的棉麻类的渲染实现。
首先,说一下棉麻类的衣服的特点。
棉麻类的布料是由线组成的,也就是一根根的线织出来的,所以它是相对来说比较平整的结构。但是呢,它还有一层在表面绒毛的存在,这是一层的绒纤维,属于一层树立在表面的短绒毛,但是这层绒毛的方向和长短都是不确定的,在渲染时,我们需要考虑一下这层绒毛的效果。
所以,为了实现棉麻类的效果,我们需要实现这两层的渲染效果。
那么,在直接光渲染时,漫反射我们还是使用默认的漫反射,但是在实现直接光的镜面高光时,我们需要使用两层高光去实现。之前也说过,正常的表面使用反向的GGX高光,然后再使用一层高光来表现表层上面的绒毛的镜面高光效果。
在实现绒毛效果上,它是在边缘的比较发亮的,所以,我们需要一张lut图取获取第二层高光的强度。
代码如下:

float3 ClothBRDF(float3 DiffuseColor, float3 SheenColor, float Roughness, float SheenRoughness, float SheenDFG, float3 N, float3 V, float3 L, float3 LightColor, float Shadow)
{
	float a2 = Pow4(Roughness);
	float3 H = normalize(L + V);
	float NoH = saturate(dot(N, H));
	float NoV = saturate(abs(dot(N, V)) + 1e-5);
	float NoL = saturate(dot(N, L));
	float VoH = saturate(dot(V, H));
	float3 Radiance = NoL * LightColor * Shadow * PI;
	
	//默认的漫反射
	float3 DiffuseLighting = Diffuse_Lambert(DiffuseColor) * Radiance;
	
	//默认的brdf
	float D = D_Charlie_Filament(Roughness, NoH);
	float Vis = Vis_Cloth(NoV, NoL);
	float3 F = F_Schlick_UE4(0.04, VoH);
	float3 SpecularLighting = ((D * Vis) * F) * Radiance;

	//第二层绒毛类的brdf
	float D2 = D_Charlie_Filament(SheenRoughness, NoH);
	float Vis2 = Vis_Cloth(NoV, NoL);
	float3 F2 = SheenColor;
	float3 SheenLighting = ((D2 * Vis2) * F2) * Radiance;

	//能量守恒,求出第二层的强度,减少其它强度
	float sheenScaling = 1.0 - max(max(SheenColor.r, SheenColor.g), SheenColor.b) * SheenDFG;
	DiffuseLighting *= sheenScaling;
	SpecularLighting *= sheenScaling;

	float3 DirectLighting = DiffuseLighting + SpecularLighting + SheenLighting;
	return DirectLighting;
}

在这里插入图片描述
可以使用类似于上面的图,根据视角和法向作为u的值,然后以粗糙度作为v的值去获取当前第二层高光的强度。

//求出绒毛层的dfg (反射强度)
half2 dfgUV = half2(saturate(dot(normalWS, viewDirWS)), sfd.sheenRoughness);
half dfg = SAMPLE_TEXTURE2D(_DiffuseMap, sampler_DiffuseMap, dfgUV).r;

在这里插入图片描述
调的低一些,效果更明显
在这里插入图片描述

绒毛的效果是杂乱无章的,所以,我们需要一张贴图来表现出那种效果,还需要一张绒毛效果的图
在这里插入图片描述

//求出绒毛层的dfg (反射强度)
half2 dfgUV = half2(saturate(dot(normalWS, viewDirWS)), sfd.sheenRoughness);
half dfg = SAMPLE_TEXTURE2D(_ClothDGF_LUT, sampler_ClothDGF_LUT, dfgUV).r;
half2 fuzzUV = TRANSFORM_TEX(UV, _FuzzMap);
half fuzz = SAMPLE_TEXTURE2D(_FuzzMap, sampler_FuzzMap, fuzzUV).r;
dfg *= fuzz;

在这里插入图片描述
使用图片以后,会发现有那种杂乱无章的绒毛的效果了。
在这里插入图片描述
然后加一个颜色用于控制第二层的颜色效果。
能量守恒,高光的强度全体为1,所以我们需要在生产第二次高光时,做一下处理。

使用的dvf三项的代码,我也列出来

//Filament引擎的渲染衣服使用的D项
float D_Charlie_Filament(float Roughness, float NoH)
{
	// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
	float invAlpha = 1.0 / Pow2(Roughness);
	float cos2h = NoH * NoH;
	float sin2h = max(1.0 - cos2h, 0.0078125); // 2^(-14/2), so sin2h^2 > 0 in fp16
	return(2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);
}
//衣服类brdf的v项
float Vis_Cloth(float NoV, float NoL)
{
	return saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));
}
//ue的pbr使用的f项
// [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"]
float3 F_Schlick_UE4(float3 SpecularColor, float VoH)
{
	float Fc = Pow5(1 - VoH);					// 1 sub, 3 mul
	//return Fc + (1 - Fc) * SpecularColor;		// 1 add, 3 mad
	
	// Anything less than 2% is physically impossible and is instead considered to be shadowing
	return saturate(50.0 * SpecularColor.g) * Fc + (1 - Fc) * SpecularColor;
}

接下来是间接光部分的处理
间接光漫反射还是使用球谐光照的方式去处理

//SH
float3 DiffuseAO = AOMultiBounce(DiffuseColor, Occlusion);
float3 RadianceSH = SampleSH(N);
float3 IndirectDiffuse = RadianceSH * DiffuseColor * DiffuseAO;
float3 AOMultiBounce(float3 BaseColor, float AO)
{
	float3 a = 2.0404 * BaseColor - 0.3324;
	float3 b = -4.7951 * BaseColor + 0.6417;
	float3 c = 2.7552 * BaseColor + 0.6903;
	return max(AO, ((AO * a + b) * AO + c) * AO);
}

在间接光镜面反射部分,使用到了双层处理的方案

float3 IndirectLighting(float3 DiffuseColor, float3 SheenColor, float Roughness, float SheenRoughness, float ClothDFG, float SheenDFG,
float3 WorldPos, float3 N, float3 V, float Occlusion, float EnvRotation)
{
	float NoV = saturate(abs(dot(N, V)) + 1e-5);
	//SH
	float3 DiffuseAO = AOMultiBounce(DiffuseColor, Occlusion);
	float3 RadianceSH = SampleSH(N);
	float3 IndirectDiffuse = RadianceSH * DiffuseColor * DiffuseAO;
	//IBL
	half3 R = reflect(-V, N);
	R = RotateDirection(R, EnvRotation);

	//获取第一层的镜面反射
	half3 SpeucularLD = GlossyEnvironmentReflection(R, WorldPos, Roughness, 1.0f); //在反射球上获取镜面反射颜色
	half3 SpecularDFG = ClothDFG * 0.04; //获取到衣服的反射强度 0.04是默认的非金属反射强度
	float SpecularOcclusion = GetSpecularOcclusion(NoV, Pow2(Roughness), Occlusion); //计算镜面反射的AO
	float3 SpecularAO = AOMultiBounce(float3(0.04, 0.04, 0.04), SpecularOcclusion); //AO和基础色进行混合
	float3 IndirectSpecular = SpeucularLD * SpecularDFG * SpecularAO;

	//获取绒毛层的镜面反射
	half3 SheenSpeucularLD = GlossyEnvironmentReflection(R, WorldPos, SheenRoughness, 1.0f);
	half3 SheenSpecularDFG = SheenColor * SheenDFG; //绒毛的反射强度
	float SheenOcclusion = GetSpecularOcclusion(NoV, Pow2(SheenRoughness), Occlusion); //计算镜面反射的AO
	float3 SheenAO = AOMultiBounce(SheenColor, SheenOcclusion); //AO和基础色进行混合
	float3 SheenSpecular = SheenSpeucularLD * SheenSpecularDFG * SheenAO;

	//能量守恒
	float sheenScaling = 1.0 - max(max(SheenColor.r, SheenColor.g), SheenColor.b) * SheenDFG;
	IndirectDiffuse *= sheenScaling;
	IndirectSpecular *= sheenScaling;

	return IndirectDiffuse + IndirectSpecular + SheenSpecular;
}

里面新增加的ClothDFG 是使用DFG_LUT贴图使用默认的roughness求得。
在这里插入图片描述
最终,就有了带有绒毛效果的棉麻织物的效果了。

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值