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
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
// Streamingle: cullResults / custom culling 코드 제거. manual DrawRenderer가 cullResults에 의존하지 않으므로 불필요.
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Set uniform (before context.DrawRenderers)
|
// 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);
|
DrawNiloToonCharsManuallyLegacy(cmd);
|
||||||
context.ExecuteCommandBuffer(cmd);
|
context.ExecuteCommandBuffer(cmd);
|
||||||
cmd.Clear();
|
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
|
// copy and edit of https://docs.unity3d.com/6000.0/Documentation/Manual/urp/render-graph-draw-objects-in-a-pass.html
|
||||||
private class PassData
|
private class PassData
|
||||||
{
|
{
|
||||||
// Create a field to store the list of objects to draw
|
// Streamingle: RendererListHandle 제거. manual DrawRenderer로 대체됨.
|
||||||
public RendererListHandle rendererListHandle;
|
|
||||||
public bool shouldRender;
|
public bool shouldRender;
|
||||||
public Matrix4x4 _NiloToonSelfShadowWorldToClip;
|
public Matrix4x4 _NiloToonSelfShadowWorldToClip;
|
||||||
public Vector4 _NiloToonSelfShadowParam;
|
public Vector4 _NiloToonSelfShadowParam;
|
||||||
@ -860,21 +816,10 @@ namespace NiloToon.NiloToonURP
|
|||||||
UniversalCameraData cameraData = frameContext.Get<UniversalCameraData>();
|
UniversalCameraData cameraData = frameContext.Get<UniversalCameraData>();
|
||||||
UniversalRenderingData renderingData = frameContext.Get<UniversalRenderingData>();
|
UniversalRenderingData renderingData = frameContext.Get<UniversalRenderingData>();
|
||||||
UniversalLightData lightData = frameContext.Get<UniversalLightData>();
|
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"
|
// Streamingle: RendererList 기반 그리기 제거. ExecutePass의 manual DrawRenderer가
|
||||||
ShaderTagId shadersToOverride = new ShaderTagId("NiloToonSelfShadowCaster");
|
// characterList를 직접 그리므로 cullResults에 의존하는 RendererList는 불필요 + double-draw 방지.
|
||||||
|
// RendererList CPU 컬링 비용도 절약.
|
||||||
// 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);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// create RT (temp)
|
// create RT (temp)
|
||||||
// Create texture properties that match the screen size
|
// Create texture properties that match the screen size
|
||||||
@ -891,21 +836,17 @@ namespace NiloToon.NiloToonURP
|
|||||||
{
|
{
|
||||||
shouldRender = true;
|
shouldRender = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the list to a list handle that the render graph system can use
|
|
||||||
passData.rendererListHandle = renderGraph.CreateRendererList(rendererListParameters);
|
|
||||||
passData.shouldRender = shouldRender;
|
passData.shouldRender = shouldRender;
|
||||||
|
|
||||||
RenderTextureDescriptor renderTextureDescriptor = new RenderTextureDescriptor(shadowMapSize, shadowMapSize, RenderTextureFormat.Shadowmap, 16);
|
RenderTextureDescriptor renderTextureDescriptor = new RenderTextureDescriptor(shadowMapSize, shadowMapSize, RenderTextureFormat.Shadowmap, 16);
|
||||||
|
|
||||||
// Create a temporary texture
|
// Create a temporary texture
|
||||||
TextureHandle shadowMapRT = UniversalRenderer.CreateRenderGraphTexture(renderGraph, renderTextureDescriptor, "_NiloToonCharSelfShadowMapRT", true);
|
TextureHandle shadowMapRT = UniversalRenderer.CreateRenderGraphTexture(renderGraph, renderTextureDescriptor, "_NiloToonCharSelfShadowMapRT", true);
|
||||||
|
|
||||||
// Set the render target as the color and depth textures of the active camera texture
|
// Set the render target as the color and depth textures of the active camera texture
|
||||||
UniversalResourceData resourceData = frameContext.Get<UniversalResourceData>();
|
UniversalResourceData resourceData = frameContext.Get<UniversalResourceData>();
|
||||||
|
|
||||||
builder.UseRendererList(passData.rendererListHandle);
|
|
||||||
|
|
||||||
//builder.SetRenderAttachment(resourceData.activeColorTexture, 0);
|
//builder.SetRenderAttachment(resourceData.activeColorTexture, 0);
|
||||||
builder.SetRenderAttachmentDepth(shadowMapRT, AccessFlags.Write);
|
builder.SetRenderAttachmentDepth(shadowMapRT, AccessFlags.Write);
|
||||||
|
|
||||||
@ -1335,13 +1276,8 @@ namespace NiloToon.NiloToonURP
|
|||||||
|
|
||||||
cmd.SetKeyword(GlobalKeyword.Create(_NILOTOON_RECEIVE_SELF_SHADOW_Keyword), true);
|
cmd.SetKeyword(GlobalKeyword.Create(_NILOTOON_RECEIVE_SELF_SHADOW_Keyword), true);
|
||||||
|
|
||||||
// Draw the objects in the list (uses main camera cullResults — character가 frustum 안일 때만)
|
// Streamingle: cullResults 의존성 완전 제거. manual draw만 사용.
|
||||||
cmd.DrawRendererList(data.rendererListHandle);
|
// characterList의 모든 NiloToon 캐릭터를 직접 그려 카메라 frustum 무관하게 shadow map 채움.
|
||||||
|
|
||||||
// Streamingle: cullResults 우회용 manual draw.
|
|
||||||
// 카메라가 캐릭터 frustum 밖이면 rendererListHandle에 캐릭터가 없어 shadow map이 비어 그림자 사라짐.
|
|
||||||
// 모든 NiloToon 캐릭터의 모든 NiloToonSelfShadowCaster pass를 수동으로 한 번 더 그려 cullResults 의존성 제거.
|
|
||||||
// 같은 renderer가 두 번 그려질 수 있으나 depth test가 처리하므로 시각적 영향 없음.
|
|
||||||
DrawNiloToonCharsManually(cmd);
|
DrawNiloToonCharsManually(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user