百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
V

vex_tutorial

> 编程语言
开源

:bookmark_tabs: 包含代码片段和示例的集合,展示了 SideFX Houdini 中 VEX 语言的语法和功能

756 stars0 点赞0 次浏览
访问官网GitHub

工具介绍

:bookmark_tabs: 包含代码片段和示例的集合,展示了 SideFX Houdini 中 VEX 语言的语法和功能

VEX tutorial

A collection of code snippets and examples showing syntax and capabilities of VEX language inside SideFX Houdini

by Juraj Tomori

How to use it

You can clone, or directly download this repository.

It contains examples.hipnc and vex/include/myLib.h files which are full of various examples with explanations in comments.

It is the best to check all the nodes with open Geometry Spreadsheet and Console Output windows to see values of attributes and output text. Alternatively you can use this page for quick looking at the topics covered and most of the code that I include here as well. I am not including here all of the code since sometimes it might not make a lot of sense outside of Houdini. Where necessary I include related functions from myLib.h or attach screenshots.

Topics

  • Reading parameter values
  • Reading attributes
  • Exporting attributes
  • Reading arrays
  • Arrays
  • Arrays and strings example
  • Reading and writing Matrices
  • Checking for attributes
  • Automatic attribute creation
  • Getting transformation from OBJs
  • Intrinsics
  • VDB intrinsics
  • Volumes
  • VOPs / Using Snippets
  • VOPs / Using Inline Code
  • DOPs / Volumes workflow
  • DOPs / Gas Field Wrangle
  • DOPs / Gas Field Wrangle - accessing DOPs and SOPs data
  • DOPs / Geometry workflow
  • DOPs / Geometry Wrangle
  • DOPs / Geometry Wrangle - accessing fields
  • Conditions
  • Loops
  • Stopping For-Each SOP from VEX
  • Printing and formatting
  • Printing attributes
  • Including external VEX files
  • Include math.h
  • Using macros
  • Functions
  • Functions overloading
  • Variables casting
  • Vectors swizzling
  • Functions casting
  • Structs
  • Structs in Attribute Wrangle
  • Groups
  • Attribute typeinfo
  • Attributes to create
  • Enforce prototypes
  • Attribute default values

Tutorial

Reading parameter values

/*
multi-line comments can be typed
using this syntax
*/

// in vex you can evaluate values from parameters on this node
// by calling ch*() function, with * representing a signature, check the docs
// for the full list, some of them: chv() - vector, chu() - vector2, chs() - string
// chramp() - ramp, chp() - vector4, chi() - int, chf() - float, ch4() - matrix, ch3() - matrix3 ...
// you can also use optioinal argument for time which will enable you to evaluate
// the channel at different frame
//
// once you type ch*() in your code, you can press a button on the right, to
// generate a UI parameter for it automatically, you can do the same by hand as well
float y = chf("y_position");
vector col = chv("color");
matrix3 xform = ch3("xform");

// you can also reference parameters from external nodes
// if there is an expression (Python/hscript) in the parameter,
// it will be evaluated
float up = chf("../params_1/move_up");

// apply variables to attributes
[email protected] += y*5;
v@Cd = col;
v@P *= xform;
[email protected] += up;

v@myVec = 1.456;
v@myVec += [email protected];

Reading attributes

float blend = chf("blend");
float blendPig = chf("blend_pig");
vector P1, P2, P3, P_new;

// this is one way of reading attributes, this is only valid, when
// point count is exactly the same in both inputs, then attribute from
// point from second input with the same @ptnum is retrieved
// v@P can also be replaced with @P, since its signature can be guessed as it is
// commonly used attribute, however I prefer explicit declaration :)
// v@ - vector, i@ - integer, f@ - float, 3@ - matrix3, p@ - vector4
// 4@ - matrix4, 2@ - matrix2, u@ - vector2, s@ - string,
//P1 = v@P;
//P2 = v@opinput1_P; // inputs numbering starts at 0, therefore 1 refers to the second input

// this approach is useful for querying attributes from different points (other from the currently processed one)
// node input numbering starts from 0 (first input), 1 (second input) ...
P1 = point(0, "P", @ptnum);
P2 = point(1, "P", @ptnum);

// note that you can also read attributes from node, which is not connected
// to the current node using the "op:" syntax
// this is valid for any function which is expecting geo handle (sampling from other volumes...)
// note that Houdini network UI will not detect this dependency when Show -> Dependency links display is enabled
P3 = point("op:../pig_shape", "P", @ptnum);

// blend positions
P_new = lerp(P1, P2, blend);
P_new = lerp(P_new, P3, blendPig);

v@P = P_new;

Exporting attributes

// create a new attribute simply by typing *@attrib_name with
// * representing its signature
// v@ - vector, i@ - integer, f@ - float, 3@ - matrix3, p@ - vector4
// 4@ - matrix4, 2@ - matrix2, u@ - vector2, s@ - string

v@myVector = {1,2,3};
// vectors with functions/variables in them need to be created with set()
u@myVectorFunc = set(@Frame, [email protected]);
u@myVector2 = {4,5};
f@myFloat = 400.0;
i@myInteger = 727;
3@myMatrix3x3 = matrix3( ident() ); // this line contains function casting, which is explained in functions_casting section
4@myMatrix4x4 = matrix( ident() );
s@myString = "abc";

// attributes can be set to different point from the currently processed one
// and if they do not exist, they need to be added first
// setpointattrib() is also the only way of setting an attribute on newly
// created points
addpointattrib(0, "Cd", {0,0,0});
setpointattrib(0, "Cd", 559, {1,0,0});

// arrays can be exported as well
v[]@myVectorArray = { {1,2,3}, {4,5,6}, {7,8,9} };
u[]@myVector2Array = { {4,5}, {6,7} };
f[]@myFloatArray = { 4.0, 2.7, 1.3};
i[]@myIntegerArray = {132, 456, 789};
// arrays containing functions/variables need to be initialized with array() function
3[]@myMatrix3x3Array = array( matrix3( ident() ), matrix3( ident() ) * 5 );
4[]@myMatrix4x4Array = array( matrix( ident() ), matrix( ident() ) * 9 );
s[]@myStringArray = { "abc", "def", "efg" };

Reading arrays

// this is how you can create local array variables and load array attributes into them
vector myVectorArray[] = v[]@myVectorArray;

matrix3 a = ident() * 5;

[email protected] *= a.yy; // you can access matrix components using this syntax
// x -> 1st element, y -> 2nd, z -> 3rd, w -> 4th
[email protected] = 4[]@myMatrix4x4Array[1].ww; // second array matrix, last element
[email protected] = u[]@myVector2Array[1][0]; // this is how you can access array of vectors - second array, first element

Arrays

int numbers[] = array(1,2,3,4);

// arrays can be handled in Pythonic way
numbers = numbers[::-1]; // array reverse

// rading from arrays
i@firstItem = numbers[0];
// writing into arrays
numbers[0] += 1;
// indexing can also go backwards
i@secondLastItem = numbers[-2];

// slicing
i[]@firstHalf = numbers[:2];
i[]@secondHalf = numbers[2:];

// some useful functions
i@returnedPopVal = pop(numbers); // removes the last element and returns it
push(numbers, i@returnedPopVal); // appends element to the array
i@lenghtOfArray = len(numbers);

// export into integer array attribute
i[]@numbers = numbers;

// flattening an array of vectors and reverting it
vector vectors[] = { {1,2,3}, {4,5,6}, {7,8,9} };
f[]@serializedVectors = serialize(vectors);
v[]@unserializedFloats = unserialize(f[]@serializedVectors);

Arrays and strings example

// simple example of manipulating strings and arrays
// it will convert /path/to/the/project/file/project_v3.hipnc
// into            /path/to/the/project/file/preview/project_v3_img_0001.jpg
// with 0001 being current frame number

string path = chs("path"); // get string from path parameter of the current hipfile
s@pathOrig = path; // store into attribute original value

string pathSplit[] = split(path, "/"); // split path into array of strings based on "/" character

string fileName = pop(pathSplit); // remove last value of the array and assign it into a variable
string fileNameSplit[] = split(fileName, "."); // split string into an array based on "." character
fileNameSplit[0] = fileNameSplit[0] + sprintf("_img_%04d", @Frame); // append into the string _img_0001 (current frame number)
fileNameSplit[-1] = "jpg"; // change file extension
fileName = join(fileNameSplit, "."); // convert array of strings into a one string with "." between original array elements
push(pathSplit, "preview"); // append "preview" string into the array of strings
push(pathSplit, fileName); // append file name into the array of strings

path = "/" + join(pathSplit, "/"); // convert array of strings into one string, starting with "/" for root, because it is not added before the first element, only to in-betweens

s@path = path; // output into the attribute

Reading and writing Matrices

// To intilize a vector or a matrix with a variable/attribute we have to use the set method
float   f = 0;
vector  v = set(f,f,f);
matrix3 m = set(f,f,f,f,f,f,f,f,f);
        m = set(v,v,v);

// We can then read the value back by
float f = getcomp(m,0,0);
// However we can not read back a vector directly instead we have to use:
f = set(getcomp(m,0,0));
v = set(getcomp(m,0,0),
        getcomp(m,0,1),
        getcomp(m,0,2));
// Likewise the setcomp can be used
setcomp(m,f,0,0);

Checking for attributes

// it is also possible to determine if incoming geometry has an attribute

i@hasCd = hasattrib(0, "point", "Cd");
i@hasN = hasattrib(0, "point", "N");
i@hasOrient = hasattrib(0, "point", "orient");
i@hasPscale = hasattrib(0, "point", "pscale");

Automatic attribute creation

// if you use @attribute and it does not exist, 
// then it will be automatically created
// this might lead to problems, when you have a typo and a 
// new attribute is created

f@foo = 4;
f@boo = [email protected];
//v@CD = {1,1,0}; // this line does not work here, otherwise it would crete new v@CD attribute

// if you remove * chracter from "Attributes to Create" parameter
// bellow, then you need to manually specify new attributes
// to be created, if you then have a typo and use v@CD instead
// of v@Cd, node will report an error

Getting transformation from OBJs

// VEX is well integrated into Houdini, it can for example fetch
// world space transformation matrix from an OBJ node, let it be a null OBJ
// or part from a rig, camera or whatever object there which has a transformation
// optransform() will contain also all parent transformations

string nodePath = chs("node_path"); // parameter is a string, but I went into "Edit Parameter Interface" and specified it to be a Node Path
matrix xform = optransform(nodePath);

v@P *= invert(xform);

Intrinsics

// a lot of information and functionality is stored in
// "intrinsic" attributes, they might be hidden to many users
// because they do not show up in primitive attributes list
// by default
// they are however very useful and important for manipulating
// and controlling those primitives from VEX

// you can display intrinsics in Geometry Spreadsheet, in primitive attributes
// and Show All Intrinsics in Intrin

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

Choudinitutorialvexvfx

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言