MME编写入门(三)一个最简单的着色
小林呓
2023年03月06日 22:10
收录于文集
共8篇

从一个最简单的着色器入手。

代码块
clike
自动换行
复制代码
float4 outColor = float4(0,0,0,1);
//此处为UI配置处,我定义了一个outColor,这里的值暂时为黑色,即RGB为000

float4x4 WorldViewProjMatrix      : WORLDVIEWPROJECTION;
//引入最长的那个转换矩阵,用于转换顶点坐标
struct VS_OUTPUT
{
	float4 Pos			: POSITION;
};
//传入结构体,将所需要的数据传入,目前仅仅需要位置
//下面是顶点着色器,我给他命名为 First_VS 
VS_OUTPUT First_VS(float4 Pos : POSITION)
{
    VS_OUTPUT Out = (VS_OUTPUT)0;
    Out.Pos 	= mul(Pos,WorldViewProjMatrix);
   //将位置信息的齐次坐标 和 世界视察投影变换矩阵 相乘
    return Out;
}
//下面是像素着色器
float4 First_PS(VS_OUTPUT IN) : COLOR0
{
	return outColor;
}
//下面是绘制
technique FirstMainPass_SS  < string MMDPass = "object_ss"; > {
    pass DrawObject {
        VertexShader = compile vs_2_0 First_VS();
        PixelShader  = compile ps_2_0 First_PS();
    }
}

technique EdgeTec < string MMDPass = "edge"; > {
}
复制成功

第一次看的话想必会有不少的疑问。不过耐下心来细细地去拆解就明白了,如果有c语言或者c++的学习经历,那么会更容易许多。

一个完整的效果文件,它是由 UI配置项、转换矩阵、结构体、顶点着色器、像素着色器、technique-pass绘制构成。其中,UI配置项可以有也可以没有,有的目的只是为了好修改其中的一些参数。

代码块
clike
自动换行
复制代码
float4 outColor = float4(0,0,0,1);
复制成功

首先是这里,定义了一个四维向量outColor,他的值为0,0,0,1,分别对应着R\G\B\A,A是透明度,这里就显示为黑色。1,0,0,1就是红色,其他同理。

对于向量类型,最多有四个元素,可以通过xyzw(位置向量)或rgba(颜色向量)来访问,这两种访问方式是等效的,但是不能混着用。

代码块
clike
自动换行
复制代码
float4x4 WorldViewProjMatrix      : WORLDVIEWPROJECTION;
复制成功

然后是转换矩阵,这里只用到了这个WORLDVIEWPROJECTION。

前边的WorldViewProjMatrix可以随便起名字,但冒号后边的语义不可以乱写。

然后是结构体。

代码块
clike
自动换行
复制代码
struct VS_OUTPUT
{
	float4 Pos			: POSITION;
};
复制成功

结构体就是把散乱的数据整理到一起,便于管理和使用。

我们需要物体的齐次坐标。

这个特殊的冒号语法表示一个语义,冒号后面的标志符用来指定变量的用途。

POSITION标志符表明该变量表示顶点位置,另外还有诸如COLOR、NORMAL等很多表示其他意义的标志符。

  • 语义是附加到着色器输入或输出的字符串,用于传达有关参数预期使用的信息。 着色器阶段之间传递的所有变量都需要语义。

代码块
clike
自动换行
复制代码
VS_OUTPUT First_VS(float4 Pos : POSITION)
{
    VS_OUTPUT Out = (VS_OUTPUT)0;
    Out.Pos 	= mul(Pos,WorldViewProjMatrix);
    return Out;
}
复制成功

接着,顶点着色器 从结构体中得到需要的数据。

VS_OUTPUT Out = (VS_OUTPUT)0;

这一行的作用初始化定义Out输出。

也可以这么写 VS_OUTPUT Out;

Out.Pos = mul(Pos,WorldViewProjMatrix);

对我们的顶点坐标和WVPMatrix相乘,完成顶点的世界观察投影变换。

return Out;

输出变换后的顶点信息。

代码块
clike
自动换行
复制代码
float4 First_PS(VS_OUTPUT IN) : COLOR0
{
	return outColor;
}
复制成功

接下来是像素着色器。

return outColor,在此之前我们已经定义过颜色。

代码块
clike
自动换行
复制代码
technique FirstMainPass_SS  < string MMDPass = "object_ss"; > {
    pass DrawObject {
        VertexShader = compile vs_2_0 First_VS();
        PixelShader  = compile ps_2_0 First_PS();
    }
}
复制成功

接下来的是绘制。

代码块
clike
自动换行
复制代码
technique EdgeTec < string MMDPass = "edge"; > {
}
复制成功

最后一行是我额外加上去的。完成之后,就得到了一个全黑的miku!

关于对象绘制有两种,舞力介入P在basic.fx ver2.0中是分为两种。

一种是セルフシャドウOFF,自阴影OFF。

一种是セルフシャドウON,自阴影ON。

自阴影就是模型的这里。

如果单纯的用一次pass,而且这个pass没有_ss,模型还开启了本影,那么就绘制不了。

比如这里,我把_ss删掉了。全黑miku没有了……

有的模型存在轮廓线,可以选择改变大小和颜色,大小为0的时候就关闭了轮廓线。

(注意,要在模型的模式下才能选择轮廓线)

如果删掉这一指令

technique EdgeTec < string MMDPass = "edge&#​34;; > {

}

那么轮廓线就无法正常绘制。就会变成这样。

这么写相当于不绘制轮廓线。

也可以这么写。

代码块
clike
自动换行
复制代码
technique EdgeTec < string MMDPass = "edge"; > {
    pass DrawObject {
        VertexShader = compile vs_2_0 First_VS();
        PixelShader  = compile ps_2_0 First_PS();
    }
}
复制成功

关于MME,我还只是初学者,慢慢学习吧。