#ifndef ALLIN13DSHADER_COMMON_FUNCTIONS #define ALLIN13DSHADER_COMMON_FUNCTIONS #define ALLIN13DSHADER_PI 3.14159265359f #define ALLIN13DSHADER_TWO_PI 6.28318530718f #define ALLIN13DSHADER_FOUR_PI 12.56637061436f #define ALLIN13DSHADER_INV_PI 0.31830988618f #define ALLIN13DSHADER_INV_TWO_PI 0.15915494309f #define ALLIN13DSHADER_INV_FOUR_PI 0.07957747155f #define ALLIN13DSHADER_HALF_PI 1.57079632679f #define ALLIN13DSHADER_INV_HALF_PI 0.636619772367f #define CUSTOM_TRANSFORM_TEX(uv, increment, name) ((uv.xy + increment.xy) * ACCESS_PROP_FLOAT4(name##_ST).xy/*ACCESS_PROP_TILING_AND_OFFSET(name##_ST).xy*/ + ACCESS_PROP_FLOAT4(name##_ST).zw/*ACCESS_PROP_TILING_AND_OFFSET(name##_ST).zw*/) #define SIMPLE_CUSTOM_TRANSFORM_TEX(uv, name) uv.xy * ACCESS_PROP_FLOAT4(name##_ST).xy/*ACCESS_PROP_TILING_AND_OFFSET(name##_ST).xy*/ + /*ACCESS_PROP_FLOAT4(name##_ST).zw*/ACCESS_PROP_TILING_AND_OFFSET(name##_ST).zw #define DEFAULT_NORMAL_MAP_VALUE float4(1, 0.5, 0.5, 0.5) #ifdef _CUSTOM_SHADOW_COLOR_ON #define SHADOW_COLOR global_shadowColor #else #define SHADOW_COLOR 0 #endif float Pow_5(float x) { float x2 = x * x; float res = x2 * x2 * x; return res; } float EaseOutQuint(float x) { return 1 - Pow_5(1 - x); } float RemapFloat(float inValue, float inMin, float inMax, float outMin, float outMax) { return outMin + (inValue - inMin) * (outMax - outMin) / (inMax - inMin); } float3 RemapFloat3(float3 inValue, float3 inMin, float3 inMax, float3 outMin, float3 outMax) { float3 res = float3 ( RemapFloat(inValue.x, inMin.x, inMax.x, outMin.x, outMax.x), RemapFloat(inValue.y, inMin.y, inMax.y, outMin.y, outMax.y), RemapFloat(inValue.z, inMin.z, inMax.z, outMin.z, outMax.z) ); return res; } float GetLuminanceRaw(float4 col) { float res = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b; res *= col.a; return res; } float GetLuminance(float4 col) { return GetLuminanceRaw(col); } float GetLuminance(float3 col) { return GetLuminance(float4(col, 1.0)); } float noise(float2 p) { return frac(sin(dot(p, float2(12.9898, 78.233))) * 43758.5453); } float noise2D(float2 p) { float2 ip = floor(p); float2 fp = frac(p); fp = fp * fp * (3 - 2 * fp); float n00 = noise(ip); float n01 = noise(ip + float2(0, 1)); float n10 = noise(ip + float2(1, 0)); float n11 = noise(ip + float2(1, 1)); return lerp(lerp(n00, n01, fp.y), lerp(n10, n11, fp.y), fp.x); } //hash for randomness float2 hash2D2D(float2 s) { //magic numbers return frac(sin(fmod(float2(dot(s, float2(127.1, 311.7)), dot(s, float2(269.5, 183.3))), 3.14159)) * 43758.5453); } //float4x3 getStochasticOffsets(float2 uv, float scale = 3.464, float skewAmount = 0.57735027) float4x3 getStochasticOffsets(float2 uv, float scale, float skewAmount) { //triangle vertices and blend weights //BW_vx[0...2].xyz = triangle verts //BW_vx[3].xy = blend weights (z is unused) float4x3 BW_vx; //uv transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3) float2 skewUV = mul(float2x2(1.0, 0.0, -skewAmount, 1.15470054), uv * scale); //vertex IDs and barycentric coords float2 vxID = float2(floor(skewUV)); float3 barry = float3(frac(skewUV), 0); barry.z = 1.0 - barry.x - barry.y; BW_vx = ((barry.z > 0) ? float4x3(float3(vxID, 0), float3(vxID + float2(0, 1), 0), float3(vxID + float2(1, 0), 0), barry.zyx) : float4x3(float3(vxID + float2(1, 1), 0), float3(vxID + float2(1, 0), 0), float3(vxID + float2(0, 1), 0), float3(-barry.z, 1.0 - barry.y, 1.0 - barry.x))); return BW_vx; } #ifdef _NORMAL_MAP_ON float3 GetNormalWSFromNormalMap(float3 tnormal, float normalStrength, float3 tspace0, float3 tspace1, float3 tspace2) { tnormal.xy *= normalStrength; float3 res = 0; res.x = dot(tspace0, tnormal); res.y = dot(tspace1, tnormal); res.z = dot(tspace2, tnormal); res = normalize(res); return res; } //float3 GetNormalWSFromNormalMap(sampler2D normalMap, float2 uv, float normalStrength, // float3 tspace0, float3 tspace1, float3 tspace2) //{ // float3 tnormal = UnpackNormal(SAMPLE_TEX2D(normalMap, uv)); // return GetNormalWSFromNormalMap(tnormal, normalStrength, tspace0, tspace1, tspace2); // //tnormal.xy *= normalStrength; // //float3 res = 0; // //res.x = dot(tspace0, tnormal); // //res.y = dot(tspace1, tnormal); // //res.z = dot(tspace2, tnormal); // //res = normalize(res); // //return res; //} #endif float3 BlendingUnpackedNormals(float3 unpackedNormal0, float3 unpackedNormal1) { float2 unpackedBlendedNormalXY = unpackedNormal0.xy + unpackedNormal1.xy; float unpackedBlendedNormalZ = unpackedNormal0.z * unpackedNormal1.z; float3 res = normalize(float3(unpackedBlendedNormalXY.x, unpackedBlendedNormalXY.y, unpackedBlendedNormalZ)); return res; } #ifdef REQUIRE_SCENE_DEPTH float ComputeEyeDepth(float3 vertexWS) { float3 positionVS = mul(UNITY_MATRIX_V, float4(vertexWS, 1.0)).xyz; float res = -positionVS.z; return res; } float GetNormalizedDepth(float4 projPos) { float nearClip = _ProjectionParams.y + global_MinDepth; float farClip = nearClip + global_DepthZoneLength; float cameraRange = farClip - nearClip; float distanceToNearClip = projPos.z - global_MinDepth; float res = distanceToNearClip / cameraRange; res = saturate(res); return res; } float GetEyeDepth(float3 vertexVS) { return -vertexVS.z; } #endif #ifdef _AOMAP_ON float3 GetAOMapTerm(float2 uv) { float aoTex = SAMPLE_TEX2D(_AOMap, uv).r; //float ao = smoothstep(ACCESS_PROP_FLOAT(_AOContrast), 1 - ACCESS_PROP_FLOAT(_AOContrast), aoTex); float3 ao = max(0, (aoTex - float3(0.5, 0.5, 0.5)) * ACCESS_PROP_FLOAT(_AOContrast) + float3(0.5, 0.5, 0.5)); ao = saturate(ao + 1 - ACCESS_PROP_FLOAT(_AOMapStrength)); float3 res = lerp(ACCESS_PROP_FLOAT4(_AOColor).rgb, 1, ao); return res; } #endif #ifdef _DITHER_ON float4 Dither_float4(float4 input, float4 screenPos, float normalizedDistance) { static const float DITHER_THRESHOLDS[16] = { 0.0, 0.5, 0.125, 0.625, 0.75, 0.25, 0.875, 0.375, 0.1875, 0.6875, 0.0625, 0.5625, 0.9375, 0.4375, 0.8125, 0.3125 }; float2 screenUV = screenPos.xy / screenPos.w; screenUV = screenUV * 0.5 + 0.5; float2 pixelPos = screenUV * _ScreenParams.xy * ACCESS_PROP_FLOAT(_DitherScale); uint index = (uint(pixelPos.x) & 3) * 4 + (uint(pixelPos.y) & 3); float dither = DITHER_THRESHOLDS[index] * normalizedDistance; float4 result = input; result.a = saturate(result.a - dither); return result; } #endif float AntiAliasing(float gradient, float cutOff) { cutOff = max(0.01, cutOff); float gradientCutOff = cutOff - gradient; float2 ddxVector = float2(ddx(gradientCutOff), ddy(gradientCutOff)); float res = gradientCutOff / length(ddxVector); res = saturate(0.5 - res); return res; } #endif