Jörn Alexander Quent's notebook

where I share semi-interesting stuff from my work

Matlab function to create stacked texture maps for Unity

I’ve been experimenting with different materials and shaders in Unity recently. One problem is that especially if you want use the same texture for the same large object you get these nasty tiling effects:


Luckily, I found this obscure shader on Unity’s GitHub page, which is amazing but it asked for something called a map texture, which took me ages to figure out.

Essentially what you need to do is to use grayscale images of your metallic, ambient occlusion, detail mask and smoothness map and plug them into one RGBA image (more information), which is illustrated below:

Illustration of procedure.

I’ve spent hours trying to do this in GIMP but I failed so I quickly cooked up a function in MATLAB called createStackedTexture.m (GitHub repository).

Example how to use the function

createStackedTexture("factorylargerocksplain_maskMap.png", ...
                     "factorylargerocksplain_metallic.png", ...
                     "factorylargerocksplain_ao.png", ...
                     zeros(250, 250, 3, 'uint8'), ... % To leave out just add zeros. 

Code for the function

function createStackedTexture(fileName, go2R, go2G, go2B, go2A)
%createStackedTexture This functions takes greyscale texture maps (currently only .png) and
%copies them into one RGBA images in the respective channels. 
% go2R = Greyscale image or array that should go into the R channel. 
% go2G = Greyscale image or array that should go into the G channel. 
% go2B = Greyscale image or array that should go into the B channel. 
% go2A = Greyscale image or array that should go into the A channel. 

%% Reade files or copy if arrays
if isstring(go2R) || ischar(go2R)
    R = imread(go2R);
    R = go2R;

if isstring(go2G) || ischar(go2G)
    G = imread(go2G);
    R = go2G;

if isstring(go2B) || ischar(go2B)
    B = imread(go2B);
    B = go2B;

if isstring(go2A) || ischar(go2A)
    A = imread(go2A);
    A = go2A;

%% Check dimensions
if ~all(size(R) == size(G)) || ~all(size(G) == size(B)) || ~all(size(R) == size(B)) || ~all(size(A) == size(B))
   error('Not all files have the same dimensions.');

%% Get new image
textureMap = zeros(size(R, 1), size(R, 1), 3, 'uint8'); %initialise
textureMap(:, :, 1) = R(:, :, 1);
textureMap(:, :, 2) = G(:, :, 1);
textureMap(:, :, 3) = B(:, :, 1);

%% Write new image
imwrite(textureMap, fileName, 'png', 'Alpha', A(:, :, 1));