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

Red dot sight

Discussion in 'Shaders' started by NightHawk, Aug 9, 2012.

  1. NightHawk

    NightHawk

    Joined:
    May 30, 2012
    Posts:
    127
    Hello!

    I am looking for a red dot sight that places a dot in the middle of the screen. I used the search feature and looked for a while, but nothing came up.
    A shader based one would be nice but if there are simpler, better methods then I can go with those. :)
    I was thinking something like this: http://forum.unity3d.com/threads/116171-Shader-based-Red-Dot-Sights-anyone

    Also sorry if this is in the wrong section.

    Thanks, Nighthawk.
     
  2. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    You could cast a ray (Physics.Raycast) to determine the distance of the next hit object and then (depending on that distance) attenuate the color and scale the size of a GUITexture in the middle of the screen. I think that would be quite simple and efficient but not very accurate since the colliders for physics are different from the visible meshes and you would only have one distance; thus, the whole dot would always appear to hit only one object (as opposed to a part of it hitting one object and other parts hitting other objects).

    The more complicated and more accurate but probably less efficient approach would be to use a Projector: http://docs.unity3d.com/Documentation/ScriptReference/Projector.html
     
  3. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Red dot isn't a laser pointer, it's like a "holographic" dot that sits in the middle of the sight.

    I'm not sure you need a shader for this, wouldn't an additive blending texture work?
     
  4. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    There are a few things to consider here. The red dot is holographically projected, so it appears to be 50m beyond the sight. However:

    1. The dot is only visible through the sight
    2. It appears on in front of anything that is behind the sight
    3. It is obscured by any object in front of the sight
    You could accomplish this entirely in a shader that does the projection, but a simpler method might be to use the frame buffer alpha channel and a pair of renderers: one for the glass of the sight, and one for the red dot, at 50m. The glass would only write to the alpha channel, either all 1.0 or add some vignetting/noise. The red dot would render without alpha testing, and using destination alpha blending, such as Blend DstAlpha One, or Blend DstAlpha OneMinusDstAlpha if you want a linear interpolation.
     
  5. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Ah, I was under the impression it was more like a standard crosshair that was just interfered less with the user's view through the scope.

    Yeah, projecting it ahead shouldn't be too hard to do... you'd have to feed in the vector that the gun is pointing in and then you could offset the UVs (with a clamped dot texture) accordingly, compared to the view vector?
     
  6. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
  7. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
  8. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Sorry
     
  9. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Hello.
    Maybe it is a bit late for this thread but I hope my answer will help others.
    Ok.
    1)So first of all what you'll need Gimp/Photoshop or any similar application to create needed texture.
    2)Within gimp create new drawing with 1024x1024 dimensions.
    3)Erase everything from this image so it became fully transparent.
    4)Put big red dot in the center of the image and export it to png.
    5)Import this texture to your project. Set wrap mode for this texture to clamp in the texture's inspector panel.
    6)Create new material.
    7)Select "Transparent/Parallax Deffuse" from the drop down menu in the material's inspector panel.
    8 )Drag and drop red dot texture to the material's Base(RGB). Set the "Height" level to max.
    That is all. Now you have red dot material to attach to your red dot sight's lens.
    NOTE: Max height level for default "Transparent/Parallax Deffuse" shader is 0.8 m. So red dot would behave like it is only 0.8 meters away.
    If you need to at another distance(like 50 meters) you'll need to create your own shader.
    1)In red dot material press the "Edit" button.
    2) Select all code and copy.
    3)Create new shader. Open it.
    4)Replace new shader's code with one you've copied.
    5)Change shader's name to "Custom/Red Dot".
    6)Change 0.8 in the _Height parameter to what ever you need(like 50). Save and close.
    7)Select "Custom/Red Dot" from material's drop down menu.
    8 )Adjust the "Height" parameter to you likings.
    Cheers
     
    Last edited: Apr 19, 2014
    GAZEREAPER likes this.
  10. GAZEREAPER

    GAZEREAPER

    Joined:
    Feb 15, 2014
    Posts:
    9
    Thanks a ton m8! i definitely r8 8/8!
     
  11. mouurusai

    mouurusai

    Joined:
    Dec 2, 2011
    Posts:
    350
    Code (csharp):
    1.  
    2. Shader "Cg/ReflectorSight"{
    3. Properties
    4. {
    5.         _MainTex ("Base (RGB)", 2D)="white"{}
    6.         _ReticleSize("ReticleSize",float)=2.0
    7. }
    8.  
    9. SubShader
    10. {
    11.         Tags {"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent"}
    12.         Blend SrcAlpha One
    13.        
    14.        
    15.         Pass
    16.        {
    17.                 CGPROGRAM
    18.                        #pragma vertex vert
    19.                        #pragma fragment frag
    20.                        
    21.                        #include "UnityCG.cginc"
    22.  
    23.                        struct appdata_t
    24.                        {
    25.                                 float4 vertex : POSITION;
    26.                        };
    27.  
    28.                        struct v2f
    29.                        {
    30.                                 float4 vertex : SV_POSITION;
    31.                                 half2 texcoord : TEXCOORD0;
    32.                        };
    33.  
    34.                        sampler2D _MainTex;
    35.                        float _ReticleSize;
    36.                        
    37.                         v2f vert (appdata_t v)
    38.                        {
    39.                                 v2f o;
    40.                                 o.vertex= mul(UNITY_MATRIX_MVP, v.vertex);
    41.                                 o.texcoord= v.vertex.xy*_ReticleSize-mul((float3x3)_World2Object, _WorldSpaceCameraPos-mul(_Object2World, float4(0,0,0,1))).xy*_ReticleSize+float2(0.5,0.5);
    42.                                return o;
    43.                        }
    44.                        
    45.                         fixed4 frag (v2f i): COLOR
    46.                        {
    47.                                 fixed4 col = tex2D(_MainTex, i.texcoord);
    48.                                return col;
    49.                        }
    50.                 ENDCG
    51.        }
    52. }
    53.  
    54. }
    55.  
    56.  
     
  12. GilbertLau

    GilbertLau

    Joined:
    Dec 3, 2017
    Posts:
    26

    Sorry, I am new. But in this case, it is just a dot on the optics but the red dot will not be accurate. Am I missing something?
     
  13. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Hello,
    I'm not sure if this approach is still applicable. But when I tested it created quite good illusion of red dot in the distance. I know that actual reflective sights project reticle into infinity but you would get discrepancies only when you have large angle between view and surface normal.