【MME编写入门】光照模型

发布时间 2023-11-01 12:45:07作者: 小林呓
float4x4 WorldViewMatrix        : WORLDVIEW;
float4x4 WorldViewProjMatrix    : WORLDVIEWPROJECTION;
float4x4 WorldMatrix            : WORLD;
//需要用到的矩阵
//需要用到光的位置、相机位置
float3   LightDirection    : DIRECTION < string Object = "Light"; >;
float3   CameraPosition    : POSITION  < string Object = "Camera"; >;

//需要用到物体的材质色
//漫反射、环境色、自发光色、镜面反射色
float4   MaterialDiffuse   : DIFFUSE  < string Object = "Geometry"; >;
float3   MaterialAmbient   : AMBIENT  < string Object = "Geometry"; >;
float3   MaterialEmmisive    : EMISSIVE    < string Object = "Geometry"; >;
float3   MaterialSpecular    : SPECULAR    < string Object = "Geometry"; >;
//镜面反射强度、toon色
float    SpecularPower        : SPECULARPOWER < string Object = "Geometry"; >;
float3   MaterialToon      : TOONCOLOR;
//需要的光源颜色,取三份,方便下面计算
float3   LightDiffuse      : DIFFUSE   < string Object = "Light"; >;
float3   LightAmbient      : AMBIENT   < string Object = "Light"; >;
float3   LightSpecular     : SPECULAR  < string Object = "Light"; >;
//计算漫反射颜色、环境色颜色、镜面反射颜色
static float4 DiffuseColor  = MaterialDiffuse  * float4(LightDiffuse, 1.0f);
static float3 AmbientColor  = saturate(MaterialAmbient  * LightAmbient + MaterialEmmisive);
static float3 SpecularColor = MaterialSpecular * LightSpecular;
//先定义,后面调用
bool UseTexture;
bool UseToon ;
//材质纹理和采样器
texture ObjectTexture: MATERIALTEXTURE;
sampler ObjTexSampler = sampler_state {
    texture = <ObjectTexture>;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
    ADDRESSU  = WRAP;
    ADDRESSV  = WRAP;
};
//结构体,准备需要的数据
struct VS_OUTPUT
{
    float4 Pos        : POSITION;
    float2 Tex        : TEXCOORD1;
    float3 Normal      : TEXCOORD2;
    float3 Eye        : TEXCOORD3;
};
//顶点着色器部分
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
//这里把pos另存了一份
    float4 Pos0 = Pos;
//位置变换
    Pos = mul( Pos, WorldViewProjMatrix );
//视线位置变换
    float3 Eye = CameraPosition - mul( Pos0, WorldMatrix );
//顶点法线
    Normal = normalize( mul( Normal, WorldMatrix ) );
//输出
    VS_OUTPUT Out = { Pos, Tex, Normal, Eye };
    return Out;
}

//像素着色器部分
float4 Basic_PS( float2 Tex : TEXCOORD1, float3 Normal : TEXCOORD2, float3 Eye : TEXCOORD3 ) : COLOR0
{
    float4 Color = 0;
//漫反射和环境色计算
    Color.rgb = saturate( max(0,dot( Normal, -LightDirection )) * DiffuseColor.rgb + AmbientColor );
    Color.a = DiffuseColor.a;
//镜面反射计算
    float3 HalfVector = normalize( normalize(Eye) + -LightDirection );
    float3 Specular = pow( max(0,dot( normalize(Normal),HalfVector )), SpecularPower ) * SpecularColor;
 //纹理应用
    Color *= tex2D( ObjTexSampler, Tex );
 //TOON应用
    if (UseTexture = true) {
        float LightNormal = dot(Normal,-LightDirection);
        Color.rgb *= lerp(MaterialToon, float3(1,1,1), saturate(LightNormal * 16 + 0.5));
    }
//镜面反射色加入
    Color.rgb += Specular;
//最终输出
    return Color;
}

//绘制
technique BasicLight < string MMDPass = "object_ss"; > {
    pass DrawObject
    {
        VertexShader = compile vs_2_0 Basic_VS();
        PixelShader  = compile ps_2_0 Basic_PS();
    }
} 

 

语义参考MME手册……实在是懒得搬了……

这个模型是用的bling-phong的那一套半程向量计算的,具体的在原文里有捋顺过一遍思路

原文地址https://www.bilibili.com/read/cv22301522

mme中文参考手册https://zhuanlan.zhihu.com/p/147320030