Created
May 24, 2017 21:17
-
-
Save mejje/9b0dcb853f23cb2e298df84d75bfae41 to your computer and use it in GitHub Desktop.
UnitySVG.cginc Unity 5.6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' | |
#ifndef UNITY_SVG_INCLUDED | |
#define UNITY_SVG_INCLUDED | |
struct VertexInput_SVG | |
{ | |
float4 vertex : POSITION; | |
fixed4 color : COLOR; | |
half3 normal : NORMAL; | |
float2 uv0 : TEXCOORD0; | |
float2 uv1 : TEXCOORD1; | |
#if defined(DYNAMICLIGHTMAP_ON) || defined(UNITY_PASS_META) | |
float2 uv2 : TEXCOORD2; | |
#endif | |
#ifdef _TANGENT_TO_WORLD | |
half4 tangent : TANGENT; | |
#endif | |
}; | |
float4 TexCoords_SVG(VertexInput_SVG v) | |
{ | |
float4 texcoord; | |
texcoord.xy = TRANSFORM_TEX(v.uv0, _MainTex); // Always source from uv0 | |
texcoord.zw = TRANSFORM_TEX(((_UVSec == 0) ? v.uv0 : v.uv1), _DetailAlbedoMap); | |
return texcoord; | |
} | |
//Forward Pass | |
struct VertexOutputForwardBase_SVG | |
{ | |
float4 pos : SV_POSITION; | |
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) | |
fixed4 color : COLOR; | |
// 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 | |
}; | |
VertexOutputForwardBase_SVG vertForwardBase_SVG (VertexInput_SVG v) | |
{ | |
VertexOutputForwardBase_SVG o; | |
UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase_SVG, 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_SVG(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); | |
// Static lightmaps | |
#ifndef LIGHTMAP_OFF | |
o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; | |
o.ambientOrLightmapUV.zw = 0; | |
// Sample light probe for Dynamic objects only (no static or dynamic lightmaps) | |
#elif UNITY_SHOULD_SAMPLE_SH | |
#if UNITY_SAMPLE_FULL_SH_PER_PIXEL | |
o.ambientOrLightmapUV.rgb = 0; | |
#elif (SHADER_TARGET < 30) | |
o.ambientOrLightmapUV.rgb = ShadeSH9(half4(normalWorld, 1.0)); | |
#else | |
// Optimization: L2 per-vertex, L0..L1 per-pixel | |
o.ambientOrLightmapUV.rgb = ShadeSH3Order(half4(normalWorld, 1.0)); | |
#endif | |
// Add approximated illumination from non-important point lights | |
#ifdef VERTEXLIGHT_ON | |
o.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 | |
#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 | |
o.color = v.color; | |
UNITY_TRANSFER_FOG(o,o.pos); | |
return o; | |
} | |
half4 fragForwardBase_SVG (VertexOutputForwardBase_SVG i) : SV_Target | |
{ | |
FRAGMENT_SETUP(s) | |
UnityLight mainLight = MainLight (); | |
UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld); | |
half occlusion = Occlusion(i.tex.xy); | |
UnityGI gi = FragmentGI ( | |
s.posWorld, occlusion, i.ambientOrLightmapUV, atten, s.smoothness, s.normalWorld, s.eyeVec, mainLight); | |
half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect); | |
c *= i.color; | |
c.rgb += Emission(i.tex.xy); | |
UNITY_APPLY_FOG(i.fogCoord, c.rgb); | |
return OutputForward (c, s.alpha * i.color.a); | |
} | |
//Deferred Pass | |
struct VertexOutputDeferred_SVG | |
{ | |
float4 pos : SV_POSITION; | |
fixed4 color : COLOR; | |
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 | |
}; | |
VertexOutputDeferred_SVG vertDeferred_SVG (VertexInput_SVG v) | |
{ | |
VertexOutputDeferred_SVG o; | |
UNITY_INITIALIZE_OUTPUT(VertexOutputDeferred_SVG, 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_SVG(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 | |
#ifndef LIGHTMAP_OFF | |
o.ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; | |
o.ambientOrLightmapUV.zw = 0; | |
#elif UNITY_SHOULD_SAMPLE_SH | |
#if (SHADER_TARGET < 30) | |
o.ambientOrLightmapUV.rgb = ShadeSH9(half4(normalWorld, 1.0)); | |
#else | |
// Optimization: L2 per-vertex, L0..L1 per-pixel | |
o.ambientOrLightmapUV.rgb = ShadeSH3Order(half4(normalWorld, 1.0)); | |
#endif | |
#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 | |
o.color = v.color; | |
return o; | |
} | |
void fragDeferred_SVG ( | |
VertexOutputDeferred_SVG 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 (SHADER_TARGET < 30) | |
outGBuffer0 = 1; | |
outGBuffer1 = 1; | |
outGBuffer2 = 0; | |
outEmission = 0; | |
return; | |
#endif | |
FRAGMENT_SETUP(s) | |
// 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; | |
emissiveColor *= i.color; | |
#ifdef _EMISSION | |
emissiveColor += Emission (i.tex.xy); | |
#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); | |
// Emisive lighting buffer | |
outEmission = half4(emissiveColor, 1); | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment