CCXL: Eye Textures

This will show you how to use the CCXL Eyes template to add custom eye options to Character Creator without replacing basegame options.

Summary

Published: Aug 9, 2025 by nutboy | island_dancer Last documented edit: Aug 9, 2025 by nutboy

Wait, this is not what I want!

Requirements

Step 0: Make a project

Start by making a new project in WolvenKit. Name your project.

Open your new project's root folder by clicking the yellow folder button on the top right of the project explorer:

In file explorer, open and drag the template files into your project.

It will show the files in WolvenKit's project explorer. If it does not, hit the blue refresh 🔄 button next to the yellow root folder button.

Here's what the project template will look like:

Step 1: Replace template folder & file names

Check this page on how to update file and folder paths inside the structure.

Next, we need to replace all placeholders of "moddername" and "modderinitials" and "modname" in the project.

The template in a nutshell:

"moddername" — change this to YOUR NAME

"modderinitials" — change this to YOUR INITIALS (or a shortened version of your name, less than 3-4 letters ideally)

"modname" — change this to a UNIQUE NAME for your mod Do not use the same name for multiple mods.

Here are the full steps:

Locate the Archive section of your project explorer.

Select the first folder, then right click and click Rename (or press F2).

  • Change folder "moddername" to YOUR OWN modder name, and check the box "update in project files". I am using my own name in the example images.

  • Change the next folder "modname_ccxl" to a unique project name for this project, and check the box "update in project files"

WolvenKit's logs will print a list of places it updated the names.

Next, find the Resources folder in project explorer, at the bottom.

Rename the following:

  • .xl file and .yaml - "modderinitials_modname" to the same as what you just named your project.

  • the "moddername" folder in r6/tweaks to your modder name.

Next, rename the .inkcharactercustomization files with "Update in project files" checked.

Next, rename the .inkatlas and icon .xbms with "Update in project files" checked.

Next, rename the placeholder files in the textures folders by replacing modderinitials with your initials, with "Update in project files" checked.


Step 2: Update renamed paths inside files

Open your .xl file in your text editor of choice, such as Notepad++ or Visual Studio Pro.

In WolvenKit, copy the path to the inkcharactercustomization file by hovering it and clicking the orange 🟧 button (or right click > "Copy relative path to game file").

In the xl, under customizations, delete the old path after female: and paste in your new path. Next, delete and paste the same path after male: as well.

Next, copy the relative path to your patch.mesh from Wolvenkit, and replace the placeholder path on the line under resource: patch:

Save your .xl file.

Next, open your .yaml file. Delete the old path after atlasresourcepath:

Copy the path to your renamed/updated inkatlas file and paste it into the yaml where the old path was.

Do not update modderinitials_modname in the first line for now; we'll come back to it and update it later.

Save your yaml.

Next, open your patch.mesh and right click the RDTDataViewModel header.

Select "Search and Replace in selection" and set the search for "modderinitials" and the replacement to your initials. Click Finish.

Wolvenkit logs will print an update about the replacements.

Next, scroll down to localMaterialBuffer and expand materials and values until you see Albedo.

You'll see there's one file path of moddername/modname that still needs to be replaced.

Update the path to match your files. Make sure to keep everything else the same, including the asterisk * at the beginning and {material}

{material} is a substitution; it tells AXL to match the names of the files in your materials folder for each appearance listed in the patch.mesh appearances section.

Next right click, and convert inkcharcustomization file to .json

Scroll down to the raw folder to find the .json it created.

Open your .json file a text editor such as Visual Studio Code or Notepad++ and CTRL+F

  • In the search box, type "modderinitials" In the replace box, put your initials

  • Apply the search and replace

  • Save your file

  • Right click the json in the raw folder, and convert it back

  • If the file was open as you converted it back in Wolvenkit, it will ask if you'd like to reload it with the changes you just made. Click yes.


Step 3: Check for broken paths

Now that you've updated a bunch of files, check to make sure nothing broke in the process.

At the top of WolvenKit's UI, go to Project > Scan File for Broken File References

It will open a window. Ignore the inkatlas if it says "none" underneath, it's not an issue. If there are no other missing paths logged, you did it! You're ready to move onto the next step.

If there are any other files listed in the window, you have broken paths that need to be fixed. Expand below to fix this.

(optional) Fixing broken paths

The first file listed in the broken file reference window is the file you need to open, and the indented list of other file(s) underneath are the paths that need to be updated.

Open any files listed and expand menus as necessary to find the incorrect file path, or right click the first header RDTDataViewModel and click "Search and Replace", searching and replacing instances of "moddername", "modderinitials", or "modname" in the project.

Remember to save your files as you update any broken paths.

Repeat scanning for broken file references until the only one left is inkatlas - none.

Test your updated project

Install your mod with WolvenKit, open your game, and open Character Customization to ensure everything still works: template icons show in the eye list, template eye colors show on the character when you select them, etc.

If not, go back and check all your paths again.

If everything appears in CC after you've updated all the file names and paths, you're ready to move on and add your own eye textures.


Step 4: Eye textures

Now that the project is set up, it's finally time to add textures to your eyes! You can do this in a few ways:

Using existing textures

If you already have .xbm diffuse and normal textures from another eye mod project, go ahead and add them to your project's textures folder, then skip to Step 5: Naming your textures/appearances

If you're converting a Unique Eyes mod, go to Converting textures from a Unique Eyes mod

If you're starting from scratch, go to Creating new textures

Converting textures from a Unique Eyes mod

  • If you are updating a mod that was made for Halvkyrie's Unique Eyes, open the Wolvenkit Asset Browser with Mod Browser turned on.

  • In Asset Browser, navigate to the mod archive that contains your textures. They will look like the image below (normals and roughness files may not be included depending on the mod).

  • To start you will need the files ending with _diffuse. Add the diffuse files to your project.

  • Delete the template project's placeholder files in the materials folder, and then drag the diffuse files you just added to the project into your project's materials folder. Delete the base/eyes/textures folders that were created.

  • Next, in Asset Browser, click some of the mod's _normals and _roughness files to check if each number is a copy of the same image.

  • If all the numbered _normals files look to be the same image, only add one to your project.

    • If there are multiple images for normals, see CCXL: Eye Textures

    • If the mod doesn't include a _normal option at all, you can do one of two things:

      • Use the modderinitials_eyes_n.xbm texture provided with the template project, if it looks like it will fit the shape of your eyes/iris, or

      • Open your patch.mesh, and navigate to the localMaterialBuffer, expanding @eyes > values > Normal. Path to the game's placeholder normal by copying and pasting this: engine\textures\editor\normal.xbm into the Normal section. Save your file.

  • If a _roughness file is included and looks like the below image, you can skip adding it to your project, it is not needed for CCXL eyes.

  • If the mod offers a custom roughness map (and does not look like the image above):

    • Add the roughness file(s) to your project in the materials folder and rename it.

    • Note that the basegame eye roughness map is not a conventional greyscale roughness map. It is an RGB colour image with linear gamma. See xbm setup above. If using a custom roughness map, you must use the import settings shown in the xbm setup above or it will not display correctly in-game.

    • Next, open your patch.mesh and expand your localMaterialBuffer > @eyes > values section

    • Right click the "Normal" value and duplicate it

    • Change "Normal" to "Roughness"

    • Replace the path to the normal with the path to your Roughness file

    • Save your file.

Creating new textures

You can download a folder of eye texture resources from the template page here. It contains sclera, irises, and normal maps to get you started for both diffuse and gradient eyes.

Use template placeholder textures to make your own

  • Export the project placeholder textures to PNG in the raw folder, then open them in an image editing program of your choice.

  • Save over the PNGs, and import them back in to Wolvenkit to replace the existing textures.

  • The eye mesh UV map is inverted on the y axis. Therefore your custom Albedo texture also needs to be inverted y:

  • Normal maps should not be inverted y. Doing so will change the direction of the xyz vectors encoded as per pixel greyscale value in the rgb channels of the texture. Normal maps are vector maps and not colour images. You should instead re-generate a normal map using an inverted y Albedo texture -> convert to greyscale -> height map:

  • The above screenshot is from Substance Designer and shows a node group that generates a normal map generated from an albedo texture. You can achieve something similar using stock Blender nodes, although the graph will be much less concise.

  • If you downloaded the tutorial resources file (Eye Texture Design Resources.zip) from Nexus, you will find template textures and photoshop.psd files you can use to make creating eye textures easier: Just remember that when combining normal maps you need to do so in Blender/Substance Designer and not GIMP/Photoshop. You need to convert from rgb colour to xyz vector, then multiply add (multiply by 2 then subtract 1). Now you can sum vector components and the direction of the vector can be positive or negative and its magnitude greater than 1.0. Once you have summed vectors, you have to re-normalize xyz back down to a range of 0 to 1.0 which can be converted back to rgb colour. Substance Designer is nice because it has stock nodes like "Normal Combine" and "Normal Blend" which do all of these operations for you, so its as simple as adding nodes and connecting them with wires.

  • For more info on how to export/import and edit textures: Textures: Importing, editing, exporting

Other ways to add eye textures

Including _d (diffuse), _n (normal), or _r (roughness) at the end of the file name helps Wolvenkit to automatically use the correct import settings for your PNG images.

Using multiple normal maps in one project

Want a more detailed, 3D effect in your character's eyes, showing more depth? Or maybe your mod has a few of different iris shapes with their own normals?

Download the example project here. (NexusMods link)

Credits: Thank you to IslandDancer for the project materials

.mlsetup Eyes

Prefer to use Cyberpunk's Multilayered materials to create your eyes?

Download the example project here. (NexusMods link)

Credits: Thank you to Beaniebby for the project materials

.gradient textures

TBD

Step 5: Naming your textures/appearances

Like usernames, eye appearance names must be unique and used only once across all CCXL eye mods, not just your own, but other modder's as well, or they will overwrite each other.

In your textures folder, one by one, select and rename your textures to follow the same naming pattern as the template textures:

modderinitials_eyename_d

"modderinitials" — change this to YOUR INITIALS "eyename" — change this to a unique name for that texture "_d" — include this suffix at the end of the file for Wolvenkit import/export settings

You do not need to check the "update in project files" box when renaming.

(optional) I have multiple sclera variants of one texture!

If you have an eye design with one name, but multiple sclera options, you can use a naming convention like modderinitials_scleracolor_eyename_d.xbm

Substitute "scleracolor" for your sclera colors, and "eyename" for whatever you've named your eyes option(s).

If you follow this convention, it will make it easier when we're adding our custom icons a few steps below.

Example: I named my texture "eyename"s to blurple, green_goblin, pink_panther, and I have two options of each texture for white sclera and black sclera.

Next, open your patch.mesh and expand your Appearances section.

You already updated your "modderinitials" in Step 2: Update renamed paths inside files, so we'll use the Search and Replace function to replace only the placeholder names (ex: black_blue) with your new unique "eyename"s.

Example:

The full appearance names should match your texture file names, only without the suffix _d

Remember to save your file.

Step 6: Update appearance names in other files

Now that we have added your new eye textures with their new names, we need to update the other files to use them.

Find & Replace inkCC names

  1. Right click your inkcharcustomization, and click "Convert to json". It will put the converted .json in your RAW folder section of the project explorer.

  2. Open your .json file in a text editor such as Visual Studio Code or Notepad++ and CTRL+F

  3. In the search box, type "modderinitials" and update it with your own modder initials

  4. CTRL + F again, then search the name of the first placeholder "eyename" (you can use the .yaml as reference if needed) from before you updated them with your own

  5. In the replace box, put your first new eyecolor name

  6. Repeat step 5 for each color for each placeholder.

  7. Save your .json file

  8. Right click it in the raw folder, convert it back from .json

  9. Open your newly updated inkcc file. Expand headCustomizationOptions > gameuiAppearanceInfo > definitions and check to make sure the definitions match the appearance names in your patch.mesh

(optional) If you have more appearances than placeholders
  1. Duplicate your last definitions entry and rename it to match the next appearance in your mesh

  2. Repeat until there is an entry for every appearance option in your mesh

  3. Highlight all the new definitions you added manually and right click > Copy from Array/Buffer

  4. Expand the second gameuiAppearanceInfo entry below the one you just edited

  5. Right click the definitions array and select Paste into Array/Buffer

You should now have the same number of definitions in each gameuiAppearanceInfo section and the same number in your patch.mesh appearances list, all with matching names.

(optional) If you have less appearances than placeholders
  1. Highlight all extra placeholders definitions and right click > Delete Item in Array/Buffer

  2. Expand the second gameuiAppearanceInfo entry below the one you just edited

  3. Expand the definitions section

  4. Highlight all extra placeholders definitions and right click > Delete Item in Array/Buffer

Update .yaml names

  1. Next, open your .yaml.

  2. In the section under $instances:, edit or delete the placeholder names. After each "eyename:" add your own eyename. No need to include your modderinitials here, just the eyename.

  3. Repeat for each line until all of your appearance options are listed.

Example:

(Optional) If you have multiple sclera options, make sure to include each of them.

(Optional) If you had more placeholders than appearances, delete any extra lines you did not update.

(Optional) If you have more appearances than placeholder options, copy and paste one of the existing options, making sure you copy the entire line to add onto the list. All indents/spaces must be the same as the line(s) above, and do not change or delete the - or { } brackets.


Step 7: Add Custom Icons

  • Icons for character creator are 160 x 160 pixels with an optional 80 x 80 pixel version for the mini icon preview in the CC menu.

  • If you downloaded the tutorial resources file (Eye Texture Design Resources.zip) from Nexus you will find two template photoshop.psd files called tutorial_icon_2k.psd and tutorial_icon_160x160.psd. You can use these to create icons using your newly created albedo texture.

  • Your albedo texture should be inverted y axis, but we want our icons to be the right way up, so we invert y again, ctrl+a, ctrl+c to copy to clipboard. Open tutorial_icon_2k.psd and ctrl+v to paste as new layer. Use the template layer as a guide for where the pupil should line up. When you are satisfied with placement, flatten all layers, scale the image to 160 x 160 pixels and ctrl+a, ctrl+c to copy to clipboard.

  • Open tutorial_icon_160x160.psd and ctrl+v to paste in as new layer. Move the transparency mask up to your new layer and delete the old layer. ctrl+shift+s to save as new image as PNG.

  • I recommend making a folder of your icon PNGs, with each named exactly after each of your "eyename" (no "modderinitials", no _d suffix, just the eye name itself)

  • Use the icon python script to generate a brand new inkatlas.

  • Name your new inkatlas exactly the same as your inkatlas (it should follow the same naming convention we've been using: modderinitials_modname_icons)

  • Delete the placeholder .inkatlas/.xbm files from your archive. In your raw folder, import the .xbms generated by the python script and right click "Convert from json" the inkatlas.json

  • Open the new .inkatlas file and click PartMapping tab to confirm everything lines up properly.

If you've never made custom icons or used inkatlases before, check out these articles first:


Step 8: Connect your icons to Character Creator

  1. Open your .yaml file.

  1. On the first line, you'll see there's one instance of "modderinitials_modname" that we never replaced. Update it to your name and mod name, save the file.

  2. Next, we need to update our inkcc files to match this change so it knows which icons to use. Open one of your .inkcharcustomization files.

  3. Expand headCustomizationOptions, then expand the first gameuiAppearanceInfo, and expand definitions

  4. Click your first appearance. It will open a panel on the right, where you'll see a section called "icon:" It may be empty, but it might read OptionsIcons.modderinitials_modname_black_blue (or some other color)

  5. Copy and paste the first line of our .yaml into this icon: section. Then change $(eyename) to the color name you have open.

  6. Click through each color in the definitions list, and update the icon: section, replacing $(eyename) with the corresponding color each time. Save your inkcharcustomization file.

  7. Next, highlight all definitions you just updated. Right click > Copy from array buffer

  8. Collapse this first gameuiAppearanceInfo section, then expand the next one underneath.

  9. Right click definitions, click "Clear Array/Buffer". (if it doesn't allow you to clear, expand the definitions list, highlight all the definitions, and right click clear array/buffer that way)

  10. Once cleared, right click definitions again, paste selection into array buffer.

  11. Save.

Step 9: Test your finished mod

Install your mod, check in game at that icons are working in the menu, and your eye textures appear.

You have successfully added new eye options to character creator!


Troubleshooting

I can't scroll down in character creator to see the new eye options!

My icons are black!

  • double check that your OptionsIcons in each definitions entry correctly matches the format in the first line of your yaml, and that all your names are exactly the same, with the same underscore placements, etc.

  • double check that your .xbms are pathed correctly in the inkatlas

  • double check that your inkatlas "parts" listed are named the same as all texture .xbm names listed in your .yaml

My icons are white!

  • Reimport your icons .xbms with compression settings set to TCF_None

No eye textures / Eyeballs are invisible / I only see a creepy set of weird eyes inside V's skull!

  • Material paths are wrong in your patch.mesh

  • Your path to patch mesh is wrong in .xl

  • Your .xbms are in the wrong folder

  • The inkcc definitions names do not match the appearance names in your mesh

My eye textures look extremely dark in the Character Creator screen

  • Make sure you do not have the Eye Depth (Normals) fix mod installed, if so, uninstall it. This mod is no longer necessary, as AXL now has a built-in eye normal fix.

  • Your mod's normals aren't pathed correctly (in .mesh or .xl links if you're using multiple normals)

  • Your mod is missing a normals file for the eyes

    • Use the modderinitials_eyes_n.xbm texture provided with the template project, if it looks like it will fit the shape of your eye textures OR

    • Open your patch.mesh, and navigate to the localMaterialBuffer, expanding @eyes > values > Normal. Path to the game's placeholder normal by copying and pasting this: engine\textures\editor\normal.xbm into the Normal section. Save your file.

Last updated