Houdini 学习文档 -VEX language reference

VEX是一种专为特定上下文(如表面、光照、CHOP)编写的语言,其语法与C类似,支持常见的C语言语句及特有的光照和采集循环。VEX具有丰富的内置函数库,函数可以被重载,但不支持递归。用户函数必须先声明后使用,主函数负责计算和修改全局变量。VEX提供了标准的C运算符,支持向量和矩阵运算,且具有特定的数据类型和类型转换规则。此外,VEX允许在结构体中定义函数,实现有限的面向对象编程。
摘要由CSDN通过智能技术生成

Details of VEX syntax, data types, and so on.

VEX语法、数据类型等的详细信息

 

Contexts 环境


VEX programs are written for a specific context. For example, a shader that controls the surface color of an object is written for the surface context. A shader that determines the illuminance from a light is written for the light context. A VEX program that creates or filters channel data is written for the chop context.

VEX程序是针对特定上下文编写的。例如,控制对象表面颜色的着色器是为表面上下文编写的。一个着色器,确定了从一个光的照度是为光的上下文编写的。创建或筛选通道数据的VEX程序是为chop上下文编写的。

The context affects which functions, statements, and global variables are available.

上下文影响哪些函数、语句和全局变量可用。

See VEX contexts for an overview of the ways in which you can use VEX.

If you are writing for a shading context (surface, displacement, light, etc.), you should also read the shading context specific information.

Statements 状态


VEX supports the usual statements familiar from C. It also supports shading-specific statements such as the illuminance and gatherloops that are only available in certain contexts.

VEX支持c语言中常见的语句,它还支持特定于着色的语句,比如光照和采集量循环,这些语句只在特定上下文中可用。

 

Built-in function 内置函数 

VEX contains a large library of built-in functions. Some functions are only available in certain contexts.

VEX包含一个内置函数的大型库。有些函数只在某些上下文中可用。

See VEX functions.

 

User-defined functions 自定义函数

Functions are defined similarly to C: specify the return type, the function name, and parenthesized list of arguments, followed by the code block.

函数的定义类似于C:指定返回类型、函数名和参数的圆括号列表,后面跟着代码块。

Arguments of the same type can be declared in a comma separated list without re-declaring the type. Other arguments must be separated by a semi-colon.

相同类型的参数可以在逗号分隔的列表中声明,而无需重新声明类型。其他参数必须用分号分隔。

int test(int a, b; string c) {
    if (a > b) {
        printf(c);
    }
}

You can overload functions with the same name but different argument signatures and/or return type.

您可以重载具有相同名称但不同参数签名和/或返回类型的函数。

You can introduce a function definition with the optional function keyword to avoid type ambiguity.

可以使用可选函数关键字引入函数定义,以避免类型模糊。

  • Notes 节点
    • User functions must be declared before they are referenced.

    • 在引用用户函数之前,必须声明它们。

    • The functions are in-lined automatically by the compiler, so recursion will not work. To write a recursive algorithm, you should useshader calls instead.

    • 函数由编译器自动内联,因此递归不能工作。要编写递归算法,应该使用eshader调用。

    • As in RenderMan Shading Language, parameters to user functions are always passed by reference, so modifications in a user function affect the variable the function was called with. You can force a shader parameter to be read-only by prefixing it with the constkeyword. To ensure that the user function writes to an output parameter, prefix it with the export keyword.

    • 在RenderMan着色语言中,用户函数的参数总是通过引用传递的,所以用户函数中的修改会影响函数调用的变量。您可以使用const关键字前缀强制着色器参数为只读。要确保用户函数写入输出参数,请在其前面加上export关键字。

    • There is no limit on the number of user functions.

    • 用户函数的数量没有限制。

    • You can have more than one return statement in a function.

    • 一个函数中可以有多个return语句。

    • You can access global variables directly (unlike RenderMan Shading Language, you do not need to declare them with extern). However, we recommend you avoid accessing global variables, since this limits your function to only work in one context (where those globals exist). Instead, pass the global(s) to the function as parameters.

    • 您可以直接访问全局变量(与RenderMan着色语言不同,您不需要使用extern声明它们)。但是,我们建议您避免访问全局变量,因为这将您的函数限制为只能在一个上下文中工作(在全局变量存在的地方)。相反,将全局作为参数传递给函数。

    • Functions can be defined inside of a function (nested functions).

    • 函数可以在函数(嵌套函数)中定义。

Main(context) function 主函数

A VEX program must contain one function whose return type is the name of the context. This is the main function of the program that is called by mantra. The compiler expects one context function per file.

VEX程序必须包含一个函数,该函数的返回类型是上下文的名称。这是mantra程序的主函数。编译器期望每个文件有一个主函数

This function should do the work (by calling out to built-in and/or user-defined functions) of calculating any required information and modifying global variables. You do not use the return statement to return a value from the context function. See the specific context pages for the global variables available in each context.

这个函数应该执行计算所需信息和修改全局变量的工作(通过调用内置和/或用户定义的函数)。主函数不能使用return语句返回值。有关每个上下文中可用的全局变量,请参阅特定上下文页面。

The arguments to the context function, if any, become the user interface for the program, for example the parameters of a shading node that references the VEX program.

主函数的参数(如果有的话)将成为程序的用户界面,例如引用VEX程序的着色节点的参数。

If a geometry attribute exists with the same name as a parameter of the context function, the attribute overrides the parameter’s value. This lets you paint attributes onto geometry to control VEX code.

如果存在与主函数的参数同名的几何属性,则该属性将覆盖该参数的值。这允许您在几何图形上绘制属性来控制VEX代码。

 

  • User interface pragmas 用户界面编译指示
  • The user interface generated from this program by Houdini will be minimal, basically just the variable name and a generic text field based on the datatype. For example, you might want to specify that frequency should be a slider with a certain range, and that clr should be treated as a color (giving it a color picker UI). You can do this with user interface compiler pragmas.
  • 程序从houdini生成的用户界面将是最小的,基本上只是变量名和基于数据类型的通用文本字段。例如,您可能希望指定频率应该是一个具有特定范围的滑块,并且clr应该被视为一种颜色(给它一个颜色选择器UI)。您可以使用用户界面编译器pragmas来实现这一点。

 

 

Operators 运算符

VEX has the standard C operators with C precedence, with the following differences.

VEX具有C优先级的标准C操作符,但有以下不同之处。

Multiplication is defined between two vectors or points. The multiplication performs an element by element multiplication (rather than a dot or cross product; see cross and dot).

乘法定义在两个向量或点之间。乘法执行一个元素到另一个元素的乘法(而不是点乘或叉乘;见十字和圆点)。

Many operators are defined for non-scalar data types (i.e. a vector multiplied by a matrix will transform the vector by the matrix).

许多运算符是为非标量数据类型定义的(即一个向量乘以一个矩阵将把这个向量转换为这个矩阵)。

In ambiguous situations where you combine two different types with an operator, the result has the type of the second (right hand side) value, for example

例如,在将两种不同类型与操作符组合在一起的模糊情况下,结果的类型为second(右手边)值

int + vector = vector

 

  • Dot operator 点运算符

You can use the dot operator (.) to reference individual components of a vector, matrix or struct.

可以使用点操作符(.)引用向量、矩阵或结构的各个组件。

For vectors, the component names are fixed.

对于向量,组件名称是固定的。

  • .x or .u to reference the first element of vector2.

  • .x or .r to reference the first element of vector and vector4.

  • .y or .v to reference the second element of vector2.

  • .y or .g to reference the second element of vector and vector4.

  • .z or .b to reference the third element. of vector and vector4

  • .w or .a to reference the fourth element of a vector4.

这一段的意思是说向量(例如:(x,y,z,w)(u,v) ,(r,g,b,a))中的元素通过固定的名字来获取 .x .u 表示取向量的第一位,位置依次对应前面列的三个向量。

 

The choice of the letters u,v/x,y,z/r,g,b is arbitrary; the same letters apply even if the vector doesn’t hold a point or color.

字母u v/x y z/r g b的选择是任意的;同样的字母也适用,即使向量没有点或颜色。

For matrices, you can use a pair of letters:

对于矩阵,你可以使用一对字母:

  • .xx to reference the [0][0] element

  • .zz to reference the [2][2] element

  • .ax to reference the [3][0] element

就是说x就是表示第0位,依次类似 y表示第二位。在矩阵中我们也可以使用dot运算符来获取矩阵中的某个值。

In addition, the dot operator can be used to "swizzle" components of a vector. For example

此外,点算符可以用来“混叠”向量的分量。例如

  • v.zyx is equivalent to set(v.z, v.y, v.x)

  • v4.bgab is equivalent to set(v4.b, v4.g, v4.a, v4.b)

此处还没完全弄清楚,看起来是为向量的zyx赋值的意思,待验证

 

  • Comparisons 比较

The comparison operators (==, !=, <, <=, >, >=) are defined when the left hand of the operator is the same type as the right hand side, for string, float and integer types only. The operations result in integer types.

比较操作符(==,!=,<,<=,>,>=)是在操作符的左手与右手类型相同时定义的,仅用于字符串、浮点数和整数类型。这些操作产生整数类型。

The logical (&&, ||, and !) and bitwise (& |, ^, and ~) operators are only defined for integers.

逻辑操作符(&&,||,and !)和位操作符(& |,^,and ~)只定义整数。

 

  • Precedence table 优先级表

Operators higher in the table have higher precedence. 表中较高的操作符具有较高的优先级。

Order

Operator

Associativity

Description

15

()

LtR

Function call, expression grouping, structure member.

13

!

LtR

Logical negation

13

~

LtR

One’s complement

13

+

LtR

Unary plus (for example, +5)

13

-

LtR

Unary minus (for example, -5)

13

++

LtR

Increment (for exmaple, x++)

13

--

LtR

Decrememt (for example, x--)

13

(type)

LtR

Type cast (for example, (int)x).

12

*

LtR

Multiplication

12

/

LtR

Division

12

%

LtR

Modulus

11

+

LtR

Addition

11

-

LtR

Subtraction

10

<

LtR

Less-than

10

>

LtR

Greater than

10

<=

LtR

Less-than or equal

10

>=

LtR

Greater than or equal

9

==

LtR

Equal

9

!=

LtR

NOT Equal

8

&

LtR

Bitwise AND

7

^

LtR

Bitwise XOR

6

|

LtR

Bitwise OR

5

&&

LtR

Logical AND

4

||

LtR

Logical OR

3

?:

LtR

Ternary conditional (for example, x ? "true" : "false")

2

= += -= *= /= %= &= |= ^=

RtL

Variable assignment

1

,

LtR

Argument separator

  • Operator type interactions 运算符交互

When you apply an operation to a float and an int, the result is the type to the left of the operator.

当您将操作应用于浮点数和整型数时,结果是操作符左边的类型。

That is, float * int = float, while int * float = int.

If you add, multiple, divid, or subtract a vector with a scalar value (int or float), VEX returns a vector of the same size, with the operation applied component-wise.

如果您使用标量值(int或float)加、乘、除或减去一个向量,VEX将返回相同大小的向量,并按组件的方式应用该操作。

For example:

{1.0, 2.0, 3.0} * 2.0 == {2.0, 4.0, 6.0}

If you add, multiply, divide, or subtract vectors of different size, VEX returns a vector of the larger size. The operation is applied component-wise.

如果您加、乘、除或减去不同大小的向量,VEX将返回一个更大的向量。操作是按组件应用的。

Important: the "missing" component(s) on the smaller vector are filled in as {0.0, 0.0, 0.0, 1.0}

重要提示:较小向量上的“缺失”组件被填入{0.0,0.0,0.0,1.0}

{1.0, 2.0, 3.0} * {2.0, 3.0, 4.0, 5.0} == {2.0, 6.0, 12.0, 5.0}

This can give surprising results if you're not expecting it,

如果你没有预料到,这可能会给你带来意想不到的结果。

for example:

// Third element of the vector2 is treated as 0,第三位补0
// but fourth element is treated as 1.0,第四位补1
{1.0, 2.0} + {1.0, 2.0, 3.0, 4.0} == {2.0, 4.0, 3.0, 5.0}

If you're combining different-sized vectors, you might want to break out the components and operate on them "manually" to get the results you want without surprises.、

如果您正在组合不同大小的向量,您可能希望分解这些组件并“手动”操作它们,以在没有意外的情况下得到您想要的结果。

 

Data types 数据类型

 

Warning

VEX uses 32 bit integers. If you use the AttribCast SOP to cast a geometry attribute to 64 bits, VEX will silently discard the extra bits if you manipulate the attribute in VEX code.

VEX使用32位整数。如果使用AttribCast SOP将几何属性强制转换为64位,那么VEX将在VEX代码中处理额外的位

You can use underscores to break up long numbers.

您可以使用下划线来分割长数字。

Type

Definition

Example

int

Integer values

21, -3, 0x31, 0b1001, 0212, 1_000_000

float

Floating point scalar values

21.3, -3.2, 1.0, 0.000_000_1

vector2

Two floating point values. You might use this to represent texture coordinates (though usually Houdini uses vectors) or complex numbers

{0,0}, {0.3,0.5}

vector

Three floating point values. You can use this to represent positions, directions, normals or colors (RGB or HSV)

{0,0,0}, {0.3,0.5,-0.5}

vector4

Four floating point values. You can use this to represent positions in homogeneous coordinates, or color with alpha (RGBA)

{0,0,0,1}, {0.3,0.5,-0.5,0.2}

array

A list of values. See arrays for more information.

{ 1, 2, 3, 4, 5, 6, 7, 8 }

struct

A fixed set of named values. See structs for more information.

matrix2

Four floating point values representing a 2D rotation matrix

{ {1,0}, {0,1} }

matrix3

Nine floating point values representing a 3D rotation matrix or a 2D transformation matrix

{ {1,0,0}, {0,1,0}, {0,0,1} }

matrix

Sixteen floating point values representing a 3D transformation matrix

{ {1,0,0,0}, {0,1,0,0}, {0,0,1,0}, {0,0,0,1} }

string

A string of characters. See strings for more information.

"hello world"

bsdf

bidirectional scattering distribution function. See writing PBR shaders for information on BSDFs.

 

Structs 结构体

Note

You must define structs before using them in the source file.

在源文件中使用结构体之前,必须定义它们。

As of Houdini 12, you can define new structured types using the struct keyword.

从Houdini 12开始,您可以使用struct关键字定义新的结构化类型。

Member data can be assigned default values in the struct definition similar to C++11 member initialization.

成员数据可以在结构定义中分配默认值,类似于c++ 11成员初始化。

Two implicit constructor functions are created for each struct. The first takes initialization arguments in the order they are declared in the struct, the second takes no arguments but sets all members to their default values.

为每个结构创建两个隐式构造函数。第一种方式按照结构中声明的顺序接受初始化参数,第二中方式不接受参数,但将所有成员设置为默认值。

#include <math.h> 

struct basis { 
    vector i, j, k; 
} 

struct bases { 
    basis m, n, o; 
    string description; 
} 

struct values {
    int uninitialized;        // Uninitialized member data
    int        ival = 3;
    float fval = 3.14;
    float aval[] = { 1, 2, 3, 4.5 };
}

basis rotate(basis b; vector axis; float amount) { 
    matrix m = 1; 
    rotate(m, amount, axis); 
    basis result = b; 
    result.i *= m; 
    result.j *= m; 
    result.k *= m; 
    return result; 
}

// Declare struct variables
basis b0;        // Initialize using default values (i.e. 0 in this case)
basis b1 = basis({1,0,0}, {0,1,0}, {0,0,1});        // Initialize using constructor
basis b2 = { {1,0,0}, {0,1,0}, {0,0,1} };         // Initialize as explicit struct
b1 = rotate(b1, {0,0,1}, M_PI/6);

 

 

  • Struct functions 结构体函数

You can define functions inside structs to organize your code and allow a limited form of object-oriented programming.

您可以在结构体中定义函数来组织代码,并允许有限形式的面向对象编程。

  • Inside a struct function, you can use this to refer to the struct instance.

  • 在struct函数中,可以使用它引用struct实例。

  • Inside a struct function, you can refer to struct fields by name as if they were variables (for example, basis is a shortcut for this.basis).

  • 在struct函数中,可以按名称引用struct字段,就像它们是变量一样(例如,basis是this.basis的快捷方式)。

  • You can call struct functions on a struct instance using the -> arrow operator, for example sampler->sample(). Note inside a struct function that you can call other methods on the struct using this->method().

  • 您可以使用->箭头操作符调用struct实例上的struct函数,例如sampler->sample()。注意,在struct函数中,可以使用this->method()调用struct上的其他方法。

  • struct randsampler {
        // Fields
        int        seed;
    
        // Methods
        float sample()
        {
            // Struct functions can refer to fields by name
            return random(seed++);
        }
    } 
    
    cvex shader()
    {
        randsampler sampler = randsampler(11); //传参的构造函数初始化 sampler.seed = 11
        for (int i = 0; i < 10; i++)
        {
            // Use -> to call methods on struct instances
            printf("%f\n", sampler->sample());
        }
    }

Mantra Specific Types( Mantra 特殊类型)

Mantra has some pre-defined struct types that are used in shading-specific functions.

Mantra有一些预定义的结构类型,用于特定于着色的函数中。

light

Defined in mantra shading contexts only. This is a struct representing a handle to a light source. The struct has methods:

只在mantra 阴影上下文中定义。这是一个结构体,表示光源的句柄。结构体有以下方法:

  • illuminate(…) Invokes the VEX surface shader bound to the vm_illumshader property of the light source.

  • illuminate(…)调用绑定到光源vm_illumshader属性的VEX表面着色器。

In an IFD, you may see lines like ray_property light illumshader diffuselighting or ray_property light illumshader mislighting misbias 1.000000.

在IFD中,您可能会看到类似这样的行,,,

These statements define the shader invoked when the illuminate() method is called on a light object.

这些语句定义了当在light对象上调用illuminate()方法时调用的着色器。

material

Defined in mantra shading contexts only. This is opaque struct representing the material assigned to an object.

lpeaccumulator

Defined in mantra shading contexts only. This is a struct representing an accumulator for Light Path Expressions. The struct has methods:

只在 mantra 阴影上下文中定义。这是一个表示光路表达式累加器的结构体。结构体有以下方法:

 

  • begin() Construct and initialize accumulator. 构造和初始化累加器。

  • end() Finalize and destroy. 结束并销毁

  • move(string eventtype; string scattertype; string tag, string bsdflabel) Modifies internal state based on current event. If an empty string is passed in, it’s assumed to be 'any'.根据当前事件修改内部状态。如果传入一个空字符串,则假定它是“any”。

  • pushstate() Push internal state onto stack.将内部状态推入堆栈。

  • popstate() Pop internal state from stack. Used to pushstate() to "undo" move().从堆栈中弹出内部状态。用于pushstate()来“撤销”move()..

  • int matches() Returns non-zero if the current internal state matches any of the light path expressions defined by user.如果当前内部状态匹配用户定义的任一光程表达式,则返回非零。

  • accum(vector color, …) Accumulates input color onto intermediate buffer. Also takes in optional prefix strings to be compared against prefixes that were declared with LPE image plane. All prefixes must match in order to accumulate.将输入颜色累积到中间缓冲区。还接受可选的前缀字符串,以便与用LPE图像平面声明的前缀进行比较。所有前缀必须匹配才能累加。

  • flush(vector multiplier) Multiply the intermediate buffer by the multiplier and add it onto image planes. The intermediate buffer exists to allow for variance anti-aliasing (i.e. the multiplier would be 1/number_of_samples).将中间缓冲区乘以乘数,并将其添加到图像平面上。中间缓冲区的存在是为了允许方差抗混叠(即乘数为1/number_of_samples)。

  • int getid() Returns an integer id assigned to lpeaccumulator.返回分配给lpeaccumulator的整数id。

  • lpeaccumulator getlpeaccumulator(int id) Returns lpeaccumulator based on id. Used with getid() to pass lpeaccumulator accross shader boundaries.基于id返回lpeaccumulator。与getid()一起使用,以通过着色器边界传递lpeaccumulator。

Type casting 类型转换

  • Variable casting 变量转换

This is similar to type casting in C++ or Java: you transform a value of one type into another (for example, an int into a float).

这类似于c++或Java中的类型转换:将一种类型的值转换为另一种类型(例如,将int转换为float)。

This is sometimes necessary, as when you have the following:

这有时是必要的,当你有以下几点:

int a, b;
float c;
c = a / b;

In this example, the compiler will do integer division (see type resolution ). If you wanted to do floating point division instead, you need to explicitly cast a and b as floats:

在本例中,编译器将执行整数除法(参见类型解析)。如果你想做浮点除法,你需要显式地将a和b转换为浮点:

int a, b;
float c;
c = (float)a / (float)b;

This generates additional instructions to perform the casts. This may be an issue in performance-sensitive sections of your code.

这将生成执行强制转换的附加指令。在代码的性能敏感部分,这可能是个问题。

  • Function casting 函数转换

Comments 注解

VEX uses C++ style comments: 使用C++的注解模式

  • One-line comments are preceded by // 单行注释用 //

  • Freeform comments begin with /* and end with */ 

Reserved Keywords 关键字

breakbsdfcharcolorconstcontinuedoelseexportfalsefloatforforpointsforeachgatherhpointifilluminanceimportintintegermatrixmatrix2matrix3normalpointreturnstringstructtrue,typedefunionvectorvector2vector4voidwhile

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值