This is a temporary small task to find a bug in the rendering after the modification of the engine. After some modifications have been made to the underlying calling code of the code, the problem of rendering in the scenario is as follows, because it is just getting started with the code, you can only use Nsight to find the problem. First, use Nsight to compare the correct and wrong versions. This is the correct version, first, locate the problem, draw the event, locate the problem that should be FOG, and then look at the Source code of the Pixel Shader set in the current API.
Pixout FogPassPS (events IN) {pixout; float expires; half4 localFogColor; float3 worldPos, cameraToWorldPos; expires (IN, sceneDepth, localFogColor, worldPos, cameraToWorldPos); localFogColor. a = 1.0-localFogColor. a; localFogColor. xyz * = HDRParams2.y; HDROutput (OUT, localFogColor, 1); return OUT ;}
According to the shader name, it is indeed a FogPass problem. After the code is rolled back to the correct version, there is no difference between the two versions of fogpass's shader code, the shader source code error is excluded.
Then, SrcBlendAlpha IS set incorrectly for the Output of the correct version of IS, VS, XFORM/RS, PS, and OT of the two versions, the AlphaBelnd settings for drawing fog are also incorrect, and stenpencil output is incorrect. However, when this draw event occurs, SeperateAlphaBlendEnable and StencilEnable are both FALSE, this is not the reason for the problem of image rendering. However, you still need to record the problem and modify it later. Then, we can find the Texture Sample that Ps always uses when drawing the fog. There is also a difference between the two versions. One is SceneDiffuseAcc, that is, the problem of diffuse reflection of deferred light.
In addition, ZTarget is different for ZMap's deep output information in ZPass, because ZTarget's output is at the beginning, solve the problem first. The ZTarget of the ZTraget version with the correct version shows that the information of SceneNormalsMap and ZTarget is different, in addition, the error version seems that the information of the two rt outputs is exchanged. The RT format of SceneNormalsMap is A8R8G8B8, and the RT format of ZTarget is R32F. To verify this guess, we track it to the vicinity of the Draw Event for ZTarget calculation, and compare the RT output in the context to the correct version. The wrong version can be determined, finally, the target surface output from RT_0 of gbuffer is incorrect. This should be SceneNormalsMap in the A8R8G8B8 format, which is changed to ZTarget in the R32F format. After the error is located, the BUG = v = is found in the code. The idea at the beginning was relatively simple and thought it should be the problem that renderTarget's target was incorrectly set. Then, based on the Perf Marker information, locate the function that processes the ZPASS stage.
PROFILE_LABEL_PUSH ("ZPASS"); FX_ProcessZPassRenderLists (); PROFILE_LABEL_POP ("ZPASS ");CD3D9Renderer: FX_ProcessZPassRenderLists, and it sets the rendertarget by calling CD3D9Renderer: FX_ZScene.
If (bRenderNormalsOnly) {FX_PushRenderTarget (0, CTexture: success, & Found, false,-1, true);} else {FX_PushRenderTarget (0, CTexture: s_ptexZTarget, & found, false,-1, true); FX_PushRenderTarget (1, CTexture: s_ptexSceneNormalsMap, NULL );}Here, FX_PushRenderTarget does not immediately call the d3d api to set the rendertarget. Instead, it stores the information in the RT stack and sets the condition statement if the branch is successful, is to set ZTarget to the RT0 stage, but from
However, according to the debug code in runtime, this part of pointer passing is okay. There is no problem with the upper-layer API, so you can only find the problem from the SetRenderTarget of the underlying d3ddevice.
If (NewRenderTargets = NULL |! RTs [I]-> GetRenderTargetView () {mNativeD3D9Device-> SetRenderTarget (I, NULL);} else {IDirect3DSurface9 * pSurf = (IDirect3DSurface9 *) RTs [I]-> GetRenderTargetView ()-> GetNativeResource (); mNativeD3D9Device-> SetRenderTarget (I, pSurf );}The above is the SetRednerTarget function modified by a colleague. Here we set a breakpoint. The result shows that the pSurf pointer passed in is correct. It indicates that the call of this part of API is correct, it is very likely that SetRenderTarget fails. As a result, the RT0 surface set in the previous pass, that is, R32F ZTarget, is retained to the next pass and continues to be used.
Repeat the single-step debugging and traverse the process. When you call the CD3D9Renderer: FX_PopRenderTarget () function, that is, the current RT is saved to texutre, and the SetRednerTarget operation is also performed. It is called between the previously switched RT0 bound surface. That is to say, if we have set SceneNormalsMap to RT1 and set it to RT0 without clearing RT1, this operation will not succeed. That is
D3D9Device-> SetRenderTarget (0, ZTarget); D3D9Device-> SetRenderTarget (1, SceneNormal); D3D9Device-> SetRenderTarget (0, scenenenormal); // error
D3D9Device-> SetRenderTarget (0, ZTarget); D3D9Device-> SetRenderTarget (1, SceneNormal); D3D9Device-> SetRenderTarget (1, 0); D3D9Device-> SetRenderTarget (0, expiration ); // correct
The modified code is skipped because of some logic problems.
Open the Nsight Event list and you can see that the Eevnt99 part of the correct version has an operation that sets RT1 to NULL. If you skip this operation, the Event135 setting will return an error code. That is, the previous ZTarget will be set on RT0. After my colleague modified the code, this part was correct = 0 =. During the bug search process, we also found that the brightness of the texture to be drawn is different from that of the correct version. After checking the correct version, we found that the problem was caused by the SRGBTexture setting.
In earlier CE versions, the DX11 style is changed to unified settings, and we forget this parameter.
LPDIRECT3DDEVICE9 dv = gcpRendD3D-> GetD3DDevice (); bool sRGBRead = gRenDev-> IsLinearSpaceShadingEnabled () & (m_bIsSRGB | s_TexStates [nt]. 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 );}Then, the problem of SceneDiffuseAcc rendering error is returned. This problem is a bit difficult and no correct solution has been found,
In the correct version, the normal, UV, and other values are output as output values.
NormalUV. x, we can see that the above part has been dropped by clip, and the possible status has been checked. The setting is false and our new version does not set these statuses. The above part should also be drawn, therefore, the version with the ScenediffuseAcc error message error is displayed. The red box is partially too deep and should not be drawn. The solution is to temporarily add a clip function to the shader to remove the excessive depth. If the real implementation method is found, I will write another article to explain it.
Use Nsight to find the rendering bug of S3.