diff options
author | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
commit | b82da95b5181ac8bbae38efb13e950d5e88a4caa (patch) | |
tree | 48a6f3269276484bbc7cfc95f0651f40a2176aa1 /Assets/ThirdParty/MaterializeFX/Shaders/Standart/UnityStandardCore.cginc | |
parent | 917e9e0b320775634dc2e710f7deac74fd0822f0 (diff) |
*移动amplify shader editor到third party目录
Diffstat (limited to 'Assets/ThirdParty/MaterializeFX/Shaders/Standart/UnityStandardCore.cginc')
-rw-r--r-- | Assets/ThirdParty/MaterializeFX/Shaders/Standart/UnityStandardCore.cginc | 780 |
1 files changed, 780 insertions, 0 deletions
diff --git a/Assets/ThirdParty/MaterializeFX/Shaders/Standart/UnityStandardCore.cginc b/Assets/ThirdParty/MaterializeFX/Shaders/Standart/UnityStandardCore.cginc new file mode 100644 index 00000000..1db6fa6c --- /dev/null +++ b/Assets/ThirdParty/MaterializeFX/Shaders/Standart/UnityStandardCore.cginc @@ -0,0 +1,780 @@ +// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
+
+#ifndef UNITY_STANDARD_CORE_INCLUDED
+#define UNITY_STANDARD_CORE_INCLUDED
+
+#include "UnityCG.cginc"
+#include "UnityShaderVariables.cginc"
+#include "UnityInstancing.cginc"
+#include "UnityStandardConfig.cginc"
+#include "UnityStandardInput.cginc"
+#include "UnityPBSLighting.cginc"
+#include "UnityStandardUtils.cginc"
+#include "UnityGBuffer.cginc"
+#include "UnityStandardBRDF.cginc"
+#include "AutoLight.cginc"
+
+//MFX
+#include "Assets/MaterializeFX/Shaders/cginc/MFX.cginc"
+
+//-------------------------------------------------------------------------------------
+// counterpart for NormalizePerPixelNormal
+// skips normalization per-vertex and expects normalization to happen per-pixel
+half3 NormalizePerVertexNormal (float3 n) // takes float to avoid overflow
+{
+ #if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
+ return normalize(n);
+ #else
+ return n; // will normalize per-pixel instead
+ #endif
+}
+
+half3 NormalizePerPixelNormal (half3 n)
+{
+ #if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
+ return n;
+ #else
+ return normalize(n);
+ #endif
+}
+
+//-------------------------------------------------------------------------------------
+UnityLight MainLight ()
+{
+ UnityLight l;
+
+ l.color = _LightColor0.rgb;
+ l.dir = _WorldSpaceLightPos0.xyz;
+ return l;
+}
+
+UnityLight AdditiveLight (half3 lightDir, half atten)
+{
+ UnityLight l;
+
+ l.color = _LightColor0.rgb;
+ l.dir = lightDir;
+ #ifndef USING_DIRECTIONAL_LIGHT
+ l.dir = NormalizePerPixelNormal(l.dir);
+ #endif
+
+ // shadow the light
+ l.color *= atten;
+ return l;
+}
+
+UnityLight DummyLight ()
+{
+ UnityLight l;
+ l.color = 0;
+ l.dir = half3 (0,1,0);
+ return l;
+}
+
+UnityIndirect ZeroIndirect ()
+{
+ UnityIndirect ind;
+ ind.diffuse = 0;
+ ind.specular = 0;
+ return ind;
+}
+
+//-------------------------------------------------------------------------------------
+// Common fragment setup
+
+// deprecated
+half3 WorldNormal(half4 tan2world[3])
+{
+ return normalize(tan2world[2].xyz);
+}
+
+// deprecated
+#ifdef _TANGENT_TO_WORLD
+ half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3])
+ {
+ half3 t = tan2world[0].xyz;
+ half3 b = tan2world[1].xyz;
+ half3 n = tan2world[2].xyz;
+
+ #if UNITY_TANGENT_ORTHONORMALIZE
+ n = NormalizePerPixelNormal(n);
+
+ // ortho-normalize Tangent
+ t = normalize (t - n * dot(t, n));
+
+ // recalculate Binormal
+ half3 newB = cross(n, t);
+ b = newB * sign (dot (newB, b));
+ #endif
+
+ return half3x3(t, b, n);
+ }
+#else
+ half3x3 ExtractTangentToWorldPerPixel(half4 tan2world[3])
+ {
+ return half3x3(0,0,0,0,0,0,0,0,0);
+ }
+#endif
+
+half3 PerPixelWorldNormal(float4 i_tex, float4 mfxUv, half4 tangentToWorld[3], float3 mfxVertexPos)
+{
+#ifdef _NORMALMAP
+ half3 tangent = tangentToWorld[0].xyz;
+ half3 binormal = tangentToWorld[1].xyz;
+ half3 normal = tangentToWorld[2].xyz;
+
+ #if UNITY_TANGENT_ORTHONORMALIZE
+ normal = NormalizePerPixelNormal(normal);
+
+ // ortho-normalize Tangent
+ tangent = normalize (tangent - normal * dot(tangent, normal));
+
+ // recalculate Binormal
+ half3 newB = cross(normal, tangent);
+ binormal = newB * sign (dot (newB, binormal));
+ #endif
+
+ half3 normalTangent = NormalInTangentSpace(i_tex);
+ normalTangent = GetMfxNormal(i_tex.xy, mfxUv, mfxVertexPos, normalTangent);
+ half3 normalWorld = NormalizePerPixelNormal(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z); // @TODO: see if we can squeeze this normalize on SM2.0 as well
+#else
+ half3 normalWorld = normalize(tangentToWorld[2].xyz);
+#endif
+ return normalWorld;
+}
+
+#ifdef _PARALLAXMAP
+ #define IN_VIEWDIR4PARALLAX(i) NormalizePerPixelNormal(half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w))
+ #define IN_VIEWDIR4PARALLAX_FWDADD(i) NormalizePerPixelNormal(i.viewDirForParallax.xyz)
+#else
+ #define IN_VIEWDIR4PARALLAX(i) half3(0,0,0)
+ #define IN_VIEWDIR4PARALLAX_FWDADD(i) half3(0,0,0)
+#endif
+
+#if UNITY_REQUIRE_FRAG_WORLDPOS
+ #if UNITY_PACK_WORLDPOS_WITH_TANGENT
+ #define IN_WORLDPOS(i) half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w)
+ #else
+ #define IN_WORLDPOS(i) i.posWorld
+ #endif
+ #define IN_WORLDPOS_FWDADD(i) i.posWorld
+#else
+ #define IN_WORLDPOS(i) half3(0,0,0)
+ #define IN_WORLDPOS_FWDADD(i) half3(0,0,0)
+#endif
+
+#define IN_LIGHTDIR_FWDADD(i) half3(i.tangentToWorldAndLightDir[0].w, i.tangentToWorldAndLightDir[1].w, i.tangentToWorldAndLightDir[2].w)
+
+#define FRAGMENT_SETUP(x, worldPos) FragmentCommonData x = \
+ FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX(i), i.tangentToWorldAndPackedData, IN_WORLDPOS(i), i.mfxUv, worldPos);
+
+#define FRAGMENT_SETUP_FWDADD(x, worldPos) FragmentCommonData x = \
+ FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX_FWDADD(i), i.tangentToWorldAndLightDir, IN_WORLDPOS_FWDADD(i), i.mfxUv, worldPos);
+
+struct FragmentCommonData
+{
+ half3 diffColor, specColor;
+ // Note: smoothness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level.
+ // Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.
+ half oneMinusReflectivity, smoothness;
+ half3 normalWorld, eyeVec;
+ half alpha;
+ float3 posWorld;
+
+#if UNITY_STANDARD_SIMPLE
+ half3 reflUVW;
+#endif
+
+#if UNITY_STANDARD_SIMPLE
+ half3 tangentSpaceNormal;
+#endif
+};
+
+#ifndef UNITY_SETUP_BRDF_INPUT
+ #define UNITY_SETUP_BRDF_INPUT SpecularSetup
+#endif
+
+inline FragmentCommonData SpecularSetup (float4 i_tex, float4 mfxUv, float3 mfxVertexPos)
+{
+ half4 specGloss = SpecularGloss(i_tex.xy);
+ half3 specColor = specGloss.rgb;
+ half smoothness = specGloss.a;
+
+ half oneMinusReflectivity;
+ half3 diffColor = EnergyConservationBetweenDiffuseAndSpecular (Albedo(i_tex), specColor, /*out*/ oneMinusReflectivity);
+
+ FragmentCommonData o = (FragmentCommonData)0;
+ //MFX
+ o.diffColor = GetMfxAlbedo(i_tex.xy, mfxUv, mfxVertexPos, diffColor);
+ o.specColor = specColor;
+ o.oneMinusReflectivity = oneMinusReflectivity;
+ o.smoothness = smoothness;
+
+ //MFX
+ o.alpha = GetMfxDissolve(mfxUv, mfxVertexPos);
+
+ return o;
+}
+
+
+inline FragmentCommonData RoughnessSetup(float4 i_tex, float4 mfxUv, float3 mfxVertexPos)
+{
+ half2 metallicGloss = MetallicRough(i_tex.xy);
+ half metallic = metallicGloss.x;
+ half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.
+
+ half oneMinusReflectivity;
+ half3 specColor;
+ half3 diffColor = DiffuseAndSpecularFromMetallic(Albedo(i_tex), metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
+
+ FragmentCommonData o = (FragmentCommonData)0;
+ //MFX
+ o.diffColor = GetMfxAlbedo(i_tex.xy, mfxUv, mfxVertexPos, diffColor);
+ o.specColor = specColor;
+ o.oneMinusReflectivity = oneMinusReflectivity;
+ o.smoothness = smoothness;
+
+ //MFX
+ o.alpha = GetMfxDissolve(mfxUv, mfxVertexPos);
+
+ return o;
+}
+
+inline FragmentCommonData MetallicSetup (float4 i_tex, float4 mfxUv, float3 mfxVertexPos)
+{
+ half2 metallicGloss = MetallicGloss(i_tex.xy);
+ half metallic = metallicGloss.x;
+ half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.
+
+ half oneMinusReflectivity;
+ half3 specColor;
+ half3 diffColor = DiffuseAndSpecularFromMetallic (Albedo(i_tex), metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
+
+ FragmentCommonData o = (FragmentCommonData)0;
+ //MFX
+ o.diffColor = GetMfxAlbedo(i_tex.xy, mfxUv, mfxVertexPos, diffColor);
+ o.specColor = specColor;
+ o.oneMinusReflectivity = oneMinusReflectivity;
+ o.smoothness = smoothness;
+
+ //MFX
+ o.alpha = GetMfxDissolve(mfxUv, mfxVertexPos);
+
+ return o;
+}
+
+// parallax transformed texcoord is used to sample occlusion
+inline FragmentCommonData FragmentSetup (inout float4 i_tex, half3 i_eyeVec, half3 i_viewDirForParallax, half4 tangentToWorld[3], float3 i_posWorld, float4 mfxUv, float3 mfxVertexPos)
+{
+ i_tex = Parallax(i_tex, i_viewDirForParallax);
+
+ //MFX
+ half alpha = GetMfxDissolve(mfxUv, mfxVertexPos);
+ MfxClip(alpha);
+
+ //half alpha = Alpha(i_tex.xy);
+ //#if defined(_ALPHATEST_ON)
+ // clip (alpha - _Cutoff);
+ //#endif
+
+ FragmentCommonData o = UNITY_SETUP_BRDF_INPUT (i_tex, mfxUv, mfxVertexPos);
+ o.normalWorld = PerPixelWorldNormal(i_tex, mfxUv, tangentToWorld, mfxVertexPos);
+ o.eyeVec = NormalizePerPixelNormal(i_eyeVec);
+ o.posWorld = i_posWorld;
+
+ // NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
+ //MFX
+ half3 diffColor = PreMultiplyAlpha (o.diffColor, alpha, o.oneMinusReflectivity, /*out*/ o.alpha);
+ o.diffColor = GetMfxAlbedo(i_tex.xy, mfxUv, mfxVertexPos, diffColor);
+
+ o.alpha = alpha;
+
+ return o;
+}
+
+inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light, bool reflections)
+{
+ UnityGIInput d;
+ d.light = light;
+ d.worldPos = s.posWorld;
+ d.worldViewDir = -s.eyeVec;
+ d.atten = atten;
+ #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
+ d.ambient = 0;
+ d.lightmapUV = i_ambientOrLightmapUV;
+ #else
+ d.ambient = i_ambientOrLightmapUV.rgb;
+ d.lightmapUV = 0;
+ #endif
+
+ d.probeHDR[0] = unity_SpecCube0_HDR;
+ d.probeHDR[1] = unity_SpecCube1_HDR;
+ #if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)
+ d.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending
+ #endif
+ #ifdef UNITY_SPECCUBE_BOX_PROJECTION
+ d.boxMax[0] = unity_SpecCube0_BoxMax;
+ d.probePosition[0] = unity_SpecCube0_ProbePosition;
+ d.boxMax[1] = unity_SpecCube1_BoxMax;
+ d.boxMin[1] = unity_SpecCube1_BoxMin;
+ d.probePosition[1] = unity_SpecCube1_ProbePosition;
+ #endif
+
+ if(reflections)
+ {
+ Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.smoothness, -s.eyeVec, s.normalWorld, s.specColor);
+ // Replace the reflUVW if it has been compute in Vertex shader. Note: the compiler will optimize the calcul in UnityGlossyEnvironmentSetup itself
+ #if UNITY_STANDARD_SIMPLE
+ g.reflUVW = s.reflUVW;
+ #endif
+
+ return UnityGlobalIllumination (d, occlusion, s.normalWorld, g);
+ }
+ else
+ {
+ return UnityGlobalIllumination (d, occlusion, s.normalWorld);
+ }
+}
+
+inline UnityGI FragmentGI (FragmentCommonData s, half occlusion, half4 i_ambientOrLightmapUV, half atten, UnityLight light)
+{
+ return FragmentGI(s, occlusion, i_ambientOrLightmapUV, atten, light, true);
+}
+
+
+//-------------------------------------------------------------------------------------
+half4 OutputForward (half4 output, half alphaFromSurface)
+{
+ #if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)
+ output.a = alphaFromSurface;
+ #else
+ UNITY_OPAQUE_ALPHA(output.a);
+ #endif
+ return output;
+}
+
+inline half4 VertexGIForward(VertexInput v, float3 posWorld, half3 normalWorld)
+{
+ half4 ambientOrLightmapUV = 0;
+ // Static lightmaps
+ #ifdef LIGHTMAP_ON
+ ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
+ ambientOrLightmapUV.zw = 0;
+ // Sample light probe for Dynamic objects only (no static or dynamic lightmaps)
+ #elif UNITY_SHOULD_SAMPLE_SH
+ #ifdef VERTEXLIGHT_ON
+ // Approximated illumination from non-important point lights
+ ambientOrLightmapUV.rgb = 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, posWorld, normalWorld);
+ #endif
+
+ ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, ambientOrLightmapUV.rgb);
+ #endif
+
+ #ifdef DYNAMICLIGHTMAP_ON
+ ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
+ #endif
+
+ return ambientOrLightmapUV;
+}
+
+// ------------------------------------------------------------------
+// Base forward pass (directional light, emission, lightmaps, ...)
+
+struct VertexOutputForwardBase
+{
+ UNITY_POSITION(pos);
+ float4 tex : TEXCOORD0;
+ half3 eyeVec : TEXCOORD1;
+ half4 tangentToWorldAndPackedData[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax or worldPos]
+ half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV
+ UNITY_SHADOW_COORDS(6)
+ UNITY_FOG_COORDS(7)
+
+ // next ones would not fit into SM2.0 limits, but they are always for SM3.0+
+ //#if UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT
+ float3 posWorld : TEXCOORD8;
+ //#endif
+
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+
+ //MFX
+ float4 mfxUv : TEXCOORD9;
+};
+
+VertexOutputForwardBase vertForwardBase (VertexInput v)
+{
+ UNITY_SETUP_INSTANCE_ID(v);
+ VertexOutputForwardBase o;
+ UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase, o);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+ float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
+ //#if UNITY_REQUIRE_FRAG_WORLDPOS
+ #if UNITY_PACK_WORLDPOS_WITH_TANGENT
+ o.tangentToWorldAndPackedData[0].w = posWorld.x;
+ o.tangentToWorldAndPackedData[1].w = posWorld.y;
+ o.tangentToWorldAndPackedData[2].w = posWorld.z;
+ #else
+ o.posWorld = posWorld.xyz;
+ #endif
+ //#endif
+ o.pos = UnityObjectToClipPos(v.vertex);
+
+ o.tex = TexCoords(v);
+ o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
+ float3 normalWorld = UnityObjectToWorldNormal(v.normal);
+ #ifdef _TANGENT_TO_WORLD
+ float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
+
+ float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
+ o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0];
+ o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1];
+ o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2];
+ #else
+ o.tangentToWorldAndPackedData[0].xyz = 0;
+ o.tangentToWorldAndPackedData[1].xyz = 0;
+ o.tangentToWorldAndPackedData[2].xyz = normalWorld;
+ #endif
+
+ //We need this for shadow receving
+ UNITY_TRANSFER_SHADOW(o, v.uv1);
+
+ o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);
+
+ #ifdef _PARALLAXMAP
+ TANGENT_SPACE_ROTATION;
+ half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
+ o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x;
+ o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y;
+ o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z;
+ #endif
+
+ //MFX
+ PassMfxVertex2Fragment(v.uv0.xy, o.mfxUv);
+
+ UNITY_TRANSFER_FOG(o,o.pos);
+ return o;
+}
+
+half4 fragForwardBaseInternal (VertexOutputForwardBase i)
+{
+ UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
+
+#if UNITY_PACK_WORLDPOS_WITH_TANGENT
+ float3 posWorld = float3(i.tangentToWorldAndPackedData[0].w, i.tangentToWorldAndPackedData[1].w, i.tangentToWorldAndPackedData[2].w);
+#else
+ float3 posWorld = i.posWorld;
+#endif
+
+ FRAGMENT_SETUP(s, posWorld)
+
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+
+ UnityLight mainLight = MainLight ();
+ UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld);
+
+ half occlusion = Occlusion(i.tex.xy);
+ UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, atten, mainLight);
+
+ half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect);
+ //c.rgb += Emission(i.tex.xy);
+
+ //MFX
+ c.rgb += GetMfxEmission(i.tex.xy, i.mfxUv, posWorld, Emission(i.tex.xy), s.alpha);
+
+ UNITY_APPLY_FOG(i.fogCoord, c.rgb);
+ return OutputForward (c, s.alpha);
+}
+
+half4 fragForwardBase (VertexOutputForwardBase i) : SV_Target // backward compatibility (this used to be the fragment entry function)
+{
+ return fragForwardBaseInternal(i);
+}
+
+// ------------------------------------------------------------------
+// Additive forward pass (one light per pass)
+
+struct VertexOutputForwardAdd
+{
+ UNITY_POSITION(pos);
+ float4 tex : TEXCOORD0;
+ half3 eyeVec : TEXCOORD1;
+ half4 tangentToWorldAndLightDir[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:lightDir]
+ float3 posWorld : TEXCOORD5;
+ UNITY_SHADOW_COORDS(6)
+ UNITY_FOG_COORDS(7)
+
+ // next ones would not fit into SM2.0 limits, but they are always for SM3.0+
+#if defined(_PARALLAXMAP)
+ half3 viewDirForParallax : TEXCOORD8;
+#endif
+
+ UNITY_VERTEX_OUTPUT_STEREO
+
+ //MFX
+ float4 mfxUv : TEXCOORD9;
+};
+
+VertexOutputForwardAdd vertForwardAdd (VertexInput v)
+{
+ UNITY_SETUP_INSTANCE_ID(v);
+ VertexOutputForwardAdd o;
+ UNITY_INITIALIZE_OUTPUT(VertexOutputForwardAdd, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+ float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
+ o.pos = UnityObjectToClipPos(v.vertex);
+
+ o.tex = TexCoords(v);
+ o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
+ o.posWorld = posWorld.xyz;
+ float3 normalWorld = UnityObjectToWorldNormal(v.normal);
+ #ifdef _TANGENT_TO_WORLD
+ float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
+
+ float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
+ o.tangentToWorldAndLightDir[0].xyz = tangentToWorld[0];
+ o.tangentToWorldAndLightDir[1].xyz = tangentToWorld[1];
+ o.tangentToWorldAndLightDir[2].xyz = tangentToWorld[2];
+ #else
+ o.tangentToWorldAndLightDir[0].xyz = 0;
+ o.tangentToWorldAndLightDir[1].xyz = 0;
+ o.tangentToWorldAndLightDir[2].xyz = normalWorld;
+ #endif
+ //We need this for shadow receiving
+ UNITY_TRANSFER_SHADOW(o, v.uv1);
+
+ float3 lightDir = _WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w;
+ #ifndef USING_DIRECTIONAL_LIGHT
+ lightDir = NormalizePerVertexNormal(lightDir);
+ #endif
+ o.tangentToWorldAndLightDir[0].w = lightDir.x;
+ o.tangentToWorldAndLightDir[1].w = lightDir.y;
+ o.tangentToWorldAndLightDir[2].w = lightDir.z;
+
+ #ifdef _PARALLAXMAP
+ TANGENT_SPACE_ROTATION;
+ o.viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
+ #endif
+
+ //MFX
+ PassMfxVertex2Fragment(v.uv0.xy, o.mfxUv);
+
+ UNITY_TRANSFER_FOG(o,o.pos);
+ return o;
+}
+
+half4 fragForwardAddInternal (VertexOutputForwardAdd i)
+{
+ UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
+
+ FRAGMENT_SETUP_FWDADD(s, i.posWorld)
+
+ UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld)
+ UnityLight light = AdditiveLight (IN_LIGHTDIR_FWDADD(i), atten);
+ UnityIndirect noIndirect = ZeroIndirect ();
+
+ half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, light, noIndirect);
+
+ UNITY_APPLY_FOG_COLOR(i.fogCoord, c.rgb, half4(0,0,0,0)); // fog towards black in additive pass
+ return OutputForward (c, s.alpha);
+}
+
+half4 fragForwardAdd (VertexOutputForwardAdd i) : SV_Target // backward compatibility (this used to be the fragment entry function)
+{
+ return fragForwardAddInternal(i);
+}
+
+// ------------------------------------------------------------------
+// Deferred pass
+
+struct VertexOutputDeferred
+{
+ UNITY_POSITION(pos);
+ float4 tex : TEXCOORD0;
+ half3 eyeVec : TEXCOORD1;
+ half4 tangentToWorldAndPackedData[3]: TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax or worldPos]
+ half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UVs
+
+ //#if UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT
+ float3 posWorld : TEXCOORD6;
+ //#endif
+
+ UNITY_VERTEX_OUTPUT_STEREO
+
+ //MFX
+ float4 mfxUv : TEXCOORD7;
+};
+
+
+VertexOutputDeferred vertDeferred (VertexInput v)
+{
+ UNITY_SETUP_INSTANCE_ID(v);
+ VertexOutputDeferred o;
+ UNITY_INITIALIZE_OUTPUT(VertexOutputDeferred, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+ float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
+ //#if UNITY_REQUIRE_FRAG_WORLDPOS
+ #if UNITY_PACK_WORLDPOS_WITH_TANGENT
+ o.tangentToWorldAndPackedData[0].w = posWorld.x;
+ o.tangentToWorldAndPackedData[1].w = posWorld.y;
+ o.tangentToWorldAndPackedData[2].w = posWorld.z;
+ #else
+ o.posWorld = posWorld.xyz;
+ #endif
+ //#endif
+ o.pos = UnityObjectToClipPos(v.vertex);
+
+ o.tex = TexCoords(v);
+ o.eyeVec = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
+ float3 normalWorld = UnityObjectToWorldNormal(v.normal);
+ #ifdef _TANGENT_TO_WORLD
+ float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
+
+ float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w);
+ o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0];
+ o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1];
+ o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2];
+ #else
+ o.tangentToWorldAndPackedData[0].xyz = 0;
+ o.tangentToWorldAndPackedData[1].xyz = 0;
+ o.tangentToWorldAndPackedData[2].xyz = normalWorld;
+ #endif
+
+ o.ambientOrLightmapUV = 0;
+ #ifdef LIGHTMAP_ON
+ o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
+ #elif UNITY_SHOULD_SAMPLE_SH
+ o.ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, o.ambientOrLightmapUV.rgb);
+ #endif
+ #ifdef DYNAMICLIGHTMAP_ON
+ o.ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
+ #endif
+
+ #ifdef _PARALLAXMAP
+ TANGENT_SPACE_ROTATION;
+ half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
+ o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x;
+ o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y;
+ o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z;
+ #endif
+
+ //MFX
+ PassMfxVertex2Fragment(v.uv0.xy, o.mfxUv);
+
+ return o;
+}
+
+void fragDeferred (
+ VertexOutputDeferred i,
+ out half4 outGBuffer0 : SV_Target0,
+ out half4 outGBuffer1 : SV_Target1,
+ out half4 outGBuffer2 : SV_Target2,
+ out half4 outEmission : SV_Target3 // RT3: emission (rgb), --unused-- (a)
+#if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
+ ,out half4 outShadowMask : SV_Target4 // RT4: shadowmask (rgba)
+#endif
+)
+{
+ #if (SHADER_TARGET < 30)
+ outGBuffer0 = 1;
+ outGBuffer1 = 1;
+ outGBuffer2 = 0;
+ outEmission = 0;
+ #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
+ outShadowMask = 1;
+ #endif
+ return;
+ #endif
+
+ UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
+
+#if UNITY_PACK_WORLDPOS_WITH_TANGENT
+ float3 posWorld = float3(i.tangentToWorldAndPackedData[0].w, i.tangentToWorldAndPackedData[1].w, i.tangentToWorldAndPackedData[2].w);
+#else
+ float3 posWorld = i.posWorld;
+#endif
+
+ //MFX
+ FRAGMENT_SETUP(s, posWorld)
+
+ // no analytic lights in this pass
+ UnityLight dummyLight = DummyLight ();
+ half atten = 1;
+
+ // only GI
+ half occlusion = Occlusion(i.tex.xy);
+#if UNITY_ENABLE_REFLECTION_BUFFERS
+ bool sampleReflectionsInDeferred = false;
+#else
+ bool sampleReflectionsInDeferred = true;
+#endif
+
+ UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, atten, dummyLight, sampleReflectionsInDeferred);
+
+ half3 emissiveColor = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect).rgb;
+
+ #ifdef _EMISSION
+ //emissiveColor += Emission (i.tex.xy);
+
+ //MFX
+ emissiveColor += GetMfxEmission(i.tex.xy, i.mfxUv, posWorld, Emission(i.tex.xy), s.alpha);
+ #endif
+
+ #ifndef UNITY_HDR_ON
+ emissiveColor.rgb = exp2(-emissiveColor.rgb);
+ #endif
+
+ UnityStandardData data;
+ data.diffuseColor = s.diffColor;
+ data.occlusion = occlusion;
+ data.specularColor = s.specColor;
+ data.smoothness = s.smoothness;
+ data.normalWorld = s.normalWorld;
+
+ UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
+
+ // Emissive lighting buffer
+ outEmission = half4(emissiveColor, 1);
+
+ // Baked direct lighting occlusion if any
+ #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
+ outShadowMask = UnityGetRawBakedOcclusions(i.ambientOrLightmapUV.xy, IN_WORLDPOS(i));
+ #endif
+}
+
+
+//
+// Old FragmentGI signature. Kept only for backward compatibility and will be removed soon
+//
+
+inline UnityGI FragmentGI(
+ float3 posWorld,
+ half occlusion, half4 i_ambientOrLightmapUV, half atten, half smoothness, half3 normalWorld, half3 eyeVec,
+ UnityLight light,
+ bool reflections)
+{
+ // we init only fields actually used
+ FragmentCommonData s = (FragmentCommonData)0;
+ s.smoothness = smoothness;
+ s.normalWorld = normalWorld;
+ s.eyeVec = eyeVec;
+ s.posWorld = posWorld;
+ return FragmentGI(s, occlusion, i_ambientOrLightmapUV, atten, light, reflections);
+}
+inline UnityGI FragmentGI (
+ float3 posWorld,
+ half occlusion, half4 i_ambientOrLightmapUV, half atten, half smoothness, half3 normalWorld, half3 eyeVec,
+ UnityLight light)
+{
+ return FragmentGI (posWorld, occlusion, i_ambientOrLightmapUV, atten, smoothness, normalWorld, eyeVec, light, true);
+}
+
+#endif // UNITY_STANDARD_CORE_INCLUDED
|