VEX —— 简介

28 篇文章 4 订阅

目录

一,背景介绍

二,相关概念介绍

语境 Context

语句 Statements

内置函数 Built-in Functions

用户自定义函数 User-defined Functions

外部预安装函数

主(语境)函数 Main (context) function


一,背景介绍

        VEX全称Vector Expression,是性能接近C/C++的高性能表达式脚本语言,也是一种更小、更高效的用于Shader和自定义节点的通用语言;VEX基于C语言,也采纳了C++的思想(如强类型、操作符重载、指针和引用概念等)类似Renderman shading language;

        VEX是一种嵌入式语言,不作为一个独立的编程环境来运行,而是内置于houdini软件中,专为houdini设计并于其紧密结合,由houdini实时编译和执行;VEX的编译器称为VCC,不是一个解释器,需在执行前完成编译步骤;

        在Houdini中VEX主要用于Rendering、Compositing、Particles、Modeling、CHOPS、Fur等适合底层、高性能的图形处理和着色任务;不同于另一个语言Python(解释型),Python主要用于编写宏、工具、脚本和插件,及自动化工作流程等高层逻辑、自动化和扩展houdini的功能;

VEX特点
  • 高性能,直接与Houdini内部数据交互,执行效率高,非常适合大规模数据和计算密集的任务;
  • 类C语法,语法类似于C语言,对会编程用户友好;
  • Shader编写,可编写自定义Shader,实现特定渲染效果;
  • 几何体处理,可处理几何体如点线面等三维数据,实现复杂的几何操作和变换;
  • 集成于节点,可通过节点如wrangle、vop等节点嵌入到节点工作流中;

        虽然VEX基于C/C++,但其功能的核心是不同的;其需在指定的语境Context内编程,依赖于语境可选择特定的函数和语句;类似于C/C++,有常用的语句如do、for、foreach、if等,指定语境的语句如getglobalraylevel(返回计算全局光照的光线深度);总的来说,Houdini VEX拥有巨大的内置函数库;另外,用户还可创建无限的自定义函数(默认使用VCC编译器,不可使用递归),建议不要访问全局变量;

        此外,在VEX语法,对于属性需使用符号“@”;属性存储在vertex、point、primitive、detail上,本质是几何体各个级别的数据块;简单的说,point是在3D空间具有X/Y/Z坐标的点,primitive类似面(当将点连接起来的时候可以得到),vertex则是可以把primitive赋予到point上,detail则可以理解为表示整个几何体的属性;

参考于Houdini VEX 基本语法与常用命令速查 #Houdini单词本 - 哔哩哔哩 (bilibili.com)

二,相关概念介绍

语境 Context

        VEX为特定的语境编写,如在Surface Context下编写对象表面颜色的Shader,在Light Context下编写灯光的照明Shader,在Chop Context下创建或过滤通道数据;Context影响哪些函数、语句、全局变量的可用性;

语句 Statements

        VEX支持常见C中的语句,也支持着色指定的语句如illuminance和gather;

内置函数 Built-in Functions

        VEX包含一个大型的内置函数库,一些函数仅能在特定的语境下有效;

  • 一部分vex编译器直接支持的基础函数(vex语言本身的组成部分),如数学运算、向量操作等;
  • 通过houdini提供的接口API来实现的函数,以实现与houdini环境交互,如访问几何体属性、创建点、获取变换信息等;

        VEX Functions

用户自定义函数 User-defined Functions

        类似于C函数的定义,指定返回类型、函数名、参数列表;

type funname(arg, ...) {...;}
  • 自定义函数必需在使用前声明;
  • 函数自动会被编译器内联(调用时展开),因此递归不起作用;使用shader call去编写递归算法;
  • 类似RenderMan Shading Language,参数总是被引用传递;函数中修改会影响调用的变量,可使用const强制只读;为确保函数写出一个输出参数,在其前添加关键字export;
  • 自定义函数的数量没有限制;
  • 可直接访问全局变量(不像RenderMan Shading Language,需要用extern声明),建议不要访问全局变量(会限制函数的使用(只有全局变量存在的地方));
  • 可在函数内部定义函数;
//参数,相同类型可逗号隔开,不同类型封号隔开
int test(int a,b; string c){
    if(a>b) return a;
    else return b;
    printf(c);
}

//可重载函数,用不同的参数或返回类型
//可添加可选的关键字function,以明确函数
function int test(int a,b){
    if(a>b) return a;
    else return b;
}
void test(int a,b){
    printf("c");
}
//参数总是被引用传递
void test(export int a){
    a += 1;
    printf("%d",a);
} 
int a=0;
printf("%d",a); 
test(a);
printf("%d",a);
//返回011
//函数内部定义函数
void test(){
   void test1(){printf("test1");}
    test1();
} 

外部预安装函数

路径 C:\Program Files\Side Effects Software\Houdini 19.5.303\houdini\vex\include

#include "groom.h"
adjustPrimLength(0, @primnum, @perimeter, @perimeter*ch('scale'));

将自定义的函数头文件放入其中,然后在houdini内引用;

//自定义头文件 test.h
void test(float ang, rad; vector pos){
    vector newpos = pos + set(sin(3.14*0.1*ang), 0, cos(3.14*0.1*ang))*rad;
    addpoint(0, newpos);
}
//houdini内引用
#include "test.h"
vector pos = point(0, 'P', 0);
for(int i=0; i<100; i++){
    test(i*ch('ang'),i*0.05,pos);
    
}

主(语境)函数 Main (context) function

  • 一个VEX程序必需包含一个函数,其返回类型是语境的名字;这是程序的主函数,被mantra调用的主函数;编译器要求每一个文件都有一个语境函数;
  • 该函数应该完成计算任何所需的信息和修改全局变量的工作(通过调用内置和/或用户定义的函数);不应在语境函数使用return返回值;
  • 语境函数的参数,会成为程序的用户界面,如shading节点的参数;
  • 如几何体属性和语境函数参数有相同的名字,属性会覆盖参数的值,即可通过几何体属性控制vex代码;
#pragma opname        noise_surf
#pragma oplabel        "Noisy Surface"

#pragma label    clr            "Color"
#pragma label    frequency    "Frequency"

#pragma hint    clr            color
#pragma range    frequency    0.1 10

surface noise_surf(vector clr = {1,1,1}; float frequency = 1;
           export vector nml = {0,0,0})
{
    Cf = clr * (float(noise(frequency * P)) + 0.5) * diffuse(normalize(N));
    nml = normalize(N)*0.5 + 0.5;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值