vertex shader(2)

一次只有一个vertex shader是活跃的。你可以有多个vertex shader,如果一个物体特殊的变换或者灯光,你可以选择合适的vertex shader来完成这个任务。

你可能想使用vertex shaders在每个物体或每个网格上,例如,十个网格,你可以使用十个不同的vertex shader,但那样可能会harm你的游戏的运行。

每个vertex shader-driven程序必须通过下面的步骤运行:

1。检查你的设备是否支持vertex shader。 (在direct X9以后已经不需要了)

2。用D3DVSD_* 宏声明vertex shader,用于将顶点缓冲(vertex buffer streams)映射(map)到输入寄存器(input register)。

3。用SetVertexShaderConstant()设置顶点着色器的常量寄存器。

4。用D3DXAssembleShader*()编译事先写的顶点着色器。

5。用CreateVertexShader()创建一个顶点着色器句柄。

6。用SetVertexShader()为一个要特效化的物体设置顶点着色器。

7。用DeleteVertexShader()删除顶点着色器。

由于第一步在directX 9以后就不需要了,所以这里省略它。

以下实现均对应于上述步骤。

---------------------------------------------------------------------------------------------------------------------------------------------------------------

2。声明顶点着色器。

在使用一个顶点着色器之前必须声明它。这个声明可以被称作一个静态的外部接口。

 1 float c[4] = {0.0f,0.5f,1.0f,2.0f};
 2 DWORD dwDesc10[] = {
 3    D3DVSD_STREAM(0),
 4    D3DVSD_REG(0,D3DVSDT_FLOAT3),    //input register v0
 5    D3DVSD_REG(5,D3DVSDT_D3DCOLOR),  //input register v5
 6
 7 // set a few constants
 8    D3DVSD_CONST(0,1),
 9    *(DWORD*)&c[0],
10    *(DWORD*)&c[1],
11    *(DWORD*)&c[2],
12    *(DWORD*)&c[3],
13    D3DVSD_END()
14 };

这个顶点着色器声明用D3DVSD_STREAM(0)设置数据流0。之后,通过使用这个声明,SetStreamSource()绑定一个顶点缓冲区到设备数据流。

你必须声明哪一个输入顶点属性或输入顶点数据被映射到哪一个输入寄存器。D3DVSD_REG从顶点流中绑定一个单个的顶点寄存器到一个顶点元素。在我们这个声明的例子中,D3DVSD_FLOAT3值应该被放在第一个输入寄存器,而D3DVSD_D3DCOLOR颜色值应该被放在第六个输入寄存器。例如,位置数据可以被输入寄存器0(v0)用D3DVSD_REG(0,D3DVSDT_FLOAT3)处理,法线数据可以被输入寄存器3(v3)用D3DVSD_REG(3,D3DVSDT_FLOAT3)处理。

注意,除非你想使用N-Patches,这需要位置数据在v0,法线数据在v3,否则,开发者可以自由定义顶点数据输入到的寄存器的映射。

相比之下,在固定管线中,顶点数据输入到特定寄存器的映射是固定的。

D3DVSD_CONST将常量值载入到顶点着色器的常量寄存器。第一个参数是常量数组开始填充数据的开始位置,可能的值范围是0-95(in the case of the RADEON 8500, from 0-191.)我们在0处开始。第二个参数是要载入的常量向量的数目,如果你要载入一个4x4矩阵(也就是4个向量),可以如下载入:

1 float c[16] = (0.0f, 0.5f, 1.0f, 2.0f,
2 0.0f, 0.5f, 1.0f, 2.0f,
3 0.0f, 0.5f, 1.0f, 2.0f,
4 0.0f, 0.5f, 1.0f, 2.0f);
5 D3DVSD_CONST(0, 4), *(DWORD*)&c[0],*(DWORD*)&c[1],*(DWORD*)&c[2],*(DWORD*)&c[3],
6 *(DWORD*)&c[4],*(DWORD*)&c[5],*(DWORD*)&c[6],*(DWORD*)&c[7],
7 *(DWORD*)&c[8],*(DWORD*)&c[9],*(DWORD*)&c[10],*(DWORD*)&c[11],
8 *(DWORD*)&c[12],*(DWORD*)&c[13],*(DWORD*)&c[14],*(DWORD*)&c[15],

D3DVSD_END生成一个END,标志顶点着色器的结束。

1 D3DVSD_END()

3。SetVertexShaderConstant() 设置顶点着色器常量寄存器

你可以用SetVertexShaderConstant()填充顶点着色器常量寄存器,用GetVertexShaderConstant()得到这些寄存器中的值。

SetVertexShaderConstant()的声明如下:

HRESULT SetVertexShaderConstant(
DWORD Register,
CONST void* pConstantData,
DWORD ConstantCount);

设置顶点着色器常量:

m_pd3dDevice->SetVertexShaderConstant( 0, &vZero, 1 );
m_pd3dDevice->SetVertexShaderConstant( 1, &vOne, 1 );
m_pd3dDevice->SetVertexShaderConstant( 2, &vWeight, 1 );
m_pd3dDevice->SetVertexShaderConstant( 4, &matTranspose, 4 );
m_pd3dDevice->SetVertexShaderConstant( 8, &matCameraTranspose, 4 );
m_pd3dDevice->SetVertexShaderConstant( 12, &matViewTranspose, 4 );
m_pd3dDevice->SetVertexShaderConstant( 20, &fLight, 1 );
m_pd3dDevice->SetVertexShaderConstant( 21, &fDiffuse, 1 );
m_pd3dDevice->SetVertexShaderConstant( 22, &fAmbient, 1 );
m_pd3dDevice->SetVertexShaderConstant( 23, &fFog, 1 );
m_pd3dDevice->SetVertexShaderConstant( 24, &fCaustics, 1 );
m_pd3dDevice->SetVertexShaderConstant( 28, &matProjTranspose, 4 );
  如之前所述,至少有96个常量寄存器可以被填充。SetVertexShaderConstant()第一个参数为寄存器的索引,最后一个参数为常量的数目。比如,matViewTranspose将被载入到寄存器12,载入数目为4个,寄存器16-19未被使用,fLight被载入到寄存器20,载入数目为1.

那么 ,用在着色器声明中的D3DVSD_CONST和SetVertexShaderConstant()有什么不同呢?D3DVSD_CONST只能是用仅仅一次,而SetVertexShaderConstant()可以在每次DrawPrimitive*()之前调用。待续.....
时间: 2024-11-11 08:10:32

vertex shader(2)的相关文章

【Shader实战】卡通风格的Shader(一)

写在前面 呜,其实很早就看到了这类Shader,实现方法很多,效果也有些许不一样.从这篇开始,陆续学习一下接触到的卡通类型Shader的编写. 本篇的最后效果如下(只有怪物和苹果部分): 本篇文章里指的卡通效果具有如下特点: 简化了模型中使用的颜色 简化光照,使模型具有明确的明暗区域 在模型边缘部分绘制轮廓(也就是描边) 我们再来回顾一下Unity Surface Shader的pipeline.(来源:Unity Gems) 由上图可以看出,我们一共有4个可修改渲染结果的机会(绿色方框中的代码

基于Cocos2d-x学习OpenGL ES 2.0系列——编写自己的shader(2)

在上篇文章中,我给大家介绍了如何在Cocos2d-x里面绘制一个三角形,当时我们使用的是Cocos2d-x引擎自带的shader和一些辅助函数.在本文中,我将演示一下如何编写自己的shader,同时,我们还会介绍VBO(顶点缓冲区对象)和VAO(顶点数组对象)的基本用法. 在编写自己的shader之前,我觉得有必要提一下OpenGL渲染管线. 理解OpenGL渲染管线,对于学习OpenGL非常重要.下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段) 此图是从wiki中拿过来的

OpenGL学习(3)——Shader(补)

完成章节后练习. 练习 1. Adjust the vertex shader so that the triangle is upside down. #version 330 core layout (location = 0) in vec3 Pos; layout (location = 1) in vec3 Col; out vec4 Color; void main() { gl_Position = vec4(Pos.x, -Pos.y, Pos.z, 1.0f); Color =

【Unity Shader实战】卡通风格的Shader(二)

写在前面 好久没写博客了,一定是因为课程作业比较多,一定不是因为我懒,恩恩. 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判断的,因此,对于那些平整的表面,它们的法线通常是一个常量或者会发生突变(例如立方体的每个面),这样就会导致最后的效果并非如我们所愿.如下图所示: 因此,我们有一个更好的方法来实现描边效果,也就是通过两个pass进行渲染--首先渲染对

三言两语说shader(九)钻石

这次的目标是绘制一颗闪闪发光的钻石,追求效果是越接近真实越好. 先说说为此我这几天干了些什么. 1.看了stalendp blog里那篇<钻石效果>后头的参考文献 最有价值的就是ATI在2004年GDC上作的演讲,题目就叫Drawing a Diamond.但是由于只有ppt,所以很难重现工程深入学习.思路大概是预备了一张折射CubeMap,一张带模拟色散的反射CubeMap,最后再加上耀斑混合而成. 2.试验了一些简单的镜面反射 非实时的CubeMap反射最简单没什么好说的,需要注意的是要做

(译)Minimal Shader(最小的着色器)

(原文:https://en.wikibooks.org/wiki/Cg_Programming/Unity/Minimal_Shader) This tutorial covers the basic steps to create a minimal Cg shader in Unity. 本节课包含了在Unity中创建一个最小的Cg着色器的基本步骤. Starting Unity and Creating a New Project(打开Unity创建一个新工程) After downlo

基于Cocos2d-x学习OpenGL ES 2.0系列——OpenGL ES渲染之Shader准备(7)

Cocos2d-x底层图形绘制是使用OpenGL ES协议的.OpenGL ES是什么呢? OpenGL ES(OpenGl for Embedded System)是OpenGL三维图形API的子集,针对手机.Pad和游戏主机等嵌入式设备而设计.该API由Khronos集团定义推广,Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准.OpenGL ES是OpenGL三维图形API的子集,针对手机.Pad和游戏主机等嵌入式设备而设计.Cocos2d-x底层图形渲染使

基于Cocos2d-x学习OpenGL ES 2.0系列——使用VBO索引(4)

在上一篇文章中,我们介绍了uniform和模型-视图-投影变换,相信大家对于OpenGL ES 2.0应该有一点感觉了.在这篇文章中,我们不再画三角形了,改为画四边形.下篇教程,我们就可以画立方体了,到时候就是真3D了. 为什么三角形在OpenGL教程里面这么受欢迎呢?因为在OpenGL的世界里面,所有的几何体都可以用三角形组合出来.我们的四边形也一样,它可以用两个三角形组合出来. 你的第一个四边形 首先,因为OpenGL里面没有直接绘制四边形的命令的,所以我们需要画两个三角形来拼成一个四边形.

Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0

管道 如前所属,本书讲解的API版本是OpenGL ES 3.0.本书的目标是,深入讲解OpenGL ES 3.0的技术细节,给出具体的例子来说明如何使用某个特性,并且讨论了各种性能优化技术.当您读完这本书,您应该可以对OpenGL ES 3.0API有一个很好的把握.您将可以轻松的写出让人新服的OpenGL ES 3.0的应用程序,并且您不必通过阅读多种OpenGL ES的规范来搞懂某个特性是如何工作的. OpenGL ES 3.0实现了可编程着色图形管道.OpenGL ES 3.0规范包含两