

Shader "test/MyShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
float3 worldPosition : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.normal = v.normal;
o.worldPosition = mul(_Object2World, v.vertex).xyz;
return o;
}
[maxvertexcount(3)]
void geom(triangle v2f input[3], inout TriangleStream<v2f> OutputStream)
{
v2f test = (v2f)0;
float3 normal = normalize(cross(input[1].worldPosition.xyz - input[0].worldPosition.xyz, input[2].worldPosition.xyz - input[0].worldPosition.xyz));
for(int i = 0; i < 3; i++)
{
test.normal = normal;
test.vertex = input[i].vertex;
test.uv = input[i].uv;
OutputStream.Append(test);
}
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
float3 lightDir = float3(1, 1, 0);
float ndotl = dot(i.normal, normalize(lightDir));
return col * ndotl;
}
ENDCG
}
}
}
Shader "Custom/GeometryShaderTest1"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_Size("Size", float) = 0.5
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
LOD 100
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Cull Off
Pass
{
CGPROGRAM
#pragma target 5.0
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#include "UnityCG.cginc"
// Vars
float4 _Color;
float _Size;
float3 _worldPos;
struct data
{
float4 pos0;
};
StructuredBuffer<data> buf_Points;
struct input
{
float4 pos : SV_POSITION;
float4 color: COLOR;
};
input vert(uint id : SV_VertexID)
{
input o;
o.pos = float4(buf_Points[id].pos0 + _worldPos, 1.0f);
return o;
}
[maxvertexcount(8)]
void geom(line input p[2], inout TriangleStream<input> triStream)
{
float4 s[2];
s[0] = mul(UNITY_MATRIX_VP, p[0].pos);
s[1] = mul(UNITY_MATRIX_VP, p[1].pos);
s[0].x /= s[0].w;
s[0].y /= s[0].w;
s[1].x /= s[1].w;
s[1].y /= s[1].w;
s[0].z = s[1].z = 0.1;
s[0].w = s[1].w = 1;
float4 ab = s[1] - s[0];
float4 normal = float4(-ab.y, ab.x, 0, 0);
normal = normalize(normal);
normal.x /= (_ScreenParams.x / _ScreenParams.y);
input pIn;
pIn.pos = s[0] - normal * _Size;
pIn.color = float4(1.0, 0.0, 0.0, 1.0);
triStream.Append(pIn);
pIn.pos = s[0] + normal * _Size;
pIn.color = float4(1.0, 0.0, 0.0, 1.0);
triStream.Append(pIn);
pIn.pos = s[1] - normal * _Size;
pIn.color = float4(0.0, 1.0, 0.0, 1.0);
triStream.Append(pIn);
pIn.pos = s[1] + normal * _Size;
pIn.color = float4(0.0, 1.0, 0.0, 1.0);
triStream.Append(pIn);
}
float4 frag(input i) : COLOR
{
return i.color;
}
ENDCG
}
}
FallBack "Diffuse"
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
struct data
{
public Vector3 pos;
}
public class LineSegmentRenderer : MonoBehaviour
{
public Shader geomShader;
public float Size = 0.05f;
Material material;
ComputeBuffer outputBuffer;
List<Vector3> points;
// Use this for initialization
void Start ()
{
material = new Material(geomShader);
points = new List<Vector3>();
SetupTest();
}
void SetupTest()
{
for (int i = 0; i < 10; i++)
{
AddLineSegmentGS(
new Vector3(Random.Range(-10f, 10f), Random.Range(-10f, 10f), Random.Range(-1f, 1f)),
new Vector3(Random.Range(-10f, 10f), Random.Range(-10f, 10f), Random.Range(-1f, 1f))
);
}
Apply();
}
// Update is called once per frame
void Update ()
{
}
public void AddLineSegmentGS(Vector3 a, Vector3 b)
{
points.Add(a);
points.Add(b);
}
public void Apply()
{
outputBuffer = new ComputeBuffer(points.Count, 24);
outputBuffer.SetData(points.ToArray());
}
public void OnRenderObject()
{
material.SetPass(0);
material.SetBuffer("buf_Points", outputBuffer);
material.SetFloat("_Size", Size);
Graphics.DrawProcedural(MeshTopology.Lines, outputBuffer.count);
}
public void OnDestroy()
{
outputBuffer.Release();
}
}
