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/LdotHhalf3 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(原群已满员)