123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- #ifndef SPRITE_VERTEX_LIGHTING_INCLUDED
- #define SPRITE_VERTEX_LIGHTING_INCLUDED
- #include "ShaderShared.cginc"
- #include "SpriteLighting.cginc"
- #include "SpriteSpecular.cginc"
- ////////////////////////////////////////
- // Defines
- //
- //Define to use spot lights (more expensive)
- #define SPOT_LIGHTS
- //Have to process lighting per pixel if using normal maps or a diffuse ramp or rim lighting or specular
- #if defined(_NORMALMAP) || defined(_DIFFUSE_RAMP) || defined(_RIM_LIGHTING) || defined(SPECULAR)
- #define PER_PIXEL_LIGHTING
- #endif
- //Turn off bump mapping and diffuse ramping on older shader models as they dont support needed number of outputs
- #if defined(PER_PIXEL_LIGHTING) && (SHADER_TARGET < 30)
- #undef PER_PIXEL_LIGHTING
- #undef _NORMALMAP
- #undef _DIFFUSE_RAMP
- #undef _RIM_LIGHTING
- #endif
- //In D3D9 only have a max of 9 TEXCOORD so can't have diffuse ramping or fog or rim lighting if processing lights per pixel
- #if defined(SHADER_API_D3D9) && defined(PER_PIXEL_LIGHTING)
- #if defined(_NORMALMAP)
- #undef _DIFFUSE_RAMP
- #undef _FOG
- #undef _RIM_LIGHTING
- #elif defined(_DIFFUSE_RAMP)
- #undef _FOG
- #undef _RIM_LIGHTING
- #elif defined(_RIM_LIGHTING)
- #undef _FOG
- #undef _DIFFUSE_RAMP
- #else
- #undef _DIFFUSE_RAMP
- #undef _RIM_LIGHTING
- #endif
- #endif
- #if defined(PER_PIXEL_LIGHTING)
- #if defined(_NORMALMAP) && defined(_DIFFUSE_RAMP)
- #define ATTENUATIONS TEXCOORD9
- #if defined(_RIM_LIGHTING)
- #define _POS_WORLD_INDEX TEXCOORD10
- #define _FOG_COORD_INDEX 11
- #else
- #define _FOG_COORD_INDEX 10
- #endif
- #elif defined(_NORMALMAP) != defined(_DIFFUSE_RAMP)
- #define ATTENUATIONS TEXCOORD8
- #if defined(_RIM_LIGHTING)
- #define _POS_WORLD_INDEX TEXCOORD9
- #define _FOG_COORD_INDEX 10
- #else
- #define _FOG_COORD_INDEX 9
- #endif
- #else //!_DIFFUSE_RAMP && !_NORMALMAP
- #if defined(_RIM_LIGHTING)
- #define _POS_WORLD_INDEX TEXCOORD8
- #define _FOG_COORD_INDEX 9
- #else
- #define _FOG_COORD_INDEX 8
- #endif
- #endif
- #else //!PER_PIXEL_LIGHTING
- #define _FOG_COORD_INDEX 2
- #endif
- ////////////////////////////////////////
- // Vertex output struct
- //
- struct VertexOutput
- {
- float4 pos : SV_POSITION;
- fixed4 color : COLOR;
- float3 texcoord : TEXCOORD0;
- #if defined(PER_PIXEL_LIGHTING)
- half4 VertexLightInfo0 : TEXCOORD1;
- half4 VertexLightInfo1 : TEXCOORD2;
- half4 VertexLightInfo2 : TEXCOORD3;
- half4 VertexLightInfo3 : TEXCOORD4;
- half4 VertexLightInfo4 : TEXCOORD5;
- #if defined(_NORMALMAP)
- half4 normalWorld : TEXCOORD6;
- half4 tangentWorld : TEXCOORD7;
- half4 binormalWorld : TEXCOORD8;
- #else
- half3 normalWorld : TEXCOORD6;
- half3 VertexLightInfo5 : TEXCOORD7;
- #endif
- #if defined(_DIFFUSE_RAMP)
- half4 LightAttenuations : ATTENUATIONS;
- #endif
- #if defined(_RIM_LIGHTING)
- float4 posWorld : _POS_WORLD_INDEX;
- #endif
- #else //!PER_PIXEL_LIGHTING
- half3 FullLighting : TEXCOORD1;
- #endif // !PER_PIXEL_LIGHTING
- #if defined(_FOG)
- UNITY_FOG_COORDS(_FOG_COORD_INDEX)
- #endif // _FOG
- UNITY_VERTEX_OUTPUT_STEREO
- };
- ////////////////////////////////////////
- // Light calculations
- //
- struct VertexLightInfo
- {
- half3 lightDirection;
- fixed3 lightColor;
- #if defined(_DIFFUSE_RAMP)
- float attenuation;
- #endif // _DIFFUSE_RAMP
- };
- inline VertexLightInfo getVertexLightAttenuatedInfo(int index, float3 viewPos)
- {
- VertexLightInfo lightInfo;
- //For directional lights unity_LightPosition.w is set to zero
- lightInfo.lightDirection = unity_LightPosition[index].xyz - viewPos.xyz * unity_LightPosition[index].w;
- float lengthSq = dot(lightInfo.lightDirection, lightInfo.lightDirection);
- // don't produce NaNs if some vertex position overlaps with the light
- lengthSq = max(lengthSq, 0.000001);
- lightInfo.lightDirection *= rsqrt(lengthSq);
- float attenuation = 1.0 / (1.0 + lengthSq * unity_LightAtten[index].z);
- #if defined(SPOT_LIGHTS)
- //Spot light attenuation - for non-spot lights unity_LightAtten.x is set to -1 and y is set to 1
- {
- float rho = max (0, dot(lightInfo.lightDirection, unity_SpotDirection[index].xyz));
- float spotAtt = (rho - unity_LightAtten[index].x) * unity_LightAtten[index].y;
- attenuation *= saturate(spotAtt);
- }
- #endif // SPOT_LIGHTS
- //If using a diffuse ramp texture then need to pass through the lights attenuation, otherwise premultiply the light color with it
- #if defined(_DIFFUSE_RAMP)
- lightInfo.lightColor = unity_LightColor[index].rgb;
- lightInfo.attenuation = attenuation;
- #else
- lightInfo.lightColor = unity_LightColor[index].rgb * attenuation;
- #endif // _DIFFUSE_RAMP
- return lightInfo;
- }
- //Magic constants used to tweak ambient to approximate pixel shader spherical harmonics
- static const fixed3 worldUp = fixed3(0, 1, 0);
- static const float skyGroundDotMul = 2.5;
- static const float minEquatorMix = 0.5;
- static const float equatorColorBlur = 0.33;
- fixed3 calculateAmbientLight(half3 normalWorld)
- {
- #if defined(_SPHERICAL_HARMONICS)
- float upDot = dot(normalWorld, worldUp);
- //Fade between a flat lerp from sky to ground and a 3 way lerp based on how bright the equator light is.
- //This simulates how directional lights get blurred using spherical harmonics
- //Work out color from ground and sky, ignoring equator
- float adjustedDot = upDot * skyGroundDotMul;
- fixed3 skyGroundColor = lerp(unity_AmbientGround, unity_AmbientSky, saturate((adjustedDot + 1.0) * 0.5));
- //Work out equator lights brightness
- float equatorBright = saturate(dot(unity_AmbientEquator.rgb, unity_AmbientEquator.rgb));
- //Blur equator color with sky and ground colors based on how bright it is.
- fixed3 equatorBlurredColor = lerp(unity_AmbientEquator, saturate(unity_AmbientEquator + unity_AmbientGround + unity_AmbientSky), equatorBright * equatorColorBlur);
- //Work out 3 way lerp inc equator light
- fixed3 equatorColor = lerp(equatorBlurredColor, unity_AmbientGround, -upDot) * step(upDot, 0) + lerp(equatorBlurredColor, unity_AmbientSky, upDot) * step(0, upDot);
- //Mix the two colors together based on how bright the equator light is
- return lerp(skyGroundColor, equatorColor, saturate(equatorBright + minEquatorMix));
- #else // !_SPHERICAL_HARMONICS
- //Flat ambient is just the sky color
- return unity_AmbientSky.rgb;
- #endif // !_SPHERICAL_HARMONICS
- }
- ////////////////////////////////////////
- // Light Packing Functions
- //
- #if defined(_DIFFUSE_RAMP)
- inline fixed3 calculateLightDiffuse(fixed3 lightColor, half3 viewNormal, half3 lightViewDir, float attenuation)
- {
- float angleDot = max(0, dot(viewNormal, lightViewDir));
- fixed3 lightDiffuse = calculateRampedDiffuse(lightColor, attenuation, angleDot);
- return lightDiffuse;
- }
- #else
- inline fixed3 calculateLightDiffuse(fixed3 attenuatedLightColor, half3 viewNormal, half3 lightViewDir)
- {
- float angleDot = max(0, dot(viewNormal, lightViewDir));
- fixed3 lightDiffuse = attenuatedLightColor * angleDot;
- return lightDiffuse;
- }
- #endif // _NORMALMAP
- #if defined(PER_PIXEL_LIGHTING)
- #define VERTEX_LIGHT_0_DIR VertexLightInfo0.xyz
- #define VERTEX_LIGHT_0_R VertexLightInfo4.x
- #define VERTEX_LIGHT_0_G VertexLightInfo4.y
- #define VERTEX_LIGHT_0_B VertexLightInfo4.z
- #define VERTEX_LIGHT_1_DIR VertexLightInfo1.xyz
- #define VERTEX_LIGHT_1_R VertexLightInfo0.w
- #define VERTEX_LIGHT_1_G VertexLightInfo1.w
- #define VERTEX_LIGHT_1_B VertexLightInfo2.w
- #define VERTEX_LIGHT_2_DIR VertexLightInfo2.xyz
- #define VERTEX_LIGHT_2_R VertexLightInfo3.w
- #define VERTEX_LIGHT_2_G VertexLightInfo4.w
- #define VERTEX_LIGHT_2_B texcoord.z
- #define VERTEX_LIGHT_3_DIR VertexLightInfo3.xyz
- #if defined(_NORMALMAP)
- #define VERTEX_LIGHT_3_R normalWorld.w
- #define VERTEX_LIGHT_3_G tangentWorld.w
- #define VERTEX_LIGHT_3_B binormalWorld.w
- #else
- #define VERTEX_LIGHT_3_R VertexLightInfo5.x
- #define VERTEX_LIGHT_3_G VertexLightInfo5.y
- #define VERTEX_LIGHT_3_B VertexLightInfo5.z
- #endif
- #if defined(_DIFFUSE_RAMP)
- #define LIGHT_DIFFUSE_ATTEN_0 LightAttenuations.x
- #define LIGHT_DIFFUSE_ATTEN_1 LightAttenuations.y
- #define LIGHT_DIFFUSE_ATTEN_2 LightAttenuations.z
- #define LIGHT_DIFFUSE_ATTEN_3 LightAttenuations.w
- #define PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo) \
- { \
- output.LIGHT_DIFFUSE_ATTEN_##index = lightInfo.attenuation; \
- }
- #define ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \
- { \
- diffuse += calculateLightDiffuse(lightColor, viewNormal, lightViewDir, input.LIGHT_DIFFUSE_ATTEN_##index); \
- }
- #else
- #define PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo)
- #define ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \
- { \
- diffuse += calculateLightDiffuse(lightColor, viewNormal, lightViewDir); \
- }
- #endif
- #define PACK_VERTEX_LIGHT(index, output, viewPos) \
- { \
- VertexLightInfo lightInfo = getVertexLightAttenuatedInfo(index, viewPos); \
- output.VERTEX_LIGHT_##index##_DIR = lightInfo.lightDirection; \
- output.VERTEX_LIGHT_##index##_R = lightInfo.lightColor.r; \
- output.VERTEX_LIGHT_##index##_G = lightInfo.lightColor.g; \
- output.VERTEX_LIGHT_##index##_B = lightInfo.lightColor.b; \
- PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo); \
- }
- #define ADD_VERTEX_LIGHT(index, input, viewNormal, diffuse) \
- { \
- half3 lightViewDir = input.VERTEX_LIGHT_##index##_DIR; \
- fixed3 lightColor = fixed3(input.VERTEX_LIGHT_##index##_R, input.VERTEX_LIGHT_##index##_G, input.VERTEX_LIGHT_##index##_B); \
- ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \
- }
- #if defined(SPECULAR)
- #define ADD_VERTEX_LIGHT_SPEC(index, input, viewNormal, specData, combinedLightData, indirectDiffuse, indirectSpecular) \
- { \
- half3 lightViewDir = input.VERTEX_LIGHT_##index##_DIR; \
- fixed3 lightColor = fixed3(input.VERTEX_LIGHT_##index##_R, input.VERTEX_LIGHT_##index##_G, input.VERTEX_LIGHT_##index##_B); \
- SpecularLightData lightData = calculatePhysicsBasedSpecularLight(specData.specColor, specData.oneMinusReflectivity, specData.smoothness, viewNormal, fixed3(0,0,1), lightViewDir, lightColor, indirectDiffuse, indirectSpecular); \
- combinedLightData.lighting += lightData.lighting; \
- combinedLightData.specular += lightData.specular; \
- }
- #endif
- #else //!PER_PIXEL_LIGHTING
- ////////////////////////////////////////
- // Vertex Only Functions
- //
- inline fixed3 calculateLightDiffuse(int index, float3 viewPos, half3 viewNormal)
- {
- VertexLightInfo lightInfo = getVertexLightAttenuatedInfo(index, viewPos);
- float angleDot = max(0, dot(viewNormal, lightInfo.lightDirection));
- return lightInfo.lightColor * angleDot;
- }
- #endif // !PER_PIXEL_LIGHTING
- ////////////////////////////////////////
- // Vertex program
- //
- VertexOutput vert(VertexInput input)
- {
- VertexOutput output;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
- output.pos = calculateLocalPos(input.vertex);
- output.color = calculateVertexColor(input.color);
- output.texcoord = float3(calculateTextureCoord(input.texcoord), 0);
- float3 viewPos = UnityObjectToViewPos(input.vertex); //float3 viewPos = mul(UNITY_MATRIX_MV, input.vertex); //
- #if defined(FIXED_NORMALS_BACKFACE_RENDERING) || defined(_RIM_LIGHTING)
- float4 powWorld = calculateWorldPos(input.vertex);
- #endif
- float backFaceSign = 1;
- #if defined(FIXED_NORMALS_BACKFACE_RENDERING)
- backFaceSign = calculateBackfacingSign(powWorld.xyz);
- #endif
- #if defined(PER_PIXEL_LIGHTING)
- #if defined(_RIM_LIGHTING)
- output.posWorld = powWorld;
- #endif
- PACK_VERTEX_LIGHT(0, output, viewPos)
- PACK_VERTEX_LIGHT(1, output, viewPos)
- PACK_VERTEX_LIGHT(2, output, viewPos)
- PACK_VERTEX_LIGHT(3, output, viewPos)
- output.normalWorld.xyz = calculateSpriteWorldNormal(input, backFaceSign);
- #if defined(_NORMALMAP)
- output.tangentWorld.xyz = calculateWorldTangent(input.tangent);
- output.binormalWorld.xyz = calculateSpriteWorldBinormal(input, output.normalWorld, output.tangentWorld, backFaceSign);
- #endif
- #else // !PER_PIXEL_LIGHTING
- //Just pack full lighting
- float3 viewNormal = calculateSpriteViewNormal(input, backFaceSign);
- //Get Ambient diffuse
- float3 normalWorld = calculateSpriteWorldNormal(input, backFaceSign);
- fixed3 ambient = calculateAmbientLight(normalWorld);
- fixed3 diffuse = calculateLightDiffuse(0, viewPos, viewNormal);
- diffuse += calculateLightDiffuse(1, viewPos, viewNormal);
- diffuse += calculateLightDiffuse(2, viewPos, viewNormal);
- diffuse += calculateLightDiffuse(3, viewPos, viewNormal);
- output.FullLighting = ambient + diffuse;
- #endif // !PER_PIXEL_LIGHTING
- #if defined(_FOG)
- UNITY_TRANSFER_FOG(output, output.pos);
- #endif // _FOG
- return output;
- }
- ////////////////////////////////////////
- // Fragment program
- //
- fixed4 frag(VertexOutput input) : SV_Target
- {
- fixed4 texureColor = calculateTexturePixel(input.texcoord.xy);
- RETURN_UNLIT_IF_ADDITIVE_SLOT(texureColor, input.color) // shall be called before ALPHA_CLIP
- ALPHA_CLIP(texureColor, input.color)
- #if defined(PER_PIXEL_LIGHTING)
- #if defined(_NORMALMAP)
- half3 normalWorld = calculateNormalFromBumpMap(input.texcoord.xy, input.tangentWorld.xyz, input.binormalWorld.xyz, input.normalWorld.xyz);
- #else
- half3 normalWorld = input.normalWorld.xyz;
- #endif
- //Get Ambient diffuse
- fixed3 ambient = calculateAmbientLight(normalWorld);
- half3 normalView = normalize(mul((float3x3)UNITY_MATRIX_V, normalWorld));
- #if defined(SPECULAR)
- SpecularCommonData specData = getSpecularData(input.texcoord.xy, texureColor, input.color);
- SpecularLightData combinedLightData = (SpecularLightData)0;
- ADD_VERTEX_LIGHT_SPEC(0, input, normalView, specData, combinedLightData, ambient, unity_IndirectSpecColor.rgb)
- ADD_VERTEX_LIGHT_SPEC(1, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0))
- ADD_VERTEX_LIGHT_SPEC(2, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0))
- ADD_VERTEX_LIGHT_SPEC(3, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0))
- fixed4 pixel = calculateLitPixel(fixed4(specData.diffColor, specData.alpha), combinedLightData.lighting);
- pixel.rgb += combinedLightData.specular * specData.alpha;
- APPLY_EMISSION_SPECULAR(pixel, input.texcoord)
- #else
- //Find vertex light diffuse
- fixed3 diffuse = fixed3(0,0,0);
- //Add each vertex light to diffuse
- ADD_VERTEX_LIGHT(0, input, normalView, diffuse)
- ADD_VERTEX_LIGHT(1, input, normalView, diffuse)
- ADD_VERTEX_LIGHT(2, input, normalView, diffuse)
- ADD_VERTEX_LIGHT(3, input, normalView, diffuse)
- fixed3 lighting = ambient + diffuse;
- APPLY_EMISSION(lighting, input.texcoord.xy)
- fixed4 pixel = calculateLitPixel(texureColor, input.color, lighting);
- #endif
- #if defined(_RIM_LIGHTING)
- pixel.rgb = applyRimLighting(input.posWorld, normalWorld, pixel);
- #endif
- #else // !PER_PIXEL_LIGHTING
- APPLY_EMISSION(input.FullLighting, input.texcoord.xy)
- fixed4 pixel = calculateLitPixel(texureColor, input.color, input.FullLighting);
- #endif // !PER_PIXEL_LIGHTING
- COLORISE(pixel)
- APPLY_FOG(pixel, input)
- return pixel;
- }
- #endif // SPRITE_VERTEX_LIGHTING_INCLUDED
|