Image texture bug while using custom UV texture scrolling shader
Hi.
I am having a problem in my AR app. I have two textures which are tiled along a spiral shape and I want to animate them scrolling. Since Unity doesn't import UV coordinates animation from C4D, I had to do it inside Unity. Luckily, I found the code in the Unity forums for a custom shader:
Properties {
_MainTex ( "Base (RGB)", 2D ) = "white" {}
_XScrollSpeed ( "X Scroll Speed", Float ) = 1
_YScrollSpeed ( "Y Scroll Speed", Float ) = 1
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
float _XScrollSpeed;
float _YScrollSpeed;
struct Input {
float2 uv_MainTex;
};
void surf( Input IN, inout SurfaceOutput o ) {
fixed2 scrollUV = IN.uv_MainTex;
fixed xScrollValue = _XScrollSpeed * _Time.x;
fixed yScrollValue = _YScrollSpeed * _Time.x;
scrollUV += fixed2( xScrollValue, yScrollValue );
half4 c = tex2D( _MainTex, scrollUV );
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
This is what I see in the unity editor:
Unfortunately, while I am previewing on the phone, the texture is very strange (next picture). I had sucess with this technique with another SDK, but this must be causing some problem with MAXST.
I tried changing shader to Unlit/Texture and the texture looks okay, but with this shader, the texture is not animated/scrolling. I really need to have the animation because I will use the same technique in other targets/models.
Is there any way to correct this? Is it a problem in the code of the shader?
Thank you
S.
We repect of your deep diving into our sdk.
Could you please give our team some data for reproducing same problem?
It may contain c3d file and shader code.
Thanks
- Maxst support team
Hi.
Thanks! It's being very fun exploring AR in my area of studies (graphic design), but the technical aspect can be sometimes intimidating, for someone with zero experience in this matter.
I couldn't attach a file to this post so I uploaded it to my Dropbox, if that's okay: https://www.dropbox.com/s/glik9tvi42j5j11/unityproblem.zip?dl=0
In this ZIP you have one C4D file with the spiral geometry (three separate objects): the inside, the ouside and the border between these two. The inside should have the texture 'emptiness.png' and the outside 'substance.png'. The border is just a black material. These images are inside the folder 'tex'. I also attached my CS file for the shader.
Here are my inspector settings for each texture in Unity:
Let me know if you need something more and thank you very much for your kind help!
S.
Hi again. I managed to fix it! :-) However, I am having some doubts if this solution could cause future problems. I remember that I had this exact same issue on another SDK that I tried before experimenting with MAXST. I have tried 3 SDKs so far. The first one worked well while the two last SDKs (including MAXST) were having this issue. I didn't bother trying to fix it in the second SDK because the tracking was working really bad.
Anyway, the only thing I remembered that MAXST and the second SDK I used had in common was the instructions to disable Auto Graphic API and prioritize OpenGLES 2 over OpenGLES 3, so I thought I could try setting it to Auto like in the first SDK and see what happened.
I did it and built the app and it's working perfectly now - at least on my device (running Android 7.1.1).
My question is: since it's Auto Graphic API, do you think that the app could have this issue on a device that would be automatically using OpenGLES 2? Or would it be preferable to disable Auto Graphic API to set OpenGLES 3 only and delete OpenGLES 2? In my understanding this would force OpenGLES 3 all the times, preventing this issue to happen. This leads to another question: Are there any phones nowadays that don't support OpenGLES 3? What would happen in those cases?
Maybe the optimal solution would be to modify the shader code to make it work with the two different OpenGLES versions? I don't know if that's possible and I have no idea how to even begin doing that.
Please let me know your thoughts regarding this situation.
Thank you,
S.
Thanks a lot for your long and detailed explanations.
So.. is your conclusion that you could have fixed shader issue by yourself, by any chance?
We are planning to upgrade our sdk as it doesn't need to change graphic api settings.
As you mentioned most of android devices support GLES3 but we can't confirm all the devices support it or not.
That's why we recommend to set as GLES2 because all android devices support GLES2.
Google empowers to Vulkan graphic api and Apple does to Metal recently.
Unity already supports metal and vulkan api and as we know unity sellects proper api in runtime automatically.
It's a hard thing to follow many technical changes but we are doing our best for our developers and clients :-)
Thanks again
- Maxst support team
Hi. I don't really know how to fix the shader because of my lack of programming skills, so I'll go with another solution for now:
I will select OpenGLES 3.0 only (disabling Auto and removing OpenGLES 2.0). From what I found online, Android devices that are shipped with 4.3 or higher should support OpenGLES 3.0. In that case, I will raise the minimum API level to version 4.3 so that devices that don't support OpenGLES 3.0 can't install the app. I think that won't be a very common scenario nowadays, and I'd rather block the installation on devices that don't support OpenGLES 3.0 than having them install and seeing the content in that bugged state.
That's my workaround for now. In the meantime, I will be trying to search if someone wrote and posted another shader for the same function. Maybe with a different shader/code it would work in OpenGLES 2.0? I'm not sure but I'll give it a try. If I manage to fix it with OpenGLES 2.0 I will share the shader code here for future developers who could need it. :-)
Thanks for your help and keep up the good work!
S.
Yes, your comment about supported opengles version is almost correct.
But android devices are very fragmented so we can not assure about it.
If you want to filter android devices that support gles3.0 or over please refer to below script in Androidmanifest.xml.
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
If you have knowledge about unity shader coding you could be better keep going for getting opengles 2.0 support.
If not, we recommend to pause for deeper investigating about it. Actually shader programming is not easy work.
Finding solution is our task.
Thanks
- Maxst support team
Hi again,
We have been struggling to import your C4d file but failed to load in the end.
To import C4d file we need payed C4d program but we don't have.
Could you please send our team with fbx file?
- Maxst support team
Thanks! I will add it to android manifest for now, to block below 3.0 and I will try to find a solution for the shader.
Regarding the FBX file, here's a link to it: https://www.dropbox.com/s/7pl3igvzfvnc20v/spiral.fbx?dl=0
I will investigate better about the shaders to see if I can figure it out.
S.
Hi again,
I found the perfect solution, I think. Because I have no idea how to write or modify the shader, I looked for another way to do it. I read in the Unity forums that it is possible to animate the UV coordinates using a script instead of a shader. Then I found a script that does that on this video and then I tried to implement it.
Javascript:
var scrollSpeed = 0.90;
var scrollSpeed2 = 0.90;
function FixedUpdate() {
var offset = Time.time * scrollSpeed;
var offset2 = Time.time * scrollSpeed2;
renderer.material.mainTextureOffset = Vector2 (offset2,-offset);
}
I used a Mobile/Diffuse shader to get the same look/colors as I was getting in the UV Animation shader I was using, and then I assigned the script to the elements that needed the texture to scroll. I also disabled Auto API and set OpenGL ES 2 first and built my app. I also removed the line from the manifest to remove the restriction to OpenGL ES 3.
It's working perfectly! I hope this helps someone out in the future.
One question: in the video he is using JavaScript, but in the comments he provided also a C# version.
C# Script:
using UnityEngine;
using System.Collections;
public class ScrollingScript : MonoBehaviour
{
public float scrollSpeed = 0.9f;
public float scrollSpeed2 = 0.9f;
void FixedUpdate ()
{
float offset = Time.time * scrollSpeed;
float offset2 = Time.time * scrollSpeed2;
renderer.material.mainTextureOffset = new Vector2 (offset2, -offset);
}
}
Which one should I use? The JS is working just fine but I don't know if C# would be preferable? Maybe one of them is lighter/faster? What do you think?
Thanks,
S.
We are sorry to make you waiting.
By unity document there is no difference between javascript and c# script because unity uses compiled binary code at runtime.
Congratulations of your great work!
Our team now developing our sdk to support all graphic api (also metal) for easy using.
And next update (It may be 3.5) will be released early next month.
So..we recommend you to use your great solution at this monent.
Thanks a lot again for using our sdk.
- Maxst support team
Thanks for the help! I'll be looking forward to 3.5 :-)
S.