Gamebryo系列材质详解:四(一个最简单的VS)

总结上第三课的内容。写一个shader。我用gamebryo生成的写法。对应的hlsl或者cg的大家自己去google

1.首先确定VS中的入参,以及出参,还有寄存器中的东西。
讲下这里的内容:寄存中一般存储了世界矩阵,视矩阵,材质颜色,灯光等相关的环境信息。因为显卡寄存器的数量是有限的,而环境越多能做的变化也越多,所以这里要做一个权衡。到底需要什么样的效果,需要用到哪些寄存器都要事先估算好。
入参的一般是顶点的位置坐标信息。这个显然不能卸载寄存器里,因为顶点数量太多了。有些特殊的做法,比方在做Instancing的时候我们有时候会把顶点的变换信息存储到寄存器里。这以后再讨论。
先写一个简单的:(取自gamebryo自动生成的shader脚本)
程序代码 程序代码

/*
Shader description:
TRANSFORM = 0
OUTPUTWORLDPOS = 0
OUTPUTWORLDNBT = 0
OUTPUTWORLDVIEW = 0
OUTPUTTANGENTVIEW = 0
NORMAL = 0
SPECULAR = 0
FOGTYPE = 0
ENVMAPTYPE = 0
PROJLIGHTMAPCOUNT = 0
PROJLIGHTMAPTYPES = 0
PROJSHADOWMAPCOUNT = 0
PROJSHADOWMAPTYPES = 0
OUTPUTUVCOUNT = 1
UVSET00 = 0
UVSET00TEXOUTPUT = 0
UVSET01 = 0
UVSET01TEXOUTPUT = 0
UVSET02 = 0
UVSET02TEXOUTPUT = 0
UVSET03 = 0
UVSET03TEXOUTPUT = 0
UVSET04 = 0
UVSET04TEXOUTPUT = 0
UVSET05 = 0
UVSET05TEXOUTPUT = 0
UVSET06 = 0
UVSET06TEXOUTPUT = 0
UVSET07 = 0
UVSET07TEXOUTPUT = 0
UVSET08 = 0
UVSET08TEXOUTPUT = 0
UVSET09 = 0
UVSET09TEXOUTPUT = 0
UVSET10 = 0
UVSET10TEXOUTPUT = 0
UVSET11 = 0
UVSET11TEXOUTPUT = 0
POINTLIGHTCOUNT = 0
SPOTLIGHTCOUNT = 0
DIRLIGHTCOUNT = 0
VERTEXCOLORS = 0
VERTEXLIGHTSONLY = 1
AMBDIFFEMISSIVE = 0
LIGHTINGMODE = 1
APPLYMODE = 0
*/

//----------------------------------------------------------
// 常量寄存中中的变量(这里需要在引擎里每帧设置进去)
//----------------------------------------------------------

float4x4 g_World;
float4x4 g_ViewProj;

//----------------------------------------------------------
// 入参:我们定义一个结构叫Input来确定入参结构
//----------------------------------------------------------

struct Input
{
    float3 Position : POSITION0;
    float2 UVSet0 : TEXCOORD0;
};

//---------------------------------------------------------------------------
// Output:
//----------------------------------------------------------

struct Output
{
    float4 PosProjected : POSITION0;
    float2 UVSet0 : TEXCOORD0;
};

//----------------------------------------------------------
// 函数:这里是用到的一些函数,简单的主要写了上次提到的几个函数。都是关于坐标系转换
// 的,关于坐标系转换的更高级内容,请参阅我写的:番外篇
//----------------------------------------------------------

/*

    This fragment is responsible for applying the view projection transform
    to the input position. Additionally, this fragment applies the world
    transform to the input position.
    
*/

void TransformPosition(float3 Position,
    float4x4 World,
    out float4 WorldPos)
{

    // 用于灯光啊,projected space的转换,转换到世界坐标系下。
    WorldPos = mul( float4(Position, 1.0f), World );

}
//----------------------------------------------------------
/*

    This fragment is responsible for applying the view projection transform
    to the input world position.
    
*/

void ProjectPositionWorldToProj(float4 WorldPosition,
    float4x4 ViewProjection,
    out float4 ProjPos)
{

    ProjPos = mul(WorldPosition, ViewProjection);
    
}
//----------------------------------------------------------
//----------------------------------------------------------
// Main():这是VS的主函数,从这里入参被处理好了以后交给像素处理管线去处理
//----------------------------------------------------------

Output Main(Input In)
{
    Output Out;
// Function call #0  把局部坐标转化为世界坐标
    float4 WorldPos_CallOut0;
    TransformPosition(In.Position, g_World, WorldPos_CallOut0);

// Function call #1  把世界坐标转换为视坐标
    ProjectPositionWorldToProj(WorldPos_CallOut0, g_ViewProj, Out.PosProjected);

    // 这里是UV信息,不做任何处理,用于像素着色器
    Out.UVSet0 = In.UVSet0;
    return Out;
}
///////////////////////////////////////////////////////////////////////////////////////////

这个是最简单的gamebryo vertex shader。
总结一下,最后被我们忽视的两个东西,也是在我看来最重要的东西。1个是Shader description,全是大写字母的描述。有些是=0,有些是=1.
实际上这就是最早说的这个VS里预定义的特性。由于这个vs非常简单,所以大部分都是0。现在不理解也不要紧,以后会继续讲到。
再一个就是main函数。Main函数里的两个注视很有意思一个是Function call #0。Function call #1,其实就这就是生成好shader tree以后
顺着tree向下走的过程。 下一张将进入一个精彩的部分。gamebryo光照方程。



收藏到网摘:

[本日志由 volfmath 于 2010-07-28 10:52 PM 编辑]
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags:
相关日志:
评论: 0 | 引用: 0 | 查看次数: 295
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 关闭 | [img]标签 关闭