カラードシャドウペナブラ:Unreal Engine 5.7におけるカラフルな影
原題: Colored Shadow Penumbra: sombras con color en Unreal Engine 5.7
分析結果
- カテゴリ
- エネルギー
- 重要度
- 64
- トレンドスコア
- 26
- 要約
- Unreal Engine 5.7では、カラードシャドウペナブラ機能を使用して、影に色を付けることが可能です。この技術により、よりリアルで魅力的なビジュアルを実現し、ゲームやシミュレーションの表現力を向上させます。影の色を調整することで、シーンの雰囲気や感情を強調することができ、開発者は新たなクリエイティブな表現手法を手に入れることができます。
- キーワード
El colored shadow penumbra es uno de esos efectos que pasan inadvertidos hasta que alguien los apaga: ver una escena sin él hace que las sombras parezcan, de repente, demasiado limpias, demasiado neutras, demasiado 3D . La técnica reproduce un fenómeno óptico real (la transición coloreada entre la zona iluminada y la sombra dura) y, hasta hace poco, implementarla en Unreal Engine 5 implicaba pelearse con post-procesos frágiles que rompían con Lumen o con ciclos día/noche. La nueva implementación que el artista técnico Romain Durand puso de moda en redes y que Chosker liberó este mes resuelve el problema editando directamente los shaders del motor, con un costo de rendimiento prácticamente cero. En este artículo desarmamos cómo funciona, copiamos línea por línea el código HLSL que se inyecta en los shaders de iluminación diferida, explicamos por qué necesita penumbras anchas para verse y discutimos cuándo conviene activarlo en producción. Si trabajás con UE5 desde LATAM, ya sea en un estudio indie o haciendo arch-viz, el colored shadow penumbra es una de esas mejoras de pulido que separan un render técnicamente correcto de uno que se siente vivo. Qué es exactamente colored shadow penumbra La luz, cuando atraviesa el borde de un objeto, no proyecta una sombra binaria entre iluminado y oscuro . Hay una región de transición llamada penumbra , donde la fuente de luz queda parcialmente ocluida y solo aporta una fracción de su intensidad. En esa franja, los rebotes indirectos (la luz que viene de paredes, suelos y el ambiente general) tienen relativamente más peso que la directa, y como la luz indirecta arrastra el color de las superficies que rebota, la penumbra termina teñida de los colores de la escena. El fenómeno se conoce también como shadow terminator coloring en literatura de raytracing offline. Renderizadores no-real-time como Arnold, V-Ray o Cycles lo computan de forma natural porque trazan rayos secundarios. En tiempo real, Unreal Engine 5 simplifica el cálculo: usa un único término de sombra ( SurfaceShadow ) que va de 0 (en sombra completa) a 1 (totalmente iluminado) y modula la luminancia diffuse por ese factor. Esa simplificación es rápida pero borra la información cromática de la transición. La técnica de Chosker reintroduce el efecto sin pagar el costo de un trazado real. La idea es ingeniosa: en la región donde SurfaceShadow es intermedio (la penumbra), saturar artificialmente el color base de la superficie. Con un colored shadow penumbra bien calibrado, una pared roja en sombra muestra rojos más vivos en su transición, una camisa azul deja un halo azulado al borde de su sombra y los materiales metálicos ganan profundidad sin lookdev adicional. El efecto se nota más en bordes suaves de luces grandes y materiales saturados. Por qué editar el shader del motor (y no un post-process) Existen al menos tres caminos para introducir colored shadows en una escena de UE5: un Material Function aplicado por objeto, un Post Process Material global, o editar los shaders del engine directamente. Chosker descartó las primeras dos por una razón concreta: con Lumen activado o con ciclos día/noche, los valores que llegan al post-process ya están mezclados (luz directa, GI, especulares) y reconstruir cuál fragmento corresponde a sombra y cuál a iluminación se vuelve un ejercicio de adivinanza. Editar el shader de iluminación diferida resuelve el problema en su origen: ahí todavía existe la separación clara entre DiffuseLuminance y SurfaceShadow . La ventaja adicional es que funciona con todos los tipos de luz (direccionales, puntuales, focales, rectangulares) sin código extra y se ejecuta una sola vez por píxel, en el mismo pase donde ya se está mezclando la sombra. El costo en GPU es marginal: un dot product y dos lerp , instrucciones que cualquier hardware moderno absorbe sin pestañear. 📌 Nota: Editar los shaders del motor no requiere clonar el repositorio completo de Epic ni compilar Unreal desde código fuente. Basta con la versión Launcher: los shaders del engine son archivos .usf / .ush en la carpeta Engine\Shaders\Private y se recompilan en frío con Ctrl + Shift + . dentro del editor. Implementación con Substrate (UE 5.7) Substrate es el nuevo sistema de materiales de Unreal Engine introducido como experimental en 5.2 y promovido a beta en 5.7. Si tu proyecto lo tiene activado (lo que es cada vez más común en producciones nuevas), el shader que necesitás editar es Engine\Shaders\Private\Substrate\SubstrateDeferredLighting.ush . Alrededor de la línea 190 vas a encontrar la línea que calcula la luminancia especular: float3 SpecularLuminance = BSDFEvaluate . IntegratedSpecularValue * LightData . SpecularScale ; Inmediatamente después, agregás el bloque de colored shadow penumbra : // Colored shadow penumbra - Start const float PenumbraSaturation = 4 . 0 f ; float3 LuminanceFactors = float3 ( 0 . 3 f , 0 . 59 f , 0 . 11 f ); float3 PenumbraColor = dot ( DiffuseLuminance , LuminanceFactors ); PenumbraColor = lerp ( PenumbraColor , DiffuseLuminance , PenumbraSaturation ); DiffuseLuminance = lerp ( DiffuseLuminance , PenumbraColor , 1 . 0 f - BSDFShadowTerms . SurfaceShadow ); // Colored shadow penumbra - End El valor PenumbraSaturation = 4.0f es un punto de partida agresivo, pensado para que el efecto se vea en capturas comparativas. En producción, valores entre 1.5 y 2.5 dan un resultado más natural. Con 1.0 el efecto desaparece completamente (el lerp de saturación se cancela). Implementación clásica sin Substrate Si tu proyecto sigue usando el pipeline tradicional de iluminación diferida, el archivo objetivo es Engine\Shaders\Private\DeferredLightPixelShaders.usf . Alrededor de la línea 397 buscás: OutColor += Radiance ; Y agregás justo después: // Colored shadow penumbra - Start const float PenumbraSaturation = 4 . 0 f ; float3 LuminanceFactors = float3 ( 0 . 3 f , 0 . 59 f , 0 . 11 f ); float3 PenumbraColor = dot ( OutColor . xyz , LuminanceFactors ); PenumbraColor = lerp ( PenumbraColor , OutColor . xyz , PenumbraSaturation ); OutColor . xyz = lerp ( OutColor . xyz , PenumbraColor , 1 . 0 f - SurfaceShadow ); // Colored shadow penumbra - End La lógica es idéntica; solo cambian los nombres de las variables porque el flujo de Substrate usa una estructura distinta para encapsular el resultado de la BSDF. Cómo funciona el código línea por línea Vale la pena desarmar las cinco líneas porque condensan tres conceptos importantes de teoría de color y composición: Vector de luminancia (0.3, 0.59, 0.11) — son los pesos perceptuales del estándar Rec. 601 para convertir RGB a una intensidad gris equivalente. El verde pesa más porque el ojo humano es más sensible a esa banda. Hacer un dot entre el color y este vector colapsa cualquier color a su luminancia.- Saturación inversa — el primer lerp mueve el color desde su versión gris ( PenumbraColor ) hacia el color original ( DiffuseLuminance ) usando un factor mayor a 1. Cuando el factor pasa de 1, el lerp extrapola y produce una versión más saturada que la original. Es el mismo truco que usan los nodos de saturación de Photoshop o After Effects.- Mezcla por shadow term — el segundo lerp combina el color saturado con el color original usando 1.0 - SurfaceShadow como peso. En zonas totalmente iluminadas ( SurfaceShadow = 1 ) el peso es 0 y no pasa nada. En zonas totalmente en sombra ( SurfaceShadow = 0 ) el peso es 1 pero el color a mezclar ya es muy oscuro, así que tampoco se nota. Solo en la franja de transición se ve la versión saturada. Es elegante porque no necesita detectar dónde está la penumbra: la propia función 1.0 - SurfaceShadow tiene su pico justo en esa región (cerca de 0.5) y cae hacia los extremos. La saturación se modula sola. Visualización del flujo graph LR A["Luz directa"] --> B["BSDF + Shadow Term"] B --> C["DiffuseLuminance RGB"] C --> D["Luminancia gris (Rec. 601)"] D --> E["Saturación inversa (lerp > 1)"] E --> F["Mezcla por (1 - SurfaceShadow)"] F --> G["Color final con penumbra coloreada"] Ajustar PenumbraSaturation: el parámetro que importa El único hiperparámetro de la técnica es PenumbraSaturation . Vale la pena dedicar tiempo a calibrarlo, porque el rango útil es estrecho: 1.0 — desactiva el efecto. Útil como sentinela durante debugging.- 1.2 a 1.8 — efecto sutil, perceptible solo en escenas con materiales saturados o luces grandes. Buen rango para arch-viz fotorrealista.- 2.0 a 3.0 — sweet spot para juegos estilizados, escenas con paleta artística o cinemáticas. El efecto se ve sin gritar.- 4.0 o más — exagerado a propósito, ideal para capturas de marketing pero rompe el realismo. 💡 Tip: Como el valor está hardcodeado en el shader, cada cambio implica recompilar shaders (varios minutos la primera vez, segundos después). Si vas a iterar mucho, conviene exponerlo como una console variable usando FAutoConsoleVariableRef en C++ o, más rápido todavía, parametrizarlo desde un material function global. Limitaciones y casos donde no se ve El colored shadow penumbra tiene tres limitaciones honestas que conviene comunicar al equipo de arte antes de venderlo como solución mágica: Solo luces dinámicas — la sombra baked se calcula offline antes de que el shader corra, así que no hay penumbra que colorear. Si tu proyecto depende de iluminación pre-baked (común en mobile o VR de bajos requerimientos), esta técnica no aporta nada.- Necesita penumbras anchas — luces puntuales pequeñas con shadow maps duros producen penumbras de pocos píxeles, donde el efecto pasa desapercibido. Funciona mejor con luces rectangulares grandes, sky lights con soft shadows o virtual shadow maps con kernel amplio.- No se ve en grises ni saturados — un material totalmente gris no tiene color que saturar, y un material ya saturado al máximo tampoco gana. El efecto luce mejor en colores medios y materiales con reflectividad media. Por qué importa para estudios indie en LATAM El argumento más fuerte para adoptar la técnica no es estético sino económico. Un estudio indie en LATAM compite con