- Home /
Vertex Animation Shader Not Compatible with Android
I've kit-bashed the shader below in order to add some simple motion to background objects in my scene (trees, bushes, etc). I'm fairly happy with the results in the Editor and on PC builds, however it does not work at all when i build to Android devices (tested on Nexus 6 and Nexus 9).
Any ideas on what part of the code is making Android unhappy and any ways to make it work? I'm very new to working with Shaderlab in Unity (or working shaders at all for that matter) and can't seem to figure this one out.
Thanks (Sorry for the messy commenting)
// Unlit alpha-cutout shader.
// - no lighting
// - no lightmap support
// - no per-material color
Shader "Custom/Unlit/Transparent Cutout Wave" {
Properties {
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_WaveX ("Wave X", Vector) = (0.01, 0.01, 0.01, 0.01)
_WaveZ ("Wave Z", Vector) = (0, 0, 0, 0)
_WaveSpeed ("Wave Speed", Vector) = (1, 1.5, 1.1, .9)
}
SubShader {
//Ztest Less
Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
LOD 100
Lighting Off
Pass {
CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//#include "waves.cginc" // Get in the helper wave functions
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
//float4 pos : POSITION;
//float fog : FOGC;
};
void FastSinCos (float4 val, out float4 s, out float4 c)
{
val = (val * 1.02 - .5) * 6.28318530; // scale to range: -pi to pi & make it cyclic
// powers for taylor series
float4 r5 = val * val; // wavevec ^ 2
float4 r1 = r5 * val; // wavevec ^ 3
float4 r6 = r1 * val; // wavevec ^ 4;
float4 r2 = r6 * val; // wavevec ^ 5;
float4 r7 = r2 * val; // wavevec ^ 6;
float4 r3 = r7 * val; // wavevec ^ 7;
float4 r8 = r3 * val; // wavevec ^ 8;
//Vectors for taylor's series expansion of sin and cos
float4 sin7 = {1, -0.16161616, 0.0083333, -0.00019841};
float4 cos8 = {-0.5, 0.041666666, -0.0013888889, 0.000024801587};
// sin
s = r1 * sin7.y + val + r2 * sin7.z + r3 * sin7.w;
// cos
c = 1 + r5 * cos8.x + r6 * cos8.y + r7 * cos8.z + r8 * cos8.w;
}
float4 DoCalcWave (float4 waveoffsets, inout float3 vertex, inout float3 normal, float4 waveHeights, float4 waveDirX, float4 waveDirY)
{
float4 s, c;
FastSinCos (waveoffsets, s, c);
// wave height
float height = dot (s, waveHeights);
// offset vertex by normal
vertex.xyz += normal * height;
// offset normal by cos (wave)
float4 coswave = c * waveHeights;
//normal.xz += float2 (dot (coswave, waveDirX), dot (coswave, waveDirY)) * uvParams.z;
//normal.xz += float2 (dot (coswave, waveDirX), dot (coswave, waveDirY));
normal = normalize (normal);
return s;
}
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _Cutoff;
uniform float4 _WaveX, _WaveZ, _WaveSpeed;
//uniform float3 _obstacle;
//uniform float _affectDist, _bendAmount;
v2f vert (appdata_t v)
{
v2f o;
const float4 _waveXSize = _WaveX * 2;
const float4 _waveZSize = _WaveZ * 2;
const float4 waveSpeed = _WaveSpeed * 4;
float4 _waveXmove = _waveXSize * waveSpeed * 25;
float4 _waveZmove = _waveZSize * waveSpeed * 25;
// Calculate the wind input to leaves from their vertex positions....
float3 worldPos = mul ((float3x4)_Object2World, v.vertex);
// OBSTACLE AVOIDANCE CALC
//float3 bendDir = normalize (float3(worldPos.x,worldPos.y,worldPos.z) - float3(_obstacle.x,_obstacle.y,_obstacle.z));//direction of obstacle bend
//float distLimit = _affectDist;// how far away does obstacle reach
//float distMulti = (distLimit-min(distLimit,distance(float3(worldPos.x,worldPos.y,worldPos.z),float3(_obstacle.x,_obstacle.y,_obstacle.z))))/distLimit; //distance falloff
//OBSTACLE AVOIDANCE END
// This is the input to the sinusiodal warp
float4 waves;
waves = worldPos.x * _waveXSize;
waves += worldPos.z * _waveZSize;
// Add in time to model them over time
waves += _Time.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
float waveAmount = v.texcoord.y;
s *= waveAmount;
// Fast winds move the grass more than slow winds
s *= normalize (waveSpeed);
s = s * s;
float fade = dot (v.texcoord.y * v.texcoord.y, 2);
s = s * s;
float3 waveMove = float3 (0,0,0);
waveMove.x = dot (s, _waveXmove);
waveMove.z = dot (s, _waveZmove);
v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz;
//v.vertex.xz += bendDir.xz * distMulti * v.texcoord.y * v.texcoord.y * _bendAmount; //ADD OBSTACLE BENDING
//optional y bending
//v.vertex.xyz += bendDir.xyz * distMulti * v.texcoord.y * v.texcoord.y * _bendAmount; //ADD OBSTACLE BENDING
//o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
//o.fog = o.pos.w;
//o.uv = v.texcoord;
//o.color = lerp (_Color, _Color2, fade.xxxx);
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord);
clip(col.a - _Cutoff);
return col;
}
ENDCG
}
}
Fallback "Unlit/Transparent Cutout"
}
Answer by calwilliams · Feb 19, 2015 at 04:13 PM
Here is the shader/scripts that ended up working for me. Its modified version of the shader found in the "Palm Trees Pack" which you can get for Free on the Asset Store.
Shader "Custom/WavingDoublePass" {
Properties {
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_WaveAndDistance ("Wave and distance", Vector) = (12, 3.6, 1, 1)
_Cutoff ("Cutoff", float) = 0.5
}
SubShader
{
Tags{"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
Lighting Off
CGPROGRAM
#pragma surface surf Lambert vertex:AtsWavingGrassVert addshadow
#include "TerrainEngine.cginc"
#include "wavingAlpha.cginc"
struct Input
{
float2 uv_MainTex;
};
sampler2D _MainTex;
fixed _Cutoff;
void surf (Input IN, inout SurfaceOutput o) {
clip(tex2D (_MainTex, IN.uv_MainTex).a - _Cutoff);
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgba;
o.Emission = 0;
}
ENDCG
}
Fallback "Unlit/Transparent Cutout"
}
wavingAlpha.cginc
void AtsWavingGrassVert (inout appdata_full v) {
////////// start bending
float4 _waveXSizeMove = float4(0.048, 0.06, 0.24, 0.096);
float4 _waveZSizeMove = float4 (0.024, .08, 0.08, 0.2);
float4 waveSpeed = float4 (1.2, 2, 1.6, 4.8);
float4 waves;
waves = v.vertex.x * _waveXSizeMove;
waves += v.vertex.z * _waveZSizeMove;
_waveXSizeMove = float4(0.024, 0.04, -0.12, 0.096);
_waveZSizeMove = float4 (0.006, .02, -0.02, 0.1);
// Add in time to model them over time
waves += _WaveAndDistance.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
float waveAmount = v.color.a * _WaveAndDistance.z;
// Faster winds move the grass more than slow winds
s *= normalize (waveSpeed);
s = s * s;
float lighting = dot (s, normalize (float4 (1,1,.4,.2))) * .7;
s *= waveAmount;
fixed3 waveColor = lerp (fixed3(0.5,0.5,0.5), _WavingTint.rgb, lighting);
v.color.rgb = v.color.rgb * waveColor * 2;
float3 waveMove = float3 (0,0,0);
waveMove.x = dot (s, _waveXSizeMove);
waveMove.z = dot (s, _waveZSizeMove);
v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz * 8;
////////// end bending
}
Waving Animation Script
using UnityEngine;
using System.Collections;
public class WavingAnimationScript : MonoBehaviour {
public Shader shader;
public Material mat;
// Update is called once per frame
void Update () {
Vector4 waving = mat.GetVector("_WaveAndDistance");
float wavingPower = waving.w;
float wavingMod = Time.deltaTime*0.10f*wavingPower*Random.value;
waving.x += wavingMod;
waving.y -= wavingMod;
mat.SetVector("_WaveAndDistance", new Vector4(waving.x,waving.y,waving.z,waving.w));
}
}
Answer by giulio-pierucci · Feb 14, 2015 at 02:12 AM
Maybe Shader error in 'Custom/Unlit/Transparent Cutout Wave': Program 'frag', unknown semantics "SV_Target" specified for "frag" at line 151?
BTW, too many float for a mobile! Use fixed and half, if you can
Sorry for the late response. I don't believe that "SV_Target" is to blame as the built-in Unlit/Transparent Cutout shader uses it and it work fine on mobile.
After much testing, I still couldn't get it to work on device, so I ended up going with a different shader and got this one to work on device.