2014-05-29 18:55:57 needspeedboy 阅读数 5722

unity3d 4.0以后用的mecanim也启用了navmesh寻路;

mecanim处理转弯之类的行为时一般是程序和动画结合让动画更生动自然。这样一般会有转弯动画,另外采用阻尼的思路,让动画更加平滑过渡;

官方的mecanime例子中的Locomotion.cs比如:


    public float m_AnguarSpeedDampTime = 0.3f;
    public float m_DirectionResponseTime = 0.3f;

    float angularSpeed = direction / m_DirectionResponseTime;
        
    m_Animator.SetFloat(m_AgularSpeedId, angularSpeed, angularSpeedDampTime, Time.deltaTime);
    m_Animator.SetFloat(m_DirectionId, direction, directionDampTime, Time.deltaTime);



上面的m_AnguarSpeedDampTime/m_DirectionResponseTime上是阻尼参数;如果动画有抖动可以这个数稍稍设高一点,这样不会那么容易变化幅度大,这两个参

数经常作为转动的重要参数,切换动画一般用它作判断。 



2019-08-06 15:33:27 qq_39588003 阅读数 314

2D贴图绘制方式有两种,第一种由 GUI 绘制,第二种是将贴图以材质的形式绘制在游戏对象中。

GUI绘制

在屏幕中绘制一张静态贴图,需要使用 GUI.DrawTexture() 方法,该方法原型如下:

GUI.DrawTexture(位置,  图片对象,  缩放模式,  是否开启图片混合模式,  图片缩放宽高比);

例如:GUI.DrawTexture(new Rect(100,100,120,120), texSingle, ScaleMode.StretchToFill, true, 0);

第一个参数表示图片绘制的区域,第二个参数表示绘制图片的对象,第三个参数表示图片缩放模式,第四个参数表示是否开启图片混合模式,第五个参数表示图片缩放宽高比。

 

示例1

分别读取单个图片与多个图片,并且将加载的图片绘制在屏幕当中。

一定要将加载的图片保存在“Assets”下的“Resources”文件夹(自己创建一个)中,否则的话程序将无法识别。

其中 Resource.Load()方法 和 Resource.LoadAll()方法的参数均为资源文件夹的完整路径,但是前者返回的是读取的资源对象,后者返回的是资源数组对象。

两者读取的都是“Resources”文件夹的对象

Resources.Load(string path) ;        //加载储存在Resources文件夹中path处的资源,加载单一的贴图资源。

Resources.Load(string path ,Type type) ;        //加载储存在Resources文件夹中path处的资源,只返回type的物体。

Resources.LoadAll(string path) ;        //加载Resources文件夹中的path文件夹或者文件中的所有资源。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class toPictrue : MonoBehaviour {

    private Texture2D tex;    //贴图
    private Object[] texs;    //贴图数组
    void OnGUI()
    {
        if(GUI.Button(new Rect(10,10,100,50),"加载一张贴图"))
        {
            if(tex == null)
            {
                //加载一张贴图
                tex = (Texture2D)Resources.Load("single/0");
            }
        }
        if(GUI.Button(new Rect(10,160,100,50),"加载一组图片"))
        {
            if(texs == null)
            {
                //加载一组贴图
                texs = Resources.LoadAll("textures");
            }
        }
        if(tex != null)
        {
            //绘制贴图
            GUI.DrawTexture(new Rect(110,10,120,120),tex,ScaleMode.StretchToFill,true,0);

        }
        if(texs != null)
        {
            for(var i = 0;i<texs.Length;i++)
            {
                GUI.DrawTexture(new Rect(110+i*120,160,120,120),(Texture)texs[i],ScaleMode.StretchToFill,true,0);
            }
        }

    }
}

运行结果:点击“加载一张贴图”按钮会显示上面那一张图,点击“加载一组图片”按钮会把指定文件夹的图片全部显示

 

绘制动画

帧动画绘制原理:首先需要一组帧动画资源,然后在屏幕中设定一个显示区域,接着将动画的每一帧图片按照固定的时间在这个区域顺序切换,实现动画的播放。

使用程序将动画资源存储在动画数组中,然后设定刷新时间,每次刷新动画时将在原有显示区域中绘制下一帧图片,到了最后一帧则从第一帧重新开始。

示例2

下图是“Assets”文件夹里的资源。

人物行走循环动画已经在屏幕中播放,并且播放帧数的序列号以标签的形式绘制在屏幕中

示例中,将播放动画的功能封装在 DrawAnimation() 方法中,该方法第一个参数表示动画资源数组对象,第二个参数表示动画的显示区域。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class E3_06 : MonoBehaviour {

    private Object[] anim;    //动画数组
    private int nowFram;    //帧序列
    private int mFrameCount;    //动画帧的总数
    private float fps = 5;    //限制一秒多少帧
    private float time = 0;    //限制帧的时间
	void Start () {
        //得到帧动画中的所有图片资源
        anim = Resources.LoadAll("WalkingCartoons");
	    //得到该动画共有多少帧
        mFrameCount = anim.Length;
    }
    void OnGUI()
    {
        //绘制帧动画
        DrawAnimation(anim, new Rect(50, 80, 32, 48));
    }

    void DrawAnimation(Object[] tex,Rect rect)
    {
        //绘制动画信息
        GUILayout.Label("当前动画播放:第"+nowFram+"帧");
        //绘制当前帧
        GUI.DrawTexture(rect,(Texture)tex[nowFram],ScaleMode.StretchToFill,true,0);
        //计算限制时间
        time += Time.deltaTime;
        //超过限制帧则切换图片
        if(time >= 1.0 / fps)
        {
            nowFram++;  //帧序列切换
            time = 0;   //限制帧清空
            if(nowFram >= mFrameCount)
            {
                nowFram = 0;
            }
        }
        
    }
	
}

运行结果:

2016-11-05 11:08:59 arxobject 阅读数 7056

今天我们讨论一下,如何在unity3d的一个plane中显示多张贴图的一部分,组合贴图。

首先新建一个plane



然后在project面板新建一个材质





将材质赋给这个plane


然后编写shader whiteboard.shader

将这个shader赋给材质

Shader "Custom/WhiteBoard" {
	Properties
    	{
//下面三个是要叠加的贴图
        _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
		_MiddleTex ("Middle (RGB),Alpha (A)", 2D) = "white" {}
		_TopTex ("Top (RGB),Alpha (A)", 2D) = "white" {}
		_WhiteBoardTex ("WhiteBoard (RGB),Alpha (A)", 2D) = "white" {}//需要一个白色的贴图做底色

        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255

        _ColorMask ("Color Mask", Float) = 15
        // 以 1 - _Height 长度为高度
        _Height ("Radius", Range(0,0.5)) = 0.5

		_TopRate ("TopRate", Range(0,1)) = 0.33  //显示裁剪的比例
		_MiddleRate ("MiddleRate", Range(0,1)) = 0.33
		_ButtomRate ("ButtomRate", Range(0,1)) = 0.33
    }
    
    SubShader
    {
        LOD 100

        Tags
        {
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
            "PreviewType"="Plane"
        }

        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp] 
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]
        }
        
        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Offset -1, -1
        Fog { Mode Off }
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask [_ColorMask]

        

        Pass
        {
            CGPROGRAM
                #pragma target 3.0
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"

                float _Height;
				float _TopRate;
				float _MiddleRate;
				float _ButtomRate;

                struct appdata_t
                {
                    float4 vertex : POSITION;
                    float2 texcoord : TEXCOORD0;
                    fixed4 color : COLOR;
                };
    
                struct v2f
                {
                    float4 vertex : SV_POSITION;
                    half2 texcoord : TEXCOORD0;
                    fixed4 color : COLOR;
                };
    
                sampler2D _MainTex;
				sampler2D _MiddleTex;
				sampler2D _TopTex;
				sampler2D _WhiteBoardTex;
                float4 _MainTex_ST;
                
                v2f vert (appdata_t v)
                {
                    v2f o;
                    o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                    o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                    o.color = v.color;
#ifdef UNITY_HALF_TEXEL_OFFSET
                    o.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
                    return o;
                }
                
                fixed4 frag (v2f i) : COLOR
                {
				    fixed4 col2 = tex2D(_MiddleTex, i.texcoord) ;//获得贴图的rgba,颜色像素信息
					fixed4 base_col = tex2D(_MainTex, i.texcoord) ;
					fixed4 top_pic = tex2D(_TopTex, i.texcoord) ;
					fixed4 white_canva = tex2D(_WhiteBoardTex, i.texcoord) ;

                    float2 uv = i.texcoord.xy; //输入的面的uv坐标
                    float4 c = i.color;  //输入的面的颜色信息
					float4 c1 = i.color;
					float4 c3 = i.color;
					float4 c_alpha_mask = i.color;
			
					fixed4 col4 = col2;
              
                    if( uv.y < _TopRate && uv.y > 0.0)
                    {        
							c.rgba = col2.rgba;//根据不同的uv坐标显示不同贴图的颜色信息
                    }
                     if( uv.y > _TopRate + _MiddleRate && uv.y <1.0)
                    {        
							c1.rgba = base_col.rgba;
                    }

					if(uv.y>_TopRate && uv.y<_TopRate + _MiddleRate)
					{
						c3.rgba = top_pic.rgba;
					}
					
                    fixed4 col_a = white_canva * c * c1 *c3;//将颜色信息与白色底图叠加
                    return col_a; //最后输出叠加后的颜色信息,贴图就叠加完成
                }
                                
            ENDCG
        }
    }
}



最后看到效果



这样就可以实现在不同的uv坐标下,显示不同的贴图,达到贴图的叠加了。

2013-03-18 17:29:31 nnsword 阅读数 11290

使用Unity3D 中的 ShaderLab 实现两张不同贴图之前的混合 类似于3dsMAX 中的Blend材质.

1.在Properties 中定义三个变量.我们需要使用的..1. _Color 主要是用它的 Alpha 来进行两张图的混合 ,2.两张需要进行操作的贴图

2.在混合时主要是使用 SetTexture 中的 Combine scr1 lerp(constant) src2. 这里要注意.在一个SetTextrue 中我们只能对一个texture来操作. 所以在混合前我们需要先用一个SetTexture 将第一张图贴上去.

 然后再用 Combine previous lerp(constant) texture .将第二张与之前的(previous)来混合,lerp(constant) 就是以_Color的Alpha来做为混合的界定.

 

View Code 
 Shader "ztc_Blend" 
 {
     Properties 
     {
         _Color ("Main Color",Color) = (1,1,1,0.5)
         _MainTex ("FrontTex (RGB)", 2D) = "white" {}
         _BackTex ("BackTex (RGB)", 2D) = "white" {}
     }
     SubShader 
     {
         Pass
         {
             Material
             {
                 Diffuse[_Color]
             }
             Lighting On
             
             SetTexture [_MainTex] //the default Texture
             {
                 Combine texture
             }
             SetTexture [_BackTex] //use the combine lerp to mix two texture by the Main color's Alpha
             {
                 constantColor [_Color]
                 Combine previous lerp(constant) texture
             }
             
         }
     } 
     FallBack "Diffuse"
 }


2018-06-12 10:30:58 lhcmt1 阅读数 1434

复习第三章:(学习请看下面的文章链接)

原文:https://catlikecoding.com/unity/tutorials/rendering/part-3/

译文:http://gad.qq.com/program/translateview/7173931

第三章使用多张纹理贴图

1.   对多张纹理贴图进行采样。

2.   使用细节纹理贴图。

3.   在线性空间中处理颜色

4.   使用splat贴图。

 

多个纹理的采样

float4 MyFragmentProgram (Interpolators i) : SV_TARGET {

float4 color = tex2D(_MainTex, i.uv)* _Tint;

color = tex2D(_MainTex,i.uv * 10);

    returncolor;

}

 

以上的代码color被赋值了两次,编译器会自动去掉第一行无用的代码

color *=tex2D(_MainTex, i.uv * 10);

两个纹理贴图结果通过相乘,进行混合

单独的细节纹理贴图

两个纹理贴图相乘在一起的时候,结果将变得更暗。除非至少有一个纹理是白色的。纹理像素的每个颜色通道的值介于0和1之间。当向纹理添加细节贴图的时候,你可能需要进行变暗处理,也可以进行增亮处理。

例如:color *= tex2D(_MainTex, i.uv * 10) * 2;

或者使用另一张细节纹理贴图,在顶点数据结构增加一对UV

 float2 uvDetail : TEXCOORD1;

顶点UV坐标值介于0和1之间,需要在顶点着色器中变换到贴图坐标系,输入到片段着色器中。

贴图的细节从这张贴图上采样,这样就可以可以单独编辑

float4 MyFragmentProgram(Interpolators i) : SV_TARGET {

    float4color = tex2D(_MainTex, i.uv) * _Tint;

    color *=tex2D(_DetailTex, i.uvDetail) * 2;

    return color;

}

 

让细节纹理贴图淡出

添加细节纹理贴图原因:可以在离得很近或者纹理被放大的时候改善材质的外观表现

通过使用Fadeout Mip贴图,可以使得远处的纹理淡出

 

 

线性颜色空间

两种颜色空间,线性空间(斜率1),伽马空间

参考文章https://blog.csdn.net/bill2ccssddnn/article/details/53423410

 

最广泛使用的图像颜色格式是sRGB:存储颜色 = 原始颜色  ^ 1 /2.2

要将sRGB图像颜色格式中的数据转换回其原始颜色,请应用2.2的伽玛校正。

         

使用gamma 1 / 2.2进行编码和使用gamma 2.2进行解码。

在gama空间渲染时,直接访问sRGB中的原始颜色,

线性空间的颜色值的优点之一是它可以实现更加逼真的光照计算

将上述Gama空间中的计算转换到线性空间时,细节贴图会变暗,原因是,转换为线性颜色空间后,细节纹理采样值更小了,假设原本为 0.5, 转换后变成,

Unity定义了一个变量unity_ColorSpaceDouble

color *=tex2D(_DetailTex, i.uvDetail) * unity_ColorSpaceDouble;

这样可以保证无论哪个细节材质都是一样的。

 

 

TextureSplatting

Splatting纹理是一张只存储0 1 贴图,它可以只有一个通道,R,也可以是RGB分别存储。

通过这个技术,可以用Splatting纹理来规定哪些像素使用哪一张纹理,例如,在地形可以标记哪些位置是草地,哪些是泥土等。


要启用“Bypass sRGB Sampling”,保证采样结果为0或者1。

使用R通道

return

    tex2D(_Texture1, i.uv) * splat.r +

    tex2D(_Texture2, i.uv) * (1 - splat.r);

 

同时使用RGB通道

return

    tex2D(_Texture1, i.uv) * splat.r +

    tex2D(_Texture2, i.uv) * splat.g +

    tex2D(_Texture3, i.uv) * splat.b +

    tex2D(_Texture4, i.uv) * (1 - splat.r -splat.g - splat.b);

 

Unity3D地形创建

阅读数 8189

没有更多推荐了,返回首页