Shader "Shader/OldschoolPlus"
{
Properties
{
[Header(Texture)] //面板需要的参数
_MainTex ("color texture", 2D) = "white"{}
_NormTex ("normal texture",2D) = "bump" {}
_SpecTex ("specular texture", 2D) = "gray" {}
_Cubemap ("cubemap",cube) = "_Skybox" {}
[Header(Diffuse)]
_MainCol ("main color", color) = (0.5, 0.5, 0.5, 1.0)
_EnvDiffInt("diffuse intense", Range(0,1)) = 0.2
_EnvUpCol ("up color", Color) = (1.0, 1.0, 1.0, 1.0)
_EnvSideCol ("sude color", Color) = (0.5, 0.5, 0.5, 1.0)
_EnvDownCol ("ground color", Color) = (0.0, 0.0, 0.0, 0.0)
[Header(Specular)]
_SpecPow ("specular power", Range(1, 90)) = 30
_FresnelPow("FresnelPow",Range(0,10)) = 1
_EnvSpecInt("EnvSpecInt",Range(0,5)) = 1
_CubemapMip ("cubemap Mip", Range(1, 7)) = 1
}
SubShader
{
Tags {
"RenderType"="Opaque"
}
Pass
{
Name "FORWARD"
Tags {
"LightMode"="ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// 追加投影相关包含文件
#include "AutoLight.cginc"
#include "Lighting.cginc"
#pragma multi_compile_fwdbase_fullshadows
#pragma target 3.0
uniform sampler2D _MainTex;
uniform sampler2D _NormTex;
uniform sampler2D _SpecTex;
uniform samplerCUBE _Cubemap;
uniform float3 _MainCol;
uniform float _EnvDiffInt;
uniform float3 _EnvUpCol;
uniform float3 _EnvSideCol;
uniform float3 _EnvDownCol;
uniform float _SpecPow;
uniform float _FresnelPow;
uniform float _EnvSpecInt;
uniform float _CubemapMip;
struct vertexInput
{
float4 vertex : POSITION;
float4 normal : NORMAL;
float2 uv0 : TEXCOORD0;
float4 tangent : TANGENT; //切线信息
};
struct vertexOutput
{
float4 pos :SV_POSITION; //注意!此处必须命名为pos,需要和Unity封装好的方法的参数对应
float4 posWS : TEXCOORD0;
float3 nDirWS : TEXCOORD1;
float3 tDirWS : TEXCOORD2;
float3 bDirWS : TEXCOORD3; //世界副切线方向
float2 uv : TEXCOORD4;
LIGHTING_COORDS(5,6)
};
vertexOutput vert (vertexInput v)
{
vertexOutput o = (vertexOutput)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.posWS = mul(unity_ObjectToWorld, v.vertex);
o.nDirWS = UnityObjectToWorldNormal(v.normal);
o.uv = v.uv0;
o.tDirWS = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz,0.0)).xyz);
o.bDirWS = normalize(cross(o.nDirWS, o.tDirWS) * v.tangent.w);//切线和法线方向叉乘
TRANSFER_VERTEX_TO_FRAGMENT(o)
return o;
}
fixed4 frag (vertexOutput i) : SV_Target
{
// 准备向量
float3 nDirTS = UnpackNormal(tex2D(_NormTex, i.uv)).rgb;
float3x3 TBN = float3x3(i.tDirWS, i.bDirWS, i.nDirWS);
float3 nDirWS = normalize(mul(nDirTS, TBN));
float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWS.xyz);
float3 vrDirWS = reflect(-vDirWS, nDirWS);
float3 lDirWS = _WorldSpaceLightPos0.xyz;
float3 lrDirWS = reflect(-lDirWS, nDirWS);
// 准备点积结果
float ndotl = dot(nDirWS, lDirWS);
float vdotr = dot(vDirWS, lrDirWS);
float vdotn = dot(vDirWS, nDirWS);
// 采样纹理
float4 var_MainTex = tex2D(_MainTex, i.uv);
float4 var_SpecTex = tex2D(_SpecTex, i.uv);
float3 var_Cubemap = texCUBElod(_Cubemap, float4(vrDirWS, lerp(_CubemapMip, 0.0, var_SpecTex.a))).rgb;
//随着var_SpecTex.a的值cubemap的mip值在0到给定的_CubemapMip之间变化,如果var_SpecTex.a=0,那就是_CubemapMip,var_SpecTex.a=1,那就是0
//直接光照
float3 baseCol = var_MainTex.rgb * _MainCol;
float3 lambert = max(0.0, ndotl);
float specCol = var_SpecTex.rgb;
float specPow = lerp(1, _SpecPow, var_SpecTex.a);
float phong = pow(max(0.0, vdotr),specPow);
float shadow = LIGHT_ATTENUATION(i);
float3 dirLighting = (baseCol * lambert + specCol * phong) * _LightColor0 * shadow;
//环境光照
float upMask = max(0.0, nDirWS.g); // 获取朝上部分遮罩
float downMask = max(0.0, -nDirWS.g); // 获取朝下部分遮罩
float sideMask = 1.0 - upMask - downMask; // 获取侧面部分遮罩
float3 envCol = _EnvUpCol * upMask +
_EnvSideCol * sideMask +
_EnvDownCol * downMask; // 混合环境色
float fresnel = pow(max(0.0, 1.0 - vdotn), _FresnelPow); // 菲涅尔
float occlusion = var_MainTex.a;
float3 envLighting = (baseCol * envCol * _EnvDiffInt + var_Cubemap * fresnel * _EnvSpecInt * var_SpecTex.a) * occlusion;
// 返回结果
float3 finalRGB = dirLighting + envLighting;
return float4(finalRGB, 1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}