Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[RELEASED] Volumetric Lines

Discussion in 'Assets and Asset Store' started by j00hi, Feb 20, 2015.

  1. owen_proto

    owen_proto

    Joined:
    Mar 18, 2018
    Posts:
    118
    Thanks for the suggestions @bgolus ! Unfortunately I was animating the line with a sinusoidal function (and also translating the line object in 3d space) so that only increases the likelihood of the artifacts being noticeable. I'll either keep the curves shallow or attempt implementing the method I linked in my last post at some point.
     
  2. starfoxy

    starfoxy

    Joined:
    Apr 24, 2016
    Posts:
    183
    Can anyone give me some guidance as to dynamically changing the line start and line end points from another script? Even a small code sample would be helpful. Thank you!

    ---edit---

    Figured it out. This asset is awesome and very performant. Great work!
     
    Last edited: Jun 19, 2019
  3. endasil_unity

    endasil_unity

    Joined:
    Jun 28, 2018
    Posts:
    19
    How would i go about if i want two beams with different colors? If i duplicate the line object and change the shot_mat of one of them i change the other one to. How can I make the objects have their own copy of the shot mat? Changing
     
  4. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72


    Changing a Volumetric Line's color using the VolumetricLineBehavior's "Line Color" is everything that should be required for getting differently colored lines. Materials are created and set automatically according to this property.
     
  5. Deleted User

    Deleted User

    Guest

    Hi! I was planning on using the volumetric line for a laser, but for some reason, it hides behind an object that isn't even between it and the shooting target. Any idea how to fix this? Thanks in advance. I would show a pic if I could. I basically have a spacecraft with the laser in front of it, and a planet behind them. The "laser" is strangely blocked by the planet but shows up if it's over the spacecraft.
     
  6. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    Please check if the volumetric line material's Render Queue is set to 'Shader' or 'Transparent'. If it isn't, please change it (preferably to 'Shader'). It might be that it is set to 'Geometry' in your case, which could lead to the effects you have described.
     
  7. Deleted User

    Deleted User

    Guest

    Thanks! Works like a charm!
     
  8. Excession

    Excession

    Joined:
    Jun 18, 2018
    Posts:
    6
    Hi, I've been using your volumetric lines for laser shots etc. very successfully but noticed the they don't work with the new URP. Do you have any plans to update the Asset to support URP?
     
  9. Pourya-MDP

    Pourya-MDP

    Joined:
    May 18, 2017
    Posts:
    145
    Hello and so much thanks for the free asset
    I have a problem and i hop it will be a fixable one
    Im trying to create a laser effect with your shader
    Everything is perfect except one thing
    There is an green line that will pass through the scene objects
    And i dont want this to happen
    Is this something hopefully we can fix??
    I Appreciate any help

    Edit: i think i found it
    It's a gizmo i think ,and i shoud just disable it
    Will try and update my post

    Ps: my bad
    That was gizmo
    Your asset is priceles dude
    Keep up the good work
     
    Last edited: Mar 23, 2020
  10. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    Thanks for your interest in this asset. I have good news for you: URP support is here.

    I have decided to submit it as a paid package to the asset store, called "Volumetric Lines URP". Review is still pending, however. I.e. it is not available on the asset store yet. As soon as it is released, please consider supporting the development of this asset by purchasing it.

    If you want to try it before purchasing or if you do not deem this asset worthy of your financial support, you can get it directly from GitHub: https://github.com/johannesugb/VolumetricLinesUnity/tree/universal_render_pipeline
    It is available as of now and should be working fine with the universal render pipeline.

    In any case, please send me your feedback --- especially if you are encountering any problems.
    May Volumetric Lines URP serve you well in reaching your goals!
     
    nicloay and chelnok like this.
  11. liaochenhan

    liaochenhan

    Joined:
    Aug 25, 2018
    Posts:
    2
    Hi, this asset is brilliant and I am so inpressed. I am curious about the volumetric line algorithm, but I can't understand some steps in _SingleLineShader.cginc. Do you have the article about the volumetric lines algorithm by Sébastien Hillaire? The link about the volumetric lines algorithm that you shared in 2013 can't open. Thanks!
     
  12. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    Thank you for your kind words!

    Unfortunately, Sébastien Hillaire's website is no longer online for quite a while now. I have little hope that it will change anytime soon. You can try your luck with an internet archive like this: https://web.archive.org/

    The algorithm is described in detail in OpenGL Insights, Chapter 11: http://openglinsights.com/
    I don't know if it is available for free anywhere, but sometimes the electronic version of the book can be purchased for little money (you can look for humble bundles).

    Good luck!
     
  13. liaochenhan

    liaochenhan

    Joined:
    Aug 25, 2018
    Posts:
    2
    Thank you for your advise!
     
  14. Abnormalia_

    Abnormalia_

    Joined:
    Jul 23, 2013
    Posts:
    128
    Thanks for free cool asset. Here's my 2 cents. Modified "_SingleLineShader.cginc" so it works correctly in VR single pass stereo mode.

    Code (CSharp):
    1. #ifndef VOL_LINE_SINGLE_LINE_SHADER_INC
    2. #define VOL_LINE_SINGLE_LINE_SHADER_INC
    3.    
    4.     #include "UnityCG.cginc"
    5.    
    6.     // Property-variables declarations
    7.     sampler2D _MainTex;
    8.     float _LineWidth;
    9.     float _LineScale;
    10. #ifdef LIGHT_SABER_MODE_ON
    11.     fixed _LightSaberFactor;
    12.     fixed4 _Color;
    13. #endif
    14.  
    15.     // Vertex shader input attributes
    16.     struct a2v
    17.     {
    18.         float4 vertex : POSITION;
    19.         float3 otherPos : NORMAL; // object-space position of the other end
    20.         half2 texcoord : TEXCOORD0;
    21.         float2 texcoord1 : TEXCOORD1;
    22.  
    23.         UNITY_VERTEX_INPUT_INSTANCE_ID
    24.     };
    25.    
    26.     // Vertex out/fragment in data:
    27.     struct v2f
    28.     {
    29.         float4 pos : SV_POSITION;
    30.         half2 uv : TEXCOORD0;
    31.  
    32.         UNITY_VERTEX_INPUT_INSTANCE_ID
    33.         UNITY_VERTEX_OUTPUT_STEREO
    34.     };
    35.    
    36.     // Vertex shader
    37.     v2f vert (a2v v)
    38.     {
    39.         v2f o;
    40.         // Pass on texture coordinates to fragment shader as they are:
    41.  
    42.         UNITY_SETUP_INSTANCE_ID(v);
    43.         UNITY_INITIALIZE_OUTPUT(v2f, o);
    44.         UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    45.  
    46.         o.uv = v.texcoord;
    47.        
    48.         // Transform to homogeneous clip space:
    49.         float4 csPos = UnityObjectToClipPos(v.vertex);
    50.         float4 csPos_other = UnityObjectToClipPos(float4(v.otherPos, 1.0));
    51.  
    52.         // Scale to properly match Unity's world space units:
    53.         // The `projScale` factor also handles different field of view values, which
    54.         // used to be handled via FOV_SCALING_OFF in previous versions of this asset.
    55.         // Furthermore, `projScale` handles orthographic projection matrices gracefully.
    56.         float projScale = unity_CameraProjection._m11 * 0.5;
    57.         float scaledLineWidth = _LineWidth * _LineScale * projScale;
    58.  
    59.         float aspectRatio = _ScreenParams.x / _ScreenParams.y;
    60.         // The line direction in (aspect-ratio corrected) clip space (and scaled by witdh):
    61.         float2 lineDirProj = normalize(
    62.             csPos.xy * aspectRatio / csPos.w - // screen-space pos of current end
    63.             csPos_other.xy * aspectRatio / csPos_other.w // screen-space position of the other end
    64.         ) * sign(csPos.w) * sign(csPos_other.w) * scaledLineWidth;
    65.        
    66.         // Offset for our current vertex:
    67.         float2 offset =
    68.             v.texcoord1.x * lineDirProj +
    69.             v.texcoord1.y * float2(lineDirProj.y, -lineDirProj.x)
    70.         ;
    71.  
    72.         // Apply (aspect-ratio corrected) offset
    73.         csPos.x += offset.x / aspectRatio;
    74.         csPos.y += offset.y;
    75.         o.pos = csPos;
    76.  
    77.         return o;
    78.     }
    79.    
    80.     // Fragment shader
    81.     fixed4 frag(v2f i) : SV_Target
    82.     {
    83.         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
    84.  
    85.         fixed4 tx = tex2D(_MainTex, i.uv);
    86.        
    87. #ifdef LIGHT_SABER_MODE_ON
    88.         return tx.a > _LightSaberFactor ? float4(1.0, 1.0, 1.0, tx.a) : tx * _Color;
    89. #else
    90.         return tx;
    91. #endif
    92.     }
    93.    
    94. #endif
    95.  
     
    virtualjay and j00hi like this.
  15. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    Wow, thanks for sharing!

    So, do the modifications still work outside of VR mode?
    And do you happen to know if this also works for the VR mode with the Universal Render Pipeline?

    I will -- with your permission -- integrate the changes into the asset's code and add your name to the list of contributors in the source files. I am also accepting pull requests. The asset is open source and available on GitHub: https://github.com/johannesugb/VolumetricLinesUnity
     
  16. Abnormalia_

    Abnormalia_

    Joined:
    Jul 23, 2013
    Posts:
    128
    Sure it will work, I just applied Unity recommended code to make it compatible with Single pass, without that it renders only in one eye. Not sure about URP, have not tested there.
     
    j00hi likes this.
  17. bostonvaulter

    bostonvaulter

    Joined:
    Jan 14, 2021
    Posts:
    15
    Thanks for this great asset! Here's a simple script to make it work like a laser that stops when it hits something


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Laser : MonoBehaviour {
    6.     [SerializeField]
    7.     private VolumetricLines.VolumetricLineBehavior lines;
    8.     void Update()
    9.     {
    10.         RaycastHit objectHit;
    11.         Transform transform = GetComponent<Transform>();
    12.         Vector3 fwd = transform.TransformDirection(Vector3.forward);
    13.         if (Physics.Raycast(transform.position, fwd, out objectHit, 40))
    14.         {
    15.  
    16.             lines.EndPos = new Vector3(0, 0, objectHit.distance); //This produces the laser of fitting length
    17.         }
    18.         else
    19.         {
    20.             lines.EndPos = new Vector3(0, 0, 30); //Laser goes offscreen
    21.  
    22.         }
    23.     }
    24. }
    25.  
     
    j00hi and starfoxy like this.
  18. starfoxy

    starfoxy

    Joined:
    Apr 24, 2016
    Posts:
    183

    This looks great! How would I go about using this?
     
  19. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    I've finally included this in the asset. An updated package (version 3.1.0) will come to the asset store in the next few days. Thanks again for posting the fix. I've tested in VR and it looks like it works fine now.

    The new package will also include a new "light saber mode" that can be activated and should give better quality (see image).
     

    Attached Files:

  20. jason_ars

    jason_ars

    Joined:
    Dec 24, 2020
    Posts:
    1
    Is there a way to make this render on top of materials when the shader is set to transparent? If I keep the render queue at 3000 then the volumetric line is never drawn on top of the transparent material, and if I set it to 3001 then the volumetric line is visible through the transparent material (when I want it to occlude the line).
     
  21. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    I guess the problem is that neither of the transparent materials writes to the depth buffer. Volumetric Lines perform depth testing, but do not write to the depth buffer. Do you see any chance to modify your other transparent material so that it writes meaningful depth values? If that could be established, rendering Volumetric Lines on queue 3001 should produce the desired result.

    If you could share some screen shots, we could discuss the problem better.
     
  22. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    43
    hello j00hi, could you tell me how do i color the lightsaberfactor? it's possible
     
  23. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    This is not supported out of the box. You'll have to modify the shaders. You could make a copy of the shader files and modify the copied files, or you could extend the shaders by a parameter for the colour of the inner white part.

    The line you'd have to change is the following:
    https://github.com/johannesugb/Volu...erPipeline/Shaders/_SingleLineShader.hlsl#L77
    You'll have to change float4(1.0, 1.0, 1.0, tx.a) (which means 'white') to some other color.
     
  24. virtualjay

    virtualjay

    Joined:
    Aug 4, 2020
    Posts:
    68
    Did this code make it in completely? When I play it in Unity over Link the the Quest (basically acting like a Rift), I get no lights. I get the other cubes and stuff I drop in the test scene. No errors.

    I tried replacing _SingleLineShader.cginc with the code above, and that DOES make it work. (I also replaced the main camera with an OculusCameraRig). Well, sort of.

    At design-time, it looks like
    upload_2021-6-2_16-19-42.png

    But then upon running, it looks like
    upload_2021-6-2_16-19-55.png

    FWIW, I also get the same thing when I build a native APK.

    BTW, sometimes the line
    [Error] [16:54:53.739] [Shader] [Shader] Shader error in 'VolumetricLine/LineStrip-LightSaber': invalid subscript 'stereoTargetEyeIndex' at Assets/VolumetricLines/BuiltInRenderPipeline/Shaders/_LineStripShader.cginc(90) (on d3d11)
    would show up in the error log. Not every time. I think it has to do with if and when Unity gets around to compiling shaders.

    It definitely seems to not be drawing the LineStrip ones and is fine with the SingleLine ones, with the code that was posted.
     
    Last edited: Jun 2, 2021
  25. virtualjay

    virtualjay

    Joined:
    Aug 4, 2020
    Posts:
    68
    I tried riffing off Abnormalia's modification above and doing the same thing with _LineStripShader.cginc. This worked for me:
    Code (CSharp):
    1. #ifndef VOL_LINE_LINE_STRIP_SHADER_INC
    2. #define VOL_LINE_LINE_STRIP_SHADER_INC
    3.    
    4.     #include "UnityCG.cginc"
    5.    
    6.     // Property-variables declarations
    7.     sampler2D _MainTex;
    8.     float _LineWidth;
    9.     float _LineScale;
    10. #ifdef LIGHT_SABER_MODE_ON
    11.     fixed _LightSaberFactor;
    12.     int _UvBasedLightSaberFactor;
    13.     fixed4 _Color;
    14. #endif
    15.    
    16.     // Vertex shader input attributes
    17.     struct a2v
    18.     {
    19.         float4 vertex : POSITION;
    20.         float3 prevPos : NORMAL;
    21.         float3 nextPos : TANGENT;
    22.         half2 texcoord : TEXCOORD0;
    23.         float2 texcoord1 : TEXCOORD1;
    24.         UNITY_VERTEX_INPUT_INSTANCE_ID
    25.     };
    26.    
    27.     // Vertex out/fragment in data:
    28.     struct v2f
    29.     {
    30.         float4 pos : SV_POSITION;
    31.         half2 uv : TEXCOORD0;
    32.         UNITY_VERTEX_INPUT_INSTANCE_ID
    33.         UNITY_VERTEX_OUTPUT_STEREO
    34.     };
    35.    
    36.     // Vertex shader
    37.     v2f vert (a2v v)
    38.     {
    39.         v2f o;
    40.         // Pass on texture coordinates to fragment shader as they are:
    41.         UNITY_SETUP_INSTANCE_ID(v);
    42.         UNITY_INITIALIZE_OUTPUT(v2f, o);
    43.         UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    44.  
    45.         o.uv = v.texcoord;
    46.        
    47.         // Transform to homogeneous clip space:
    48.         float4 csPos = UnityObjectToClipPos(v.vertex);
    49.         float4 csPos_prev = UnityObjectToClipPos(float4(v.prevPos, 1.0));
    50.         float4 csPos_next = UnityObjectToClipPos(float4(v.nextPos, 1.0));
    51.        
    52.         // Scale to properly match Unity's world space units:
    53.         // The `projScale` factor also handles different field of view values, which
    54.         // used to be handled via FOV_SCALING_OFF in previous versions of this asset.
    55.         // Furthermore, `projScale` handles orthographic projection matrices gracefully.
    56.         float projScale = unity_CameraProjection._m11 * 0.5;
    57.         float scaledLineWidth = _LineWidth * _LineScale * projScale;
    58.  
    59.         float aspectRatio = _ScreenParams.x / _ScreenParams.y;
    60.         // The line direction in (aspect-ratio corrected) clip space (and scaled by witdh):
    61.         float2 lineDirProj_prev = normalize(
    62.             csPos.xy * aspectRatio / csPos.w - // screen-space pos of current end
    63.             csPos_prev.xy * aspectRatio / csPos_prev.w // screen-space position of the other "previous" end
    64.         ) * sign(csPos.w) * sign(csPos_prev.w) * scaledLineWidth;
    65.         float2 lineDirProj_next = normalize(
    66.             csPos.xy * aspectRatio / csPos.w - // screen-space pos of current end
    67.             csPos_next.xy * aspectRatio / csPos_next.w // screen-space position of the other "next" end
    68.         ) * sign(csPos.w) * sign(csPos_next.w) * scaledLineWidth;
    69.        
    70.         float2 offset;
    71.         if (distance(v.prevPos, v.nextPos) < 1.0)
    72.         {
    73.             offset =
    74.                 v.texcoord1.x * lineDirProj_prev +
    75.                 v.texcoord1.y * float2(lineDirProj_prev.y, -lineDirProj_prev.x);
    76.         }
    77.         else
    78.         {
    79.             float2 deltaNextPrev = lineDirProj_prev - lineDirProj_next;
    80.             offset = 0.5 * (
    81.                 v.texcoord1.x * deltaNextPrev +
    82.                 v.texcoord1.y * float2(deltaNextPrev.y, -deltaNextPrev.x)
    83.             );
    84.         }
    85.  
    86.         // Apply (aspect-ratio corrected) offset
    87.         csPos.x += offset.x / aspectRatio;
    88.         csPos.y += offset.y;
    89.         o.pos = csPos;
    90.  
    91.         return o;
    92.     }
    93.  
    94.     // Fragment shader
    95.     fixed4 frag(v2f i) : SV_Target
    96.     {
    97.         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
    98.         fixed4 tx = tex2D(_MainTex, i.uv);
    99.        
    100. #ifdef LIGHT_SABER_MODE_ON
    101.         if (_UvBasedLightSaberFactor == 1)
    102.         {
    103.             float2 uv2 = i.uv * 2.0 - 1.0;
    104.             float c = sqrt(uv2[0] * uv2[0] + uv2[1] * uv2[1]);
    105.             return lerp(tx * _Color, float4(1.0, 1.0, 1.0, tx.a), clamp((1.02 - c - _LightSaberFactor) * 100.0, 0, 1));
    106.         }
    107.         else
    108.         {
    109.             return tx.a > _LightSaberFactor ? float4(1.0, 1.0, 1.0, tx.a) : tx * _Color;
    110.         }
    111. #else
    112.         return tx;
    113. #endif
    114.     }
    115.    
    116. #endif
    117.  
     
  26. LittleGeek

    LittleGeek

    Joined:
    Oct 18, 2013
    Posts:
    7
    Does this work with arbitrary directions? I have this parented to another GO, and set StartPos to Vector3.zero (It starts in the right place) and EndPos to be difference between world point i want it to hit and the line's GO transform.position. When I'm on one side of the destination point it's OK but as soon as I got to the other side it faces the wrong direction. It's like the z coords always want to be positive to work.

    If I debug.DrawLine the coords it's perfect, but as soon as I put a EndPos, it fails on one side.
     
  27. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    This should work without any problems for arbitrary directions. But please note that EndPos expects coordinates in the local coordinate system of the object where VolumetricLineBehavior is attached to! I have the suspicion that you might have passed coordinates of a different coordinate system (maybe/probably world space?!) to EndPos.

    Given that you have the destination point in world space, please try the following:

    Code (CSharp):
    1. Vector3 destinationPositionInWorldSpace; // TODO: assign
    2. VolumetricLineBehavior myLine; // TODO: assign
    3. myLine.EndPos = myLine.transform.InverseTransformPoint(destinationPositionInWorldSpace);
     
  28. SavedByZero

    SavedByZero

    Joined:
    May 23, 2013
    Posts:
    124
    Is there a reason why the unity recorder doesn't process the effects for these when I'm recording sprite frames? The glow does not get recorded -- only the core line.
     
  29. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    Uh, I have to admit that I have never tried playing back the effect in the recorder, and I think that I haven't used the recorder before, so in order to be able to reproduce the problem: Could you please describe the steps in detail that lead to the problem?

    Maybe you could also post a video showing the problem?
     
    twobob likes this.
  30. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    FWIW. you just press "The record" button like an old walkman. I suspect the feedback will be "I just pressed record and in the recording the glows did not show" Not to be obtuse, there is just very little to it. (do you do a really late pass? or something "unusual..."? I must admit I didn't look over the code) I am actually pretty surprised you can fail to record what is in the selected window.
     
  31. SavedByZero

    SavedByZero

    Joined:
    May 23, 2013
    Posts:
    124
    There's no movie to show -- here are the settings I use in the recorder:

    Screen Shot 2022-01-10 at 9.42.36 AM.png

    And here is what it outputs (just that line):


    Screen Shot 2022-01-10 at 9.44.17 AM.png

    Clearly something is broken here. I just don't know whether it's a unity recorder bug, or a bug in the library.
     
  32. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    Hmm, that's very strange. You said that you are recording sprite frames (i.e., "Image Sequence"), hmm, I don't really see how the library/asset should prevent the rendered output to look correct. It is just running ordinary shaders with blending enabled... actually just like any other ordinary graphics effect.

    Can you maybe reproduce the same problem with a different shader? Maybe just rendering some semi-transparent plane?

    I just tried and recording an "Image Sequence" produced the correct output with Unity 2021.2.12f1.
    Does the problem still persist for you?
     
  33. giwon2004_unity

    giwon2004_unity

    Joined:
    Mar 30, 2022
    Posts:
    1
    How do I change the color of the lightsaber object by code? Is it under the namespace 'VolumetricLines'? There is no type 'LineColor' in that namespace though...
     
  34. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    Of course there is no type 'LineColor' in the namespace, because color values are represented with the 'UnityEngine.Color' type. But 'VolumetricLineBehavior' offers a property 'LineColor'!
     
  35. baumannkev

    baumannkev

    Joined:
    Sep 14, 2022
    Posts:
    1
    Has anyone had any success changing the Light GameObject Emission Color in Update() or another function repeatedly in run time?
    When I do, the game experiences very slow frame rates, like close to 1fps.
    Thanks!
     
  36. NeilAgg

    NeilAgg

    Joined:
    Jun 8, 2023
    Posts:
    9
    I have several assets from Blender exported to fbx files.
    Is it possible to use the materials from Volumetric Lines on that asset to make parts of it glow?
     
  37. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    So you have tracked down Volumetric Lines being the cause of that bad performance?
    Can you post the code how you are setting the emission color repeadedly?
     
  38. j00hi

    j00hi

    Joined:
    Nov 18, 2012
    Posts:
    72
    I'm afraid that won't be easily possible.
    One would have to write a script, which creates volumetric lines for the lines of the imported mesh geometry.