View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0005183 | NoesisGUI | Unity | public | 2026-08-21 20:59 | 2026-08-21 21:01 |
| Reporter | sagzain | Assigned To | jsantos | ||
| Priority | normal | Severity | major | ||
| Status | assigned | Resolution | open | ||
| Product Version | 4.0 | ||||
| Target Version | 4.0.1 | ||||
| Summary | 0005183: HDRP issue with multiple viewports | ||||
| Description | When rendering multiple Views in subrectangles of the screen, the viewport coordinates are not properly applied to the GPU before rendering noesis. | ||||
| Platform | Any | ||||
|
Patch provided by EF games HDRP.diff (5,478 bytes)
index 1354f22..5f639f0 100644
--- a/NoesisGUIUnity/Runtime/NoesisView.cs
+++ b/NoesisGUIUnity/Runtime/NoesisView.cs
@@ -1140,15 +1140,43 @@ public class NoesisView: MonoBehaviour, ISerializationCallbackReceiver
if (ctx.hdCamera.camera.TryGetComponent(out NoesisView view))
{
if (InjectionPoint == view.InjectionPoint)
{
bool flipY = SystemInfo.graphicsUVStartsAtTop && !IsBackbuffer(ctx.cameraColorBuffer);
- view.OnExecuteCustomPass(ctx.cmd, flipY);
+ view.OnExecuteCustomPass(ctx.cmd, flipY, NeedsExplicitViewport(ctx.cameraColorBuffer));
}
}
}
+ // [RIVALS] PARCHE LOCAL — split-screen. Si se actualiza NoesisGUI hay que RE-APLICARLO.
+ // Lo defiende el tripwire de fuente Assets/1_Tests/EditMode/NoesisHdrpViewportTests.cs.
+ //
+ // Devuelve true cuando HDRP NO ha dejado atado el viewport de esta camara, asi que dibujar
+ // sin atarlo estira la pagina sobre TODO el render target.
+ //
+ // El mecanismo, de arriba abajo:
+ // 1. CustomPass.SetCustomPassTarget llama a CoreUtils.SetRenderTarget(cmd, color, depth, ...)
+ // y ese cmd.SetRenderTarget deja el viewport cubriendo el target ENTERO.
+ // 2. CoreUtils.SetViewportAndClear intenta corregirlo con CoreUtils.SetViewport(cmd, color),
+ // pero esa funcion es literalmente `if (target.useScaling) { ... }`: sobre un RTHandle
+ // SIN escalado no hace NADA (CoreUtils.cs:899-906).
+ // 3. HDRP entrega el BACKBUFFER importado (useScaling == false) siempre que el post-proceso
+ // sea el pase final, y eso lo decide HDUtils.PostProcessIsFinalPass:
+ // `!aov && !Debug.isDebugBuild && !WillCustomPassBeExecuted(AfterPostProcess) && !hasCaptureActions`.
+ // `Debug.isDebugBuild` es true en el EDITOR y en una development build, y false en una
+ // build de RELEASE; y `WillCustomPassBeExecuted` solo mira los CustomPassVolume de la
+ // escena, nunca la lista global donde vive este pase, asi que Noesis no se cuenta a si
+ // mismo. Resultado: editor y dev build van por el buffer intermedio (viewport correcto)
+ // y la build de release va por el backbuffer (viewport a pantalla completa).
+ //
+ // Con la camara a pantalla completa el viewport correcto y el completo COINCIDEN, y por eso
+ // esto no se habia visto nunca: solo se manifiesta con camaras de rect parcial (split-screen).
+ private static bool NeedsExplicitViewport(RTHandle buffer)
+ {
+ return !buffer.useScaling;
+ }
+
private static bool IsBackbuffer(RTHandle buffer)
{
var id = new RenderTargetIdentifier(buffer.nameID, 0, CubemapFace.Unknown, 0);
return id == BuiltinRenderTextureType.CameraTarget;
}
@@ -1205,16 +1233,37 @@ public class NoesisView: MonoBehaviour, ISerializationCallbackReceiver
}
}
public static readonly CustomSampler _customSampler = CustomSampler.Create("Noesis.RenderOnscreen", true);
- private void OnExecuteCustomPass(CommandBuffer commands, bool flipY)
+ // [RIVALS] PARCHE LOCAL — split-screen. Si se actualiza NoesisGUI hay que RE-APLICARLO.
+ // `bindViewport` lo decide NoesisCustomPass.NeedsExplicitViewport (ver el porque completo alli).
+ private void OnExecuteCustomPass(CommandBuffer commands, bool flipY, bool bindViewport)
{
if (_uiView != null && _visible)
{
// In HDRP, the custom pass is configured to always clear the stencil buffer before execution
commands.BeginSample(_customSampler);
+
+ // [RIVALS] Noesis dibuja con una proyeccion ortografica de su TAMANO LOGICO al NDC y no ata
+ // viewport en ninguna parte (ni aqui ni en el plugin nativo), asi que el mapeo a pixeles lo
+ // decide entero el viewport que este atado. Su tamano logico son exactamente
+ // `_camera.pixelWidth/pixelHeight` (ver UpdateSize), o sea que atar el rect de la camara con
+ // esos MISMOS dos enteros hace el mapeo 1:1 por construccion.
+ //
+ // La expresion es la misma que HDCamera.GetPixelRect() —origen de `pixelRect`, tamano de
+ // `pixelWidth/pixelHeight`— porque de ahi sale el `finalViewport` con el que HDRP acaba de
+ // pintar la ESCENA de esta camara en el backbuffer: asi el HUD cae exactamente sobre ella.
+ //
+ // Con la camara a pantalla completa esto es un no-op bit a bit, de modo que solo puede
+ // cambiar el render en el unico caso que estaba roto.
+ if (bindViewport && _camera != null)
+ {
+ commands.SetViewport(new UnityEngine.Rect(
+ _camera.pixelRect.x, _camera.pixelRect.y, _camera.pixelWidth, _camera.pixelHeight));
+ }
+
NoesisRenderer.RenderOnscreen(_uiView, flipY, commands, true, _clearStencil);
commands.EndSample(_customSampler);
}
} |
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-08-21 20:59 | jsantos | New Issue | |
| 2026-08-21 21:00 | jsantos | Reporter | jsantos => sagzain |
| 2026-08-21 21:00 | jsantos | Assigned To | => jsantos |
| 2026-08-21 21:00 | jsantos | Status | new => assigned |
| 2026-08-21 21:00 | jsantos | Target Version | => 4.0.1 |
| 2026-08-21 21:01 | jsantos | Note Added: 0012559 | |
| 2026-08-21 21:01 | jsantos | File Added: HDRP.diff |