Skip to content
Flaxbeard edited this page Nov 26, 2020 · 6 revisions

Introduction

This section will provide a bit of background for how these graphs work and what you can do with them. If you're experienced with HOI4 GUIs, feel free to skip directly to the documentation pages for each of the graphs.

This documentation assumes you have a working knowledge of HOI4 Scripted GUIs. If not, I highly recommend the Iron Workshop's tutorial and the Paradox Wiki page.

Quick Links

High-level Background

HOI4, and especially its mods, often make use of Progress Bars in their GUIs. Most are familiar with the ability to customize the textures of the progress bar, or alter basic properties like its orientation. However, one field that is seldom considered is effectFile, which typically shows up as effectFile = "gfx/FX/progress.lua". This indicates a fragment shader file, which is responsible for determining the color of each pixel in the rendered progress bar. Your traditional progress bar simply checks the x position of a pixel and then based on the progress (frame property in your GUI file) chooses to take the base texture or the filled texture. However, modders can implement their own progress bar shaders with much more powerful effects.

This repo contains several examples of the exciting things you can do with custom shaders. These shaders are written in HLSL (click for reference), which is fairly accessible for those with some formal programming knowledge (C, Java etc.)

Technical Details

A HOI4 shader file contains several components, most of which are irrelevant to writing custom behavior. Each file actually has two shaders, a vertex shader and a fragment shader. There may be cool things you can do with the former, but I haven't delved into that rabbithole yet. The fragment shader, marked by PixelShader = { ... } determines the color of each pixel in your output. In particular, the function MainCode PixelTexture [[ ... ]] is where most of the heavy lifting is done.

You are provided with a few inputs to work with, vTexCoord0, which is a float2 (a tuple of 2 float data types) marking the x and y position of the pixel you are working with. These values range from 0.0 - 1.0. If your texture is 200x400 pixels, vTexCord0 of (0.1, 0.5) would correspond to pixel (20, 200). The other input is CurrentState, a float ranging from 0.0 - 1.0 representing the frame property of the progress bar. Note that your fidelity here is (to my knowledge) limited, you can only pass a single integer value, 0-100, to your progress bar. This means that you'll have to employ some tricks to pass more than one value.

The radar graph is one example of how this can be done. The radar graph draws triangles with a predetermined angle, but whose edge lengths are determined by 2 inputs. These inputs range from 0-9, and are passed as the first and second digit, respectively, of the frame. In this case, 43 can be easily broken down into a 4 and a 3 in the shader code through basic modulus/division/floor operations. You could pass in three 0-3 values, for example, using a similar strategy using powers of two (effectively allocating 2 bits each of the frame to each value).

Clone this wiki locally