使用Cg在Unity 3D中重新创建着色器

时间:2015-07-01 12:37:55

标签: cg

我正在练习编写着色器,但我遇到了一些问题。我想创建这个着色器:

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;

 }

来自http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter03.html。目前我有一些东西,但结果真的很奇怪。

enter image description here

这就是我所拥有的:

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"
}

提前致谢!

1 个答案:

答案 0 :(得分:0)

我发现我需要在顶点操作后应用矩阵:

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"
}