1)在URP中的BRDF计算公式问题
2)Job System占用主线程工夫问题
3)在Profiler中定位TempBuffer问题
4)Unity 2019应用HDRP的摄像机的GL画线问题
5)Unity WebCamTexture获取到的相机图片被旋转
这是第248篇UWA技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫10分钟,认真读完必有播种。
UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)
Shader
Q:最近在看URP Shader的时候发现个问题,不晓得是不是我了解的不对。首先贴代码:
先是URP的Lighting.hlsl里初始化BRDF的局部:
inline void InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, out BRDFData outBRDFData)
{
#ifdef _SPECULAR_SETUP
half reflectivity = ReflectivitySpecular(specular);
half oneMinusReflectivity = 1.0 - reflectivity;
outBRDFData.diffuse = albedo * (half3(1.0h, 1.0h, 1.0h) - specular);
outBRDFData.specular = specular;
#else
half oneMinusReflectivity = OneMinusReflectivityMetallic(metallic);
half reflectivity = 1.0 - oneMinusReflectivity;
outBRDFData.diffuse = albedo * oneMinusReflectivity;
outBRDFData.specular = lerp(kDieletricSpec.rgb, albedo, metallic);
#endif
outBRDFData.grazingTerm = saturate(smoothness + reflectivity);
outBRDFData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(smoothness);
outBRDFData.roughness = max(PerceptualRoughnessToRoughness(outBRDFData.perceptualRoughness), HALF_MIN);
outBRDFData.roughness2 = outBRDFData.roughness * outBRDFData.roughness;
outBRDFData.normalizationTerm = outBRDFData.roughness * 4.0h + 2.0h;
outBRDFData.roughness2MinusOne = outBRDFData.roughness2 - 1.0h;
#ifdef _ALPHAPREMULTIPLY_ON
outBRDFData.diffuse *= alpha;
alpha = alpha * oneMinusReflectivity + reflectivity;
#endif
}
依照我的了解:
outBRDFData.perceptualRoughness 是咱们说的粗糙度;
outBRDFData.roughness 是粗糙度的平方;
outBRDFData.roughness2 是粗糙度的4次方;
再看URP的Lighting.hlsl里计算BRDF的局部:
// Based on Minimalist CookTorrance BRDF
// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255
//
// * NDF [Modified] GGX
// * Modified Kelemen and Szirmay-Kalos for Visibility term
// * Fresnel approximated with 1/LdotH
half3 DirectBDRF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS)
{
#ifndef _SPECULARHIGHLIGHTS_OFF
float3 halfDir = SafeNormalize(float3(lightDirectionWS) + float3(viewDirectionWS));
float NoH = saturate(dot(normalWS, halfDir));
half LoH = saturate(dot(lightDirectionWS, halfDir));
// GGX Distribution multiplied by combined approximation of Visibility and Fresnel
// BRDFspec = (D * V * F) / 4.0
// D = roughness^2 / ( NoH^2 * (roughness^2 - 1) + 1 )^2
// V * F = 1.0 / ( LoH^2 * (roughness + 0.5) )
// See "Optimizing PBR for Mobile" from Siggraph 2015 moving mobile graphics course
// https://community.arm.com/events/1155
// Final BRDFspec = roughness^2 / ( NoH^2 * (roughness^2 - 1) + 1 )^2 * (LoH^2 * (roughness + 0.5) * 4.0)
// We further optimize a few light invariant terms
// brdfData.normalizationTerm = (roughness + 0.5) * 4.0 rewritten as roughness * 4.0 + 2.0 to a fit a MAD.
float d = NoH * NoH * brdfData.roughness2MinusOne + 1.00001f;
half LoH2 = LoH * LoH;
half specularTerm = brdfData.roughness2 / ((d * d) * max(0.1h, LoH2) * brdfData.normalizationTerm);
// On platforms where half actually means something, the denominator has a risk of overflow
// clamp below was added specifically to "fix" that, but dx compiler (we convert bytecode to metal/gles)
// sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...))
#if defined (SHADER_API_MOBILE) || defined (SHADER_API_SWITCH)
specularTerm = specularTerm - HALF_MIN;
specularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles
#endif
half3 color = specularTerm * brdfData.specular + brdfData.diffuse;
return color;
#else
return brdfData.diffuse;
#endif
}
这里最终的公式是:
BRDFspec=roughness^2/( NoH^2*(roughness^2-1)+1)^2*(LoH^2*(roughness+0.5)*4.0)
而后看Unity 2015年的论文,也就是代码里写的那个地址:
https://community.arm.com/eve…
代码里的roughness实际上是图里roughness的平方,为了避免混同,上面用roughness©和roughness(n)来示意:
roughness©=roughness(n)^2
看到这里我产生了疑难,论文里roughness(n)+0.5这一步,对应到代码里,应该是roughness©^0.5+0.5才对,而URP代码里间接用了roughness©+0.5。我想问下是我了解的不对,还是URP的Shader写错了?
A:讲一下不太成熟的认识。我这边的论断是:
- 用平方(roughness(n)^2)加0.5是正当的
- 用一次方或者是平方差异不大
SIGGRAPH报告中最后V*F函数如下:
理论应用的V*F函数是对上述函数的一个近似,应用图像相近的函数进行优化:
笔者对取一次方和取平方的函数图像进行了绘制如下:
两个图像差异不大,而从走势上看,取平方仿佛更最靠近最后的VF(Modified KSK and Schlick Fresnel depend on LH)。
笔者批改了Lighting.hlsl的代码,应用一次方:
outBRDFData.normalizationTerm=outBRDFData.perceptualRoughness*4.0h+2.0h;
将应用roughness(n)+0.5和应用roughness(n)^2+0.5的材质绘制在同一个屏幕上如下,两者简直没有差异:依据图形学第一定律:如果它看起来是对的,那么它就是对的,所以了解成两个都对应该也能够。那么,是不是在差距不大的状况下就不用深究了。
感激Prin@UWA问答社区提供了答复
Script
Q:如图,为什么放到Job System去执行还会占用主线程的工夫?
A:期待子线程执行结束。
感激Walker-523103@UWA问答社区提供了答复
Rendering
Q:如图所示,在一个场景里两个TempBuffer,不是从C#脚本上创立产生的。场景没有应用后效,没有应用Grab Pass的Shader,场景摄像机都关掉了MSAA和HDR,依然有这两个TempBuffer。请问如何齐全去掉?
如同和这两个货色无关:
A1:设置一下这个试试:Camera.forceIntoRenderTexture = false;
这个选项会强制将相机渲染到TempBuffer上。在不应用后效时手动设置为false,开启后效会主动设为true。所以如果应用了后效,则TempBuffer是不可避免的了。
感激范世青@UWA问答社区提供了答复
A2:屏蔽掉所有MonoBehavior的OnRenderImage(RenderTexture source, RenderTexture destination)函数,一般来说每个OnRenderImage(RenderTexture source, RenderTexture destination)函数都会产生一个TempBuffer。
感激李星@UWA问答社区提供了答复
A3:Grab RenderTexture个别是Depth最小的相机的Clear Flags设置为Depth Only的时候会呈现。
感激Xuan@UWA问答社区提供了答复
Rendering
Q:在Unity 2019.3.0f6应用GL画线在Game视图下摄像机找不到,我的项目是属于HDRP工程。
A1:把你GL绘制的放到GLDraws()中,我在Unity 2020.2.2f1c1中,HDRP10.2.2环境下曾经胜利绘制进去成果:
protected void OnEnable() { if (GraphicsSettings.renderPipelineAsset != null) RenderPipelineManager.endFrameRendering += OnCameraRender; }
protected void OnDisable() { if (GraphicsSettings.renderPipelineAsset != null) RenderPipelineManager.endFrameRendering -= OnCameraRender; } protected void OnCameraRender(ScriptableRenderContext context, Camera[] cameraList) { foreach(var camera in cameraList) { if (CheckFilter(camera)) GLDraws(); } }
感激pp@UWA问答社区提供了答复
Script
Q:从Unity WebCamTexture获取到的相机图片被旋转了,我看微信的扫一扫,画面都是对的,而且手机旋转的时候,画面也始终是正的,没有看到图片有旋转的痕迹。手机竖屏的时候是失常的,旋转到横屏,画面就不对了。
A:能够在屏幕旋转的时候按上面这样的形式调整一下用于显示的RawImage的旋转:
感激羽飞@UWA问答社区提供了答复
封面图起源:Unity Lightcookie Caustic
https://lab.uwa4d.com/lab/5dc…
明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在UWA问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官网技术QQ群:793972859(原群已满员)
发表回复