Hello, I am creating a vertex shader to expand the model, and contract it, expand, and contract etc etc. I currently have the expanding, and the contracting I can do. Its the expanding AND THEN contracting, AND THEN expanding. I can only seem to do one at a time. Does CG have an equivalent to the Mathf.PingPong? Thanks
As far as I know, there isn't really a function that does this for you. You can probably make this yourself by swapping values after a specific condition is met, but I think you will be better of by just passing the pingpong value from script to the shader.
If you want a triangle wave, you can use abs(frac(_Time.y*speed)-0.5)*magnitude There is also _SinTime and _CosTime you can read about it here: https://docs.unity3d.com/Documentation/Components/SL-BuiltinValues.html
_SinTime! I knew I had forgotten something obvious. Thanks heaps, and thanks for the link to the values page. I was googling 'Shader math / Shader math functions' and couldnt find anything. Thanks again.
It might not really matter in your case, but would passing a value that you can use for pingpong purposes be cheaper than using a sin/cos function as those are generally expensive in use?
But it still uses the sin function I guess? Except that it's likely to be set from within the engine.
If you look in UnityShaderVariables.cginc, you see it says: Code (csharp): CBUFFER_START(UnityPerCamera) // Time values from Unity uniform float4 _Time; uniform float4 _SinTime; uniform float4 _CosTime; uniform float4 unity_DeltaTime; // dt, 1/dt, smoothdt, 1/smoothdt So I'm pretty sure they're set from the CPU, instead of being calculated on the GPU, and I assume they take about as much time as other shader properties. I should measure that of course...
I checked the cg standard library and could not find any function named Pingpong or something like that, but I think we can write one, just like this : // return value falls in [0, 1] section // float Pingpong() { int remainder = fmod(floor(_Time.y), 2); return remainder==1?1-frac(_Time.y):frac(_Time.y); } if you want to expand the return value's range just multiply by another value, I tested and it worked well. Hope this could do some help.