I've written a custom shader (with help) and I'm not sure why it does not have tiling & offset capabilities. What is the simplest way to add that feature to my shader?
current shader code
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/RadarTile"
{
Properties {
_MainTex ("Base (RGB) Trans (A)", 2D) = "black" {}
}
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
//LOD 100 // todo: may need to go up after bump map added @jkr
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
// Blend One SrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma multi_compile_fog
#include "UnityCG.cginc"
uniform float2 _Tiling;
uniform float2 _Offset;
float _EdgeUVEpsilon;
sampler2D _MainTex;
sampler2D _RadarFrame2;
sampler2D _ReflectivityLUT;
float _FrameInterpolationAmount;
float4 _ShadowColor;
sampler2D _NextTex;
float _PlaybackTime;
float _PlaybackPosition;
int _TotalFrames;
int _FirstFrameIndex;
int _LastFrameIndex;
#include "inc/TileBender.cginc"
v2f vert(appdata v)
{
// v2f output = vertBender(v, _EdgeUVEpsilon);
// return output;
// v.texcoord *= _Tiling; // Apply tiling
// v.texcoord += _Offset; // Apply offset
return vertBender(v, _EdgeUVEpsilon);
}
float4 frag (v2f i) : SV_Target
{
fixed4 col = lerp(tex2D(_MainTex, i.uv), tex2D(_RadarFrame2, i.uv), _FrameInterpolationAmount);
col = saturate(pow(col, 1.0/2.2));
col = tex2D(_ReflectivityLUT, float2(col.r, 0));
if (col.a > 0) return _ShadowColor; // comment out to disable shadows @jacksonkr_
return 0;
// return col.a > 0 ? _ShadowColor : 0;
}
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma multi_compile_fog
#include "UnityCG.cginc"
float _ReflectivityHeightMultiplier;
float _EdgeUVEpsilon;
sampler2D _MainTex;
sampler2D _RadarFrame2;
sampler2D _ReflectivityLUT;
float _FrameInterpolationAmount;
float3 _LightDirection;
float3 _LightColor;
float _NdotlEffect;
float _RadarLightAttenuation;
float _Roughness;
float _Vibrance;
#include "inc/TileBender.cginc"
v2f vert(appdata v)//appdata_tan_ v)
{
v2f output = vertBender(v, _EdgeUVEpsilon);
//this is a bit of a roundabout way to get here, but I have to work around the tile bending code so we're going with it -BH
float reflectivity = tex2Dlod(_MainTex, float4(output.uv, 0, 0)).r;
float4 offsetWorldPosition = float4(output.worldPos + output.norm * reflectivity * _ReflectivityHeightMultiplier, 1);
output.pos = UnityObjectToClipPos(mul(unity_WorldToObject, offsetWorldPosition));
//normal calculation
const float e = 1.0 / 129.0;
if(output.uv.x <= _EdgeUVEpsilon + e || output.uv.x >= 1 - _EdgeUVEpsilon - e || output.uv.y <= _EdgeUVEpsilon + e || output.uv.y >= 1 - _EdgeUVEpsilon - e)
{
return output;
}
/*
//tangent
float2 tangentUV = v.uv + float2(e,0);
float3 tangentSamplePoint = v.position + v.tangent * e;
float3 tangentWorldPosition = mul(unity_ObjectToWorld, tangentUV);
float3 tangentNormal = normalize(tangentWorldPosition);
reflectivity = tex2Dlod(_MainTex, float4(tangentUV, 0, 0)).r;
tangentWorldPosition = tangentWorldPosition + tangentNormal * reflectivity * _ReflectivityHeightMultiplier;
float3 tangent = normalize(tangentWorldPosition - offsetWorldPosition);
//binormal
tangentUV = v.uv + float2(0, e);
tangentSamplePoint = v.position + cross(v.normal, tangent) * e;
tangentWorldPosition = mul(unity_ObjectToWorld, tangentUV);
reflectivity = tex2Dlod(_MainTex, float4(tangentUV, 0, 0)).r;
tangentWorldPosition = tangentWorldPosition + tangentNormal * reflectivity * _ReflectivityHeightMultiplier;
float3 binormal = normalize(tangentWorldPosition - offsetWorldPosition);
//final calc
output.norm = -cross(tangent, binormal);
*/
return output;
}
float4 frag (v2f i) : SV_Target
{
fixed4 col = lerp(tex2D(_MainTex, i.uv), tex2D(_RadarFrame2, i.uv), _FrameInterpolationAmount);
col = saturate(pow(col, 1.0/2.2));
const float3 precipitationTypeThresholds = saturate(pow((float3(255, 200, 150) - 0.5)/ 255.0, 1.0/2.2));
float v = 0;
if( col.a > precipitationTypeThresholds.x)
{
v = .67;
}
else if(col.a > precipitationTypeThresholds.y)
{
v = .34;
}
else if(col.a > precipitationTypeThresholds.z)
{
v = 0;
}
col = tex2D(_ReflectivityLUT, float2(col.r, v));
//minnaert shading implementation
float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.norm * _EarthRadius);
float3 cameraSpaceLightDirection = mul(unity_CameraToWorld, normalize(_LightDirection));
float NdotL = max((1 - _NdotlEffect), dot( i.norm, cameraSpaceLightDirection));
float NdotV = max(0, dot( i.norm, viewDirection ));
float3 minnaert = saturate(NdotL * pow(NdotL * NdotV, _Roughness));
float3 lightingModel = minnaert * col.xyz;
float3 attenColor = _RadarLightAttenuation;
col = float4(lightingModel * attenColor, col.a);
//vibrance
half average = (col.r + col.g + col.b) / 3.0;
half maximum = max(col.r, max(col.g, col.b));
half vibrance = (maximum - average) * (-_Vibrance * 3.0);
col.rgb = lerp(col.rgb, half3(maximum, maximum, maximum), vibrance);
// float4 blend = tileblend(i, col);
// return blend;
return col;
}
ENDCG
}
}
}
TileBender.cginc
/**
// Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members worldPos)
#pragma exclude_renderers d3d11
* this cginc helps bend shaders to a sphere
*/
// #define PI_5 1.5707963267948966192313216916398f
// #define PI 3.1415926535897932384626433832795f
// #define PI2 6.283185307179586476925286766559f
// #define QUARTER_PI 0.7853981634
// float _TileOverlap;
// float _TileBlendFactor;
float _ShadowOffset;
struct appdata {
float4 pos: POSITION;
float2 uv : TEXCOORD0;
float4 normal : NORMAL;
};
// struct appdata_tan_ {
// float4 position: POSITION;
// float2 uv : TEXCOORD1;
// float4 normal : NORMAL;
// float4 tangent : TANGENT;
// };
struct v2f {
float4 pos : SV_POSITION;
float3 norm : NORMAL;
half2 uv : TEXCOORD0;
float3 worldPos : COLOR0;
// UNITY_FOG_COORDS(1)
};
float _EarthRadius;
// #pragma distance from earth
void procDistFromEarth(inout v2f o) {
float4 offsetWorldPosition = float4(o.worldPos - _ShadowOffset * o.norm, 1);
o.pos = UnityObjectToClipPos(mul(unity_WorldToObject, offsetWorldPosition));
}
// #pragma vertbender
// v2f vert(appdata v)
/**
* bends the vertices to fit a sphere shape @jacksonkr_
*/
v2f vertBender(appdata v, float _EdgeUVEpsilon)
{
v2f o;
o.pos = UnityObjectToClipPos(v.pos);
o.uv = clamp(v.uv, _EdgeUVEpsilon, 1-_EdgeUVEpsilon);
o.norm = v.normal;
o.worldPos = mul(unity_ObjectToWorld, v.pos);
procDistFromEarth(o);
return o;
}
```