完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
渲染应用阶段
LWRP现在再unity2019已经成为默认的管线了,替代了原来的builtin管线,我当前项目用的还是2018.4的lwrp,使用了一段时间,觉得还是想总结下lwrp的渲染流程。总结过程中也学到了不少东西,所以想在这里分享下我了解的lwrp管线 执行应用阶段流程顺序如下: lwrp从结果来看就是前向渲染的流程,没有gbuffer保存几何信息。他实现原理是将不透明渲染,天空盒渲染,透明渲染加入CommandBuffer里,最终一次性提交渲染。其中如果需要Depth或Opaque图片则可以拷贝到rt输出到指定全局变量给开发用。 下面我想说下我了解的lwrp的详细流程,设计的东西会比较多。也是看代码的过程中学习了很多东西。 |
|
|
|
lwrp整个渲染的主入口在LightweightRenderPipeline,他继承的RenderPipeline,是rsp的渲染流程关键类
首先是构造函数 PipelineSettings:这里会获取LightweightRenderPipelineAsset(也就是我们外部传入的管线的参数) ScriptableRenderer:srp渲染器,需要把LightweightRenderPipelineAsset传给他。他是渲染核心,他会收集所有当前帧要渲染的pass,以及他会拥有渲染相关的灯光和后处理等执行方法。 PerFrameBuffer:每帧设置的缓存数据 _GlossyEnvironmentColor:主要用于PBR这块的全局光照的颜色,在Lighting.hlsl的GlossyEnvironmentReflection,可以看到他主要是全局光照的高光部分颜色。 _SubtractiveShadowColor:主要用在除了主光源外的lightmap计算的阴影颜色。在SubtractDirectMainLightFromLightmap里使用 PerCameraBuffer:每帧摄像机的缓存数据 _InvCameraViewProj:视图空间到投影空间的转置矩阵,如果用原始矩阵乘以反向矩阵结果为identity矩阵。如果一些矩阵以一个特定的方式变换向量,反向矩阵可以将他们变换回去。例如worldToLoclaMatrix和localToWorldMatrix是互逆的。 _ScaledScreenParams:屏幕缩放参数 antiAliasing从asset中获取msaaSampleCount Shader.globalRenderPipeline = “LightweightPipeline”;设置全局管线为LightweightPipeline lightsDelegate:全局光照的回调 |
|
|
|
执行到Render中执行具体渲染流程:
SetupPerFrameShaderConstants:设置全局光照的数据,设置PerFrameBuffer中的_GlossyEnvironmentColor和_SubtractiveShadowColor。 其中_GlossyEnvironmentColor是通过球形谐波方程决定颜色的,最后要转到当前颜色空间(gamma空间或线性空间) _SubtractiveShadowColor则是直接赋值具体的除去主光源后的阴影颜色,只是也有最后转到当前颜色空间的转换。 |
|
|
|
对当前Render给过来当前有哪些相机渲染的数据来进行每个相机的渲染RenderSingleCamera。
每个相机中的渲染步骤如下: CullResults.GetCullingParameters:获取相机下的裁剪参数,如果返回false说明没有聂荣,不需要渲染这个相机。如果需要考虑到类似vr等情况需要区分左右眼的摄像机时需要把stereoAware设置为true。 CommandBuffer cmd = CommandBufferPool.Get(k_RenderCameraTag):这里从命令缓存池中获取一个gl命令缓存,CommandBuffer主要用于收集一系列gl指令,然后之后执行。 ProfilingSample是对指定名字做性能采样。 InitializeCameraData:初始化摄像机数据。 cameraData.msaaSamples:如果数量大于1说明需要多重采样 cameraData.isSceneViewCamera:这个是查看当前要渲染的是否在unity的scene视图 cameraData.isOffscreenRender:屏幕外渲染,如果摄像机的targettexture存在并且不是scene视图则这个为true。 cameraData.isStereoEnabled:就是左右眼做区别的摄像机,用于vr等 cameraData.isHdrEnabled:是否支持hdr,也就是高动态范围图像,就是可以在高光情况下能看清一些光照细节,提高细节渲染。 cameraData.postProcessLayer:后处理 cameraData.postProcessEnabled:是否开启后处理 cameraData.renderScale:渲染缩放比例 cameraData.opaqueTextureDownsampling:降采样 cameraData.isDefaultViewport:如果是正常的(0,0,1,1)则是默认的 cameraData.maxShadowDistance:最大阴影范围 cameraData.requiresDepthTexture:是否启用深度纹理 cameraData.requiresOpaqueTexture:是否保存非透明颜色信息 cameraData.defaultOpaqueSortFlags:默认的非透明渲染顺序 |
|
|
|
SetupPerCameraShaderConstants
PerCameraBuffer._ScaledScreenParams:是一个vector4,包括相机像素的长宽和纹素 PerCameraBuffer._InvCameraViewProj:设置摄像机视角的逆矩阵,通过GL.GetGPUProjectionMatrix获取到当前gpu正确坐标系的投影矩阵,再跟camera.worldToCameraMatrix视图矩阵相乘得到视图到投影的矩阵,再用Matrix4x4.Inverse获取逆矩阵。 cullingParameters.shadowDistance:设置阴影距离,这里会根据摄像机最远渲染距离来获得最远可达到的距离。 ScriptableRenderContext.ExecuteCommandBuffer(cmd):执行命令缓存 cmd.Clear();清除缓存数据 CullResults.Cull:根据裁剪的参数cullingParameters和context指定的渲染指令得到裁剪的灯光,物体等。 InitializeRenderingData:初始化渲染相关数据 GetMainLight:获取主光源,如果是直线光并且mainLightRenderingMode不为LightRenderingMode.PerPixel就是主光源 mainLightCastShadows:如果可见光存在而且阴影设置存在则为true additionalLightsCastShadows:如果additionalLightsRenderingMode是LightRenderingMode.PerPixel并且可见光存在并且lightType是LightType.Spot且阴影存在则为true InitializeLightData:初始化灯光数据,这里设置了mainLightIndex(也就是GetMainLight获取的),设置additionalLightsCount获取叠加光源的数量,maxPerObjectAdditionalLightsCount最大叠加光源数量,shadeAdditionalLightsPerVertex就是是否是叠加光源,visibleLights可视光源,supportsMixedLighting支持混合光源 InitializeShadowData:初始化阴影数据,如果有多光源会添加LWRPAdditionalLightData到光源的gameobject上,m_ShadowBiasData会设置阴影偏移和阴影发现偏移,主要用于解决自阴影的问题。supportsMainLightShadows支持主光源阴影 。mainLightShadowCascadesCount是阴影的级联个数,(mainLightShadowmapWidth、mainLightShadowmapHeight)主光源阴影贴图的宽高。mainLightShadowCascadesSplit是阴影的级联分割,supportsAdditionalLightShadows是否支持多光源阴影。additionalLightsShadowmapWidth、additionalLightsShadowmapHeight是多光源阴影贴图的宽和高都是additionalLightsShadowmapResolution。supportsSoftShadows支持软阴影 supportsDynamicBatching:是否支持动态批处理,这个是lwrp的动态批处理 |
|
|
|
设置完渲染数据后就是开始设置渲染的顺序了:
renderer.Clear():再设置之前需要清理renderer的数据,不然前一帧渲染的dc是不会清掉的,dc就会越来越高。 setupToUse.Setup(renderer, ref renderingData):默认lwrp是用DefaultRendererSetup来设置的,当然你也可以实现IRendererSetup然后传入Render来自己实现。 DefaultRendererSetup:lwrp默认会有一系列渲染过程。会再Setup中确定渲染的先后。 SetupPerObjectLightIndices设置每个对象光照信息 CreateRenderTextureDescriptor创建rt数据信息 GetCameraClearFlag获取当前摄像机清理方式,lwrp对这层做了一些处理,主要是对深度剔除做了一些选项 如果是渲染到纹理则用CreateLightweightRenderTexturesPass这个pass执行一次渲染。 如果有渲染前要执行的pass要实现IBeforeRender接口,并且可以多个pass 如果支持主光源阴影投放则执行MainLightShadowCasterPass的pass 如果支持多光源阴影投放则执行AdditionalLightsShadowCasterPass 之后执行SetupForwardRenderingPass,这个pass是必然执行的,设置摄像机到context里 如果支持深度贴图获取的话会执行DepthOnlyPass(requiresDepthPrepass决定是否执行他),这里会用一个rt保存深度贴图新消息 如果支持屏幕空间阴影获取,则会执行ScreenSpaceShadowResolvePass,这里会用一个rt记录屏幕空间中的阴影贴图 然后执行SetupLightweightConstanstPass,主要设置主光源和其他光源的颜色,位置以及其他属性。如果不设置则会是默认颜色和位置等信息。 然后执行RenderOpaqueForwardPass,这个pass定义了两个pass名,LightweightForward和SRPDefaultUnlit。然后再Execute申请cmd来做不透明渲染。 如果支持后处理则会执行OpaquePostProcessPass,里面是申请一个临时rt做相关不透明的后处理。 如果是相机是天空盒清除方式的话并且天空盒不是空的话则执行DrawSkyboxPass,里面会绘制天空盒 如果需要天空盒处理之后执行的话需要继承IAfterSkyboxPass实现相关pass 如果是支持深度贴图的话并且没有执行requiresDepthPrepass的话(就是前面执行DepthOnlyPass的判断)则会执行CopyDepthPass,这里主要是拷贝深度贴图到全局变量_CameraDepthAttachment中,shader可以直接获取这个变量(如果有开深度贴图获取) 如果开启了接收不透明贴图的话则执行CopyColorPass,这里主要是把不透明渲染后的颜色输出到临时rt中。 然后执行RenderTransparentForwardPass,透明渲染方式 如果支持后处理则执行TransparentPostProcessPass,也是一样申请一个临时rt做相关透明渲染的后处理。如果不需要并且不支持屏幕外渲染并且不是渲染到纹理的则要执行FinalBlitPass,这里主要设置贴图到全局变量_BlitTex,然后把颜色blit到内置rt中 然后如果摄像机有IAfterRender的mono则会执行pass中的GetPassToEnqueue方法。 最后还会有一个EndXRRenderingPass的渲染,这个是支持立体摄像机的情况下执行的,主要是停止立体摄像机渲染 然后再到外面renderer.Execute(context, ref renderingData);也就是把所有pass都执行一次。(前面只是加入到列表中,并没有执行每个pass的execute) |
|
|
|
只有小组成员才能发言,加入小组>>
3453个成员聚集在这个小组
加入小组物联网工程师必备:怎么选择不同的无线连接威廉希尔官方网站 ,本指南帮你忙!
3316 浏览 1 评论
【DFRobot TinkerNode NB-IoT 物联网开发板试用连载】WIFI功能测试
3967 浏览 0 评论
【DFRobot TinkerNode NB-IoT 物联网开发板试用连载】Arduino的替代SublimeText3+STino
3469 浏览 0 评论
使用端口扩展器轻松高效地向IIoT端点添加具有成本效益的子节点
4044 浏览 1 评论
20722 浏览 11 评论
模组有时候复位重启后输出日志为“REBOOT_CAUSE_SECURITY_PMU_POWER_ON_RESET”的原因?
860浏览 2评论
1089浏览 2评论
1093浏览 1评论
1221浏览 1评论
425浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-30 13:37 , Processed in 1.054621 second(s), Total 88, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号