工作临时的接的一个小任务,查找ce3引擎修改后在绘制上出的一点bug
在代码的底层调用代码做了一些修改后,场景里的绘制的问题,因为也是刚接触CE3代码,也只能通过Nsight来查找问题了。
 
首先用Nsight对正确和错误两个版本做次对比
下图是正确的版本
这个是错误版本
对比后,先是定位出问题绘制事件
 
定位到应该是FOG绘制的问题
 
再看一下当前API设置的Pixel Shader的Source code
pixout FogPassPS(vert2fragFog IN)
{
pixout OUT;
float sceneDepth;
half4 localFogColor;
float3 worldPos,cameraToWorldPos;
FogPassCommon(IN,sceneDepth,localFogColor,worldPos,cameraToWorldPos);
localFogColor.a=1.0-localFogColor.a;
localFogColor.xyz*=HDRParams2.y;
HDROutput(OUT,localFogColor,);
return OUT;
}

从shader的名字看,确实是FogPass的问题,先把代码回滚回正确的版本后,对两个版本fogpass的shader代码做比对,没有任何区别,排除了shader source code 出错的可能性。

然后再对两个版本的IS, VS, XFORM/RS, PS, OT逐一比较
正确版本的Output
错误版本的Output
发现了SrcBlendAlpha的设置错误,绘制fog时的AlphaBelnd设置也出了问题,另外Stencil的输出也不对,不过因为这个draw event的时候,SeperateAlphaBlendEnable和StencilEnable都是FALSE,所以画面绘制问题并不是这个造成的,不过还是需要记录下来以后进行修改。
然后,这时候发现绘制fog时,Ps时时使用的Texture Sample,两个版本也有区别
一个是SceneDiffuseAcc,也就是deferred light的漫反射累积光照的问题
另外就是在,ZPass阶段的ZMap的深度输出信息,ZTarget也不一样,因为ZTarget的输出在更前面,那么就先解决它的问题
 
正确版本的ZTraget
错误版本的ZTarget
从上图可以看到SceneNormalsMap和ZTarget的信息是不一样的,而且错误版本好像是这两个rt输出的信息互换了,SceneNormalsMap的RT格式是A8R8G8B8,
而ZTarget的RT格式是R32F。
 
为验证这个猜测,跟踪到计算ZTarget的Draw Event附近,对比一下上下文的RT的输出差别
正确版本
 
错误版本
可以确定了,最后gbuffer的RT_0输出的到的目标surface错误的,本应该是A8R8G8B8格式的SceneNormalsMap,变成了R32F格式的ZTarget。
定位到错误后,就是到代码里去查找BUG了=v=。
 
一开始的想法比较简单,认为应该就是renderTarget的目标被错误设置的问题,那么,先根据Perf Marker信息,定位到处理ZPASS阶段的函数
  1. PROFILE_LABEL_PUSH("ZPASS");
    FX_ProcessZPassRenderLists();
    PROFILE_LABEL_POP("ZPASS");

    CD3D9Renderer::FX_ProcessZPassRenderLists,而它通过调用CD3D9Renderer::FX_ZScene,来设置rendertarget

  1. if( bRenderNormalsOnly )
    {
    FX_PushRenderTarget(,CTexture::s_ptexSceneNormalsMap,&m_DepthBufferOrigMSAA,false,-,true);
    }
    else
    {
    FX_PushRenderTarget(,CTexture::s_ptexZTarget,&m_DepthBufferOrigMSAA,false,-,true);
    FX_PushRenderTarget(,CTexture::s_ptexSceneNormalsMap, NULL);
    }

    这里FX_PushRenderTarget并不会立即调用d3d的api设置rendertarget,而是把信息保存在RT的stack里,等commit时再统一进行设置,条件语句if成功的分支,就是把ZTarget设置到RT0的阶段,但从

但通过runtime时debug代码来看,这部分的指针传递都是没问题的。
上层API没有问题,那么就只能从底层d3ddevice的SetRenderTarget来查找问题了
  1. if(NewRenderTargets== NULL ||!RTs[i]->GetRenderTargetView())
    {
    mNativeD3D9Device->SetRenderTarget(i, NULL);
    }
    else
    {
    IDirect3DSurface9* pSurf =(IDirect3DSurface9*)RTs[i]->GetRenderTargetView()->GetNativeResource();
    mNativeD3D9Device->SetRenderTarget( i, pSurf );
    }

    上面是同事修改过后的SetRednerTarget函数,在这里设置断点,结果发现传递进去的pSurf指针也是正确的,那么说明,这部分API的调用是没问题的,很有可能是SetRenderTarget失败,导致前一个pass里,设置的RT0 surface,也就是R32F ZTarget被保留到了下一个pass里继续使用了。

重新单步调试,遍历这部分流程,发现调用CD3D9Renderer::FX_PopRenderTarget()函数的时候,也就是把当前的RT保存到texutre的操作,也会有SetRednerTarget的操作。恰好也就在前面切换RT0的绑定surface之间调用的。也就是说,如果我们已经把SceneNormalsMap设置到RT1后,如果不把RT1清空,就立即把它设置到RT0,那么这部操作是不会成功的。
 
也就是
  1. D3D9Device->SetRenderTarget(,ZTarget);
    D3D9Device->SetRenderTarget(,SceneNormal); D3D9Device->SetRenderTarget(,SceneNormal);//错误
    D3D9Device->SetRenderTarget(,ZTarget);
    D3D9Device->SetRenderTarget(,SceneNormal); D3D9Device->SetRenderTarget(,);
    D3D9Device->SetRenderTarget(,SceneNormal);//正确

    而我们修改过的代码,因为某些逻辑问题,设置RT1为NULL的操作被跳过了

打开Nsight的Event list
可以看到正确版本的Eevnt99部分有设置RT1为NULL的操作,而如果跳过这部操作的话,Event135的的设置会返回错误代码。也就是之前的ZTarget会被继续设置在RT0上。
同事修改了代码后,这部分总算是正确了=0=。
在查找bug过程中中,还发现了绘制纹理的亮度有差别
正确版本
错误版本
排查后在读取贴图的地方发现,是SRGBTexture设置的问题。

CE老版本的设置方法,而DX11风格变成了统一设置,而我们把这个参数忘记了。
  1. LPDIRECT3DDEVICE9 dv = gcpRendD3D->GetD3DDevice();
    bool sRGBRead = gRenDev->IsLinearSpaceShadingEnabled()&&( m_bIsSRGB || s_TexStates[nTS].m_bSRGBLookup &&(m_nFlags& FT_USAGE_ALLOWREADSRGB));
    STexState*pDTS =&TexStages[nTUnit].m_State;
    if(pDTS->m_bSRGBLookup != sRGBRead )
    {
    pDTS->m_bSRGBLookup = sRGBRead;
    dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_SRGBTEXTURE, sRGBRead ? TRUE : FALSE);
    }

    然后,又回到了SceneDiffuseAcc渲染错误的问题上了。这个问题略坑,还没找到正确解决方法,
    具体现象是,在正确版本里,把法线,UV,以及其他定值作为output输出

Normal
UV.x
可以看到上面部分都被clip掉了,而查看了所以可能的状态,设置都为false
而我们的新版本,不设置这些状态,上面部分也要绘制,所以才会出现ScenediffuseAcc错误信息
错误的版本,红框部分因为深度过大,本来是不应该绘制的。
解决办法,只有暂时在shader里添加一个clip函数来把深度过大的地方去掉。
 
11月7日添加: 最后发现是同事把nv的depthboundTest实现的代码注释掉了,也难怪nsight和pix都差不到= =

使用Nsight查找CE3的渲染bug的更多相关文章

  1. 【H5疑难杂症】脱离文档流时的渲染BUG

    BUG重现 最近机票团队在一个页面布局复杂的地方发现一个BUG,非常奇怪并且不好定位,这类问题一般最后都会到我这里,这个问题是,改变dom结构,页面却不渲染!!! 如图所示,我动态的改变了dom结构, ...

  2. 记 移动端页面中莫名其妙的渲染BUG

    问题描述: 在一个很简单的测试页面中 简单的两块布局,上下两块均没有单独设置字体大小,都用body继承的大小,即40px.我们现在给第一个块.fl  加上浮动 float:left; 另外一个块处于正 ...

  3. CKPlayer 只调用HTML5播放器时全屏问题 这只是Chrome浏览器的渲染bug

    如题,在系统中使用CKPlayer播放器,一切顺利,偶然发现没有全屏按钮, 正常的全屏按钮是这样的: 经过一步步调试,发现问题出在iframe, 当视频页面在iframe内时,全屏按钮不显示了,这个和 ...

  4. 如何使用Xcode调试Shader代码Bug导致的渲染问题

    我最近发现了一个与Unity中的表面着色器有关的小Bug. 你可以看到如下所示的渲染瑕疵. 有时人们会将相似的渲染瑕疵归因于同时使用HDR和Bloom效果,但实际上,表面着色器是错误的,至少在本文中所 ...

  5. 线上应用bug跟踪查找-友盟统计

    线上的应用只要用心点点都能发现些bug,连微信,QQ也不列外.但是bug中最严重的算是闪退了,这导致了用户直接不能使用我们的app. 我们公司是特别注重用户反馈和体验的,我们会定期打电话咨询用户的使用 ...

  6. 摄像头bug查找工作总结

    近期花了很长时间在libcamera中查找和解决一个bug.下面将这段时间中的工作过程,以及对camera的认识总结如下: 首先是问题的发生,在UM2801中,摄像头的代码已经基本实现,并且相应功能也 ...

  7. 有没有一个工具可以帮助查找python的bug和进行静态的代码分析?

    答:PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug, 会对代码的复杂度和格式提出警告 Pylint是另外一个工具可以进行codingstandard检查

  8. 【前端优化之渲染优化】大屏android手机动画丢帧的背后

    前言 上周我与阿里的宇果有一次技术的交流,然后对天猫H5站点做了一些浅层次的分析,后面点时间基本天天都会有联系,中途聊了一些技术细节.聊了双方团队在干什么,最后聊到了前端优化.因为我本身参与了几次携程 ...

  9. 项目中遇到的各种bug和踩过的坑

    zepto 赋值时单位转换问题 zepto 的 animate 方法移动某个元素的位置时,例如修改某个绝对定位的元素的 left 值,要与修改前的值单位一致,修改前如果是像素值,修改后也要是像素值,否 ...

随机推荐

  1. 大白菜U盘启动盘制作工具V5.0如何制作启动系统U盘

    1:切换到ISO模式或者直接点击主程序左上角的ISO制作,程序会切换到ISO制作界面. 2:在路径里选好ios文件,点击按钮. 3:打开ISO模式的一键制作启动U盘,点击ISO模式里的按钮,按照图中推 ...

  2. SPI试验---verilog(实用单通模式)

    SPI通信的读写操作 一.     SPI简介: SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时).也是所有基于SP ...

  3. DJANGO的API跨域实现

    Ajax跨域请求报错:XMLHttpRequest cannot load ''. No 'Access-Control-Allow-Origin' header is present on the ...

  4. loj 1018(状压dp+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25844 思路:首先预处理出点在同一直线上的所有的点集状态(dp[i ...

  5. Android Studio 一些使用经验

    一.Mac或Win 7 配置环境,以gradle为例 (1).可以在这里找gradle下载,或者去官网啦 Mac添加环境变量: 1.启动Terminal终端 2.输入cd ~/ 进入当前用户的home ...

  6. asp.net控件开发基础(1)(转)原文更多内容

    asp.net本身提供了很多控件,提供给我们这些比较懒惰的人使用,我认为控件的作用就在此,因为我们不想重复工作,所以要创建它,这个本身便是一个需求的关系,所以学习控件开发很有意思. wrox网站上有本 ...

  7. 2016.6.20 计算机网络复习要点第三章之CSMA/CD协议

    1.最早的以太网是将许多计算机都连接到一根总线上: (1)总线的特点是:当一台计算机发送数据时,总线上的所有计算机都检测到这个数据,这种就是广播通信方式: (2)为了实现在总线上的一对一通信,可以使每 ...

  8. git将本地仓库上传到远程仓库

    在已有的Git库中搭建新库,并且将本地的git仓库,上传到远程服务器的git库中,从而开始一个新的项目 首先,在本地新建文件夹abc,进入到abc里面,然后git init.这样就在本地初始化了一个g ...

  9. Spring计划

    团队: 郭志豪:http://www.cnblogs.com/gzh13692021053/ 杨子健:http://www.cnblogs.com/yzj666/ 刘森松:http://www.cnb ...

  10. android 常用第三方包的代码混淆

    首先在:project.properties 文件下,启动代码混淆 proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:pro ...