- Home /
Is it possible to create a scrolling texture as an image effect (shader)?
So i know about writing shaders for image effects from various tutorials. However, i can't figure out how to render a separate texture "above" the final rendered image. The texture i want to use has a lot of transparency, so that the scene itself could still be seen. Is there a way to render this texture above the scene? I imagine it should be possible to hook this texture into the final render image in screen space projection, but I can't get my head around it. Pointing me into the right direction would be greatly appreciated. Thank you.
Answer by Tobychappell · Dec 30, 2018 at 12:19 PM
(Not tested but done something similar)
Create a shader that has 2 texture inputs, then a material for the shader.
Create a script that uses OnRenderImage and attatch it to the camera.
Look at code example: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnRenderImage.html
Your overlay image will need to be in the 2nd texture slot, Your shader code will basically lerp from the original scene rendered image to the overlay image, it will need to sample texture2's alpha channel to see if there is anything to display, then if alpha is 1 or > 0.5 use overlay image color.
could also throw in some properties like a float for a side scroller, where you would compare the x of the screen position with the scroller value and have some lerping logic to hide the overlay if the screen X position is less than (or greater than) the slider value, making it fade it from left to right. n other cool stuff
Thanks a lot for your response. The thing is: I can sample the texture in the fragment shader right? However... well let me first put some code here:``` struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; };
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o = UNITY_INITIALIZE_OUTPUT(v2f, o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.uv.y += _Time.x * 10;
return o;
}
sampler2D _$$anonymous$$ainTex;
sampler2D _SecondTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_$$anonymous$$ainTex, i.uv);
fixed4 secondcol = tex2D(_SecondTex, i.uv);
//..... and so on....```
So i ofc want to sample it with the same UV-data (i.uv) right? Because both times it is the same "object" that gets textured (the screen space - final image)? But then again, I would need 2 UV sets, because when scrolling the UV-data in the vertex-shader -> it scrolls both texture's by their UV. Sorry if this might sound a little confusing. What i think it is I am trying to ask: Can i get a second float2 uv:TEXCOORD0;
for the appdata struct somehow? And if so, how does it deter$$anonymous$$e which is which? (I'm wondering: is this only possible with a second "pass"?)
Demo Project for ya: https://we.tl/t-kRPY6fTHt$$anonymous$$
Wow, that's awesome, thank you very much :)
Answer by toddisarockstar · Dec 30, 2018 at 01:25 PM
you dont need a shader for this. try a script like this on your game object:
public Material m;
public float x,y;
public void Start(){
m = gameObject.renderer.material;
}
void Update(){
x += Time.deltaTime * .5f;
y += Time.deltaTime * .25f;
if(x>1){x-=1;}if(y>1){y-=1;}
m.mainTextureOffset = new Vector2 (x, y);
}
Well yeah, I guess I could create a plane that i place in front of the camera and let it inherit the camera's movement. So, thanks for the reply, but I'm still curious if it's possible to do this with a shader.