- Home /
Shader based red dot sight
I've seen examples of realistic red dot sights made using shaders for Unity. What I'm trying to do is recreate this because the poster of the example has only posted pictures. I know the basics of writing a shader, and have already tried transforming the vertices of plane the dot is on, but this makes the dot get smaller as it gets further away, and can be seen from anywhere, not just inside the window its on. What other ways could this effect be achieved?
EDIT: In case someone is good with shaders but doesn't know what I'm talking about, a red dot sight is a type of scope on guns that projects an image onto the lens that the user looks through. This dot can only be seen from behind the sight, and appears to be 50 or so meters away, making it so that whatever the dot is on is what the gun is pointed at. This is not the same as a laser pointer used for aiming.
Import the projector package from the standard assets, try the light prefab, the it to orthographic and play along. I don't remember if there is a color property on the shader though. Anyway, make it child of the camera, pointing forward, and voila !
Hmm I played around with this, but this would act more like a laser pointer, and would need to intersect geometry to be seen.
And that's not what you want. Ok, so red dot sights isn't what I thought, sorry ^^
Answer by aldonaletto · Feb 28, 2012 at 12:35 AM
I know this is not exactly what you're looking for, but maybe it's useful for you or other guys reading this question: you could have a simple plane with the red dot assigned to a material with the Cutout/Diffuse shader, then move the plane to the hit position and align its rotation to the hit normal.
Create a red dot image with a transparent background (download it from here, if you want) and import it to Unity. Create a new material with the shader Transparent/Cutout/Diffuse, and assign the dot image to the material texture, then create a plane in Unity and assign the new material to it. Finally, attach the script below to the plane you've created. This script destroys the original plane at Start and replace it with a simple 1 x 1 mesh composed by only 2 triangles (the original plane had 200!). It also destroys the original mesh collider because the laser dot must not have a collider.
var size: float = 0.01; // dot diameter
function Start () { var mesh = GetComponent(MeshFilter).mesh; mesh.Clear(); // destroy the original plane... mesh.vertices = new Vector3[4]; // and replace it with a simple 1 x 1 mesh.triangles = new int[6]; // mesh created with only 2 triangles mesh.uv = new Vector2[4]; mesh.vertices = [ Vector3(-0.5, 0.0, -0.5), Vector3(-0.5, 0.0, 0.5), Vector3(0.5, 0.0, 0.5), Vector3(0.5, 0.0, -0.5) ]; mesh.triangles = [0,1,2,2,3,0]; mesh.uv = [ Vector2(0f, 0f), Vector2(0f, 1f), Vector2(1f, 1f), Vector2(1f, 0f) ]; mesh.RecalculateNormals(); if (collider) Destroy(collider); }
function LateUpdate(){ // create a ray from the center of the screen: var ray = Camera.main.ViewportPointToRay(Vector3(0.5, 0.5, 0.0)); var hit: RaycastHit; if (Physics.Raycast(ray, hit)){ // if something hit by the ray... renderer.enabled = true; // enable the dot rendering // position the dot a little ahead of the hit point: transform.position = hit.point+0.01*hit.normal; // align the plane normal to the hit point normal: transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal); // make the point grow with the distance: transform.localScale = (hit.distance + 0.5) size Vector3.one; } else { // if nothing hit... renderer.enabled = false; // disable the dot } } NOTE 1: transform.localScale is adjusted to provide a size correction as a function of the distance;
NOTE 2: the laser dot only appears on objects which have a collider;
Your answer
Follow this Question
Related Questions
Always included shaders (Graphics settings) 1 Answer
Dymanic Mesh Hiding 2 Answers
Shader effect gone when I hit Play 0 Answers
Effects of Graphics.Blit to rendertexture are temporary 2 Answers
Do TEXCOORDS need to be in sequence? 1 Answer