用unity surface shader 重新渲染dota2 模型

学习unity的surface shader中,先从角色的渲染搞起。

dota2的模型资源在

http://www.dota2.com/workshop/requirements 可以下载到

里面直接就有fbx的资源,还有材质的贴图。

直接导入unity工程就可以搞。dota2的模型有四张贴图,

 

 

先从简单的diffuse 贴图搞起,

直接上surface shader,和材质的结果:

Shader "Custom/actorDiffuse" {
    Properties {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf BasicDiffuse

        #pragma target 2.0

        sampler2D _MainTex;
        
        struct Input {
            float2 uv_MainTex;
            float3 viewDir;
        };
      
        inline float4 LightingBasicDiffuse(SurfaceOutput s, fixed3 lightDir, fixed atten)
        {
            float difLight = max(0, dot(s.Normal, lightDir));
            float4 col;
            
            col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
            col.a = s.Alpha;
            return col;
        }
        
        void surf (Input IN, inout SurfaceOutput o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

 

其实关键的shader就几个地方,surf function中

 fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
对diffuse 贴图采样,

然后采用diffuse的光照计算模型
float difLight = max(0, dot(s.Normal, lightDir));

float4 col;
            
col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);

这个atten 和 * 2,感觉是历史遗留问题。


然后是加入法线贴图:
Shader "Custom/actorDiffuseNormal" {
    Properties {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _NormalMap ("Normalmap", 2D) = "bump" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf BasicDiffuse

        #pragma target 2.0

        sampler2D _MainTex;
        sampler2D _NormalMap;
        
        struct Input {
            float2 uv_MainTex;
            float2 uv_NormalTex;
            float3 viewDir;
        };
      
        inline float4 LightingBasicDiffuse(SurfaceOutput s, fixed3 lightDir, fixed atten)
        {
            float difLight = max(0, dot(s.Normal, lightDir));
            float4 col;
            
            col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
            col.a = s.Alpha;
            return col;
        }
        
        void surf (Input IN, inout SurfaceOutput o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
            o.Normal = tex2D (_NormalMap, IN.uv_NormalTex);
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

关键的一句就是
 o.Normal = tex2D (_NormalMap, IN.uv_NormalTex);

就是法线的数据是直接从贴图上采样得到的


然后用mask2的贴图,做下specular,主要用了r和a两个通道
Shader "Custom/actorDiffuseMask" {
    Properties {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _NormalMap ("Normalmap", 2D) = "bump" {}
        _MaskMap ("Maskmap", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf BasicDiffuse

        #pragma target 2.0

        sampler2D _MainTex;
        sampler2D _NormalMap;
        sampler2D _MaskMap;

        struct Input {
            float2 uv_MainTex;
            float2 uv_NormalTex;
            float2 uv_MaskTex;
            float3 viewDir;
        };
      
        inline float4 LightingBasicDiffuse(SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
        {
            half3 h = normalize (lightDir + viewDir);
            float nh = max (0, dot (s.Normal, h));

            float difLight = max(0, dot(s.Normal, lightDir));
            float4 col;
            
            float spec = pow(nh, s.Specular);

            col.rgb = (s.Albedo * _LightColor0.rgb * difLight + _LightColor0.rgb * s.Gloss * spec );
            col.a = s.Alpha;
            return col;
        }
        
        void surf (Input IN, inout SurfaceOutput o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
            o.Normal = tex2D (_NormalMap, IN.uv_NormalTex);
            fixed4 mask = tex2D (_MaskMap, IN.uv_MaskTex);
            o.Specular = mask.a;
            o.Gloss = mask.r;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}


就是这样了,之后有时间再搞其他的材质。


posted @ 2015-11-05 18:02  被遗失De跳刀  阅读(1310)  评论(0编辑  收藏  举报