为顶点程序提供顶点数据

为顶点程序传递顶点信息

Cg / HLSL顶点程序,顶点信息必须通过结构体传递。几个常用的顶点结构被定义在了UnityCG.cginc 文件中。而且在大多数情况下使用它们就足够了。

  • appdata_base:顶点的位置,法线和一个纹理坐标。
  • appdata_tan:顶点的位置,切线,法线和一个纹理坐标。
  • appdata_full:顶点的位置,切线,法线,四个纹理坐标和颜色。

这个材质颜色的网格基于法线和只使用appdata_base顶点程序输入:

Shader "VertexInputSimple" {
  SubShader {
    Pass {
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #include "UnityCG.cginc"

      struct v2f {
          float4 pos : SV_POSITION;
          fixed4 color : COLOR;
      };

      v2f vert (appdata_base v)
      {
          v2f o;
          o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
          o.color.xyz = v.normal * 0.5 + 0.5;
          o.color.w = 1.0;
          return o;
      }

      fixed4 frag (v2f i) : SV_Target { return i.color; }
      ENDCG
    }
  }
}

如果你想访问不同的顶点信息,你需要声明自己的顶点结构体,或者给顶点着色器添加输入参数。顶点信息被认为是Cg/HLSL的语义,必须遵循以下规则:

语义:

  • POSITION : 顶点坐标,典型的float4.
  • NORMAL:法线顶点,典型的float3.
  • TEXCOORD0:是第一个UV坐标,典型的float2,float3
  • TEXCOORD1~TEXCOORD3 是第二道第四个UV坐标
  • TANGENT : 是切向量(用于法线映射),典型的float4
  • COLOR :是一种每个顶点都具备的颜色,典型的float

可视化UV

下面的Shader例子使用顶点坐标和第一个顶点着色器输入纹理坐标,在结构appdata中定义。这对于调试网格上的UV坐标非常有用。UV坐标可视化为红色和绿色的颜色(rg),超过0~1的范围的坐标有附加的蓝色色彩的应用。

Shader "Debug/UV 1" {
SubShader {
    Pass {
        Fog { Mode Off }
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        // vertex input: position, UV
        struct appdata {
            float4 vertex : POSITION;
            float4 texcoord : TEXCOORD0;
        };

        struct v2f {
            float4 pos : SV_POSITION;
            float4 uv : TEXCOORD0;
        };

        v2f vert (appdata v) {
            v2f o;
            o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
            o.uv = float4( v.texcoord.xy, 0, 0 );
            return o;
        }

        half4 frag( v2f i ) : SV_Target {
            half4 c = frac( i.uv );
            if (any(saturate(i.uv) - i.uv))
                c.b = 0.5;
            return c;
        }
        ENDCG
    }
}
}

可视化顶点颜色

这个Shader使用顶点位置和种每个顶点都具备的颜色作为顶点着色器输入(在结构appdata定义)。

Shader "Debug/Vertex color" {
SubShader {
    Pass {
        Fog { Mode Off }
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        // vertex input: position, color
        struct appdata {
            float4 vertex : POSITION;
            fixed4 color : COLOR;
        };

        struct v2f {
            float4 pos : SV_POSITION;
            fixed4 color : COLOR;
        };

        v2f vert (appdata v) {
            v2f o;
            o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
            o.color = fixed4(1,0.8,0.7,1);
            return o;
        }

        fixed4 frag (v2f i) : SV_Target { return i.color; }
        ENDCG
    }
}
}

调试颜色材质应用到一个模型照明进颜色

可视化法线

使用顶点位置和法线作为顶点着色器输入(在结构appdata定义)。正常的X,Y,Z组件可视化为R,G,B的颜色。因为法线的值在1 . .1范围内,

Shader "Debug/Normals" {
SubShader {
    Pass {
        Fog { Mode Off }
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        // vertex input: position, normal
        struct appdata {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
        };

        struct v2f {
            float4 pos : SV_POSITION;
            fixed4 color : COLOR;
        };

        v2f vert (appdata v) {
            v2f o;
            o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
            o.color.xyz = v.normal * 0.5 + 0.5;
            o.color.w = 1.0;
            return o;
        }

        fixed4 frag (v2f i) : SV_Target { return i.color; }
        ENDCG
    }
}
}

调试法线材质应用到一个模型。您可以看到模型硬阴影边缘。

(忽略后面不明物体..............NGUI的模型)

可视化切线和副法线

切线和副法线向量用于法线贴图。在统一只有切向量存储在顶点,和副法线来源于法线和切线。

使用顶点位置和法线作为顶点着色器输入(在结构appdata定义)。切线的X,Y,Z组件可视化为R,G,B的颜色。

切线

Shader "Debug/Tangents" {
SubShader {
    Pass {
        Fog { Mode Off }
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        // vertex input: position, tangent
        struct appdata {
            float4 vertex : POSITION;
            float4 tangent : TANGENT;
        };

        struct v2f {
            float4 pos : SV_POSITION;
            fixed4 color : COLOR;
        };

        v2f vert (appdata v) {
            v2f o;
            o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
            o.color = v.tangent * 0.5 + 0.5;
            return o;
        }

        fixed4 frag (v2f i) : SV_Target { return i.color; }
        ENDCG
    }
}
}

(忽略前面不明物体................NGUI的模型)

副法线

它使用顶点位置,法线和切线顶点输入。从法线和切线计算副法线。像正常的法线或者切线。

Shader "Debug/Binormals" {
SubShader {
    Pass {
        Fog { Mode Off }
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag

        // vertex input: position, normal, tangent
        struct appdata {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
            float4 tangent : TANGENT;
        };

        struct v2f {
            float4 pos : SV_POSITION;
            float4 color : COLOR;
        };

        v2f vert (appdata v) {
            v2f o;
            o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
            // calculate binormal
            float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
            o.color.xyz = binormal * 0.5 + 0.5;
            o.color.w = 1.0;
            return o;
        }

        fixed4 frag (v2f i) : SV_Target { return i.color; }
        ENDCG
    }
}
}

时间: 2024-11-10 01:21:49

为顶点程序提供顶点数据的相关文章

微信小程序开发本地数据缓存教程

微信小程序开发过程中,本地数据缓存是必不可少的一部分.而且本地数据缓存的用途还挺多的,下面木鱼小铺(https://www.muyu007.cn)就和大家分享一下微信小程序开发本地数据缓存教程,希望对大家有所帮助! 第一步:读写本地数据缓存 微信小程序为了方便开发者缓存数据提供了读写本地数据缓存接口,读本地数据缓存采用的是wx.getStorage/wx.getStorageSync接口,写本地数据缓存的是wx.setStorage/wx.setStorageSync接口.其中以Sync结尾的是

向顶点着色器提供顶点参数

对于 CG/HLSL 顶点程序,模型网格顶点数据被作为输入传递给顶点着色器函数.每个输入都需要一个语义来详细指定.比如,POSITION输入是 顶点的位置,NORMAL是顶点的法线. 通常,顶点数据输入被声明成一个结构体,而不是一个个的罗列他们.几个常用的顶点结构体都被丁艳在UnityCG.cginc include file里面了,并且大多数情况下,这些都够用了.这些结构体是: appdata_base:位置.法线还有一个贴图坐标 appdata_tan:位置.切线.法线.还有一个贴图坐标 a

[渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序读取相关数据

这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第六篇:为ASP.NET MVC应用程序读取相关数据 原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 译文版权所有,谢绝全文转载--但您可以在您的网站上添加到该教程的链接. 在之前的教程中您已经完成了学校数据模型.在本教程中你将

iOS应用程序间共享数据(转)

我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来分享数据,不过还是有些方法可以实现,为了方便说明,这里同时创建了两个工程Example1和Example2,实现这两个app之间的信息共享,Example1负责写数据,Example2负责读数据,具体的demo代码可以到这里获取 UIPasteboard 剪贴板是应用程序之间传递数据的简单方式,建议

[渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序更新相关数据

这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第六篇:为ASP.NET MVC应用程序更新相关数据 原文: Updating Related Data with the Entity Framework in an ASP.NET MVC Application 译文版权所有,谢绝全文转载--但您可以在您的网站上添加到该教程的链接. 在之前的教程中您已经成功显示了相关数据.在本教程中

iOS应用程序间共享数据

我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来分享数据,不过还是有些方法可以实现,为了方便说明,这里同时创建了两个工程send和receive,实现这两个app之间的信息共享,send负责写数据,receive负责读数据,具体的demo代码可以到这里获取 UIPasteboard 剪贴板是应用程序之间传递数据的简单方式,建议不要使用全局的粘贴板

原因是因为当OnCreate函数发生时,只是提供了数据初始化的机会

在Android中,有时需要对控件进行测量,得到的控件宽度和高度可以用来做一些计算.在需要自适应屏幕的情况下,这种计算就显得特别重要.另一方便,由于需求的原因,希望一进入界面后,就能得到控件的宽度和高度. 可惜的是,根据我的验证,利用网上转载的那些方法在OnCreate函数中获取到的仍然是0(希望搞技术的能自己验证过再转载),例如Measure方法之后调用getMeasuredWidth的值还是0. 原因是因为当OnCreate函数发生时,只是提供了数据初始化的机会,此时还没有正式绘制图形.而绘

从Apache的日志文件收集和提供统计数据(一个Python插件架构的简单实现)

从Apache的日志文件收集和提供统计数据 这一章我们将介绍基于插件程序的架构和实现.作为例子,我们将构建一个分析Apache服务器log文件的框架.这一次我们不再使用单片机的方式来创建,而是改为采用模块化的方式.一旦我们有了一个基本框架,我们就可以为它创建一个插件.这个插件可以基于请求者的地理位置执行分析. 程序的结构和功能 在数据维护和统计收集领域,很难有一个单一的应用程序可以适合多个用户的需求.让我们以分析Apache的web服务器日志文件为例.web服务器接受到的每一个请求都被记录在日志

使用ContentProvider进行应用程序间的数据交互

什么是ContentProvider: ContentProvider用来管理数据的访问规则.它允许你的应用程序向外界暴露需要被访问的数据. 是Android的四大组件之一. ContentProviders支持四种基本的操作,即我们平时所见到的CRUD操作(增删改查).Android系统 本身已经提供了一些内容提供者,它们允许我们查询联系人,媒体库,和短息消息等. 基于Content Uri的查询: 没有Uri,ContentProvider 类基本无法工作,就像我们上网没有网址.当我们要上网