Search code examples
cg

Recreate shader in Unity 3D with Cg


I am practicing at writing shaders but I am running into some problems. I want to create this shader:

struct C3E4_Output {

   float4 position : POSITION;

   float4 color    : COLOR;

 };



 C3E4_Output C3E4v_twist(float2 position : POSITION,

                         float4 color    : COLOR,



                         uniform float twisting)

 {

   C3E4_Output OUT;

   float angle = twisting * length(position);

   float cosLength, sinLength;

   sincos(angle, sinLength, cosLength);

   OUT.position[0] = cosLength * position[0] +

                    -sinLength * position[1];

   OUT.position[1] = sinLength * position[0] +

                     cosLength * position[1];

   OUT.position[2] = 0;

   OUT.position[3] = 1;

   OUT.color = color;

   return OUT;

 }

Its from http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter03.html. Currently I have somthing but the result is really wierd.

enter image description here

This is what I have:

Shader "Custom/NoobShader_02" {
    Properties {
        twisting ("Twist", Range(-10,10)) = 1
    }
    SubShader {
        Pass{
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        float twisting;

        struct VertexOutput
        {
            float4 pos : SV_POSITION;
            float3 nor : NORMAL;
        };

        struct VertexInput
        {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
        };

        struct FragmentOutput
        {
            float4 color : COLOR;
        };

        VertexOutput vert (VertexInput i)
        {
            VertexOutput VOUT;
            VOUT.pos = mul(UNITY_MATRIX_MVP, i.vertex);
            float angle = twisting * length(i.vertex);
            float cosLength, sinLength;
            sincos(angle, sinLength, cosLength);

            VOUT.pos[0] = cosLength * i.vertex[0] +
                             -sinLength * i.vertex[1];
            VOUT.pos[1] = sinLength * i.vertex[0] +
                             cosLength * i.vertex[1];
            VOUT.pos[2] = 0;
            VOUT.pos[3] = 1;

            VOUT.nor[0] = cosLength * i.normal[0] +
                             -sinLength * i.normal[1];
            VOUT.nor[1] = sinLength * i.normal[0] +
                             cosLength * i.normal[1];
            VOUT.nor[2] = 0;


            return VOUT;
        }

        FragmentOutput frag() 
        {
            FragmentOutput FOUT;
            float4 tempCol = {abs(_SinTime.z),0,0,1};
            FOUT.color = tempCol;
            return FOUT;
        }
        ENDCG
        }
    } 
    FallBack "Diffuse"
}

Thanks in advance!


Solution

  • I found the anwser I needed to apply the matrix after the vertex manipulation:

    Shader "Custom/NoobShader_02" {
        Properties {
            twisting ("Twist", Range(-10,10)) = 1
        }
        SubShader {
            Pass{
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
    
            float twisting;
    
            struct VertexOutput
            {
                float4 pos : SV_POSITION;
                float3 nor : NORMAL;
            };
    
            struct VertexInput
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
    
            struct FragmentOutput
            {
                float4 color : COLOR;
            };
    
            VertexOutput vert (VertexInput i)
            {
                VertexOutput VOUT;
    
                float angle = twisting * length(i.vertex);
                float cosLength, sinLength;
                sincos(angle, sinLength, cosLength);
    
                i.vertex[0] = cosLength * i.vertex[0] +
                                 -sinLength * i.vertex[1];
                i.vertex[1] = sinLength * i.vertex[0] +
                                 cosLength * i.vertex[1];
                i.vertex[2] = 0;
                i.vertex[3] = 1;
    
                i.normal[0] = cosLength * i.normal[0] +
                                 -sinLength * i.normal[1];
                i.normal[1] = sinLength * i.normal[0] +
                                 cosLength * i.normal[1];
                i.normal[2] = 0;
    
                VOUT.pos = mul(UNITY_MATRIX_MVP, i.vertex);
                VOUT.nor = mul(UNITY_MATRIX_MVP, i.normal);
                return VOUT;
            }
    
            FragmentOutput frag() 
            {
                FragmentOutput FOUT;
                float4 tempCol = {abs(_SinTime.z),0,0,1};
                FOUT.color = tempCol;
                return FOUT;
            }
            ENDCG
            }
        } 
        FallBack "Diffuse"
    }