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