赞
踩
注意点:
1.法线的归一化 normalize (如果shader光照效果怪怪的,请查看是否归一化)
2.在计算自发光emission 直接使用的normal : appdata 中的normal 转到世界空间中的normal。emission跟光照没有关系,不受光照的影响(不是所有的地方都有自发光:添加emissionMask)
3.在计算直接光照效果 diffuse 和specular的时候, 用切线空间转换到世界空间中的法线
4.AO贴图: 只作用在 间接光照中 : Indirectlight中的 diffuse 和specular
用AO来限制他们的亮度
5.用一张图的 rgba四个通道来存储相应的遮罩等值
下面是实现代码:
Shader "FishMan/12_AOE" { Properties { _MainTex ("Texture", 2D) = "white" {} _BumpMap ("Normal Map", 2D) = "bump"{} _Metallic_AO_MASK_Smoothness("_Metallic_AO_MASK_Smoothness", 2D) = "white" {} [HDR]_FresnelColor("FresnelColor", Color) = (0,0,0,0) _FresnelPower("FresnelPower", Range( 0 , 30)) = 0.8 _FresnelScale("FresnelScale", Range( 0 , 1)) = 1 } SubShader { Pass { Tags { "RenderType"="Opaque" "LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #define _FORWADR_BASE #pragma multi_compile_fwdbase #pragma multi_compile_fog #include "../ExampleLibs/12_AOEimission.cginc" ENDCG } Pass { Tags { "RenderType"="Opaque" "LightMode" = "ForwardAdd" } Blend One One ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdadd #pragma multi_compile_fog #pragma target 3.0 #include "../ExampleLibs/12_AOEimission.cginc" ENDCG } Pass { Tags {"LightMode"="ShadowCaster"} CGPROGRAM #pragma vertex vertShadowCaster #pragma fragment fragShadowCaster #pragma multi_compile_shadowcaster #include "../../ShaderLibs/Shadow.cginc" ENDCG } } }
#ifndef FMST02_AO_EIMISSION #define FMST02_AO_EIMISSION #include "UnityCG.cginc" #include "UnityPBSLighting.cginc" // PBS #include "AutoLight.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; float4 tangent : TANGENT; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 normal : TEXCOORD1; float3 worldPos: TEXCOORD2; #if defined(VERTEXLIGHT_ON) float3 vertexLightColor : TEXCOORD3; #endif SHADOW_COORDS(4) UNITY_FOG_COORDS(5) // 8 float3 T2WRow0 : TEXCOORD6; float3 T2WRow1 : TEXCOORD7; float3 T2WRow2 : TEXCOORD8; }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _BumpMap; sampler2D _Metallic_AO_MASK_Smoothness; float4 _FresnelColor; float _FresnelScale; float _FresnelPower; UnityLight CreateDirectLight(v2f i){ float3 lightDir; // float attenuation = 1; #if defined(DIRECTIONAL) lightDir = _WorldSpaceLightPos0.xyz; #else float3 lightVec= _WorldSpaceLightPos0.xyz - i.worldPos; lightDir = normalize(lightVec); #endif UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos); UnityLight light; light.color = _LightColor0.rgb * attenuation; light.dir = lightDir; light.ndotl = saturate(dot(lightDir,i.normal)); return light; } UnityIndirect CreateIndirectLight (v2f i) { UnityIndirect indirectLight; indirectLight.diffuse = 0; indirectLight.specular = 0; #if defined(VERTEXLIGHT_ON) indirectLight.diffuse = i.vertexLightColor; #endif #if defined(_FORWADR_BASE) indirectLight.diffuse += max(0, ShadeSH9(float4(i.normal, 1))); #endif return indirectLight; } void CalcVertexLightColor(inout v2f i){ #if defined(VERTEXLIGHT_ON) i.vertexLightColor = Shade4PointLights( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, unity_4LightAtten0, i.worldPos, i.normal ); #endif } v2f vert (appdata v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f,o); o.pos = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.normal = UnityObjectToWorldNormal(v.normal) ; o.worldPos = mul(unity_ObjectToWorld, v.vertex); CalcVertexLightColor(o); TRANSFER_SHADOW(o) UNITY_TRANSFER_FOG(o,o.pos); fixed3 worldNormal = o.normal; fixed3 worldTangent = UnityObjectToWorldDir( v.tangent.xyz ); fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w; fixed3 worldBinormal = cross( worldNormal, worldTangent ) * tangentSign; o.T2WRow0 = float3( worldTangent.x, worldBinormal.x, worldNormal.x); // * tNormal.xyz o.T2WRow1 = float3( worldTangent.y, worldBinormal.y, worldNormal.y); o.T2WRow2 = float3( worldTangent.z, worldBinormal.z, worldNormal.z); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 albedo = tex2D(_MainTex, i.uv); float3 normalVal = UnpackNormal( tex2D(_BumpMap,i.uv)); fixed4 metallic_AO_MASK_Smoothness = tex2D(_Metallic_AO_MASK_Smoothness, i.uv); float metallic = metallic_AO_MASK_Smoothness.r; float smoothness = metallic_AO_MASK_Smoothness.a; float occlusion = metallic_AO_MASK_Smoothness.g ; float3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos); #if defined(_FORWADR_BASE) float emissionMask = metallic_AO_MASK_Smoothness.b; float ndv = dot( normalize(i.normal), viewDir ); float fresnel = pow(1 - ndv,_FresnelPower) * _FresnelScale ; float4 emission = fresnel * emissionMask * _FresnelColor; #endif i.normal = fixed3(dot(i.T2WRow0,normalVal), dot(i.T2WRow1,normalVal), dot(i.T2WRow2,normalVal)); i.normal = normalize(i.normal); float oneMinusReflectivity ; float3 specularTint; albedo.rgb = DiffuseAndSpecularFromMetallic(albedo,metallic,specularTint,oneMinusReflectivity); UnityLight light = CreateDirectLight(i); UnityIndirect indirectLight = CreateIndirectLight(i); indirectLight.diffuse *= occlusion; indirectLight.specular *= occlusion; //light.color *= occlusion; float4 col = UNITY_BRDF_PBS(albedo,specularTint,oneMinusReflectivity,smoothness, i.normal,viewDir, light,indirectLight ); UNITY_APPLY_FOG(i.fogCoord, col); #if defined(_FORWADR_BASE) col += emission; #endif return col; } #endif
附资源百度云:
链接: https://pan.baidu.com/s/1UdDCnt6uEfhy5IPNnEam5g
提取码: 9b6s
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。