UE4 – HLSL texture sample quick tip

Software:
Unreal Engine 4.26

When sampling textures using an HLSL custom node,
The UE4 TextureObject input name, will automatically have a sampler object generated named:

<your TextureObject name>sampler

For example, if you named your TextureObject input “tex_in”, the available sampler will be named “tex_insampler”.
So the code for sampling the texture will be:

Texture2DSample(tex_in, tex_inSampler, coords);

The following is an example of a simple u-blur custom node code, with 4 node inputs:
1. tex_in – TextureObject
2. coords – float2
3. size – float
4. sample – float

int blur_samples = int(samples * 0.5f);
float3 col = 0.0f;
float2 sample_coords = 0.0f;
for (int i = -blur_samples; i < blur_samples; i ++)
{	
	sample_coords.x = i * (size / blur_samples * 2);
	col += Texture2DSample(tex_in, tex_inSampler, coords + sample_coords ) / (blur_samples * 2);
}
return col;

The above code can typed directly in the Custom node’s Code field. or loaded from an external .usf file.

See also:
Loading HLSL shaders from the project folder

UE4 – Tiny tips for tiny scale projects

Software:
Unreal Engine 4.26

When having to develop a UE4 project that deals with a tiny world scale, like the whole level being less the 50cm size for example,
The following steps may help make the project more easily navigate-able and convenient to work on.

  1. Scale down the camera Icon:
    UE4 has by default a huge, bulky, opaque camera icon.
    For a tiny scale project, this camera icon may cover the whole level and be very inconvenient to work with.
    Select the relevant camera component and scale it down.
    In my tests, this modified camera matrix isn’t breaking the camera optics in any way,
    But if you want to have no such scale offsets in your project, you can also replace the camera icon with a suitable small one.
  2. In Editor Preferences > Viewport:
    Decrease both:
    Mouse Scroll Camera Speed and Mouse Sensitivity
    To allow finer navigation at small scale

Note:
A global scale conversion factor can be used instead of taking these measures,
And in many cases this can be a more practical solution for managing a sub 50cm world,
For example, building everything 100X size so that 1 meter will be representing 1 centimeter in your project’s world.
But take into account, that if the project demands rendering realistic physical lighting and optics, extra conversions will have to be made to account for the scale conversion factor, so is such cases it may be better to setup a real-world scale project.

UE4 – Replace the Camera component icon

Software:
Unreal Engine 4.26

Note:
This seems like an awkward workaround..
So if I missed something here, and there’s a better method to do this,
I’ll be very grateful is you share it in the comments.
Also,
The following tip is only relevant for the CineCameraActor and won’t work with a regular CameraActor as it has a different built in offset (hopefully, I’ll have time to add this to the post later..)

Replacing the camera icon:
Its fairly simple to replace the Camera component’s mesh icon,
Just select the component and replace it’s Camera Mesh Static Mesh component with a different static mesh object:

So what’s the problem?
The problem is that the default mesh used for the camera icon doesn’t have its natural pivot at the focal point of the camera, but at its bottom somewhere,
And there is a hardcoded transform offset that compensates for that and places the icon mesh in a way that has the Icon lens roughly at the actual Camera actor pivot / focal point:

* I haven’t found any exposed transform parameter that allows moving the icon itself without moving the camera.
So in-order to replace the camera mesh with an alternative icon mesh, and have it be aligned properly to the camera’s pivot / focal point (without changing engine code and building it) the built-in offset must be negatively pre-added to the new mesh model:

In this example in Blender, a new icon is modeled facing positive Y, with pre-built offset to compensate for the hardcoded offset in UE.

The Camera actor with the alternative Icon:

Note:
In this example, I’ve replaced the camera icon with a much smaller model, intentionally, to suite a tiny scale project,
You can also scale the icon without replacing the model.

Python – Adding paths to external modules

Software:
Python 3.9.2

To import an external Python module,
Add its folder path to the sys.path list,
Then import the wanted code.

In this example, there is a Python file:
C:\Oded\GoogleDrive\CGL_Studio\CGL_Python\py\cgl_pixel_utils.py
Containing a function:
cgl_fill_int_range

The following Python code checks the path isn’t already found in sys.path, and if so adds the module path to sys.path,
Imports the cgl_fill_int_range function for the cgl_pixel_utils module,
And calls the cgl_fill_int_range function:

import sys

modulepath = r"C:\Oded\GoogleDrive\CGL_Studio\CGL_Python\py"

if modulepath not in sys.path:
    sys.path.append(modulepath)

from cgl_pixel_utils import cgl_fill_int_range

print(cgl_fill_int_range(-3, 3))

To force reloading of an external module,
Use the reload function from the built-in imp module.
Note that this works with importing full modules and not just specific functions:

import sys
import imp

modulepath = r"C:\Oded\GoogleDrive\CGL_Studio\CGL_Python\py"

if modulepath not in sys.path:
    sys.path.append(modulepath)

import cgl_pixel_utils

# Force reload of cgl_pixel_utils:
imp.reload(cgl_pixel_utils)

print(cgl_pixel_utils.cgl_fill_int_range(-3, 3))

Read-list: Intro to UE4 Arch-viz

A list of UE4 Architectural-Visualization related tutorials:

  1. 3ds max & V-Ray to UE4 – Datasmith workflow basics and tips
  2. UE4 – “Cleaning up” the FPS template for an Archviz project
  3. Basic architectural glazing material in UE4
  4. UE4 – HDRI Environment & Lighting
  5. UE4 – Enable DXR Raytracing
  6. UE4 – Lighting calculation tips for Archviz
  7. Creating a camera animation in UE4
  8. UE4 – Technical model visualization tips

Google Sheets – Historic currency conversion rates

Software:
Google Sheets

This is slightly off-topic in this blog, but since this subject has seriously baffled me, I decided to document and share the solution.

Getting a currency conversion rate in into a Google Sheets expression is fairly simple:

The expression:

GoogleFinance("CURRENCY:USDILS")

Simply returns the current conversion rate, in this case between US Dollars – “USD” to Israeli Shekel – “ILS”, expressed as the term “USDILS”.

So what’s the problem?
When using the GoogleFinance function to retrieve a historic conversion value like so:

GoogleFinance("CURRENCY:USDILS","price","1/1/2012")

the function doesn’t return the numeric value of the price, but instead, creates a table (see image below):

This seems like a nice feature.. so what’s the problem?
If you need to use the conversion rate within a larger scope calculation, the return value will be the string “Date” instead of a numeric value representing the conversion rate, and that will cause an error:

330*index(GoogleFinance("CURRENCY:USDILS","price","1/1/2012"),2,2)

So.. what’s the solution?
The solution is to use the index function to retrieve the wanted value from the table returned by GoogleFinance.
In this case index(weird_surprising_tabel,2,2) returns the wanted value:

330*index(GoogleFinance("CURRENCY:USDILS","price","1/1/2012"),2,2)

That’s it.
Hope you’ll find this useful! 🙂

P.S.
I do use Google Sheets for subjects directly related to CG work, and I should definitely bring some examples of that here in this blog.

Houdini – Separate continuous mesh parts to groups

Software:
Houdini 18.5

Separate a mesh to groups by continous parts (elements):

  1. Use the Connectivity SOP node to assign each mesh primitive an integer attribute based on the continuous mesh element in belongs to.
    This attribute can be named “element” or “part” for example.
  2. Use the GameDev Group by Attribute* node to assign each mesh primitive to a different group according to its “part” attribute (if you named it “part” that is..).
    Set a group name prefix, like “part_” or “element_”. the node will generate numbered groups per each mesh part like so: “element_0”, “element_1”, “element_1″….
  3. Use this group separation as a filter to create whatever part-selective effect you need.

* The GameDev Group by Attribute node ships with the Game Development Toolset

Houdini – Game Development Toolset – Manual installation (Win)

Software:
Houdini 18.5

There is an automatic method to install the Houdini Game Development Toolset, as shown in this tutorial:
https://www.sidefx.com/tutorials/game-dev-toolset-installation/
However, the auto updater method didn’t work for me,
So after looking into some discussions I learnt about the following way to it:

Note:
The linked tutorial details additional ways to set this up.
Honestly.. I don’t remember why I ended up using this specific method.
If you think this method has disadvantages compared to other, I’ll be very grateful if you comment on this.

  1. Download the Houdini Game Development Toolset here as a zip archive:
    https://github.com/sideeffects/GameDevelopmentToolset
  2. Unzip the archive and save GameDevelopmentToolset-Development the folder to a folder of your choice.
  3. Add an environment variable to Windows,
    Named: “HOUDINI_PATH”,
    Containing 2 values:
    a. The path to the GameDevelopmentToolset-Development folder.
    b. A “&” character:
  4. Open Houdini and add the Game Development Toolset Shelf to the UI:

Blender – Split curve

Software:
Blender 2.92

To split part of a curve to a separate curve:

  1. Select the split end points, press V and select Free.
    > This keeps the new curve ends at original direction, if their handle type was Automatic.
  2. In Edit mode, select a sequence of control-points.
  3. Press P and select Separate.

UE4 – Loading shaders from within the project folder

Software:
Unreal Engine 4.25

Disclaimer:
I’m probably the 10th guy that’s documenting these steps on the web,
I didn’t come up with this solution myself, I learned it from the sources listed below.
The reason I’m documenting this (again) myself is to have a clear source I can come back to for this issue because I’m absolutely incapable of remembering subjects like this…… :-\
If you find inaccuracies in the steps I’m detailing or my explanation, I’ll be very grateful if you share a comment.

  1. https://forums.unrealengine.com/development-discussion/rendering/1562454-virtual-shader-source-path-link-custom-shaders-shadertoy-demo-download
  2. https://dinwy.github.io/study/2019/july/customShaderInUE4/
  3. https://forums.unrealengine.com/community/community-content-tools-and-tutorials/1710373-using-external-shader-files-ush-usf-and-getting-the-most-of-the-custom-node

In short:
AFAIK since version 4.21 UE doesn’t load custom node shader code from your project/Shaders folder by default anymore, but only from the shaders folder in the engine installation, which makes it less practical for developing shaders for specific projects.


Steps for setting the UE project to load shaders from the project folder in UE 4.22:

> The examples here are for a project named: “Tech_Lab”

A. The project must be a C++ project:

So either create a new project, define as such or just create a new C++ class and compile the project with it to convert it to a C++ project.
Notes:
a. You may need to right click the .uproject file icon and and Generate Visual Studio Project Files for the project to load correctly into Visual Studio and compile.
b. You can delete the unneeded C++ class you added after the new settings took place.

B. Create a folder for the shader files:

Typically, it will be called “Shaders” and will be placed in the project root folder.

C. Add the RenderCore module to the project:

This is done by adding string “RenderCore” to array of public dependency modules in the <project>.build.cs file:

PublicDependencyModuleNames.AddRange(new string[] { "RenderCore", "Core", "CoreUObject", "Engine", "InputCore" });
(see image)

Notes:
a. In UE 4.21 it should be ShaderCore.
b. This addition is needed in-order to compile a new primary project module (next step).

D. Define a custom primary module for your project:

In <project_name>.h file add a new module named F<project_name>Module, with a StartupModule function overrides.
Notes:
a. We have add an include statement for “Modules/ModuleManager”.
b. The <project_name>.h file is located in the /Source/<project_name> folder.
c. Some sources state that you also have to override the ShutdownModule function, with an empty override, it works for me without this (maybe its just a mistake..)

E. Implement the function override,
and set the custom module as the project primary module:

In <project_name>.cpp file, add the StartupModule override,
With the definition of the added shaders path:
FString ShaderDirectory = FPaths::Combine(FPaths::ProjectDir(), TEXT("Shaders"));

and mapping this new path as “/Project” for conveniently including it:
AddShaderSourceDirectoryMapping("/Project", ShaderDirectory);

Last thing to do is to replace “FDefaultGameModuleImpl” with our custom module name in the IMPLEMENT_PRIMARY_GAME_MODULE macro:
IMPLEMENT_PRIMARY_GAME_MODULE(FTech_LabModule, Tech_Lab, "Tech_Lab" );

Notes:
a. We must include “Misk/Paths”
b. Note that the addition of this folder mapping is restricted to versions 4.22 and higher via a compiler directive condition. for version 4.21, you should state “ENGINE_MINOR_VERSION >= 21:

F. Wrapping up:

After taking these steps and compiling the project.
You should be able to include .ush and .usf files stored in <your_ue_project>/Shaders with the “Project” path mapping:
include "/Project/test.usf"

That’s it! 🙂

I hope you found this helpful,
And if you encountered errors, or inaccuracies,
I’ll be grateful if you’ll take the time to comment.


Related:

  1. UE4 – Cyber enhancement shader
  2. UE4 – Fog post process effect