unity3d 挖掘机模型_unity3d 模型的渲染模型 - CSDN
  • Unity虚拟现实开发,挖掘机运动关节绑定,包括动力大臂,连杆,铲斗等均已绑定;读者有兴趣请自行绑定履带;另外,Demo中的模型等资源请自觉不要用于商业目的。
  • using System.Collections; using System.Collections.Generic; using UnityEngine; public class MainarmMove2 : MonoBehaviour { public float rotSpeed; // Use this for initialization ...
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class MainarmMove2 : MonoBehaviour {
        public float rotSpeed;
        // Use this for initialization
        void Start() {
    
        }
    
        // Update is called once per frame
        void Update() {
            if (Input.GetKey(KeyCode.I)) {    //forward
                MoveI();
            }
            if (Input.GetKey(KeyCode.J)) {   //back
                MoveJ();
            }
        }
        void MoveI() {
            transform.Rotate(Vector3.forward * rotSpeed * Time.deltaTime); //围绕某轴旋转    }
        }
        void MoveJ() {
            transform.Rotate(Vector3.back * rotSpeed * Time.deltaTime);
        }
    }
    
    https://pan.lanzou.com/i0rgqmb


    展开全文
  • 好一段时间没写博客了,新年来第一天正式上班,新的一年里要求自己有新的变化,坚持每天不断的学习和提高,改变过去的晚睡晚期的不好习惯,昨天周末,利用一天休息时间去打打篮球,发现过去一百天里每天熬夜到深夜,...

    好一段时间没写博客了,新年来第一天正式上班,新的一年里要求自己有新的变化,坚持每天不断的学习和提高,改变过去的晚睡晚期的不好习惯,昨天周末,利用一天休息时间去打打篮球,发现过去三个月里每天熬夜到深夜,发现体质明显下降,今天起来发现浑身酸痛,得调整一下作息和生活,坚持锻炼,坚持早睡早起,早晨起来每天都坚持看一小时的书,如果每天都坚持在某个时间段固定去学一样东西,时间一长,一周或者一个月甚至一年下来你会惊讶的发现原来你自己学了那么多,贵在坚持,每个人都知道,但真真能做到的人比较少,如果能做到这点,就算将来即便成不了大牛那也是一直走在成为大牛做过的路上,也会受益匪浅,我写上这个也是自我勉励,另一方面也是大家共勉,生活上,学习上的点点滴滴总是那么神奇,过去未知答案时所走出的道路在未来的这天,发觉将其串联起来,现在所走的路不知道是何路,但必是将来通向未来之路,因不满足于现状,觉得可以做的更好,所以,通过不断的努力,去改变现状,一直不想当一个井底之蛙,IT技术上更是如此,如果仅仅是安于现状,那永远是跟不上时代的步伐,只会不进则退。不知何时开始,我有了自己的追求,有一股劲儿,一直想做的更好,学的更多,相信有一天能成为一个参天大树。假如抛开一切的负担,你最在乎的是什么?或者说你最想做的事是什么?燃气你的激情,为理想而奋斗。实现理想的过程是艰辛的,但如果一旦实现,发现时甜蜜的,理想or梦想,但他们不是梦,并不是遥不可及,用燃烧不进的激情,追随她~ 不要让自己迷失方向,安于现状,不要冷漠了任何事物,她总会有她神奇的一面,不断的挖掘,相信你都会有人家体会不到的收获,好奇心,永远保持一颗好奇心!以上是算给自己新年鼓鼓气,接下来还是要落地,写写今天的收获!

    问题说明:

    年前做的web和pc的一个项目,背景当时是用的一个plane然后上面放的是一个带有背景图片的一个材质球,这个通过改变plane的z轴属性是能控制它的显示在3D模型之后,但貌似自适应有点难以控制,当时是用过在界面上手动改变的Scale属性来让背景铺满整个窗口,但无法自适应所有分辨率大小的窗口,然后我就想通过动态代码在plane上添加一个Textrue2D的一个图片,但发现无论怎样拖动模型的z轴属性还是不能让模型显示在背景之前。后来经过一段摸索,搞定,这将摸索过程写下来。

    在这里我要提一下MeshRenderer,即网格渲染器,如果我们不勾选这个网格渲染器,在Game场景中是看不到plane的样子的,即网格渲染器将材质渲染出来,材质中包含Texture属性,我们可以选择自己的贴图,也可以选择颜色,网格渲染器就可以将材质中的这些给渲染出来,让我们看到,原来我就是通过这个方法来实现的背景图,下面是另一种添加GUITexture的方法来实现,利用到了多个摄像机共同合作达到效果!

    解决步骤:

    1.添加一个摄像机,命名为BackgroundCamera,然后在Layer添加一个background层。并且将plane拖放到改相机节点下。然后将BackgroundCamera和Plane都置于background层,修改ClearFlags未Depthonly深度渲染,并且设置CullingMask为只看到background层,还有设置Depth为-1,说明背景层是最深,其他model所在的相机的Depth是0,NGUI的是1,这里层次关系就是NGUI在最前面,model层其次,然后是背景层,这样确保3D模型在背景的前面!


    2.同样的操作,将MainCamera设置一下,注意的就是,将MainCamera的CullingMask不能包含background层,也就是让它看不到背景层,不然还是会出现背景遮挡住模型的情况。


    3.在plane上添加一个脚本,用于动态在plane上加载贴图
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public class AddBackground : MonoBehaviour
    {
        public Texture2D mtexture;
    
        void Awake()
        {
    //        Texture2D mtxture = new Texture2D(Screen.width, Screen.height);
    //        renderer.material.mainTexture = mtxture;
    //        mtxture.Apply();
            
            gameObject.AddComponent<GUITexture>();
        }
    
        // Use this for initialization
        void Start()
        {
            guiTexture.texture = mtexture;
            transform.localScale = new Vector3(0, 0, 0);
            transform.localPosition = new Vector3(0, 0, 25);
            guiTexture.pixelInset = new Rect(65, 0, Screen.width, Screen.height);
        }
    }
    上面Start方法中设置position的z轴属性是原来尝试的,想通过z轴来进行深度的修改后来发现行不通,还是层的关系影响渲染的深度。

    4.效果图


    ==================== 迂者 丁小未 CSDN博客专栏=================

    MyBlog:http://blog.csdn.net/dingxiaowei2013             MyQQ:1213250243

    Unity QQ群:375151422         cocos2dx QQ群:280818155

    ====================== 相互学习,共同进步 ===================


    展开全文
  • 大家好,欢迎大家关注我的博客,我是秦元培,我的博客地址是blog....好了,那么今天博主想和大家分享的是自动寻路与Mecanim动画系统结合起来实现的一个小案例,希望对大家学习Unity3D能够有所帮助。 博主曾经告诉大家

            大家好,欢迎大家关注我的博客,我是秦元培,我的博客地址是blog.csdn.net/qinyuanpei。这段时间博主将大部分的精力都放在了研究官方示例项目上,主要是希望能够从中挖掘出有价值的东西分享给大家,这样博主和大家可以共同学习。好了,那么今天博主想和大家分享的是自动寻路与Mecanim动画系统结合起来实现的一个小案例,希望对大家学习Unity3D能够有所帮助。

           博主曾经告诉大家,博主是一个仙剑迷,平时学习编程累了的时候,博主就会玩玩仙剑,如图是博主偶尔回去玩玩的《新仙剑OL》,仙剑的网游化道路似乎一直不曾平坦,从最初的《仙剑OL》到现在的《新仙剑OL》,仙剑的网游化一直处于不温不火的状态。


              虽然博主比较反感网游,可是作为一款由博主喜欢的单机游戏改编的网游,博主还是忍不住去尝试了一下。基于Unity3D的《新仙剑OL》虽然从画面质量上与同类网页游戏拉开了距离,然而在游戏的玩法和体验上依然没有摆脱国产网游的固定模式,博主叹息之余,便根据这款游戏在自动寻路上的设计写出了这篇文章。说到自动寻路,这几乎是目前所有网页游戏的标准配置了,在博主看来,自动寻路在简化玩家寻找目标的途径的同时,弱化了玩家的参与,使得本该玩家自行探索的游戏世界,变成了枯燥无味的鼠标游戏。曾几何时,我们在迷宫中探索着远方的路,曾几何时,我们开启机关、破解阵法收获着游戏的乐趣。在这样一个快节奏的时代,我们却只能一遍遍地回想着过去的生活,那个时候没有电脑、没有智能手机、没有电影.....可是我们却常常怀念那个时候简单的生活,所以,小时候,幸福是件简单的事情,长大后,简单是件幸福的事情。尽管博主讨厌自动寻路这一设定,可是这与我们学习Unity3D无关,因为我们只是为了更好地使用这个引擎来做出好的游戏产品。好了,闲话少叙,我们继续说《新仙剑OL》中的自动寻路,在游戏中玩家可以通过鼠标来控制人物,如果距离较远,则人物会以奔跑的形式到达目标位置,否则人物将步行到目标位置。而这就是我们今天想要实现的效果。好了,下面我们正式开始今天的内容,今天的内容呢,分为两个部分,第一部分讲述Mecanim动画系统,第二部分讲述自动寻路。

     

    第一部分:Mecanim动画系统

             在这一部分,我们主要讲的是动画的切换,因为从刚才的描述中我们知道,角色的动画有三种状态,即Idle、Walk、Run。通过前面的学习呢,我们知道通过Mecanim动画系统的状态机我们可以很方便地实现动画状态的切换。由此我们就可以理出一个大致的思路,通过鼠标点击获取鼠标位置,然后我们利用射线的方法,从摄像机发射一条经过该点的射线,则射线与地面的交点就是我们寻路的目标点,我们通过计算角色与目标点之间的距离来确定角色要采用什么样的动画,而寻路则交给Unity3D的Nav Mesh Agent组件来完成,这就是我们今天的实现思路,其实博主在之前的一篇文章中已经讲述过这种方法,这里不过是在之前的基础上,结合Mecanim动画系统和自动寻路组件做了些改进而已。好了,我们打开我们的项目,如图,是博主创建的一个简单的场景,我们今天的内容就以这个场景来展开:


    接下来,我们利用Mecanim动画系统来设计角色的动画,如图,在今天的项目中角色只有三种状态,因此我们可以将三种状态连接起来,这里我们定义了两个Bool类型的变量IsWalk和IsRun,默认为False,这是我们今天用来切换动画的两个变量开关。剩下的工作就是编写脚本来控制动画了,这一步我们放在第二部分来讲。



    第二部分:自动寻路

          在这一部分,我们首先要对场景进行烘培,因为Nav Mesh Agent组件是根据网格来计算寻路的路线的,所以烘培的过程相当于是在保存场景中的网格信息,只有这样我们才能够使用Unity3D的寻路组件。下面我们就来讲解下场景的烘焙:

          首先我们选中场景中不需要与玩家发生交互的物体,或者可以认为这些物体是我们的角色需要避开的障碍物,将其设置为Static,如图:


            接下来我们通过Windowe->Navigation命令打开Navigation窗口,此时被选中的物体以深色显示,确认无误后,点击Bake按钮对场景进行烘焙,这样我们就完成了场景的烘焙工作。


           好了,下面我们选中场景中的角色,为其添加Nav Mesh Agent组件,此时场景中会显示出绿色的区域,其含义是这些区域角色可以到达。关于Nav Mesh Agent组件的参数,大家可以自行查阅API文档,这里不做解释了,好了,下面我们编写脚本:

    using UnityEngine;
    using System.Collections;
    
    public class PeopleScripts : MonoBehaviour {
    
    	//动画组件
    	private Animator mAnim;
    	//移动速度
    	public float MoveSpeed=2.5F;
    	//寻路组件
    	private NavMeshAgent mAgent;
    	//寻路目标标记
    	private GameObject Ball;
        
    	//寻路标记预制件
    	public GameObject PrefabBall;
    
    	void Start () {
    	  //获取动画组件
    	  mAnim=GetComponent<Animator>();
    	  //获取寻路组件
    	  mAgent=GetComponent<NavMeshAgent>();
    	}
    
    	void Update () {
    		//按下鼠标左键
    		if(Input.GetMouseButton(0))
    		{
    			//获取鼠标位置
    			Vector3 mPos=Input.mousePosition;
    			//利用射线法取得目标位置
    			Ray mRay=Camera.main.ScreenPointToRay(mPos);
    			RaycastHit mHit;
    			if(Physics.Raycast(mRay,out mHit))
    			{
    				//这里对应于场景中的地面、墙体、楼梯三种结构
    				if(mHit.collider.tag=="Ground" || mHit.collider.tag=="Wall" || mHit.collider.tag=="Ti")
    				{
    				   //获得目标位置
    				   Vector3 mTarget=mHit.point;
    				   //使用完全面向目标的旋转
    				   transform.LookAt(mTarget);
    				   //使用平滑转身转向目标
    				   //SmoothRotate(mTarget);
    				   //计算距离
    				   float mDistance=Vector3.Distance(mTarget,this.transform.position);
    				   //当距离大于4时奔跑到目标位置,否则步行到目标位置
    				  if(mDistance>4F){
    					  mAnim.SetBool("IsRun",true);
    				  }else{
    					  mAnim.SetBool("IsWalk",true);
    				  }
    				  
    				  //根据不同的结构生成不同高度的寻路目标标记
    				  if(mHit.collider.tag=="Ground"){
    				     //标记寻路目标
    				     Ball=(GameObject)Instantiate(PrefabBall,new Vector3(mTarget.x,0.5F,mTarget.z),
    						  Quaternion.identity);
    				  }else{
    						//标记寻路目标
    						Ball=(GameObject)Instantiate(PrefabBall,new Vector3(mTarget.x,3.0F,mTarget.z),
    						     Quaternion.identity);
    				  }
    				  //设置寻路目标
    				  mAgent.SetDestination(mTarget);
    				}
    			}
    		}
    	}	
    
    	void OnTriggerEnter(Collider mCollider)
    	{
    		if(mCollider.tag=="Ball")
    		{
    			//获取目标标记
    			GameObject mBall=mCollider.gameObject;
    			//销毁目标标记
    			Destroy(mBall);
    			//将角色状态设为Idle
    			mAnim.SetBool("IsRun",false);
    			mAnim.SetBool("IsWalk",false);
    		}
    	}
    
    
    	//平滑转身,参考自Stealth
    	void SmoothRotate(Vector3 target)
    	{
    		//构造目标朝向
    		Quaternion targetRotation = Quaternion.LookRotation(target, Vector3.up);
    		//对目标朝向进行插值
    		Quaternion mRotation = Quaternion.Lerp(transform.rotation, targetRotation, 15F * Time.deltaTime);
    		//赋值
    		transform.rotation=mRotation;
    	}
    }
    

    最后,我们来看看最后的效果吧,为了让大家更清楚的看到寻路的效果,博主在寻路点处增加了一个紫色的小球,便于大家观察:



    每日箴言:别低头,别诉苦。他们以为你无坚不摧,那就随他们喜欢;别人不知道的,你没必要反驳给他听。




    喜欢我的博客请记住我的名字:秦元培,我博客地址是blog.csdn.net/qinyuanpei。
    转载请注明出处,本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/38981669


    展开全文
  • Unity机械结构仿真

    2020-07-30 23:31:30
    Unity绑定机械关节,铰链,机构插件包 绑定完整的工程机械,例如:起重机,压路机,装载机,平地机,挖掘机等。绑定曲柄滑块机构,如往复活塞式内燃机,飞机行星发动机等
  •  渲染技术这个东西,在项目前期我并没有投入太多精力去思考,在当时的环境下我更看中手游的性能,我做端游,可以无限地挖掘电脑的性能,比如多线程去处理角色的软件蒙皮之类,但是做手游,则要保护...

          有朋友私信我问我为啥很久不更新博客,是不是转行了...我当然不可能承认自己懒啊,只能回复说太忙了.不过项目开发中,确实很难有时间和心力去总结和思考一些东西,不过现在忙完一些项目以后,我又回来了.

          渲染技术这个东西,在项目前期我并没有投入太多精力去思考,在当时的环境下我更看中手游的性能,我做端游,可以无限地挖掘电脑的性能,比如多线程去处理角色的软件蒙皮之类,但是做手游,则要保护手机的硬件资源,防止手机耗电快发热.比如限帧30fps.直到两年前经历了一次美术和技术的撕逼以后,我才重新思考了一下这个东西.整个过程也很有趣,老板觉得游戏画面不行,其实是美术做得不好,但是美术领导用了一堆次世代的技术名词来忽悠老板说我们技术不行,啥都不支持...一个页游公司的美术整天吹嘘次世代我也是醉了,真正做过次世代的我反而成了外行...次世代本身就是个大坑,手游上投入的性价比更低,很多大点的公司都深陷次世代的泥潭,我要对游戏的技术负责和把关,撕逼是难免的.但是撕逼归撕逼,想要画面好是大家的共同心愿,能不能在保证效率和投入性价比的情况下,提升一些画面呢?

           我的想法是,一些牛逼技术是一定是要有的,如果性能有问题,那么尽量优化,甚至限制性的使用,有总比没有好,不管是为了应付美术,还是老板,当然这不是我的初衷.我作为一个热爱引擎的程序员,画面好本身就是我们追求的东西.做技术的一定要有追求.

           然后对整个渲染技术架构思考了几天,做出了一个大胆的想法,就是升级Unity4到Unity5,然后放弃Unity自带的surface shader和实时光照,利用Unity5新增的shader_feature功能自己写一套比较万能通用的standard shader,而避免整个项目一堆乱七八糟混乱的shader.至于为什么要这么干,主要原因有几个.

    1.角色的动态光照,用全局shader参数来模拟灯光,比在Unity场景里面摆几个光源的效率更高一些.

    2.surface shader的一些默认的定制会占据一些texture interpolator,对于我实现扩展一些效果有限制.而且不够清爽.

    3.一些特殊效果需要场景所有对象shader的支持,比如天气系统的渐变过渡.如果所有shader都自己写的,那会特别方便.

    4.Unity4的时候,光照图和Unity的动态光源是不能叠加的,如果自己实现的动态光源,就可以叠加的,当然Unity5后来是可以叠加的.

            我这套shader基本涵盖了场景中的所有对象:

    1.物件用SceneStandard.shader(有PBR版本)

    2.角色用CharacterStandard.shader(有PBR版本)

    3.粒子用ParticleStandard.shader

    4.天空用SkyBox.shader

    5.地形用TerrainT4M.shader

    6.水面用Water.shader

    7.小草用Grass.shader

           整个场景的光照方案,场景用光照图 + 全局shader光源,角色用全局shader光源 + projector shadowmap.对于角色和场景,都有两套shader,一套传统光照模型,一套PBR光照模型.

           以一个传统光照模型的SceneStandard.shader来说.

    Shader "Luoyinan/Scene/SceneStandard" 
    {
    	Properties
    	{
    		_Color ("Main Color", Color) = (1, 1, 1, 1)
    		_MainTex("Main Texture RGB(Albedo) A(Gloss & Alpha)", 2D) = "white" {}
    		_NormalTex("Normal Texture", 2D) = "bump" {}
    		_GlossTex ("Gloss Texture", 2D) = "white" {}
    
    		_HalfLambert("Half Lambert", Range (0.5, 1)) = 0.75
    
    		_SpecularIntensity("Specular Intensity", Range (0, 2)) = 0
    		_SpecularSharp("Specular Sharp",Float) = 32
    		_SpecularLuminanceMask("Specular Luminance Mask", Range (0, 2)) = 0
    	}
    
    	SubShader
    	{
    		Tags
    		{
    			"Queue" = "Background" 		
    			"RenderType" = "Opaque" // 支持渲染到_CameraDepthNormalsTexture
    		}
    
    		Pass
    		{
    			Lighting Off
    			CGPROGRAM
    
    			#pragma vertex vert
    			#pragma fragment frag
    			#pragma multi_compile_fog
    			#pragma fragmentoption ARB_precision_hint_fastest
    			#include "UnityCG.cginc"
    
    			#pragma shader_feature _NORMAL_MAP
    			#pragma shader_feature _LUMINANCE_MASK_ON
    
    			#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    			#pragma multi_compile __ _FADING_ON
    			#pragma multi_compile __ _POINT_LIGHT
    			#pragma multi_compile __ _FANCY_STUFF
    		
    			struct appdata_lightmap 
    			{
    				float4 vertex : POSITION;
    				half2 texcoord : TEXCOORD0;
    				half2 texcoord1 : TEXCOORD1;
    #if _FANCY_STUFF
    				half3 normal : NORMAL;
    	#if _NORMAL_MAP
    				half4 tangent : TANGENT;
    	#endif
    #endif 
    			};
    
    			// SM2.0的texture interpolator只有8个,要合理规划.
    			struct v2f 
    			{
    				float4 pos : SV_POSITION;
    				half2 uv0 : TEXCOORD0;
    #ifndef LIGHTMAP_OFF 
    				half2 uv1 : TEXCOORD1;
    #endif
    				UNITY_FOG_COORDS(2)
    				float3 posWorld : TEXCOORD3;
    #if _FANCY_STUFF
    				half3 normalWorld : TEXCOORD4;
    	#if _NORMAL_MAP
    				half3 tangentWorld : TEXCOORD5;
    				half3 binormalWorld : TEXCOORD6;
    	#endif
    #endif 
    			};
    		
    			fixed4 _Color;
    			sampler2D _MainTex;
    			half4 _MainTex_ST;
    
    #if _POINT_LIGHT
    			float4 _GlobalPointLightPos;
    			fixed4 _GlobalPointLightColor;
    			fixed _GlobalPointLightRange;
    #endif 
    
    #ifndef LIGHTMAP_OFF
    	#if _FADING_ON
    			sampler2D _GlobalLightMap;
    			fixed _GlobalFadingFactor;
    	#endif
    #endif
    
    #if _FANCY_STUFF
    			sampler2D _GlossTex;
    			fixed _HalfLambert;
    
    			fixed _SpecularIntensity;
    			fixed _SpecularSharp;
    			half4 _GlobalMainLightDir;
    			fixed4 _GlobalMainLightColor;
    			half4 _GlobalBackLightDir;
    			fixed4 _GlobalBackLightColor;
    
    	#if _LUMINANCE_MASK_ON
    			fixed _SpecularLuminanceMask;
    	#endif
    
    	#if _NORMAL_MAP
    			uniform sampler2D _NormalTex;
    			half4 _NormalTex_ST;
    	#endif
    #endif 
    
    			v2f vert(appdata_lightmap i)
    			{
    				v2f o;
    				o.pos = mul(UNITY_MATRIX_MVP, i.vertex);
    				o.uv0 = TRANSFORM_TEX(i.texcoord, _MainTex);
    #ifndef LIGHTMAP_OFF 
    				o.uv1 = i.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
    #endif
    				o.posWorld = mul(unity_ObjectToWorld, i.vertex).xyz;
    #if _FANCY_STUFF
    				o.normalWorld = UnityObjectToWorldNormal(i.normal);
    	#if _NORMAL_MAP
    				o.tangentWorld = UnityObjectToWorldDir(i.tangent);
    				o.binormalWorld = cross(o.normalWorld, o.tangentWorld) * i.tangent.w;
    	#endif
    #endif 
    				UNITY_TRANSFER_FOG(o, o.pos);
    				return o;
    			}
    		
    			fixed4 frag(v2f i) : COLOR
    			{			
    				fixed4 mainColor = tex2D(_MainTex, i.uv0);
    				fixed alpha = mainColor.a; 
    				fixed4 finalColor = mainColor * _Color;
    
    				// lightmap
    #ifndef LIGHTMAP_OFF 
    				fixed3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv1));
    	#if _FADING_ON
    				fixed3 lm_fading = DecodeLightmap(UNITY_SAMPLE_TEX2D(_GlobalLightMap, i.uv1));
    				lm = lerp(lm, lm_fading, _GlobalFadingFactor);			
    	#endif
    	#if _FANCY_STUFF && _LUMINANCE_MASK_ON
    				half lumin = saturate(Luminance(lm) * _SpecularLuminanceMask);
    	#endif
    				finalColor.rgb *= lm;	
    #endif				
    
    #if _FANCY_STUFF			
    				// gloss
    				alpha *= tex2D(_GlossTex, i.uv0).r;
    
    				// normalmap
    	#if _NORMAL_MAP
    				fixed3x3 tangentToWorld = fixed3x3(i.tangentWorld, i.binormalWorld, i.normalWorld);
    				half3 normalMap = UnpackNormal(tex2D(_NormalTex, i.uv0));
    				half3 fixedNormal = normalize(mul(normalMap, tangentToWorld));
    	#else
    				half3 fixedNormal = normalize(i.normalWorld);
    	#endif
    
    				// main light diffuse
    	#if _NORMAL_MAP || LIGHTMAP_OFF 
    				half nl = dot(fixedNormal, normalize(_GlobalMainLightDir.xyz));
    				half diff = saturate(nl) * (1 - _HalfLambert) + _HalfLambert; 
    				finalColor *= diff;
    	#endif	
    		
    	#if _NORMAL_MAP 
    				// main light specular
    				half3 viewDir = normalize(_WorldSpaceCameraPos - i.posWorld);
    				half3 h = normalize(normalize(_GlobalMainLightDir.xyz) + viewDir);
    				half nh = saturate(dot(fixedNormal, h));
    				nh = pow(nh, _SpecularSharp) * _SpecularIntensity;
    		#if _LUMINANCE_MASK_ON && LIGHTMAP_ON
    				finalColor.rgb += _GlobalMainLightColor.rgb * nh * alpha * _GlobalMainLightColor.a * lumin;
    		#else
    				finalColor.rgb += _GlobalMainLightColor.rgb * nh * alpha * _GlobalMainLightColor.a;
    		#endif
    		
    				// back light specular
    				h = normalize(normalize(_GlobalBackLightDir.xyz) + viewDir);
    				nh = saturate(dot(fixedNormal, h));
    				nh = pow(nh, _SpecularSharp) * _SpecularIntensity;
    		#if _LUMINANCE_MASK_ON && LIGHTMAP_ON
    				finalColor.rgb += _GlobalBackLightColor.rgb * nh * alpha * _GlobalBackLightColor.a * lumin;
    		#else
    				finalColor.rgb += _GlobalBackLightColor.rgb * nh * alpha * _GlobalBackLightColor.a;
    		#endif
    
    	#endif
    
    	#if _POINT_LIGHT			
    				half3 toLight = _GlobalPointLightPos.xyz - i.posWorld ;
    				half ratio = saturate(length(toLight) / _GlobalPointLightRange);
    				//half attenuation = 1 - ratio; // linear attenuation
    				ratio *= ratio;
    				half attenuation = 1.0 / (1.0 + 0.01 * ratio) * (1 - ratio); // quadratic attenuation
    				if (attenuation > 0) // performance
    				{
    					// point light diffuse
    					toLight = normalize(toLight);
    					half intensity = 8;
    					half nl2 = max(0, dot(fixedNormal, toLight));
    					finalColor.rgb += mainColor.rgb * _GlobalPointLightColor.rgb * nl2 * attenuation * intensity;
    
    					// point light specular
    		#if _NORMAL_MAP 
    					h = normalize(toLight + viewDir);
    					nh = saturate(dot(fixedNormal, h));
    					nh = pow(nh, _SpecularSharp) * _SpecularIntensity;
    					intensity *= _GlobalPointLightColor.a;
    					finalColor.rgb += _GlobalPointLightColor.rgb * nh * alpha * attenuation * intensity;
    		#endif
    				}	
    	#endif
    
    #endif 
    				UNITY_APPLY_FOG(i.fogCoord, finalColor);
    
    				// 没有高光贴图,alpha默认为0,便于处理Bloom的Alpha Gloss
    #if _NORMAL_MAP
    				finalColor.a = alpha;
    #else
    				finalColor.a = 0;
    #endif
    				return  finalColor;
    			}
    			ENDCG
    		}
    
    		// 没用Unity自带的阴影,只是用来来渲染_CameraDepthsTexture.
    		Pass
    		{
    			Tags { "LightMode" = "ShadowCaster" }
    
    			Fog { Mode Off }
    			ZWrite On 
    			Offset 1, 1
    
    			CGPROGRAM
    
    			#pragma vertex vert
    			#pragma fragment frag
    			#pragma multi_compile_shadowcaster
    			#pragma fragmentoption ARB_precision_hint_fastest
    			#include "UnityCG.cginc"
    
    			struct v2f
    			{
    				V2F_SHADOW_CASTER;
    			};
    
    			v2f vert(appdata_base v)
    			{
    				v2f o;
    				TRANSFER_SHADOW_CASTER(o)
    				return o;
    			}
    
    			fixed4 frag(v2f i) : COLOR
    			{
    				SHADOW_CASTER_FRAGMENT(i)
    			}
    
    			ENDCG
    		}
    	}
    
    	Fallback off
    	CustomEditor "SceneStandard_ShaderGUI"
    }

          这shader比较简单,主要用于场景中的物件,实现了几个功能

    1.光照图和光照图的融合过渡.

          光照图过渡用于天气系统的渐变效果处理,比如白天的光照图和夜晚的光照图的渐变处理.

    2.法线贴图和高光贴图

          法线贴图可用高模去生成,投入有限的公司建议直接工具生成,效果差点但是性价比高,高光贴图的分辨率可减半,效果差不多.高光贴图的通道渲染进屏幕的alpha通道,对于后期生成基于gloss的bloom效果很有用.

    3.光照图阴影区域的高光处理

           理论上来说,静态阴影区域不应该有高光效果的,但是Unity的光照图,没用alpha通道来存储阴影区域的掩码,导致我们无法知道阴影区域,这也是我一直吐槽Unity的地方,较新版本的Unity已经支持光照图阴影掩码...但是我们不可能升级到最新的Unity版本...所以只好选用了一个有些开销的方案来处理,就是用亮度来判断这是否是阴影区域.然后淡化高光.

    4.点光源

           我原来只打算用全局shader参数模拟两盏方向光,对于有些地宫的暗黑场景,确实需要点光源的支持,这样角色走到哪里,就能照亮到哪里,最早考虑过一个面片叠加的假的光源绑定在角色身上,但是效果一般,最后还是模拟了一个实时点光源.逐像素的.对于点光源的衰减处理,Unity是用一张图来处理,我试了几种曲线函数,最终选用

    half attenuation = 1.0 / (1.0 + 0.01 * ratio) * (1 - ratio); // quadratic attenuation

           这个shader的效果图如下:

    漫反射贴图:

        

        漫反射贴图 + 光照图:


    漫反射贴图 + 光照图 + 高光:


    漫反射贴图 + 光照图 + 高光 + 法线贴图 + 高光贴图:


    对于SceneStardard来说,有个功能,就是植被的随风摆动问题,原来集成在一起的,后来独立开来了一个shader.

    Shader "Luoyinan/Scene/SceneStandard_Cutout" 
    {
    	Properties
    	{
    		_Color ("Main Color", Color) = (1, 1, 1, 1)
    		_MainTex("Main Texture RGB(Albedo) A(Gloss & Alpha)", 2D) = "white" {}
    		_NormalTex("Normal Texture", 2D) = "bump" {}
    		_GlossTex ("Gloss Texture", 2D) = "white" {}
    
    		_HalfLambert("Half Lambert", Range (0.5, 1)) = 0.75
    
    		_SpecularIntensity("Specular Intensity", Range (0, 2)) = 0
    		_SpecularSharp("Specular Sharp",Float) = 32
    
    		_MainBendingFactor ("Wind Main Bending Factor (Blue)", float) = 0.25
    		_MainBendingFactor2 ("Wind Main Bending Factor 2 (Blue)", float) = 1.0
    		_BranchBendingFactor ("Wind Branch Bending Factor (Red)", float) = 2.5
    		_EdgeBendingFactor ("Wind Edge Bending Factor (Green)", float) = 1.0
    		_EdgeFrequencyFactor ("Wind Edge Frequency Factor", float) = 1.0		
    
    		[HideInInspector] _DoubleSided("", Float) = 2.0
    		[HideInInspector] _WindOn("", Float) = 1.0
    		[HideInInspector] _Cutoff("", Float) = 0.2
    	}

    自定义了shader以后,那么shader编辑器,也需要自定义.

    // 2016.5.14 luoyinan 自定义shader的编辑器
    using UnityEditor;
    using UnityEngine;
    using UnityEngine.Rendering;
    
    public class SceneStandard_Cutout_ShaderGUI : ShaderGUI
    {
        MaterialProperty cutOff = null;
        MaterialProperty wind = null;
    
        public void FindProperties(MaterialProperty[] props)
        {
            wind = FindProperty("_WindOn", props);
            cutOff = FindProperty("_Cutoff", props);
        }
    
        public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
        {
            FindProperties(props);
    
            // Check change
            EditorGUI.BeginChangeCheck();
            {
                float co = cutOff.floatValue;
                cutOff.floatValue = EditorGUILayout.Slider("Cut Off", co, 0f, 1f);
    
                bool w = wind.floatValue == 0;
                wind.floatValue = EditorGUILayout.Toggle("Wind", w) ? 0 : 1;
    
                // Render the default gui
                base.OnGUI(materialEditor, props);
            }
    
            if (EditorGUI.EndChangeCheck())
            {
                foreach (var obj in materialEditor.targets)
                {
                    MaterialChanged((Material)obj);
                }
            }
        }
    
        public static void MaterialChanged(Material material)
        {
            float value = material.GetFloat("_Cutoff");
            material.SetFloat("_Cutoff", value);
            if (value > 0)
            {
                material.EnableKeyword("_ALPHA_TEST_ON");
                material.SetFloat("_DoubleSided", (float)CullMode.Off);
            }
            else
            {
                material.DisableKeyword("_ALPHA_TEST_ON");
                material.SetFloat("_DoubleSided", (float)CullMode.Back);
            }
    
            value = material.GetFloat("_WindOn");
            material.SetFloat("_WindOn", value);
            SetKeyword(material, "_WIND_ON", value == 0);
    
            // 有纹理就自动开启
            SetKeyword(material, "_NORMAL_MAP", material.GetTexture("_NormalTex"));
        }
    
        private static void SetKeyword(Material mat, string keyword, bool enable)
        {
            if (enable)
                mat.EnableKeyword(keyword);
            else
                mat.DisableKeyword(keyword);
        }
    }
    

    传统光照模型的效果,除了反射,基本都实现了,那么反射呢,我是去掉了,移到了PBR里面,因为传统光照模型的环境反射效果其实并不好,要用反射,可用PBR的shader代替.

    Shader "Luoyinan/Scene/SceneStandard_PBR" 
    {
    	Properties
    	{
    		_Color ("Main Color", Color) = (1, 1, 1, 1)
    		_MainTex("Main Texture RGB(Albedo) A(Gloss & Alpha)", 2D) = "white" {}
    		_NormalTex("Normal Texture", 2D) = "bump" {}
    		_GlossTex ("Gloss Texture", 2D) = "white" {}
            _SpecularColor ("Specular Color", Color) = (1, 1, 1, 0.5)	
    		_Roughness ("Roughness", Range (0, 1)) = 0
    	    _RefectionTex("Refection Texture (Cubemap)", Cube) = "" {}
            _RefectionColor ("Refection Color", Color) = (1, 1, 1, 1)
    
            [HideInInspector] _UseRoughness("", Float) = 0
    	}

           如果要集成很多效果在一个shader里面,就需要利用multi_compile和shader_feature设置好各种效果的功能开关,高中低的画质的切换也特别方便.

    以上主要是对场景shader的介绍,由于内容太多了,今天我就先写到这里,下一篇我会对其他渲染技术做一些分享.

    展开全文
  • 笔者其实也是小菜鸟一枚,对于开发什么的也不算很熟练,只不过Unity一直都很关注,现在也是刚刚入门,才看了一点点教程而已,在这里写下记录,记录自己的成长过程,也算是一个监督,也可以有效的监督自己去坚持做一...
  • 上周开始做一个新项目,需要在Unity里实现一个六轴机械臂的实体与模型的联动。机械臂传输回来的数据包含每一个轴当前旋转的角度,当然,这个角度是机械臂自身按照自己的坐标系计算的。所以在Unity中要想实现转到同样...
  • 腾讯开源手游热更新方案,Unity3D下的Lua编程 http://www.infoq.com/cn/news/2017/01/C-NET-Lua-Unity3D 作者 xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其...
  • 之前在学习Unity3D,不知为何网上的教学资源真是少啊...我某段时间还卡在不知如何让物体绑个脚本自动运动。。 之所以要学习U3D是因为导师让我做的IOS项目里有个需要模拟起重,从而控制真实起重的动画(为何不是...
  • 前段时间关于Unity是否适合国内手游/网游创业团队的讨论非常火爆,本文从《蒸汽之城》的开发历程谈起,对于国内网游团队是否应该选择Unity引擎,以及如何解决使用Unity开发网游时遇到的各种主要问题进行讨论。...
  • 作者: 龙心尘 &amp;amp;amp;amp;amp;amp;amp;&amp;...本文代码部分参考了lambda等同学的tensorflow实现,在此向原作者表示感谢。...多年以后,当资深算法专家们看着无缝对接用户需求的广告收入节节攀升时,他们...
  • 本文由腾讯WeTest授权发布 作者:chunhe,腾讯资深后台开发工程师。 ...著作权归作者所有。商业转载请联系WeTest获得授权,非商业转载请注明出处。 俗话说,用户体验不谈性能就是耍流氓。 在PC游戏上的性能问题并没有...
  • 过去的 2018 年,我们认为是国内工业互联网可视化的元年,图扑...2D 3D 可视化应用案例,希望能激发行业和学术工作者对可视化的深度思考,为推进国内工业互联网发展出份薄力。 数百个工业互联网2D/3D可视化案例集:...
  • 年底了,会有各种各样诸如《2019十大技术》《明年这五大技术改变世界》《这八个技术要变天,不知道你明年就别想加薪》之类的神秘文章出现。其实吧,这类预测要么是常识,要么干脆...
  • 摘要:厦门梦加网络使用Unity3D引擎制作的第一款作品《蒸汽之城》,被福布斯、Massively、ZAM等评选为2013年最值得期待的MMORPG游戏,此款Unity网页游戏拥有多款副本挑战与PvP活动,以及优质画面场景和丰 ...
  • 将三维可视化技术与排水管网模型结合,以期为城市内涝风险评估和溢流污染控制等提供有效的决策支持。
  • 去年的一部电影《阿凡达》让我们领略到了虚拟世界与真实场景的相互交融已经不再是神话,也掀起了全民3D热潮,短短一年时间内,3D电视、3D投影、3D笔记本、3D摄像等等设备如同雨后春笋般出现,很多显示设备厂商更是...
1 2 3 4 5 ... 19
收藏数 363
精华内容 145
关键字:

unity3d 挖掘机模型