Posts tagged with "Shaders"
Posts tagged with: Shaders
  • Occlusion Cutout Effect - AlchemisTeddy đŸ§ȘđŸ»

    After experimenting with a stencil-based see-through effect Unity Tips – Creating a Stencil See-Through Effect in Unity 6, I quickly noticed limitations. In scenarios such as tight tunnels or parallel wall intersections, the stencil solution introduced artifacts and did not feel robust.

    For a second attempt, I drew inspiration from Baldur’s Gate III’s beautiful occlusion cutout system.

    Luckily, Mojang’s Senior Technical Artist Brendan “Sully” Sullivan had already broken down the technique in Unreal Engine 80.lv article, which served as a strong reference.

    The challenge was now clear: How do we reproduce this effect inside Unity?

    The full process is described below

    Read More
    Created on September 2025
  • Unity Tips - Creating a Stencil See-Through Effect in Unity 6

    In many top-down or isometric games, walls can obstruct the player’s view of the action.
    A common solution is to make obstructing geometry transparent or temporarily cut away when it blocks the line of sight.

    In this post, I’ll cover how I implemented a see-through wall system in Unity 6, combining HLSL shaders, URP configuration, and a lightweight C# layer management script.

    I’ll also share performance considerations and ideas for extending this technique.

    Stencil Setup with HLSL

    The core of this effect relies on the stencil buffer.
    We define a shader that marks walls in the stencil pass, giving us control over which parts of the geometry should later be rendered differently.

    Shader "Unlit/Cutter"
    {
        Properties
        {
            [IntRange] _StencilID ("Stencil ID", Range(0,255)) = 0
        }
        SubShader
        {
            Tags { "RenderType"="Opaque" "Queue"="Geometry-1" "RenderPipeline"="UniversalPipeline"}
    
            Pass
            {
                Blend Zero One
                ZWrite Off
    
                Stencil
                {
                    Ref [_StencilID]
                    Comp Always
                    Pass Replace
                }
            }
        }
    }
    

    This shader doesn’t render visible pixels; it only writes stencil values.
    Later, the URP pipeline uses these values to selectively apply transparency.

    Configuring the URP Renderer

    Next, I extended the URP Asset Renderer.
    Two Renderer Features were added:

    • Cutter Pass → Applies the stencil writes.
    URP AssetRenderer setup for SeeThrough feature
    • SeeThrough Pass → Overrides wall rendering when the stencil is active.
    URP AssetRenderer setup for Cutter feature

    This allows walls to remain fully opaque by default, but become see-through as soon as the script switches their layer.

    Runtime Layer Switching

    To control which walls become transparent, I wrote a simple C# script. It checks the player’s position relative to wall colliders and assigns them to either the opaque layer or the see-through layer.

    void Update()
    {
        float playerZ = m_player.transform.position.z;
        float playerY = m_player.transform.position.y;
    
        foreach (Collider wallCollider in m_wallColliders)
        {
            // Y-axis rule: if the player is above the wall, always keep it opaque
            if (playerY > wallCollider.bounds.max.y - m_playerAboveWallThreshold)
            {
                wallCollider.gameObject.layer = m_opaqueLayer;
                continue;
            }
    
            // Z-axis rule: if the wall is in front of the player, make it see-through
            if (wallCollider.bounds.min.z < playerZ || wallCollider.bounds.max.z < playerZ)
            {
                wallCollider.gameObject.layer = m_seeThroughLayer;
            }
            else
            {
                wallCollider.gameObject.layer = m_opaqueLayer;
            }
        }
    }
    

    This ensures walls in front of the camera fade out, while walls behind or under remain visible.

    Player Setup

    The final piece of the system is the Cutter object.
    In this implementation, it’s a simple sphere attached to the player character and assigned to the Cutter layer.

    Cutter object setup on the player

    As the player moves, this sphere continuously updates the stencil buffer, ensuring that any obstructing walls are correctly masked out in real time.

    Retrospective

    Performance Considerations

    While this system works well in small to mid-scale levels, there are a few things to watch out for:

    • Physics iteration cost → Iterating through many wall colliders in Update() can become expensive. A spatial partitioning structure (e.g., Physics.OverlapSphere) could reduce checks.
    • Overdraw → Transparent walls increase GPU overdraw. Using cutout shaders or depth-based dithering could mitigate this if necessary.
    • Stencil conflicts → If your project already uses the stencil buffer for UI, outlines, or decals, allocate unique IDs to avoid collisions.
    • Batching → Switching layers may break static batching. Consider using material property overrides instead of layers if batching is critical.

    Possible Extensions

    There are multiple ways this effect could be extended depending on the game’s needs:

    • Smooth transitions → Instead of instantly swapping materials, interpolate alpha or use a dithering fade for a cleaner look.
    • Multiple players/units → Extend the script to handle visibility relative to multiple characters.
    • Line-of-sight system → Instead of relying solely on axis checks, perform raycasts from the camera to the player for more precise occlusion.
    • Artist control → Expose thresholds (distance, opacity curve, fade speed) in the inspector so designers can tweak per-level.

    Conclusion

    This system is relatively lightweight but dramatically improves readability in games where the camera doesn’t follow the player directly. By combining stencil operations, URP renderer features, and runtime logic, we can create a wall-cutting effect that feels seamless to both designers and players.

    For production, I’d recommend iterating on the fade mechanics and exploring GPU-based approaches for larger levels—but as a foundation, this approach is flexible, efficient, and easy to extend.

    Read More
    Created on September 2025
  • Bottles Shader & Script - AlchemisTeddy đŸ§ȘđŸ»

    Developed as part of the asset range of AlchemisTeddy, a set of bottles combines hand-painted and shader-driven approaches. Five bottles have subtle shading variations, each featuring a specific hand-painted detail. In addition, two bottles use a custom shader.

    The shader was designed with flexibility in mind: it simulates a nebulous liquid that can be adjusted for fill level, allowing the same model to represent multiple potion types.
    The artist provided custom noise textures, which are integrated into the shader to ensure visual differentiation across the bottles.

    The entire set looks like this:

    This workflow highlights how art and code decisions were made together to achieve both creative direction and technical efficiency. The bottles are optimized for real-time use and form part of a larger playable project (WIP).

    Script

    The bottles include a custom Wobble.cs script that drives small liquid-like movements based on the object’s motion.

    • Motion-based input: The script tracks both linear velocity (movement in space) and angular velocity (rotation changes).
    • Procedural wobble: These values are converted into subtle sine-wave oscillations on the X and Z axes.
    • Shader communication: At runtime, the script passes the wobble values to the material via the WobbleX and WobbleZ shader properties.

    This setup ensures that the bottle contents appear reactive, tilting, sloshing, and “settling” naturally as the object moves in the scene. The wobble intensity is clamped and gradually recovers over time, giving a convincing physical feel without requiring expensive fluid simulations.

    Shader

    The custom shader handles the liquid simulation inside the bottles:

    • Fill-level control allows designers to reuse the same asset for multiple potion states.
    • Custom noise textures (hand-painted) add variation across bottles while still fitting the same visual style.
    • Integration with the wobble script makes the shader feel dynamic and physically reactive, without the overhead of actual fluid dynamics.

    This shader-driven workflow lets a single mesh and material cover many potion types. Efficient for memory and performant in real-time.

    Conclusion

    The bottles showcase how hand-painted detail and procedural motion can be combined into one asset. Instead of static props, they behave like interactive game objects: wobbling, tilting, and visually differentiating through shader variation.

    This workflow demonstrates a scalable approach: artists define the creative direction through textures and colors, while programmers add physical responsiveness and shader logic. Together, the result is both performant and immersive, ready for integration into a larger playable project.

    Read More
    Created on September 2025
  • Bachelor Thesis - 3D Fur Rendering

    During my last year of bachelor’s degree in Game Programming, I worked on a HLSL Fur rendering project in Unity. Project for which I wrote a memoire that can be found in a pdf version below

    Read More
    Created on July 2024
  • Unreal Stylized Shaders - Specialization projects

    Another part of my work during the project mentioned in the previous blog was to create the pipeline that would mimic a “water painting” visual.

    Scene evolution
    Read More
    Created on February 2024
  • Unreal Dynamic Shaders - Specialization projects

    During the last year of bachelor’s degree in Game Programming at the SAE-Institute, the students of the Games Programming section had to create two games in collaboration with the Game Art and Audio Engineering sections. The purpose of the module was to simulate what was, for some, a first work experience in a professional-like environment.

    For this module I had the opportunity to work on multiple aspects of the game with Unreal Engine 5.3.

    Plant Growth
    Read More
    Created on February 2024
  • OpenGL Scene

    This project was an OpenGL graphics engine created from scratch during a computer graphics module given at the SAE-Institute Geneva.

    LastScene
    Read More
    Created on July 2023
© 2025 Samuel Styles