• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Electrospeed · Jul 16, 2016 at 07:14 PM · shadereffectsshader writing

Moving tracer shader with line renderer

Hi, I'm trying to write a customizable tracer shader to use with my game. The gun raycasts outward to find a target, and passes in an origin and target to my tracer factory, which then creates a TracerPrefab consisting of an empty GameObject with a LineRenderer component and sets the line's positions to the origin and target.

The line renderer is using a custom material with a shader I'm attempting to write. At the moment, I'm stuck trying to get the shaded portion of the LineRenderer to move at a consistent speed. When aiming into the distance, it moves very fast, but when aiming at something close it moves very slowly. This is because it doesn't take into account how far along relative to the LineRenderer it is, which is my question.

Is it possible to figure out how far along the uv.x is relative to the LineRenderer?

I've attempted to use the vertex.z coordinate, but of course that deals with position from the camera, not on the line.

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         
         #include "UnityCG.cginc"

         struct appdata
         {
             float4 vertex : POSITION;
             float2 uv : TEXCOORD0;
         };

         struct v2f
         {
             float2 uv : TEXCOORD0;
             float4 vertex : SV_POSITION;
         };

         sampler2D _MainTex;
         fixed4 _Color;
         float _Length;
         float _StartTime;
         float _Speed;
         float _Offset;
         
         v2f vert (appdata v)
         {
             v2f o;
             o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
             o.uv = v.uv;
             return o;
         }
         
         fixed4 frag (v2f i) : SV_Target
         {
             float timeDiff = _Time.y - _StartTime + _Offset;
             if ((i.uv.x + _Speed) > timeDiff * _Speed)
             {
                 return fixed4(0, 0, 0, 1);
             }
             return fixed4(1, 1, 1, 0);
         }


The script that creates it passes in the current time with Time.timeSinceLevelLoad to _StartTime. This is used to move the drawn position based on how long it has existed. _Speed is a range from 0 to 2. _Offset is used to offset the spawning of the tracer from the spawning of the line.

Sorry if this is obvious, I'm slightly green with shaders in general. Thanks for any help.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Electrospeed · Jul 17, 2016 at 03:03 PM

I haven't found a way to do it directly from the shader, so I'm simply extending the LineRenderer to a predetermined maximum, and scripting _MaxDistance and _CutoffDistance values to the shader, so when the tracer needs to stop because it hit a wall, the _CutoffDistance will stop it, as well as _MaxDistance lending itself pretty well towards fixed speed calculations. Here's the shader if anyone wants it. It has controls to set base transparency and fade duration as well as things like length, color, speed, etc. Please note that the speed is partially tied to the length; if you make it longer, you should turn down the speed if you want it to move the same speed as a shorter tracer. And here's a super-professional, Grade-A tracer texture to use.

 Shader "Custom/TracerShader"
 {
 Properties
 {
     _MainTex("Tracer Texture", 2D) = "white" {}
     _Color("Color", Color) = (1, 1, 1, 1)
     _Length("Length", Range(0.1, 1000)) = 1
     _Speed("Speed", Range(0, 15)) = 2.0
     _StartTime("Start Time", Float) = 0.0
     _Offset("Offset", Range(1, 5)) = 0
     _Fade("Fade time", Range(0, 5)) = 0
     _Transparency("Transparency", Range(0, 1)) = 0
     _TailBlendCutoff("Tail Blending Cutoff", Range(0, 1)) = 0.0
     _Width("Tracer Texture Width", Float) = 0.0
     _MaxDistance("Max Distance", Float) = 1000.0
     _CutoffDistance("Cutoff Distance", Float) = 0.0
     _AlphaClamp("Alpha Clamp", Range(0, 1)) = 0.0
     _Debug("Debug", int) = 1
     _DebugColorPre("DebugColorPre", Color) = (1, 1, 1, 1)
     _DebugColorPost("DebugColorPost", Color) = (1, 1, 1, 1)
 }

 SubShader
 {
     Tags 
     {
         "RenderType" = "Transparent"
         "Queue" = "Transparent"
     }

     Pass
     {
         BlendOp Add
         Blend SrcAlpha SrcAlpha
         ZTest LEqual
         ZWrite Off

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         
         #include "UnityCG.cginc"

         struct appdata
         {
             float4 vertex : POSITION;
             float2 uv : TEXCOORD0;
         };

         struct v2f
         {
             float2 uv : TEXCOORD0;
             float4 vertex : SV_POSITION;
         };

         sampler2D _MainTex;
         fixed4 _Color;
         float _Length;
         float _StartTime;
         float _Speed;
         float _Width;
         float _Offset;
         float _Fade;
         float _Transparency;
         float _TailBlendCutoff;
         float _MaxDistance;
         float _CutoffDistance;
         float _AlphaClamp;
         int _Debug;
         fixed4 _DebugColorPre;
         fixed4 _DebugColorPost;

         fixed alpha(fixed4 col)
         {
             fixed total = max(col.r, max(col.g, col.b));
             if (total < _AlphaClamp) //if the color is too dark, clamp to transparent
                 return 1;
             return total;
         }
         
         v2f vert (appdata v)
         {
             v2f o;
             o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
             o.uv = v.uv;
             return o;
         }
         
         fixed4 frag (v2f i) : SV_Target
         {
             //if debugging is off, make the colors transparent
             if (_Debug == 0)
             {
                 _DebugColorPre = fixed4(0, 0, 0, 1);
                 _DebugColorPost = fixed4(0, 0, 0, 1);
             }
             
             //if we've passed the cutoff distance, don't sample the tracer
             float cutoff = _CutoffDistance / _MaxDistance;
             if (i.uv.x > cutoff || i.uv.x < (_Offset / _MaxDistance))
             {
                 return _DebugColorPost;
             }

             //calculate the difference between the current time and the start time
             //if the uv.x coordinate is past it, don't sample the tracer
             float timeDiff = (_Time.y - _StartTime) * ((_Speed / 10) * _Length); //divided by 10 to give reasonable speed values
             if (i.uv.x > timeDiff)
             {
                 return _DebugColorPost;
             }

             //calculate the length of the tracer by dividing the _Length parameter by the _MaxDistance parameter and multiplying by the texture width
             //NOTE: this does make tracer lengths dependent on both the _MaxDistance used and the width of the texture
             float tracerLength = (_Length / _MaxDistance) * _Width;

             //get the uv coordinate of the start of the tracer
             float tracerStart = timeDiff - tracerLength;

             if (i.uv.x > tracerStart) //if we're inside the tracer's area...
             {
                 float tracerOffset = (i.uv.x - tracerStart) / tracerLength;

                 float2 samp = i.uv;
                 samp.x = tracerOffset; //calculate the uv coordinate relative to the tracer that we need to sample
                 fixed4 col = tex2D(_MainTex, samp);

                 col = (col * _Color * (1 - _Transparency)); //calculate _Color and _Transparency

                 if (_Fade > 0)
                     col = col * (1 - timeDiff / _Fade); //calulate _Fade

                 float tailBlendUV = _TailBlendCutoff / (_MaxDistance / 10);

                 if (i.uv.x < tailBlendUV)
                 {
                     float blendVal = (i.uv.x / tailBlendUV) - 0.3; //calculate tail blend
                     col = col * min(1, blendVal);
                 }

                 col.a = alpha(col);
                 return col;
             }
             else //don't sample the tracer
             {
                 return _DebugColorPre;
             }


         }
         ENDCG
     }
 }

}

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Simple Special effects 0 Answers

Shader Color 1 Answer

Use contents of RWStructuredBuffer written by shader in another shader 0 Answers

Unity Shadergraph Alpha threshold problem 0 Answers

Where do I put this shader code? Getting weird error? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges