热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ShadersforGameProgrammersandArtists阅读笔记Chapter4

Chapter4学习第一个shader第一个Shader首先创建一个空的Effectgroup,右键该节点,导入一个Teapot模型,模

Chapter4 学习第一个shader

第一个Shader
首先创建一个空的Effect group ,右键该节点,导入一个Teapot模型,模型创建完成后你需要告诉RenderMonkey集合体信息如何发送到顶点着色器中,所以需要创建一个Stream Mapping 节点,创建后打开可以看到目前只有一个Position信息,对于这个Shader这些信息足够了。
在这里插入图片描述
对于这个简单的Shader我们还需要一个叫做View-projection matrix的矩阵,右键添加该变量到我们的效果中,这个矩阵用来将我们的模型的顶点数据由原本的物体空间转换到屏幕空间。
最后可以创建我们的渲染通道,右键效果添加通道,并删除其中的内容此时你的目录应该如下图所示
在这里插入图片描述
在渲染通道中首先需要添加模型和Stream mapping 的引用,右键通道将之前创建的模型和stream mapping引用到pass中,最后只需要添加顶点和像素着色器你的第一个shader就可以开始准备编写了,
首先你需要声明一个变量矩阵,View_proj_matrix来进行投影变换

float4x4 view_proj_matrix;

如果有其他的变量也需要在这个阶段声明,对于这个shader这个就足够了,接下来声明一个结构用来从顶点着色器向像素着色器传递顶点信息,这里我们只需要position信息就足够

struct VS_OUTPUT
{float 4 pos: POSITION;
}

这本质上是创建了一个名为pos的向量变量作为结构体的一部分。

shader的核心是进入点函数,比如进入点函数命名为vs_main,可以创建一个空函数作为顶点着色器的模板,函数的参数就是之前在Stream mapping 中定义的值,需要将其传入你的函数中,目前只需要position 数据。

VS_OUTPUT vs_main(float4 inPos:POSITION)
{VS_OUTPUT out;return Out;
}

输入参数inpos后面跟着语义声明POSITION,这告诉顶点着色器如何映射顶点流信息到这个输入参数上,请注意这个函数的返回值是VS_OUTPUT类型的参数,这个数据会从顶点着色器传输到像素着色器中在顶点着色器处理完成后,因为只是要将模型显示在视口,没有其他的效果,所以我们只需要将视口变换矩阵和模型POSITION相乘即可

Out.Pos = mul(view_proj_matrix,inPos);

这个顶点着色器将会把你的模型投射到屏幕空间中,并发送最后的信息到像素着色器中,最后顶点着色器部分完成的代码

float4x4 view_proj_matrix;struct VS_OUTPUT
{float4 Pos: POSITION;
};VS_OUTPUT vs_main(float4 inpos:POSITION,float4 innor:NORMAL)
{VS_OUTPUT Out;Out.Pos = mul(view_proj_matrix,inpos);return Out;
}

注意开头声明的view_proj_matrix和一开始你在workspace 中创建的视口投射矩阵的名称应该保持一致。

完成顶点着色器后打开之前创建的像素着色器窗口,看到默认的像素着色器代码

float4 ps_main( float4 inDiffuse:COLOR0) : COLOR0
{// Output constant color:float4 color;color[0] = color[3] = 1.0;color[1] = color[2] = 0.0;return color;
}

像素着色器的返回值是一个float4 的semantic COLOR0这定义了函数的最终返回的颜色值,另一个是函数的输入值 indiffsue的语义也是COLOR0,这映射了顶点着色器中的输出作为像素着色器的输入,我们刚才编写的顶点着色器并不包括COLOR0的输出所以在这里这个输入是多余的,所以最终你的像素着色器应为

float4 ps_main() : COLOR0
{// Output constant color:float4 color;color[0] = color[3] = 1.0;color[1] = color[2] = 0.0;return color;
}

现在第一个着色器就完成了点击编译,你会在预览窗口中看到一个红色的茶壶
在这里插入图片描述
为你的物体应用纹理
首先需要创建一个纹理,在效果上右键,添加纹理然后在通道中右键添加texture object 展开添加的texture object 右键引用之前导入的2dtexture,双击texture object节点可以打开texture的设置窗口,在这个shader中保持默认就好。

因为要将贴图映射到模型上,首先我们要在stream mapping中添加TEXCOORD通道,然后打开顶点着色器,在输出结构中添加纹理坐标的输出,同时在顶点着色器的主函数上添加坐标输入顶点着色器部分的代码完成后如下所示

float4x4 view_proj_matrix;struct VS_OUTPUT
{float4 Pos: POSITION;float2 Txrl: TEXCOORD0;
};VS_OUTPUT vs_main(
float4 inpos:POSITION,
float2 Txrl: TEXCOORD0
)
{VS_OUTPUT Out;//转换到屏幕空间Out.Pos = mul(view_proj_matrix,inpos);//传递纹理坐标Out.Txrl = Txrl;return Out;
}

然后打开像素着色器,首先需要声明一个sampler变量告诉像素着色器哪一张贴图会被调用

在像素着色器的参数输入中,加入坐标的输入 ,最后读取之前采样的纹理的像素使用tex2d函数,用输入的坐标作为读取纹理的坐标完成的像素着色器如下

sampler Texture0;float4 ps_main(
float2 inTxrl:TEXCOORD0
) : COLOR0
{return tex2D(Texture0,inTxrl);
}

添加更多模型
为了添加多个模型进入场景首先需要添加渲染通道,添加一个名为 Pass1的通道到效果中,复制之前通道的节点到新的通道中

此时第二个模型实际上已经渲染,但两个模型重叠,需要一个新的变量确定第二个模型的位置,在效果下新建一个变量名为teapot_position,xyz的值可以任意指定,只需要保持w分量的值为0。

打开pass1的顶点着色器,在开头声明之前创建的变量 teapot_position,最后用之前输入的position与该变量相加作为输出的POSTION调节teapot_position的值可以看到第二个茶壶已经被渲染,顶点着色器部分的代码如下所示

float4x4 view_proj_matrix;
float4 teapot_position;
struct VS_OUTPUT
{float4 Pos: POSITION;float2 Txrl: TEXCOORD0;
};VS_OUTPUT vs_main(
float4 inpos:POSITION,
float2 Txrl: TEXCOORD0
)
{VS_OUTPUT Out;//转换到屏幕空间inpos = inpos + teapot_position;Out.Pos = mul(view_proj_matrix,inpos);//传递纹理坐标Out.Txrl = Txrl;return Out;
}

推荐阅读
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
author-avatar
艾灸养生加盟
艾灸加盟热线:037761297867 15638966697(王经理) 18237761726(周经理)
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有