DirectX 11 shader

Uses the Geometry shader stage


Video example


Shader code


            VS_DATA MainVS(VS_DATA vsData)
            {
                return vsData;
            }

            //******************
            // GEOMETRY SHADER *
            //******************
            void CreateVertex(inout TriangleStream triStream, float3 pos, float3 normal, float4 color)
            {
                GS_DATA temp = (GS_DATA)0;
                //Step 1. Create a GS_DATA object
                float4 Position = float4( pos, 1); 
                temp.Position = mul(Position, m_MatrixWorldViewProj );
                //Step 2. Transform the position using the WVP Matrix and assign it to (GS_DATA object).Position (Keep in mind: float3 -> float4)
                float4(0, 0, 0, 1);
                temp.Normal = mul (normal, m_MatrixWorld) ;
                //Step 3. Transform the normal using the World Matrix and assign it to (GS_DATA object).Normal (Only Rotation, No translation!)
                temp.Color = color; 
                //Step 4. Assign texCoord to (GS_DATA object).TexCoord
                triStream.Append(temp); 
                //Step 5. Append (GS_DATA object) to the TriangleStream parameter (TriangleStream::Append(...))
            }

            [maxvertexcount(72)]
            void ExplosionGenerator(triangle VS_DATA v[3], inout TriangleStream triStream)
            {
                float s = 10;
                float3 explpos[3];
                float3 g = float3(0, -1, 0);
                float4 color = 0;
                float Speed = 50;
                float SpeedGrav = 2.5 + (time*time*time*time) ;
                float brightness = 1;
                float3 basePoint = (v[0].Position + v[1].Position + v[2].Position) / 3;
                

                float3 avgnormal = (v[0].Normal + v[1].Normal + v[2].Normal) / 3;
                color.r += cos((v[0].Position.y ) + (time *s)) * brightness;
                color.g += cos((v[0].Position.y ) - 0.5 + (time*s)) * brightness;
                color.b += cos((v[0].Position.y ) - 1 + (time*s)) * brightness;
                brightness = 1;
                
                color.rgb += abs(0.5+0.3*cos((v[0].Position.y+10  ) + ((time)*s)) * brightness);
                color.rgb *= 1; 
                color.a = 1; 
                brightness = 0.2;
                Speed = Speed / (1 + (time));
                basePoint = basePoint + (Speed *(avgnormal * time)) + (SpeedGrav*g);
                for (int c = 0; c < 3; c++)
                {
                    CreateVertex(triStream, v[c].Position + (Speed *(avgnormal * time)) + (SpeedGrav*g), v[c].Normal, color);
                }
                triStream.RestartStrip();

                //One Manual tesselation step
                color.rgb = abs(cos((v[0].Position.y + 10) + ((time)*s)) * brightness);

                float3 vec[3] = { v[1].Position - v[0].Position ,v[2].Position - v[1].Position, v[0].Position - v[2].Position };
                float3 n[3] = { v[0].Position + ((vec[0]) * 0.5) ,  v[1].Position + (vec[1] * 0.5),  v[2].Position + (vec[2] * 0.5) };
                float3 midpoint[4] =
                {
                    (v[0].Position + n[0] + n[2]) / 3,
                    (n[0] + v[1].Position + n[1]) / 3,
                    (n[0] + n[1] + n[2]) / 3,
                    (n[2] + n[1] + v[2].Position) / 3
                };
                s = 0.8*sin(time);
                color.a = sin(time) * abs(sin(8 * time)) + abs(0.2*sin(32 * time) + 0.2);

                color.a *= 0.2;
                color.a += 0.02;
                float3 offsetscalar = 1; 
                if (s <= 0.001) { s = -0.01; color.a = abs(0.07*sin(time * 4)) + abs(0.09*sin(time * 8 + 5)); offsetscalar *= 0.12; }

                color.b += 0.35;
                color.g += 0.45;
                color.rgb += 0.7; 
                color.r -= 0.5;
                color.g -= 0.5;
                s = 0.8*sin(time); //Extrusion Distrance from midpoint (Grow and shrink)
                float3 offsets[12] =
                {
                    (s*(midpoint[0] -v[0].Position )),
                    (s*(midpoint[0] - n[0])),
                    (s*(midpoint[0] - n[2])),
                    
                    (s*(midpoint[1] - n[0])),
                    (s*(midpoint[1] - v[1].Position)),
                    (s*(midpoint[1] - n[1])),

                    (s*(midpoint[2] - n[0])),
                    (s*(midpoint[2] - n[1])),
                    (s*(midpoint[2] - n[2])),

                    (s*(midpoint[3] - n[2])),
                    (s*(midpoint[3] - n[1])),
                    (s*(midpoint[3] - v[2].Position))
                };
                
                s = (0.8*sin(time));
                float3 offset = offsetscalar * 15 * avgnormal * s*(1 + (sin(time * 4)));
                CreateVertex( triStream, v[0].Position + offset + offsets[0], v[0].Normal, color);
                CreateVertex(triStream, n[0] + offset + offsets[1], v[0].Normal, color);
                CreateVertex(triStream, n[2] + offset + offsets[2], v[0].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[3], v[1].Normal, color);
                CreateVertex(triStream, v[1].Position + offset + offsets[4], v[1].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[5], v[1].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[6], avgnormal, color);
                CreateVertex(triStream, n[1] + offset + offsets[7], avgnormal, color);
                CreateVertex(triStream, n[2] + offset + offsets[8], avgnormal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[2] + offset + offsets[9], v[2].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[10], v[2].Normal, color);
                CreateVertex(triStream, v[2].Position + offset + offsets[11], v[2].Normal, color);
                triStream.RestartStrip();

                offset = offsetscalar * (avgnormal * 17 ) * s * (1+(sin(27 + time * 4)));
                CreateVertex(triStream, v[0].Position + offset + offsets[0], v[0].Normal, color);
                CreateVertex(triStream, n[0] + offset + offsets[1], v[0].Normal, color);
                CreateVertex(triStream, n[2] + offset + offsets[2], v[0].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[3], v[1].Normal, color);
                CreateVertex(triStream, v[1].Position + offset + offsets[4], v[1].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[5], v[1].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[6], avgnormal, color);
                CreateVertex(triStream, n[1] + offset + offsets[7], avgnormal, color);
                CreateVertex(triStream, n[2] + offset + offsets[8], avgnormal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[2] + offset + offsets[9], v[2].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[10], v[2].Normal, color);
                CreateVertex(triStream, v[2].Position + offset + offsets[11], v[2].Normal, color);
                triStream.RestartStrip();

                offset = offsetscalar * (avgnormal *18)* s * ( 1+( sin(12 + time * 4)));
                CreateVertex(triStream, v[0].Position + offset + offsets[0], v[0].Normal, color);
                CreateVertex(triStream, n[0] + offset + offsets[1], v[0].Normal, color);
                CreateVertex(triStream, n[2] + offset + offsets[2], v[0].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[3], v[1].Normal, color);
                CreateVertex(triStream, v[1].Position + offset + offsets[4], v[1].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[5], v[1].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[6], avgnormal, color);
                CreateVertex(triStream, n[1] + offset + offsets[7], avgnormal, color);
                CreateVertex(triStream, n[2] + offset + offsets[8], avgnormal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[2] + offset + offsets[9], v[2].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[10], v[2].Normal, color);
                CreateVertex(triStream, v[2].Position + offset + offsets[11], v[2].Normal, color);
                triStream.RestartStrip();
                offset = offsetscalar * (avgnormal * 19)* s * (1+( sin(19 + time * 4)));
                CreateVertex(triStream, v[0].Position + offset + offsets[0], v[0].Normal, color);
                CreateVertex(triStream, n[0] + offset + offsets[1], v[0].Normal, color);
                CreateVertex(triStream, n[2] + offset + offsets[2], v[0].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[3], v[1].Normal, color);
                CreateVertex(triStream, v[1].Position + offset + offsets[4], v[1].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[5], v[1].Normal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[0] + offset + offsets[6], avgnormal, color);
                CreateVertex(triStream, n[1] + offset + offsets[7], avgnormal, color);
                CreateVertex(triStream, n[2] + offset + offsets[8], avgnormal, color);
                triStream.RestartStrip();
                CreateVertex(triStream, n[2] + offset + offsets[9], v[2].Normal, color);
                CreateVertex(triStream, n[1] + offset + offsets[10], v[2].Normal, color);
                CreateVertex(triStream, v[2].Position + offset + offsets[11], v[2].Normal, color);
                triStream.RestartStrip();
                
                //Fins
                float3 FinLength = 0.3; 
                float3 normal[3] = { cross(v[0].Normal,vec[0]), cross(v[1].Normal,vec[1]) , cross(v[2].Normal,vec[2]) }; 
                color.a = 0.2 *  abs(sin(time * 4));
                CreateVertex(triStream, v[0].Position, normal[0], color);
                CreateVertex(triStream, v[1].Position, normal[1], color);
                CreateVertex(triStream, FinLength * v[0].Normal + v[0].Position, normal[0], color);
                CreateVertex(triStream, FinLength * v[1].Normal + v[1].Position, normal[1], color);
                triStream.RestartStrip();
                CreateVertex(triStream, v[1].Position, normal[1], color);
                CreateVertex(triStream, v[2].Position, normal[2], color);
                CreateVertex(triStream, FinLength * v[1].Normal + v[1].Position, normal[1], color);
                CreateVertex(triStream, FinLength * v[2].Normal + v[2].Position, normal[2], color);
                triStream.RestartStrip();
                CreateVertex(triStream, v[2].Position, normal[2], color);
                CreateVertex(triStream, v[0].Position, normal[0], color);
                CreateVertex(triStream, FinLength * v[2].Normal + v[2].Position, normal[2], color);
                CreateVertex(triStream, FinLength * v[0].Normal + v[0].Position, normal[0], color);
                triStream.RestartStrip();
                
                color.a = 0.002;
                
                CreateVertex(triStream, v[0].Position, v[0].Normal, color);
                CreateVertex(triStream, v[1].Position, v[1].Normal, color);
                CreateVertex(triStream, v[2].Position, v[2].Normal, color);
                triStream.RestartStrip();

                
            }

            float3 CalculateBezierPoint(float t, float3 p0, float3 p1, float3 p2, float3 p3)
            {
                float u = 1 - t; 
                float tt = t * t; 
                float uu = u * u; 
                float uuu = uu * u; 
                float ttt = tt * t; 

                float3 p = uuu * p0; 
                p += 3 * uu * t * p1; 
                p += 3 * u * tt * p2;
                p += ttt * p3;
                return p;

            }


            [maxvertexcount(93)]
            void  BezierGenerator(point VS_DATA v[1], inout TriangleStream triStream)
            {
                float3 normal = v[0].Normal;
                float4 color = { 0.8,0.8,0.8,1 };
                float3 square[3] = { 0.5,0,0 , 0,0,-0.5 , -0.5,0,0 }; float3 squarerot[3];
                float3 vertexarr[80]; float counter = 0;
                float3 up = { 0 , 1 , 0 };
                float3 axis = cross(v[0].Normal, up);
                float dt = dot(v[0].Normal, up);
                float angle = acos(dt);
                float3 offset = { 0, -1, 0 };
                float3 offset2 = { -1, 0, 0 };
                float3 vertexloc[90]; float ctr;
                float3 p0 = v[0].Position;
                float3 p1 = v[0].Position + (v[0].Normal * 5) + ((sin(time * 10))   * (-offset2 * 0.5));
                float3 p3 = v[0].Position + (v[0].Normal * 10) + (0.5 * (sin(time * 10)) + 0.5 * 3 * offset) + (4 * offset);
                float3 p2 = p3 - (5 * v[0].Normal);
                float3x3 rot =
                {
                    cos(angle) + axis.x * axis.x * (1 - cos(angle)) ,
                    axis.x * axis.y * (1 - cos(angle)) - axis.z * sin(angle),
                    axis.x * axis.z * (1 - cos(angle)) + axis.y * sin(angle),

                    axis.y * axis.x * (1 - cos(angle)) + axis.z * sin(angle),
                    cos(angle) + axis.y * axis.y * (1 - cos(angle)),
                    axis.y * axis.z * (1 - cos(angle)) - axis.x*sin(angle),

                    axis.z * axis.x * (1 - cos(angle)) - axis.x * sin(angle),
                    axis.z * axis.y * (1 - cos(angle)) + axis.x * sin(angle),
                    cos(angle) + axis.z * axis.z * (1 - cos(angle))
                };	
                for (int c = 0; c < 3; c++)
                {
                    squarerot[c] = 0.120*mul(square[c], rot);
                }

                for (int i = 0; i < 30; i++)
                {
                    float3 extrusion = sin(time) * i * v[0].Normal;
                    for (int c = 0; c < 3; c++)
                    {
                        float3 bezierloc = CalculateBezierPoint(i*0.03333333, p0, p1, p2, p3);
                        vertexloc[ctr++] = squarerot[c] + bezierloc;
                    
                    }

                }
                int resetctr = 0;
                float s = 10;
                float brightness = 1;
                for (int i = 0; i < 87; i++)
                {

                    color.r = pow(cos(vertexloc[i].y + (time *s)) *  (brightness), 3);
                    color.g = pow(cos((vertexloc[i].y - 0.5) + (time*s)) * (brightness), 3);
                    color.b = pow(cos((vertexloc[i].y - 1) + (time*s)) * (brightness), 3);
                    CreateVertex(triStream, vertexloc[i], normal[0], color);
                    color.r = pow(cos(vertexloc[i + 3].y + (time *s)) *  (brightness), 3);
                    color.g = pow(cos((vertexloc[i + 3].y - 0.5) + (time*s)) * (brightness), 3);
                    color.b = pow(cos((vertexloc[i + 3].y - 1) + (time*s)) * (brightness), 3);
                    CreateVertex(triStream, vertexloc[i + 3], normal[0], color);
                    if (++resetctr == 3) { triStream.RestartStrip(); resetctr = 0; }
                }
            }


            [maxvertexcount(93)]
            void  WireGenerator(triangle VS_DATA v[3], inout TriangleStream triStream)
            {

                float4 color = 0;
                color.a = 1;
                float s = 10;
                float brightness = 1;
                float wireframesize = size / (7+sin(time*4));
                //TriangleSides
                float3 vec1 = v[0].Position - v[1].Position;
                float3 vec2 = v[1].Position - v[2].Position;
                float3 vec3 = v[0].Position - v[2].Position;
                float3 offsetdir1 = normalize(cross(vec1, v[0].Normal)) * wireframesize;
                float3 offsetdir2 = normalize(cross(vec2, v[1].Normal)) * wireframesize;
                float3 offsetdir3 = normalize(cross(vec3, v[2].Normal)) * wireframesize;
                //Jiggle
                //Move Vertices
                v[0].Position.x += cos((v[0].Position.y  ) + (time *s)) * xscale;
                v[0].Position.y += cos((v[0].Position.y  ) + (time *s)) * yscale;
                v[1].Position.x += cos((v[1].Position.y  ) + (time *s)) * xscale;
                v[1].Position.y += cos((v[1].Position.y  ) + (time *s)) * yscale;
                v[2].Position.x += cos((v[2].Position.y  ) + (time *s)) * xscale;
                v[2].Position.y += cos((v[2].Position.y  ) + (time *s)) * yscale;

                color.r += cos((v[0].Position.y  ) + (time *s)) * brightness;
                color.g += cos((v[0].Position.y  ) -0.5+(time*s)) * brightness;
                color.b += cos((v[0].Position.y  ) -1+ (time*s)) * brightness;
                brightness = 0.2;

                //WireFrame 
                float4 color1 = 0; 
                float4 color2 = 0;
                float4 color3 = 0;
                
                color.r += cos((v[0].Position.y  ) + (time *s)) * brightness;
                color.g += cos((v[0].Position.y  ) - 0.5 + (time*s)) * brightness;
                color.b += cos((v[0].Position.y  ) - 1 + (time*s)) * brightness;
                brightness = 1;
                color1.r += cos((v[0].Position.y ) + (time *s)) * brightness;
                color1.g += cos((v[0].Position.y) - 0.5 + (time*s)) * brightness;
                color1.b += cos((v[0].Position.y ) - 1 + (time*s)) * brightness;
                color2.r += cos((v[0].Position.y ) + (time *s)) * brightness;
                color2.g += cos((v[0].Position.y ) - 0.5 + (time*s)) * brightness;
                color2.b += cos((v[0].Position.y ) - 1 + (time*s)) * brightness;
                color3.r += cos((v[0].Position.y) + (time *s)) * brightness;
                color3.g += cos((v[0].Position.y ) - 0.5 + (time*s)) * brightness;
                color3.b += cos((v[0].Position.y ) - 1 + (time*s)) * brightness;
                color1.a  = 0.75*abs(cos(time));	color2.a = 0.75*abs(cos(time));color3.a = 0.75*abs(cos(time));

                CreateVertex(triStream, v[0].Position + offsetdir1, v[0].Normal, color1);
                CreateVertex(triStream, v[1].Position + offsetdir1, v[0].Normal, color2);
                CreateVertex(triStream, v[0].Position - offsetdir1, v[0].Normal, color1);
                triStream.RestartStrip();
                CreateVertex(triStream, v[1].Position + offsetdir2, v[0].Normal, color2);
                CreateVertex(triStream, v[2].Position + offsetdir2, v[0].Normal, color3);
                CreateVertex(triStream, v[1].Position - offsetdir2, v[0].Normal, color2);
                triStream.RestartStrip();
                CreateVertex(triStream, v[0].Position + offsetdir3, v[0].Normal, color1);
                CreateVertex(triStream, v[2].Position + offsetdir3, v[0].Normal, color3);
                CreateVertex(triStream, v[0].Position - offsetdir3, v[0].Normal, color1);
                triStream.RestartStrip();
                //Extruded pass
                color1.a = 0.5*abs(cos((time)));	color2.a = 0.5*abs(cos((time))); color3.a = 0.5*abs(cos((time)));
                
                CreateVertex(triStream, v[0].Position + offsetdir1  +( 2 * v[0].Normal), v[0].Normal, color1);
                CreateVertex(triStream, v[1].Position + offsetdir1 + (2 * v[1].Normal), v[1].Normal, color2);
                CreateVertex(triStream, v[0].Position - offsetdir1 + (2 * v[0].Normal), v[0].Normal, color1);
                triStream.RestartStrip();
                CreateVertex(triStream, v[1].Position + offsetdir2 + (2 * v[1].Normal), v[1].Normal, color2);
                CreateVertex(triStream, v[2].Position + offsetdir2 + (2 * v[2].Normal), v[2].Normal, color3);
                CreateVertex(triStream, v[1].Position - offsetdir2 + (2 * v[1].Normal), v[1].Normal, color2);
                triStream.RestartStrip();
                CreateVertex(triStream, v[0].Position + offsetdir3 + (2 * v[0].Normal), v[0].Normal, color1);
                CreateVertex(triStream, v[2].Position + offsetdir3 + (2 * v[2].Normal), v[2].Normal, color3);
                CreateVertex(triStream, v[0].Position - offsetdir3 + (2 * v[0].Normal), v[0].Normal, color1);
                triStream.RestartStrip();
                //Tesselated Wireframe
                //Tesselation step
                float3 avgnormal = (v[0].Normal + v[1].Normal + v[2].Normal) / 3;
                //Vectors betweem points: 
                float3 vec[3] = { v[1].Position - v[0].Position ,v[2].Position - v[1].Position, v[0].Position - v[2].Position }; 
                //New points : 
                float3 n[3] = { v[0].Position + ((vec[0]) * 0.5) ,  v[1].Position + (vec[1] * 0.5),  v[2].Position + (vec[2] * 0.5) };
                //Vectors between new points
                float3 vecN[3] = { n[1] - n[0], n[2] - n[1], n[0] - n[2] };
                for (int i = 0; i < 3; i++) { vecN[i] = normalize(vecN[i]); };
                
                color.r = cos((n[0].y  ) + (time *s)) * brightness;
                color.g = cos((n[0].y  ) - 0.5 + ((time)*s)) * brightness;
                color.b = cos((n[0].y  ) - 1 + ((time)*s)) * brightness;
                color.a = abs( cos((time) ));
                wireframesize *= 0.5; 
                offsetdir1 = normalize(cross(vecN[0], avgnormal)) * wireframesize;
                offsetdir2 = normalize(cross(vecN[1], avgnormal)) * wireframesize;
                offsetdir3 = normalize(cross(vecN[2], avgnormal)) * wireframesize;

                //2 : 
                color.a = 0.25*abs(cos((time)));
                CreateVertex(triStream, n[1] + offsetdir1, avgnormal, color);
                CreateVertex(triStream, n[0] + offsetdir1, avgnormal, color);
                CreateVertex(triStream, n[1] - offsetdir1, avgnormal, color);
                triStream.RestartStrip();

                CreateVertex(triStream, n[2] + offsetdir2, avgnormal, color);
                CreateVertex(triStream, n[1] + offsetdir2, avgnormal, color);
                CreateVertex(triStream, n[2] - offsetdir2, avgnormal, color);
                triStream.RestartStrip();

                CreateVertex(triStream, n[0] + offsetdir3, avgnormal, color);
                CreateVertex(triStream, n[2] + offsetdir3, avgnormal, color);
                CreateVertex(triStream, n[0] - offsetdir3, avgnormal, color);
                triStream.RestartStrip();

                CreateVertex(triStream, n[1] - offsetdir1, avgnormal, color);
                CreateVertex(triStream, n[0] + offsetdir1, avgnormal, color);
                CreateVertex(triStream, n[0] - offsetdir1, avgnormal, color);
                triStream.RestartStrip();

                CreateVertex(triStream, n[2] - offsetdir2, avgnormal, color);
                CreateVertex(triStream, n[1] + offsetdir2, avgnormal, color);
                CreateVertex(triStream, n[1] - offsetdir2, avgnormal, color);
                triStream.RestartStrip();

                CreateVertex(triStream, n[0] - offsetdir3, avgnormal, color);
                CreateVertex(triStream, n[2] + offsetdir3, avgnormal, color);
                CreateVertex(triStream, n[2] - offsetdir3, avgnormal, color);
                triStream.RestartStrip();

                //Basic original geometry 
                float MinVisibility = 0.5; 
                brightness = 1; 
                color.r = pow(cos((v[0].Position.y ) + (time *s)) *  (brightness), 3);
                color.g = pow(cos((v[0].Position.y - 0.5)  + (time*s)) * (brightness), 3);
                color.b = pow(cos((v[0].Position.y - 1)  + (time*s)) * (brightness),3);
                color.a = sin(time) + abs(sin(time)) + ( cos(time)) + ((color.r + color.b + color.g) / 3 - 0.5);
                color.rgb *= 0.6; 
                CreateVertex(triStream, v[0].Position, v[0].Normal, color);

                color.r = pow(cos((v[1].Position.y) + (time *s)) *  (brightness), 3);
                color.g = pow(cos((v[1].Position.y - 0.5) + (time*s)) * (brightness), 3);
                color.b = pow(cos((v[1].Position.y - 1) + (time*s)) * (brightness), 3);
                color.rgb *= 0.6;
                CreateVertex(triStream, v[1].Position, v[0].Normal, color);

                color.r = pow(cos((v[2].Position.y) + (time *s)) *  (brightness), 3);
                color.g = pow(cos((v[2].Position.y - 0.5) + (time*s)) * (brightness), 3);
                color.b = pow(cos((v[2].Position.y - 1) + (time*s)) * (brightness), 3);
                color.rgb *= 0.6;
                CreateVertex(triStream, v[2].Position, v[2].Normal, color);
                triStream.RestartStrip();


                brightness = 1;
                color.rgb = 0.1; 
                color.a = 0.01;

                CreateVertex(triStream, v[0].Position, v[0].Normal, color);
                CreateVertex(triStream, v[1].Position, v[0].Normal, color);
                CreateVertex(triStream, v[2].Position, v[0].Normal, color);
                triStream.RestartStrip();
            }


            [maxvertexcount(75)]
            void ShellGenerator(triangle VS_DATA v[3], inout TriangleStream triStream)
            {
                //Shells & fins fur without fins. adds fuzzyness
                float s = 10;
                float brightness = 1;
                float MinVisibility = 0.5;
                float4 color[3];
                
                v[0].Position.x += cos((v[0].Position.y) + (time *s)) * xscale;
                v[0].Position.y += cos((v[0].Position.y) + (time *s)) * yscale;
                v[1].Position.x += cos((v[1].Position.y) + (time *s)) * xscale;
                v[1].Position.y += cos((v[1].Position.y) + (time *s)) * yscale;
                v[2].Position.x += cos((v[2].Position.y) + (time *s)) * xscale;
                v[2].Position.y += cos((v[2].Position.y) + (time *s)) * yscale;

                for (int i = 0; i < 3; i++)
                {
                    color[i].r = pow(cos((v[0].Position.y-0)+ (time *s))* (brightness + 0), 5);
                    color[i].g = pow(cos((v[0].Position.y-0.5) + ((time)*s))* (brightness + 0), 5);
                    color[i].b = pow(cos((v[0].Position.y-1) + ((time)*s)) * (brightness + 0), 5);
                    color[i].a = sin(time);
                    color[i].a = color[i].a*0.8;
                    color[i].rgb *= 0.7;
                    color[i].rgb += 0.4;
                }
                float scalar = 0; 
                float FurPasses = 25;
                float3 extrusion = 0;
                for (int j = 0; j < FurPasses; j++)
                {
                    scalar = j * 0.025;
                    scalar = pow(scalar, 3);
                    for (int i = 0; i < 3; i++)
                    {
                        color[i] *= 1 - scalar;
                        extrusion = (j*v[i].Normal * 0.05 + (0.001*j*float3(0,-1,0)));
                        CreateVertexUV(triStream, v[i].Position + extrusion, v[i].Normal, color[i], v[i].TexCoord);
                    }
                    triStream.RestartStrip();
                }
            }

            //***************
            // PIXEL SHADER *
            //***************
            float4 MainPS(GS_DATA input) : SV_TARGET 
            {
                input.Normal= -normalize(input.Normal);
                return float4(input.Color.rgb, input.Color.a);
            }


            float4 MainPSUV(GS_DATA_UV input) : SV_TARGET
            {
                input.Normal= normalize(input.Normal);
                float alpha =0;
                alpha = m_TextureDiffuse.Sample(samLinear, input.TexCoord).x *  input.Color.a;
                if (alpha < 0.005) discard;
                return float4(input.Color.rgb,alpha);
            }

            //*************
            // TECHNIQUES *
            //*************
            technique10 DefaultTechnique 
            {
                
                pass p0 {
                    SetRasterizerState(NoCulling);
                    SetBlendState(EnableBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
                    SetDepthStencilState(EnableDepthDisableWriting, 0);
                    SetVertexShader(CompileShader(vs_4_0, MainVS()));
                    SetGeometryShader(CompileShader(gs_4_0, WireGenerator()));
                    SetPixelShader(CompileShader(ps_4_0, MainPS()));
                }
                
                pass p1 {
                    SetRasterizerState(FrontCulling);
                    SetBlendState(EnableBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
                    SetDepthStencilState(DepthWriting, 0);
                    SetVertexShader(CompileShader(vs_4_0, MainVS()));
                    SetGeometryShader(CompileShader(gs_4_0, ShellGenerator()));
                    SetPixelShader(CompileShader(ps_4_0, MainPSUV()));
                }
                
                pass p2 {
                    SetRasterizerState(NoCulling);
                    SetBlendState(EnableBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
                    SetDepthStencilState(DepthWriting, 0);
                    SetVertexShader(CompileShader(vs_4_0, MainVS()));
                    SetGeometryShader(CompileShader(gs_4_0, ExplosionGenerator()));
                    SetPixelShader(CompileShader(ps_4_0, MainPS()));
                }
                
                pass p3 {
                    SetRasterizerState(NoCulling);
                    SetBlendState(EnableBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
                    SetDepthStencilState(DepthWriting, 0);
                    SetVertexShader(CompileShader(vs_4_0, MainVS()));
                    SetGeometryShader(CompileShader(gs_4_0, BezierGenerator()));
                    SetPixelShader(CompileShader(ps_4_0, MainPS()));
                }
            }