Gamebryo系列材质详解:四(一个最简单的VS)
作者:volfmath 日期:2010-06-30
总结上第三课的内容。写一个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光照方程。
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光照方程。
评论: 0 | 引用: 0 | 查看次数: 295
发表评论
上一篇
下一篇

文章来自:
Tags: 





![Validate my RSS feed [Valid RSS]](valid-rss.png)
![Validate my Atom 1.0 feed [Valid Atom 1.0]](valid-atom.png)
