Heavy noise calculations and normal transformations are performed on the vertex shader (Vertex) side in order to improve drawing efficiency, and the trap of "Custom Interpolator (custom interpolation)" to correctly transfer data to the pixel (Fragment) side is eliminated.

Problem symptoms and specific phenomena

In Shader Graph, when Custom Interpolator is added to pass the calculation results performed on the vertex shader side to the pixel (Fragment) side, the following drawing bug occurs.

  • The 3D model to which the material is applied is violently twisted, expanded and contracted depending on the camera angle and distance.
  • Strange noise or striped patterns appear on the surface of the model, and the drawing results are unstable.
  • A shader compilation error occurs and the model is displayed in bright pink (magenta).
  • The color gradation and wave expression become jittery and discontinuous at the boundaries of polygons.

An analogy for beginners: The flag on the mountaintop and the painter on the slope

To understand this mechanism and the cause of the problem, let's compare the vertex shader to ``a number of flags (vertices) erected on the peaks or ridges of a mountain,'' and the pixel shader to ``a painter (pixels) that paints the slopes between the flags.''

Each of the flags on the mountain ridge has the following information written on it: ``Wind strength here is 10'' and ``Wind strength is 0 over there.'' When painters paint slopes, they refer to the straight ropes (custom interpolators) strung between the flags. If the painter is at the halfway point between the two flags, he can automatically calculate that the wind strength is 5, which is in the middle, and paint smoothly. This is the correct behavior called "linear interpolation".

However, if you try to pass complex information such as "the direction (vector) in which the wind is blowing" as is, a problem will occur. Let's say one flag says "towards east (1, 0, 0)" and the other flag says "towards west (-1, 0, 0)". If a painter uses the rope as a reference at an intermediate point, he will receive strange intermediate data such as "(0, 0, 0), which means no wind" as the average value. The data is distorted because the direction vector does not change linearly. Also, if the format of the letter (number of dimensions of the data) is inconsistent, such as when the painter is waiting to receive the "direction of the wind" even though the flag is transmitting the "strength of the wind", the painter will become confused and completely abandon the painting task (painting collapse).

Assumed main causes

Custom interpolation drawing errors in Shader Graph are caused by the following causes:

  1. Distortion due to linear interpolation of vectors: If the "direction" of a vector, etc. is passed from the vertex side, the length of the vector will be shortened by linear interpolation. If you do not renormalize on the pixel side, the lighting calculation will be distorted.
  2. Mismatch between data type and number of channels: An error will occur if the Custom Interpolator type defined on the vertex side (e.g. Vector3), the output type of the node connected to it, and the type extracted on the pixel side do not match.
  3. Coordinate space mismatch: This is a case where the coordinate systems such as object space and world space are mixed when calculating at vertices and when using pixels.

Specific solutions and procedures

This is the correct operation flow of Custom Interpolators in Shader Graph.

Step 1: Definition in Graph Settings

Open **Graph Settings** in the top right corner of the Shader Graph, expand the **Custom Interpolators** settings, and add a new interpolator. Please set the name and type that match the number of dimensions of the data you want to pass (e.g. `WorldPos (Vector3)`).

Step 2: Connection at Vertex Block (vertex output section)

Once the definition is complete, the defined slot `WorldPos` will be automatically added to the **Vertex Block**, which is the output part of the vertex shader. Connect the output of the node calculated on the vertex side (e.g. the world space settings of the `Position` node) here.

Step 3: Reception and distortion correction at Fragment Block (pixel input section)

Read this data on the pixel shader side. Create a `Custom Interpolator` node and select the `WorldPos` you defined. **If the data is a "direction vector", be sure to use the `Normalize` node just before connecting. ** This restores the shortened vector to the correct orientation and length (1), normalizing the drawing.

Practical checklist & correspondence table

Check items Behavior to check Correction steps/recommended measures
Data type dimension matching Are the dimensions of the set type and the connected node the same? Unify the definition in Graph Settings and input/output of vertices and pixels.
Vector normalization Are you using the vector received on the pixel side for calculations as is? Be sure to pass through the `Normalize` node before connecting to the calculation.

The following is an example code block for using Custom Interpolator-enabled HLSL custom code in a **Custom Function node** in the Shader Graph to pass data.

// A function that performs custom calculations on the vertex shader side and outputs data.
void CalculateCustomInterpolation_float(
    float3 positionOS,      // Vertex coordinates in object space (input)
    float3 normalOS,        // Object space normal (input)
    float3 timeParameters,  // Time parameters (input)
    out float3 customData,  // Data to pass to custom interpolator (output)
    out float3 vertexOffset // Vertex deformation offset (output)
)
{
    float wave = sin(positionOS.y * 5.0 + timeParameters.x * 2.0) * 0.1;
    vertexOffset = normalOS * wave;
    customData = positionOS + float3(wave, wave * 2.0, wave * 0.5);
}

In this way, by optimizing the processing of vertex shaders and pixel shaders using Custom Interpolator, it is possible to dramatically improve the rendering load on target devices with limited GPU performance. This is an effective technique to get the highest FPS while maintaining graphics quality.