devNotes 4-22-2017 Compute/Geometry Shader – Double Color Slider

stair_case

 

shaderpipeline_simple


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();
     }
 }

 


 

gs

Leave a Reply

Your email address will not be published. Required fields are marked *