LiteralliJeff 发表于 2022-12-25 14:32

Unity Shader 转 3D Max

项目在进行角色Shader优化的时候,或多或少会涉及到模型法线的调整。法线通常在光照和视角计算,还有描边计算有着重要的影响。目前的做法是美术同学在max制作好角色模型,导入Unity后调试Shader,有些细微效果来回倒腾浪费时间。所以就有了将Unity Shader在Max中实现的需求。
Max 自定义Shader

Max中自定义Shader 是DirectX Shader。新建一个fx文件,一些结构跟Unity的ShaderLab有些区别,但是都是用的HLSL语法,所以只需了解变换结构即可。

[*]变换矩阵变化如下
//UNITY_MATRIX_MVP
float4x4 WvpXf : WorldViewProjection < string UIWidget = "None"; > ;

//unity_ObjectToWorld
float4x4 WorldXf : World < string UIWidget = "None"; > ;
//世界空间向量转换
float4x4 WorldITXf : WorldInverseTranspose < string UIWidget = "None"; > ;

//UNITY_MATRIX_MV
float4x4 WvXf : WorldView < string UIWidget = "None"; > ;
//View空间向量转换
float4x4 WvITXf : WorldViewInverseTranspose < string UIWidget = "None"; > ;

//UNITY_MATRIX_T_MV
float4x4 ViewIXf : ViewInverse < string UIWidget = "None"; > ;
//UNITY_MATRIX_IT_MV
float4x4 ViewITXf : ViewInverseTranspose < string UIWidget = "None"; > ;

//UNITY_MATRIX_V
float4x4 ViewXf : View < string UIWidget = "None"; > ;
//UNITY_MATRIX_P
float4x4 ProjectionXf : Projection < string UIWidget = "None"; > ;

float4x4 ProjInverse : ProjectionInverse < string UIWidget = "None"; > ;

[*]视角变量和灯光参数
//视角变量
WorldView = normalize(ViewIXf.xyz - Pw);
//灯光参数定义
float3 lightDir : Direction <
    string UIName = "Light Direction";
    string Object = "TargetLight";
    > = {-0.577, -0.577, 0.577};

[*]变量定义, 注意这里的纹理声明一定要指定Texcoord和MapChannel, 同时纹理需要声明采样器:
/// Point Lamp 0 ////////////
float3 lightDir : Direction <
    string UIName = "Light Direction";
    string Object = "TargetLight";
    > = {-0.577, -0.577, 0.577};

/// Base
Texture2D <float4> _BaseMap <
    string UIName = "Base Map";
    string ResourceType = "2D";
    int Texcoord = 0;
    int MapChannel = 1;
>;
float4 _BaseColor<
    string UIName = "_BaseColor";
    string UIWidget = "Color";
> = float4( 1.0f, 1.0f, 1.0f, 1.0f );   

float _HighLightScale <
    string UIName = "High Light Scale";
    string UIWidget = "slider";
    float UIMin = 0.0f;
    float UIMax = 2.0f;
    float UIStep = 0.01f;
>   = 1.0f;`
纹理采样器:
`SamplerState _BaseMapSampler
{
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};

[*]声明顶点shader和片元shader,这点和Unity ShaderLab几乎一致
/* data from application vertex buffer */
struct appdata {
    float4 vertex       : POSITION;
    float4 normal       : NORMAL;
    float4 uv       : TEXCOORD0;   
    float3 color      : COLOR;
};

/* data passed from vertex shader to pixel shader */
struct v2f {
    float4 positionCS   : SV_Position;
    float4 uv       : TEXCOORD0;
    float3 color    : TEXCOORD1;
};

v2f std_VS(appdata v) {
    v2f o = (v2f)0;
    o.uv = v.uv;
    o.color = v.color;
    o.positionCS = mul(Po,WvpXf);
    return o;
}

///////// PIXEL SHADING //////////////////////

float4 std_PS(v2f i) : SV_Target {
    float4 baseColor = _BaseMap.Sample(_BaseMapSampler, i.uv.xy);
    float4 col = float4(baseColor.rgb, 1) * _BaseColor;
    return col;   
}

[*]设置调用函数,这里指定裁剪,深度测试等效果
RasterizerState RS_CullBack
{
    FillMode = SOLID;
    CullMode = Back;
    FrontCounterClockwise = false;
};

DepthStencilState Depth
{
    DepthEnable = TRUE;
    DepthFunc = 4;//LESSEQUAL
    DepthWriteMask = ALL;
};

fxgroup dx11
{
technique11 Main_11 <
    string Script = "Pass=p0;";
> {
    pass p0 < string Script = "Draw=geometry;"; >
    {
      SetRasterizerState(RS_CullBack);
      SetDepthStencilState( Depth, 0 );   
      SetVertexShader(CompileShader(vs_5_0,std_VS()));
      SetGeometryShader( NULL );
      SetPixelShader(CompileShader(ps_5_0,std_PS()));
    }

}
}
fxgroup dx10
{
technique10 Main_10 <
    string Script = "Pass=p0;";
> {
    pass p0 <
    string Script = "Draw=geometry;";
    >
    {
      SetRasterizerState(RS_CullBack);
      SetDepthStencilState( Depth, 0 );   
      SetVertexShader(CompileShader(vs_4_0,std_VS()));
      SetGeometryShader( NULL );
      SetPixelShader(CompileShader(ps_4_0,std_PS()));
    }

}

[*] Max 中点击材质球编辑器, 点击如下采样笔选择视图模型,获取当前模型的材质球。 !(Unity Shader 转 3D Max.resources/A79AB964-E7C4-452F-9973-C44D809D1C9F.png)
[*] 编辑器中选择材质类型 DirectX Shader,!(Unity Shader 转 3D Max.resources/0000BE4A-9230-4DB8-8032-4E841D69F68F.png)
[*] 指定我们刚刚写的shader, 同时调试参数即可: !(Unity Shader 转 3D Max.resources/EE63702A-030B-4EC9-B5B6-EC2F85F02E41.png)
页: [1]
查看完整版本: Unity Shader 转 3D Max