UnitySVG.cginc Unity 5.6
// 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