Refactor : NiloToon 셀프 섀도우 double-draw 제거
이전 fix는 cullResults 기반 DrawRendererList + manual DrawRenderer 둘 다 호출해서 캐릭터가 frustum 안에 있을 때 shadow map에 두 번 그려졌음. manual draw가 cullResults에 의존하지 않으므로 DrawRendererList 자체가 불필요. 제거하여 GPU 부하 ~절반 감소 + 코드 단순화. - RG path: PassData.rendererListHandle, RendererListParams, CreateRendererList, UseRendererList, DrawRendererList 모두 제거 - Legacy path: cullingParameters/cullResults 계산, context.Cull, context.DrawRenderers 모두 제거 (terrainCrashSafeGuard 분기 자체가 무의미해짐) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ed764d7f83
commit
67c99af14f
@ -615,43 +615,7 @@ namespace NiloToon.NiloToonURP
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// set culling for shadow camera -> do culling
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
camera.TryGetCullingParameters(out var cullingParameters);
|
||||
|
||||
// update culling matrix
|
||||
cullingParameters.cullingMatrix = shadowCamProjectionMatrix * shadowCamViewMatrix;
|
||||
|
||||
// update culling planes
|
||||
GeometryUtility.CalculateFrustumPlanes(cullingParameters.cullingMatrix, cameraPlanes);
|
||||
for (int i = 0; i < cameraPlanes.Length; i++)
|
||||
{
|
||||
cullingParameters.SetCullingPlane(i, cameraPlanes[i]);
|
||||
}
|
||||
|
||||
CullingResults cullResults;
|
||||
|
||||
bool terrainExist = false;
|
||||
if (settings.terrainCrashSafeGuard)
|
||||
{
|
||||
terrainExist = Terrain.activeTerrains.Length != 0;
|
||||
}
|
||||
if (settings.perfectCullingForShadowCasters && !terrainExist)
|
||||
{
|
||||
// use the above new cullResults in DrawRenderers() below,
|
||||
// so even a renderer is not visible in the perspective of main camera,
|
||||
// it can still render correctly in shadow camera's perspective due to this new culling
|
||||
|
||||
// (2021-07-14) unity will crash if code running this line and terrain exist in scene
|
||||
// (2024-03-21) enable this will make VLB's SRP batcher mode flicker randomly, not sure why, should we do something to revert this culling line?
|
||||
cullResults = context.Cull(ref cullingParameters); // original working code, but will crash if terrain exist
|
||||
}
|
||||
else
|
||||
{
|
||||
// (2021-07-14) a special temp fix to avoid terrain crashing unity, but will make shadow culling not always correctly if shadow caster is not existing on screen
|
||||
cullResults = renderingData.cullResults;
|
||||
}
|
||||
// Streamingle: cullResults / custom culling 코드 제거. manual DrawRenderer가 cullResults에 의존하지 않으므로 불필요.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Set uniform (before context.DrawRenderers)
|
||||
@ -721,16 +685,9 @@ namespace NiloToon.NiloToonURP
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// draw all char renderer using SRP batching (must set all uniforms and executed before draw!)
|
||||
// Streamingle: cullResults 의존성 완전 제거. context.DrawRenderers + custom culling 모두 제거.
|
||||
// characterList의 모든 NiloToon 캐릭터를 manual draw로 그려 카메라 frustum 무관하게 shadow map 채움.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ShaderTagId shaderTagId = new ShaderTagId("NiloToonSelfShadowCaster");
|
||||
var drawSetting = CreateDrawingSettings(shaderTagId, ref renderingData, SortingCriteria.CommonOpaque);
|
||||
var filterSetting = new FilteringSettings(RenderQueueRange.opaque);
|
||||
context.DrawRenderers(cullResults, ref drawSetting, ref filterSetting); // using custom cullResults from shadow camera's perspective, instead of main camera's cull result
|
||||
|
||||
// Streamingle: cullResults 우회용 manual draw.
|
||||
// perfectCullingForShadowCasters=false 또는 terrain 존재 시 cullResults가 main camera cull로 fallback →
|
||||
// 캐릭터가 frustum 밖이면 shadow map에 안 그려짐. 같은 renderer가 두 번 그려질 수 있으나 depth test가 처리.
|
||||
DrawNiloToonCharsManuallyLegacy(cmd);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
@ -832,8 +789,7 @@ namespace NiloToon.NiloToonURP
|
||||
// copy and edit of https://docs.unity3d.com/6000.0/Documentation/Manual/urp/render-graph-draw-objects-in-a-pass.html
|
||||
private class PassData
|
||||
{
|
||||
// Create a field to store the list of objects to draw
|
||||
public RendererListHandle rendererListHandle;
|
||||
// Streamingle: RendererListHandle 제거. manual DrawRenderer로 대체됨.
|
||||
public bool shouldRender;
|
||||
public Matrix4x4 _NiloToonSelfShadowWorldToClip;
|
||||
public Vector4 _NiloToonSelfShadowParam;
|
||||
@ -860,21 +816,10 @@ namespace NiloToon.NiloToonURP
|
||||
UniversalCameraData cameraData = frameContext.Get<UniversalCameraData>();
|
||||
UniversalRenderingData renderingData = frameContext.Get<UniversalRenderingData>();
|
||||
UniversalLightData lightData = frameContext.Get<UniversalLightData>();
|
||||
|
||||
SortingCriteria sortFlags = SortingCriteria.CommonOpaque; //cameraData.defaultOpaqueSortFlags;
|
||||
RenderQueueRange renderQueueRange = RenderQueueRange.opaque;
|
||||
FilteringSettings filterSettings = new FilteringSettings(renderQueueRange, ~0);
|
||||
|
||||
// Redraw only objects that have their LightMode tag set to "NiloToonSelfShadowCaster"
|
||||
ShaderTagId shadersToOverride = new ShaderTagId("NiloToonSelfShadowCaster");
|
||||
|
||||
// Create drawing settings
|
||||
DrawingSettings drawSettings = RenderingUtils.CreateDrawingSettings(shadersToOverride, renderingData, cameraData, lightData, sortFlags);
|
||||
|
||||
// Create the list of objects to draw
|
||||
var rendererListParameters = new RendererListParams(renderingData.cullResults, drawSettings, filterSettings);
|
||||
|
||||
|
||||
// Streamingle: RendererList 기반 그리기 제거. ExecutePass의 manual DrawRenderer가
|
||||
// characterList를 직접 그리므로 cullResults에 의존하는 RendererList는 불필요 + double-draw 방지.
|
||||
// RendererList CPU 컬링 비용도 절약.
|
||||
|
||||
// create RT (temp)
|
||||
// Create texture properties that match the screen size
|
||||
@ -891,21 +836,17 @@ namespace NiloToon.NiloToonURP
|
||||
{
|
||||
shouldRender = true;
|
||||
}
|
||||
|
||||
// Convert the list to a list handle that the render graph system can use
|
||||
passData.rendererListHandle = renderGraph.CreateRendererList(rendererListParameters);
|
||||
|
||||
passData.shouldRender = shouldRender;
|
||||
|
||||
|
||||
RenderTextureDescriptor renderTextureDescriptor = new RenderTextureDescriptor(shadowMapSize, shadowMapSize, RenderTextureFormat.Shadowmap, 16);
|
||||
|
||||
// Create a temporary texture
|
||||
TextureHandle shadowMapRT = UniversalRenderer.CreateRenderGraphTexture(renderGraph, renderTextureDescriptor, "_NiloToonCharSelfShadowMapRT", true);
|
||||
|
||||
|
||||
// Set the render target as the color and depth textures of the active camera texture
|
||||
UniversalResourceData resourceData = frameContext.Get<UniversalResourceData>();
|
||||
|
||||
builder.UseRendererList(passData.rendererListHandle);
|
||||
|
||||
|
||||
//builder.SetRenderAttachment(resourceData.activeColorTexture, 0);
|
||||
builder.SetRenderAttachmentDepth(shadowMapRT, AccessFlags.Write);
|
||||
|
||||
@ -1335,13 +1276,8 @@ namespace NiloToon.NiloToonURP
|
||||
|
||||
cmd.SetKeyword(GlobalKeyword.Create(_NILOTOON_RECEIVE_SELF_SHADOW_Keyword), true);
|
||||
|
||||
// Draw the objects in the list (uses main camera cullResults — character가 frustum 안일 때만)
|
||||
cmd.DrawRendererList(data.rendererListHandle);
|
||||
|
||||
// Streamingle: cullResults 우회용 manual draw.
|
||||
// 카메라가 캐릭터 frustum 밖이면 rendererListHandle에 캐릭터가 없어 shadow map이 비어 그림자 사라짐.
|
||||
// 모든 NiloToon 캐릭터의 모든 NiloToonSelfShadowCaster pass를 수동으로 한 번 더 그려 cullResults 의존성 제거.
|
||||
// 같은 renderer가 두 번 그려질 수 있으나 depth test가 처리하므로 시각적 영향 없음.
|
||||
// Streamingle: cullResults 의존성 완전 제거. manual draw만 사용.
|
||||
// characterList의 모든 NiloToon 캐릭터를 직접 그려 카메라 frustum 무관하게 shadow map 채움.
|
||||
DrawNiloToonCharsManually(cmd);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user