Half-Life: Alyx

Half-Life: Alyx

Not enough ratings
Dynamic Expressions and Attributes
By piqey and 1 collaborators
Dynamic expressions and attributes in tandem are akin to Source 1's material proxies. This system, slightly more complex and scalable than the one that came before it, can be used to modify variables/parameters of a material at runtime via the use of mathematical equations and/or editor-accessible entities. There are likely a multitude of uses for dynamic expressions and attributes—but, as of now, its uses are undocumented, forcing me to test its limitations myself. This guide is my attempt at clearing up some of the mysteries behind these systems.
   
Award
Favorite
Favorited
Unfavorite
Dynamic Expressions
To access the Dynamic Expression Editor, open a material in the Material Editor, navigate to the Variables tab, locate the material variable you wish to control and click the triangle drop-down next to it. You'll want to select "Add Dynamic Expression..."
.png]
Writing a Dynamic Expression
If you've ever used After Effects before, you're likely familiar with their expression system. Variables/properties could be controlled by user-written formulae, allowing much greater control of the effects generated by the program. Dynamic Expressions, combined with Attributes, are not so different. For example, let's say we want to have a red texture that brightens and then darkens. Create a material and click the drop-down next to "Color Tint." Add a Dynamic Expression to it. Then, when prompted, enter this:
float4(abs(sin(time * 2)), 0, 0, 255)
In this case, as we are supplying the material with a color which contains four values (RGBA), float4(r, g, b, a) must be used. An expression for another material variable that takes a float value does not require float4; in all other cases, just type in a formula or attribute. Apply the expression and you should have a pulsing red texture (at least if the color of your material is plain white by default). The reason you have arrived at this result is because you have told the game that every frame, the red component of the texture should be equal to the absolute value of the sine of two times the current time since the start of the game. If you are unfamiliar with trigonometric functions, this will create a sort of "bouncing" number, starting at zero, bouncing up to one, and then falling back to zero before bouncing again. You can play with the expression by trying your own numbers and functions.
Attributes
Attributes are like variables for your Dynamic Expressions. Add one by opening a material in the Material Editor, then visiting the Attributes tab. Your attributes tab should not yet have a sun icon.
.png]
Then, under the User Material Attributes section, add an attribute. Name it however you want, but be sure to remember it. Your Attributes tab should now have a sun icon next to it. Then, using the things you learned during "Writing a Dynamic Expression," write a new expression that somehow factors in the name of your attribute as a variable (for example, if you named your attribute "AttributeNameHere," "AttributeNameHere" as an expression would just return the value of the attribute every frame, and is a perfectly good expression for learning how things work).
Changing Attributes via I/O
Once you're in the Hammer editor, spawn a point_render_attr_curve. If you've gotten this far and you can't figure out how to use that entity, you probably aren't ready to learn how to use expressions and attributes yet.
Conclusion
In this guide, you should have learned how to create and use a Dynamic Expression to influence the in-game behavior of a material. You also should have been provided the necessary pointers to get started with controlling your material's custom Attributes via Hammer inputs and outputs. If you have any questions, visit the Half-Life: Alyx Modding Hub[discord.gg] on Discord. My handle is piqey#1337. Have a nice day.
Examples
The first place I learned of Dynamic Expressions and Attributes being used were in the game's final cutscene. When G-man says my favorite spoken word in all of Half-Life: Alyx, "inflexible," his eyes glow. This is because their material's selfillum variable was set to follow an attribute controlled by a point_render_attr_curve. In one of my projects, I created my own pulsing material used to accentuate the ticking of a timer that counted down over a period of a few seconds. A logic_timer was set to fire the "Start" input of a point_render_attr_curve every second.
Addendum #1: 03 May 2022
I know this is an edge case, but: If you intend to utilize dynamic expressions to recolor portions of a model, there's a better option. Using a tint mask and an entity's render color (SetRenderColor input) will allow you to recolor specific sections of a material at runtime.

I'm not going to include images because this should be simple enough to understand. If you're far enough in Half-Life: Alyx modding to read this far into the guide, you don't need me any longer.
3 Comments
mahnenvulf 31 Oct, 2020 @ 9:22am 
thanks, very helpful!
piqey  [author] 25 Aug, 2020 @ 2:44am 
why thank you
noNameCat 25 Aug, 2020 @ 1:51am 
Nice work, very usefull!