IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 尝试在Houdini中做一个能可视化法线数据的着色器 -> 正文阅读

[游戏开发]尝试在Houdini中做一个能可视化法线数据的着色器

目标

最近有想要在Houdini中可视化模型的法线数据的情况,就像UE中这样:
在这里插入图片描述

但是发现Houdini中似乎没有现成的方法(还是我没找到?)。
我想,实现它在原理上很简单——只是将法线数据输出到颜色就可以了。不过在Houdini中我还没做过类似的东西,因此还是学习了一些内容。

本质上,目标是写一个简单的着色器,主要参考Houdini官方文档:使用GLSL写一个自定义的视口着色器(Writing a custom viewport shader in GLSL)

1. 创建一个新的GLSL着色器代码

这里主要参考了官方文档:

为了创建一个GLSL着色器,你需要创建一个新的SHOP类型。当前你并不能使用VOPs来创建一个新的GLSL着色器。

Tip
或者,你可以将 GLSL 着色器源代码存储在文本文件中,然后在材质上使用 ogl_glsl_shader 属性引用文件。

  1. 选择 File > NewAsset
    在这里插入图片描述

  2. 选择VOP类型,在 Network Type 中选择 GLSL Shader
    在这里插入图片描述

  3. 输入名字,以及标签,再指定一个合适的路径:
    在这里插入图片描述

  4. 设置好后,点击Accept。这样便新建了一个名为 VisualizeWorldNormal 的节点。

  5. 之后应该会自动弹出Edit Operator Type Properties窗口,(也可以创建一个节点右键点击Type Properties…)在Code分页就可以看到默认的着色器代码,你可以使用它作为一个起点:
    在这里插入图片描述
    Code分页提供了一个简单的编辑器来处理 GLSL 代码。编辑器有四个文本框:一个用于顶点着色器,一个用于可选的几何着色器,一个用于片段着色器,一个用于编译器输出。你可以拖动三个窗格之间的分隔线来调整它们的大小或最大化单个窗格。

  6. 点击Test Compile 以尝试编译默认代码。编译器的输出出现在第四个窗格中,如果有错误也会显示在那里。

2. 将其应用到几何体上

随意创建一个几何体,比如创建个立方体。

创建一个 Material Network 节点。
在这里插入图片描述
然后,在其中创建刚才新建的VisualizeWorldNormal节点
在这里插入图片描述
创建一个Material节点,并将材质指向刚刚创建的VisualizeWorldNormal节点:
在这里插入图片描述
现在,我们新创建的着色器已经被应用了。(只是外观上暂时还没什么变化)

3. 确保可以输出准确的颜色

观察像素着色器的代码,可以看到最后使用了HOUassignOutputs函数作为输出。
Houdini安装目录\houdini\glsl\houlib\GL32\assign_outputs.func中可以看到其定义:

void
HOUassignOutputs(vec3 point_color,
		 vec3 emit_color,
		 vec3 metal_color,
		 vec3 amb_color,
		 vec3 diff_color,
		 vec3 spec_color,
		 float alpha,
		 float emit_alpha,
		 float rough,
		 float diff_rough,
		 float ior,
		 float metal,
		 float coat_intensity,
		 float coat_rough,
		 vec4 wire,
		 vec3  nN,
		 float z,
		 float selected,
		 int spec_model,
		 int coat_model)
{
	...

可以看到第一个参数就是颜色。实验将其换成一个固定的值,比如:
在这里插入图片描述
点击Apply应用此效果。
将会看到:
在这里插入图片描述
可以看到当前输出颜色的方式肯定是不符合预期的。至少输出的颜色不应该受光照的影响,即每个面的颜色肯定是一样的且不会随着视角的变化而变化。

确保无光照的影响

如何才能输出无光照影响的颜色呢?
HOUassignOutputs 为关键字在Houdini安装目录\houdini\glsl文件夹中搜索,正好可以看到一个输出无光照的范例:
在这里插入图片描述
仿照其写法,修改代码如下:
在这里插入图片描述
之后可以在 Smooth Shaded 模式下查看
在这里插入图片描述
此时的颜色可以看到各个面是完全一样的,且不受视角的变化而变化:
在这里插入图片描述
那么,当前的颜色就符合预期了吗?

确保无Gamma矫正的影响

可以截图在画图工具中吸取颜色查看其颜色值:
在这里插入图片描述
可以看到其颜色值是 (0,230,202)。然而,代码中的值是(0,0.8,0.6)对应了(0,204,153),和预期是不一样的。

那么是什么原因造成的呢?
不难想到是 Gamma矫正 的影响。
通过计算: 0.8 2.2 = 0.9035 \sqrt[2.2]{0.8}=0.9035 2.20.8 ?=0.9035,乘255后得到230。而 0.6 2.2 = 0.7928 \sqrt[2.2]{0.6}=0.7928 2.20.6 ?=0.7928,乘255后得到202。这样就验证了猜想。

因此,为了保证代码中的值准确输出到最后的颜色,要做的就是做个相反的运算,即 2.2 次方运算:

//测试颜色:
vec3 visiualize_color = vec3(0,0.8,0.6);

//移除Gamma矫正的影响:
visiualize_color.x = pow(visiualize_color.x,2.2);
visiualize_color.y = pow(visiualize_color.y,2.2);
visiualize_color.z = pow(visiualize_color.z,2.2);

// Write out the data to either the forward renderer framebuffer or the
// deferred framebuffer (glH_MaterialPass==1).
HOUassignOutputs(vec3(0.0),
                 visiualize_color,             // emission color only
                 ...

现在的颜色:
在这里插入图片描述
颜色值:
在这里插入图片描述
可以看到现在是完全准确的。

4. 输出法线到颜色

接下来就要考虑如何输出法线了。
可以在像素着色器的代码中看到,输入到像素着色器的顶点信息被放入fsIn中:
在这里插入图片描述
因此,首先就尝试将法线直接输出:

vec3 visiualize_color = fsIn.normal;

效果:
在这里插入图片描述
可以看到当前的颜色会随着视线变化而变化。这显然不符合预期的,我想要的是世界空间法线,一定是不和视线相关的。

接下来就是确保输入到这里的法线数据是世界空间。


先观察下法线相关的代码:
在这里插入图片描述
可以看到:

  • 法线的处理分为两种情况:pointvertex。由attrmodeN来区分。
  • 假如是 point,则使用顶点着色器中的法线,假如是 vertex ,则在几何着色器中使用texelFetch来取得(推测应该是取延迟渲染的Buffer)。
  • nxform函数定义也在几何着色器的代码中,操作也类似顶点着色器中的所做的对法线的矩阵转换:
vec3 nxform(vec3 n)
{
    return normalize(glH_NormalMatrix *
                     (glH_ObjectMatrix * vec4(n,0.0)).xyz);
}

因此,我尝试去掉这些矩阵转换:
在这里插入图片描述
就得到世界空间的法线了:
在这里插入图片描述

5. 映射到 0~1

由于法线三个轴向的范围都是 [-1,1]。这样负值都会变成黑色。为了尽量让颜色有区分,所以要将其映射到 0~1。
即:

//法线转颜色:
vec3 visiualize_color = (normalize(fsIn.normal)+vec3(1,1,1))/2;

现在,效果将都符合预期了,并且在 pointvertex 模式的法线都可以显示:
在这里插入图片描述
测试一个更复杂的几何体:
在这里插入图片描述

最终代码修改:

顶点着色器:
在这里插入图片描述
几何着色器:
在这里插入图片描述
像素着色器:
在这里插入图片描述

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-17 11:47:50  更:2022-01-17 11:48:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:51:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码