Procedural Eye Shader

An anatomically correct eye with customisable colours, size and intensities with the addition of a pupil that reacts to light within Unreal Engine 5.

Procedural Eye Shader

An anatomically correct eye with customisable colours, size and intensities with the addition of a pupil that reacts to light within Unreal Engine 5.

Procedural Eye Shader

An anatomically correct eye with customisable colours, size and intensities with the addition of a pupil that reacts to light within Unreal Engine 5.

Procedural Eye Shader

An anatomically correct eye with customisable colours, size and intensities with the addition of a pupil that reacts to light within Unreal Engine 5.

Roles

Technical Artist, Unreal Blueprints Developer, 3D Artist

Roles

Technical Artist, Unreal Blueprints Developer, 3D Artist

Roles

Technical Artist, Unreal Blueprints Developer, 3D Artist

Roles

Technical Artist, Unreal Blueprints Developer, 3D Artist

The aim of this shader was to create an anatomically correct eye with customisable colours, size and intensities with the addition of a pupil that reacts to light within the Unreal Engine 5 game engine that could be used within a Character Customiser by a player, or a Technical Artist/3D Artist when creating a character.

Video Showcase

The showcase demonstrates all visual customisation and the iris interaction reacting to light on multiple meshes and angles.

Modelling

Utilising Blender, I modelled the basics of an eye and an iris so we have an anatomically correct model to put the new shader onto. This model contained the data for the sclera and the cornea and will overlap the iris model with the transparency of the cornea.

The iris is a separate object to allow for cleaner UVs to manipulate; I noticed Unreal’s MetaHumans used a circular UV map for their iris, but I dictated that expanding the UVs width-ways would allow for further customisation in the shader I am creating.

The eye models were then taken into Substance and had the normal details painted onto the textures themselves. By doing this, I was able to create detailed and life-like details for the iris of the eye, as well as create normal maps for the veins on the sclera for added depth as an eyeball is not just an entirely flat sphere.

The textures for the veins and iris were then exported from Substance and texture packed utilising Photoshop in order to increase performance and reduce draw calls. We can take each channel of the texture and use this for a different aspect of the colours and patterns.

Shaders and Materials

Utilising refraction allows our cornea to warp things behind it when looked at from an angle, like a real cornea. World Position and Object Positions combined with a Fresnel node allowed for this effect to work realistically within UE5.

Taking the normals and roughness values from our material, I also added a realistic bloodshot effect for our sclera and allowed this to be customised by users within the engine.

Using a combination of our textures and material functions, we can now create customisable eyes utilising Material Instances. The material takes the texture packed textures, and applies colour to their channels to allow layering of colours and aspect of the eye which the user is then able to customise using a User Interface created within the engine. All of these parameters are accessible to artists within the game engine as a tool inside of the Material Instance, and will allow those developing within UE5 to use the eye and customise it for a character or idea they may have.

Reacting to Light

I am able to create an expansion effect with the pupil by manipulating the tiling and size of the UVs. Combining this with the mask of the pupil utilised inside the material, it creates a convincing effect of a pupil opening and closing. But how do we create a realistic pupil changing without manual input? Detecting the light’s intensity and direction.

By taking the Cross and Dot product of the eye and light source, we can determine how far away they are from each other as well as detecting the direction (forward vector) of the light in comparison to the direction of the iris. Once this is achieved, we compare the values of the output float and we can determine the direction.

Improving on this system further, we can include a Line Trace between the light and the eye and check if this is obstructed, by doing this we can force the float used to dictate the ‘direction’ and override with a set value to show minimal light affecting the eye.

Did you enjoy this project? Why not check out this one next?

Next Project