unity3d雪地地形_unity3d 地形 - CSDN
  • Unity3D 官方教程翻译 地形引擎

    创建和编辑地形

    通过菜单中的GameObject->3D Object ->Terrain,你可以为你的场景创建一个地形对象(这也将在项目视图中增加一个对应的地形资源)。然而,初始的地表除了一个巨大而单调的平面,什么都没有。但如果当地形对象被选中时你查看检视器,你将看到Unity提供了一些工具,你可以用来创建任何你喜欢的地表元素。
    Terrain Editing Tools appear in the Inspector
    除了树木放置工具和设定面板,在工具栏的所有工具提供了“刷子”的集合,以及对刷子尺寸与透明度的设置。这些绘制工具类似于图像编辑并非巧合,因为地形中的细节正是通过这种方式精确地创建, 通过在地表上“绘制”细节。如果你选择工具栏上最左边的工具(Raise/Lower Terrain)并在场景视图中于地形上移动鼠标,你将在地形表面上看到一个类似于点光源的光标。当你点击鼠标,你可以于鼠标位置处,绘制地表在高度上逐渐的变化。通过在数字工具栏中选择不同选项,你可以绘制不同的形状。刷子的尺寸和透明度选项分别改变刷子的面积,以及它效果的强度。
    所有工具的细节将在随后的板块中给出。然而,它们都基于绘制细节的概念,并且除了树木放置工具,都有对刷子相同的选项,即尺寸和透明度。工具可以被用来设置地形的高度,也可以增加染色,平面和其它对象。

    地形的快捷键

    你可以在地形检视器中使用以下键盘快捷键:
    按shift+从Q到Y的某一按键,来选择对应的地形工具(例如,Shift-Q选择了Raise/Lower工具)。
    逗号(,)和句点(.)循环选择可用的刷子。
    小于号(<)和大于号(>)循环选择可用的树木对象,纹理和细节。
    另外,标准的F按键,对地形有轻微的不同。通常,当鼠标在场景视图中时,它将围绕整个对象适配选中状态。然而,由于地形通常很大,按F会将场景视图聚焦到地形中鼠标/刷子当前处理的区域。这提供了非常快和直管的方式来跳转到你希望编辑的区域。如果你按F当鼠标不在地形对象上,将回应标准的适配行为。

    高度工具

    在地形检视器工具栏上,前三个工具被用来绘制地形在高度上的变化。
    这里写图片描述
    从左边开始,第一个按钮激活Raise/Lower Height 工具。当你使用这个工具时,高度将随着你用鼠标在地形上扫过而升高。如果你在一处固定鼠标,高度将逐渐增加,这类似于在图像编辑器中的喷雾器工具。如果你按下shift键,高度将会降低。不同的刷子可以被用来创建不同的效果。例如你可以创建丘陵地形,通过soft-edged刷子进行抬升,然后削减陡峭的山峰和山谷通过使用hard-edged刷子进行降低。
    Rolling hills cut by a steep valley
    左起第二个工具,是Paint Height,类似于Raise/Lower工具,除了它有额外的属性来设置目标高度。当你在对象上绘制时,此高度的上方区域会下降、下方的区域会上升。你可以使用高度属性来手动设置高度,或者你可以使用在地形上shift+点击来取样鼠标位置的高度(相当类似于图片编辑器中的“eyedropper”工具)。在高度属性旁边是一个Flatten按钮,它简单地拉平整个地形到选定的高度。这对设置一个凸起的地面水平线很有用,如果你希望地表包含在水平线上的山峰和水平线下的山谷。Paint Height对于在场景中创建高原以及添加人工元素如道路、平台和台阶,都很方便。
    Hillside with a flat road
    左边第三个工具,Smooth Height 并不会明显地抬升或降低地形高度,但平均化附近的区域。这缓和了地表,降低了陡峭变化的出现,类似于图片处理中的模糊工具(blur tool)。你可以使用这个,例如,当你已经在可用集合中使用一个噪声更大的刷子绘制了细节。这些刷子图案将倾向于在地表上造成尖锐、粗糙的岩石,但可以通过使用Smooth Height来缓和。

    用高度图工作

    如之前提到的,高度工具令人联想到图片编辑器中的绘制工具。实际上,地形是使用一个在场景背后的纹理而实现的,那么这些工具实际上像纹理绘制工具那样起作用。
    地形上每个点的高度,被表示为一个矩阵列中的值。这个数组可以用一个被称为高度图(heightmap)的灰度图来表示。使用外部编辑器的高度图有时候很有用,例如Photoshop,或者在你的游戏中获取现有的地理高度图。Unity提供了为地形导入、导出高度图的选项;如果你点击Settings tool(工具栏最右边的按钮),你讲找到标记为Import RAW和Export RAW的按钮。这些允许高度图从标准RAW格式中被读取或者写入;标准RAW格式是16位灰度格式,兼容大部分图片和地表编辑器。

    纹理

    你可以添加纹理图片到地形的表面上,来创造着色和良好的细节。由于地形是如此巨大的对象,在实践中标准的做法是使用一个无空隙地重复的纹理,在表面上用它成片地覆盖(从接近地面的角色视角来看,这样的重复通常不是明显易见的)。一个纹理将作为在地表上的“背景”图片,但你也可以绘制不同的纹理区域来模拟不同的地面,如草地、沙漠和雪地。绘制出的纹理可以在不同的透明度下使用,这样你可以在乡野草地和沙滩之间有一个渐变。
    Sand dune terrain with sandy texture

    启用纹理

    工具栏中的paintbrush按钮启用纹理绘制。
    这里写图片描述
    一开始,地形将没有纹理分配用于绘制。如果你点击Edit Textures按钮并且在菜单中选择Add Texture,你讲看到一个窗口,在其中你可以设置一个纹理和它的属性。
    取决于你在Terrain Settings中设置的材质类型,主纹理图的颜色通道可能有不同的用处。
    Add Texture window (Standard)
    标准:RGB通道是地形表面的反射颜色,而alpha通道控制平滑。也有一个“Metallic”滑块,控制表面的所有金属成色。
    Add Texture window (Diffuse)
    Diffuse:RGB通道是散射颜色。Alpha通道不被使用。
    Add Texture window Specular
    Specular: RGB 通道是漫射颜色。Alpha通道为光泽。
    Add Texture window (Custom)
    Custom:纹理图如何使用,取决于你的自定义着色器,但通常你希望RGB通道为基色。
    除了主纹理贴图,你也可以为所有3个内建的材质类型指定一个法线纹理。这里被使用的法线纹理的纹理类型必须为“法线贴图”(你可以在一个纹理资源的导入选项中,改变纹理类型)。掌控法线贴图的着色器代码将被开启,仅当为地形设置了至少一个法线纹理,所以如果你不使用它们,你不需要付出性能消耗。
    Size属性(就在texture boxes下方)允许你设置宽度和高度,即图片将于地形的表面上伸缩的程度。Offset属性决定,平铺纹理开始的位置与地形锚点之间的距离;你可以将它设置为0,让平铺从角落开始。一旦你将纹理和属性设置完成,点击Add按钮让纹理对地形可用。
    为了改变一个已经添加了的地形纹理,选择它的thumbnail,点击“Edit Textures”按钮并从菜单中选择“Edit Texutre”。或者,你可以简单地双击它的thumbnail。为了移除一个地形纹理,选择它的thumbnail,点击“Edit Textures”按钮并从菜单中选择“Remove Texture”。

    纹理绘制

    你添加的第一个纹理将被作为“背景”使用而覆盖地形。然而,你可以添加你希望数量的纹理;随后的这些纹理将可以绘制,通过使用类似的刷子工具。在地形检视器纹理的下方,你可以看到通常的刷子尺寸及透明度选项,但也有另外一个称为目标强度(Target Strength)的选项。这个设置了刷子将会达到的最大透明度值,即使它重复地通过了相同的点。这对于在一个单一地形类型中,添加细微修补的颜色变动,来破坏一个巨大、平整、用相同纹理不断重复覆盖区域的单调,是个有用的办法。
    Grass terrain with dirt texture painted on corners

    树木

    Unity地形可以用树木布置。可以像高度图和纹理被使用那样,树木补丁被绘制到地形上,但树木是固定的、从表面生长出的三维对象。Unity使用了优化(例如,对远距离树木的公告板化)来维持好的渲染效果,所以你可以拥有上千棵树组成的密集森林,同时保持在可接受的帧率。
    Terrain with trees

    启用树木

    在工具栏上的tree按钮启用树木绘制。

    一开始,地形将没有可用的树木,但如果你点击Edit Trees按钮并且选择Add Tree,将弹出一个窗口来让你从自己的项目中选择一个树木资源。
    The Add Tree window
    在标准资源包中,Unity带有几个样例SpeedTree树木对象,用作蓝本(Assets->Import Package ->Terrain Assets);但也可以用SpeedTree Modeler应用,UnityTree Creator工具或者其他3D建模应用,来创建合适的对象。
    如果选中的树木对象是用Tree Creator所创建的,窗口将显示摇摆特性,用于调整对风的响应度。这些请看下面的“让树在风中摇摆”部分。

    绘制树木

    当一棵树被选中,你可以在地表上用绘制纹理或高度图的相同方式来绘制。可以用按住shift键来从区域中移除树木,而通过按下ctrl,只绘制、移除当前选中的树木。类似的刷子尺寸选项对树木绘制有效,但透明度选项被树木密度(Tree Density)所替代,这控制了在区域的一个给定单元中,绘制树木的平均数量。
    一个范围滑块让你控制树木的最小高度和最大高度。如果你停用随机(Random),你可以为所有树木的高度指定一个值。默认下,一棵树的宽被锁定关联到其高度,这样树木通常被一致地缩放。然而你可以停用“锁定宽度到高度”(Lock Width to Height)选项并分别指定其宽度。
    同样也有对颜色变化和随机树木旋转的控制。变动选项帮助创建随机、看起来自然的森林,而非由完全相同树木组成的人工种植园。
    Mass Place Trees 按钮对创建一个用树木进行完全的覆盖而不在全部地表上绘制,是非常有用的办法。在一个大量安置之后,你仍可以使用绘制来增加或移除树木,来创建更密集或更稀疏的区域。

    SpeedTree/LOD Trees

    从Unity5开始,你可以使用来自IDV的SpeedTree建模来创建带有高端视觉效果如平滑LOD过渡、快速公告板以及自然风动画的树木。请到他们的页面获取更为细节的信息。你也可以从资源商店包或其他第三方来源免费导入SpeedTree资源到你的项目文件夹中。
    查看这里来获取更多信息。

    Tree Creator树木

    Unity有它自己的树木创建器,你可以用它来产生新的树木资源;但你也可以用标准的3D建模应用来完成此项任务。树木网格必须少于2000个三角面(出于性能考虑),锚点必须在树木从地面上长出的根基处。网格应当有两个材质,一个用于树干,另一个用于树叶。
    树木必须使用自然/柔和咬合树叶(Nature/Soft Occlusion Leaves)和自然/柔和咬合树皮(Nature/Soft Occlusion Bark)着色器。为了使用这些着色器,你也不得不将树放在特定的包含了名称“Ambient-Occlusion”的文件夹中。当你在这样一个文件夹中放了个模型并再次导入它,Unity将在一种特别为树木设计的方式中计算软环境咬合。“自然/柔和咬合”着色器依赖文件夹命名习惯;如果你不遵守,树木将不会正确地渲染。
    当你从建模应用中保存一个树木资源,你需要点击Refresh按钮(当树木绘制工具被选中时在检视器中显示),目的是查看你地形上更新了的树木。

    在树木上使用碰撞器

    你可以为一个新的树木资源添加一个胶囊碰撞器,通过在场景中实例化它、添加碰撞器(菜单:Component->Physics->Capsule Collider)、为修改后的树木对象创建一个新的预物体。当你添加树木到地形中,确保你选择了带有碰撞器的预物体而不是原始的那个。你也应当在地形的Terrain Collider组件检视器中启用Create Tree Colliders。

    让树木在风中摇摆

    需要做的第一件事是创建一个有风区域。你可以通过从菜单:Game Object->Create General->WindZone来进行。
    这里,你需要确保你的树被设置为摇摆的。选择你的树,然后选择Edit Trees->Edit Tree。设置摇摆值为1将导致树进行调整,如果你尚未做这件事。
    你可能注意到了,你的树木相当狂暴地动着。为了修正,你可以改变你的摇摆值,但直接在“风区”中设置这些值或许会更简单,而保持你的树的摇摆值设置为1。为了避免树木摇动太大,降低风湍流至0.1到0.3,所有东西将明显低更平缓。如果你不希望所有树都飘向同一个方向,降低Wind Main 值与湍流相同的值。

    草地和其它细节

    一个地形可以有草丛,和其它小物体,比如覆盖表面的石头。草地使用2D图像进行渲染来表现单个草丛,而其它细节从标准网格中生成。
    Terrain with grass

    启用细节

    在工具栏上的细节按钮启用了草地/细节绘制。
    这里写图片描述
    一开始,地形没有草地或细节可用,但如果你点击在检视器中的Edit Details按钮,在出现的菜单中将看到Add Grass Texture和Add Detail Mesh选项。出现的窗口将让你选择你希望添加到地形中绘制的资源。
    对于草地,窗口是这样的:
    The Add Grass Texture window
    Detail Texture是表现草地的纹理。一些合适的纹理包含在了Unity的标准资源库中,可以从资源商店里下载。你可也可以自己创建它们。纹理就是一个小图片,其空白区域的alpha通道设置为0(当然“草地”是个专业术语,你可以使用图片来表现花朵,灌木丛,甚至一些像铁丝网之类的人造物体。
    Min Width, Min Height, Max Width and Max Height值指定了生成草地的尺寸上下限。为了看着真实,草地用随机“带噪声”模式生成,草地上散落光秃的部位。
    Noise Spread值控制替换块的近似尺寸,更大的值导致在给定区域中更大的变化。(技术说明:噪声实际上使用柏林噪声Perlin Noise所生成;噪声的传播取决于作用在地形上x,y位置之间的缩放,以及噪声图像。)在中心的草地替换块,被认为是比在边缘上的更“健康”;Healthy/Dry Color设置用它们的颜色展示草地的健康程度。
    最后,当公告板选项被启用,草地图像会被旋转,这样它们永远面向镜头。当你想要展示草地的密集区域时这个选项有用,因为二维图像不可能从哪个方向都能看到。然而,稀疏的草地,单个草丛的旋转变得明显,产生奇怪的效果。
    对细节网格,如石头,选项窗口是这样的:
    The Add Detail Mesh window
    Detail属性用来从你的项目中选择一个预物体来设置,它将用随机的Width和Height值缩放出单个实例。Noise Spread和Healthy/Dry Color值如它们对草地影响那样进行工作(尽管当应用到如石头的物体上时,“健康”的概念扩展了)。渲染模式可以被设置为草地Grass或者Vertex Lit。在草地模式中,场景中的细节物体实例将被抹平为2D图像,像草地纹理那样表现。在Vertex Lit模式中,细节将被如场景中的固定,定点光照物体那样渲染。

    风区

    你可以通过添加一个或多个带有风区组件的对象,在你的地形上创建风的效果。带有风区的树木将以逼真的动画效果摆动,而风自身将间歇性生成,来产生树木自然摆动的效果。

    使用风区

    风区对象可以直接创建(菜单:GameObject->3D Object->Wind Zone)或者你可以向场景中已经存在的任何合适物体添加这个组件(菜单:Component->Miscellaneous->Wind Zone)。风区检视器有一些选项来控制它的行为。
    Wind Zone inspector
    Mode可以被设置为定向(Directional)或球形(Spherical)。在定向模式中,风会同时影响整个地形;而一个球形风从一个用Radius属性定义的球体中向外吹。定向风在创造树木自然运动时更有用,而球形风更适合如爆炸这样的特定效果。
    Main属性决定风的整体强度,但这可以使用Turbulence进行一些随机的变化。如前文提到的,风间歇地吹在树上产生更为自然的效果。间歇的强度和时间间隔用Pulse Magnitude和Wind Frequency属性来控制。

    粒子系统

    风的主要用途是让树木运动,但它也可以影响到被使用外力模块的粒子系统产生的粒子。更深入的细节内容参考粒子系统

    展开全文
  • Unity3d森林场景资源包

    2020-07-18 23:30:21
    相对较全面的场景资源包,满足基本游戏场景的,,,,,
  • 左边是下雪后的效果 // Simplified Diffuse shader. Differences from regular Diffuse one: // - no Main Color // - fully supports only 1 directional light. Other lights can affect it, but it will be per-...

    左边是下雪后的效果

    // Simplified Diffuse shader. Differences from regular Diffuse one:
    // - no Main Color
    // - fully supports only 1 directional light. Other lights can affect it, but it will be per-vertex/SH.
    
    Shader "Mobile/Snow Diffuse" {
    Properties {
    	_MainTex ("Base (RGB)", 2D) = "white" {}
    	_SnowStep(" Snow",Range(0,1))=0.5
    }
    SubShader {
    	Tags { "RenderType"="Opaque" }
    	LOD 150
    
    CGPROGRAM
    #pragma surface surf Lambert vertex:vert noforwardadd noshadow
    
    sampler2D _MainTex;
    fixed _SnowStep;
    
    struct Input {
    	float2 uv_MainTex;
    	fixed3 customColor;
    	fixed4 vertexColor:COLOR;//顶点颜色
    };
    
    void vert (inout appdata_full v, out Input o) {
          UNITY_INITIALIZE_OUTPUT(Input,o);
          o.customColor = step(1-_SnowStep,v.normal.y)*fixed3(1,1,1);
    }
    
    void surf (Input IN, inout SurfaceOutput o) {
    	fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    	o.Albedo = c.rgb*IN.vertexColor+IN.customColor;
    	o.Alpha = c.a;
    }
    ENDCG
    }
    
    Fallback "Mobile/VertexLit"
    }
    
    如果不需要顶点颜色,可以自己去掉

    展开全文
  • 首先、unity 灯光烘焙 :Unity 3D FBX模型导入、选项Model 不导入资源球、Rig 不导入骨骼、Animations 不导入动画。在Model选项勾选 Generate Linghtmap UVs 。否则、灯光烘焙、会出现阴影错乱。灯光烘焙时FBX ...

    原地址:http://tieba.baidu.com/p/2817057297?pn=1

    首先、unity 灯光烘焙 :Unity 3D FBX模型导入、选项Model 不导入资源球、Rig 不导入骨骼、Animations 不导入动画。在Model选项勾选 Generate Linghtmap UVs 。否则、灯光烘焙、会出现阴影错乱。灯光烘焙时FBX Shader 选项 Mobile/Unlit(Supports Lightmap)

    、会出现阴影错乱。灯光烘焙时FBX Shader 选项 Mobile/Unlit(Supports Lightmap)

    因为这是地形、不需要动画、骨骼之类的东西

    动态随机地图:地图拼接的时候、注意地图不要产生重叠、有些时候、会没有问题、但是有些时候、重叠部位、会产生闪烁。

    图集 :Atlas 如果是UI 界面、最好一个界面一个图集、要是图片公用、最好单独放到一个单独的图集。

    序列帧动画: 最好别用2D TOOLKIT 推荐使用 swf 不过swf 记得记得把做好的动画放到一个元件里面、不然倒入unity 之后、没办法用。

    动作系统:大部分NPC的动作最好公共。砍杀类的、近距离砍杀、支持少量的粒子鲜血飞溅效果、如果是群攻技能、最好不要播放粒子特效。

    资源池:NPC 怪物类 :最好使用资源池管理、否则一次生成太多、游戏会出现卡顿、影响游戏体验。

    模型:
    IOS ——600-1000的高模可以接受、包括天气系统、粒子动画、周边的场景树、树叶、都可以有。
    Android—— 基本300的低模吧、树木可以有、树叶就别要了、

    关于安卓的优化: 图集大小最好不要高于1024、因为楼主之前遇见过、游戏安装之后、低端机直接崩溃、原因是手机系统版本低于2.2、超过1000的图集无法读取、导致。
    2.2 以上没有遇见这个情况。
    注意手机的RAM 与 ROM、小于 512M的手机、直接放弃机型适配。

     

    挂接SDK:
    挂接PP助手:IOS的童鞋们小心、之前PP提供的挂接、在使用重力感应的时候、会让任何游戏(不管是2D 还是 3D游戏)出现慢镜头的情况。具体是PP那边的挂接SDK的问题。有挂接PP的童鞋们要注意。
    电信SDK:启动界面只能显示 电信 爱游戏 启动logo。道具购买只能在提审点购买。不允许重复够卖(这个很操蛋)。

    关于字库:
    游戏中、若描述信息较少、可使用图片字、若描述过多、使用字库请注意:字库在unity 中压缩率为20%左右、一个10M 的字库、在打包只后、占用包大小为 8M左右。所以、若游戏描述过多、推荐使用 40K-1M 的字库、为嘛呢、为了你后期游戏包大小做提前优化、包大小每压缩1M 用户大概会上升5%。

    机型适配:


    百度与360云测试:测试之后的结果、不可全信、测试结果中有问题的机型、建议童鞋们自己使用同型号的机型、安装游戏、进行人工测试。之前楼主所在公司的测试童鞋、使用百度与360进行测试(非黑我度娘)、通过率为78.1%、失败的机型、人工测试没有任何问题。所以、若使用云测试、问题机型、建议人工测试为准、云测试的结果、仅供参考。(免得程序员被虐成程序猿)

    地图优化:如果地图使用频繁 如楼主的游戏:有草地、沙漠、雪地、可使用一个Prefab 在地图生成的时候、使用代码替换材质。灯光图烘焙的时候、最好把所有地图的灯光图做成一个。3D地图、尽量不要有丁字路口、否则、烘焙的灯光阴影会出卖你的。

     

    关于Atlas的创建:
    1、不推荐使用NGui的Atlas maker 创建图集。因为图集剩余空间较大。建议使用其他工具。比如 TexturePackerGUI 自己弄。
    2、使用NGui的Atlas maker 创建图集、建议修改 UIAtlasMaker、修改创建方式为动态创建、缺点:损耗一定的性能。 优点:占用内存较小。

     

    关于动态更新:
    如果是要做更新这块、建议是在游戏初期、就把架构、和服务器端准备好、所有的资源、代码、在服务器端管理、据说 只能更新UI部分、有挂脚本的预物体、更新之后、脚本不能被使用(最近在研究这个、研究完了、再开一帖说这个。)感觉比较蛋疼吧?解决思路有一个、没测试、有兴趣的可以自己试试看:把游戏做成几个 控制器、所有代码部分、用代码挂到预物体上(思路有了、我还没测试过)。

     

     

     

    展开全文
  • 3D地形多层纹理混合加阴影渲染方法
                    3D地形多层纹理混合加阴影渲染方法

    地形多层纹理混合加阴影渲染方法

    地形由于十分庞大,需要大量顶点,所以往往占用很多内存空间,那么就应该在地形贴图上想办法节约空间。很多游戏的地形,虽然看上去不同地点的纹理好像互不相同,地表纹理十分丰富,但其实真正用的贴图是很少的,之所以还能产生地表纹理变化多端的视觉效果,是因为使用了Alpha混合和阴影,从而产生一种错觉。2.5D的网络游戏《奇迹》(MU)、全3D引擎Torque(多人联网FPS游戏《部落2》即使用此引擎)、全3D的滑雪游戏《极限滑雪》(Supreme Snowboarding),都是这么做的。(参见文章末尾的截图)
    我对此设想了一个解决方案。需要用到顶点的Diffuse颜色、3个TextureStage。其实所谓的多层纹理,具体到一个三角形上的时候,很多游戏只用了2层纹理来做Alpha混合(因为也许玩家的显卡只支持2层MultiTexture混合),然后再一层光照纹理。前2层纹理要做Alpha混合,Alpha来自哪里?若使用Alpha贴图,就必然再增加一层TextureStage,而我选择使用顶点的Diffuse就可以省掉这一层TextureStage:由Diffuse的Alpha通道提供Alpha值供前两层TextureStage混合使用。下面是在D3D中的设置:
    // TextureStage 0
    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 ); 
    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );
    // TextureStage 1
    pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_BLENDDIFFUSEALPHA );
    pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
    pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );
    在TextureStage 0,什么也没做,把第一层纹理原封不动的留给TextureStage 1;在TextureStage 1,COLOROP使用D3DTOP_BLENDDIFFUSEALPHA,也就是使用来自顶点Diffuse的Alpha值作为混合因子混合第2层纹理和TextureStage 0原封不动留下来的第1层纹理。混合公式如下(来自DX帮助文档):
    Result = Arg1 * Alpha + Arg2 * (1 – Alpha)
    Arg1是来自第2层纹理的颜色,Arg2是来自TextureStage 0原封不动留下来的第1层纹理的颜色。并且,这里的Alpha值是D3D插值运算后得到的,因此混合效果很平滑。
    你不相信2层纹理混合就能得到丰富的地表视觉效果吗?你应该相信,因为虽然Arg1和Arg2总是恒定不变的来自2个贴图,因此对三角形上的同一点来说,这两个是常量,但Alpha值却是个变量,Alpha值取不同的值就会产生不同的Result。
    假设与Arg1相对应的贴图是一个草地的贴图,与Arg2相对应的贴图是一个沙地的贴图,在一片地形区域内,仅使用这两张贴图,但是由于各顶点的Diffuse的Alpha值不同,你会看到最终渲染出来的这片地形区域,草地的分布并不均匀,有些地方草的样子多一些,有些地方沙的样子多一些。这种效果看上去已经很自然了。
    当然并不限制你在一个地形场景上使用更多的地表纹理,但是对一个三角形来说,2张纹理已经足够,其它纹理请用在其它三角形上吧,这可以产生更丰富的地貌。比如你想让另一片地形区域是雪地和岩石的风格,那么在那片区域上就使用1张雪地贴图、1张岩石贴图。现在这个关卡里面共有4张贴图了,但同一个三角形仍然只使用2张贴图(这是硬件的限制啊!!)。
    现在来说阴影。前面已经使用了顶点Diffuse的Alpha通道,现在他的RGB三个分量也要派上用场了。在D3D中设置如下:
    // TextureStage 2
    pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP,   D3DTOP_MODULATE );
    pd3dDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
    pd3dDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_CURRENT );
    pd3dDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );
    这是第3个TextureStage,COLOROP为相乘,Arg1设为Diffuse,是来自经过D3D插值运算的顶点Diffuse颜色,Arg2是Current就是TextureStage 1产生的结果。混合公式如下:
    Result = Arg1 * Arg2
    颜色虽是RGB三个字节(或者其它颜色格式),但D3D会将它们拆成单独的3个RGB通道值(0-1之间的浮点数)。相乘运算可以贴上彩色的光影效果。
    有一个问题是,人们当初选择使用光照图就是为了能够提高光影的精确度,因为顶点光照只作用于顶点,虽然渲染API会在顶点之间做插值,但这也只在顶点很密集的时候才会有很精确的光照,如果定点很稀疏甚至不能产生正确的光照效果。这里使用顶点Diffuse,会不会也得不到令人满意的光照效果呢?
    我想过使用一整张光照图铺在整个地形上,但我忽然想起这与基于heightmap的地形生成技术面临一个同样的问题,精度。使用heightmap,为了减小游戏体积,这个heightmap不可能很大,不可能每一个高度点只对应一个顶点,而是多个顶点被映射到同一个高度点上去了。一整张光照图也面临同样的问题,也许多个顶点使用光照图上的同一个像素呢?如果两个顶点用的是光照图上的同一个像素,那顶点之间的空间也肯定是用这个像素点了,这样是不会提高精度的。把光照图的尺寸增大?那是选择512*512呢,还是1024*1024?
    而实际上,LOD地形的顶点总是很密集的。至少在靠近照相机的区域是这样的,往往比室内建筑的顶点还要密集。虽然还没密集到可以让D3D的聚光灯产生满意效果的地步,但已足够使用顶点光照模拟地形因高低起伏而产生的阴影效果。何况业界普遍认为地形渲染的精度是低于室内渲染一个档次的(新游戏FarCry是个例外)。
    更妙的是,顶点光照信息可以存储在高度图里,我们把高度点从一个unsigned char改为一个多字节的数据结构:
    struct HeightPoint
    {
      unsigned char height;  // 用于计算定点的Y坐标值,用于渲染地形高度起伏
      unsigned char alpha;  // 定点diffuse的alpha,用于多层纹理混合
      unsigned char red;  // 顶点diffuse的red,用于光照
      unsigned char green;;  // 顶点diffuse的green,用于光照
      unsigned char blue;  // 顶点diffuse的blue,用于光照
    };
    这样高度图信息不仅包含高度信息,也包含多层纹理混合信息、光照信息。当动态创建地形的时候,在读取高度数据的同时也能得到与该顶点对应的diffuse值,非常方便。
    下面是用DX自带的MFCTex程序验证理论。3个TextureStage正是使用上面所说的设置方法。
     
    图1
    env2.bmp是一个砖墙的贴图,caust11.tga是一个水面波纹的贴图,env3.bmp没有被使用。Diffuse颜色是0x77ff0000,是纯红色,但alpha值为119。
    Stage0把env2.bmp的图像数据原封不动的保留给Stage1。Stage1的COLOROP使用D3DTOP_BLENDDIFFUSEALPHA的方法,以diffuse的alpha值(119 => 0.53)为混合因子混合caust11.tga和env2.bmp,公式是:ResultOfStage1 = caust11.tga * 0.53 + env2.bmp * (1 – 0.53),得到的视觉结果是我们既能看到砖墙又能看到水面波纹,他们被半透明的混合起来了。Stage2使用相乘,把diffuse的RGB三分量与ResultOfStage1(Current就是ResultOfStage1)上对应点的RGB三分量乘起来,由于diffuse的RGB是ff0000纯红色,完全没有green和blue分量,所以这次得到的视觉结果是整个墙壁偏红色。这样我们就产生了墙壁上被投上了水面折射的波纹,而整个墙壁又被一片红光照亮的效果。
    下面来看看Torque引擎、《极限滑雪》的地形贴图渲染效果。
    首先是Torque。Torque引擎的Demo所使用的纹理文件都没有打包,所以我很容易找到这些文理,用Photoshop给它们画上标记,再到游戏中看他们是如何被混合、以及怎样贴到地面上去。这个Demo只用了3张地形纹理:1个grass.jpg,1个sand.jpg,1个patchy.jpg。每张纹理我先用红色粗线条勾出它的4条边,再在左上角和右下角用写上它的文件名,我还给它们写上中文译名,grass.jpg是“草”,sand.jpg是“沙”,patchy.jpg是“稀疏的草地”。来看截图:
     
    图2
    每张地形纹理都是256*256的,从空中这个角度看,每张纹理都被映射到地形上一个相当大的方形区域,所以镜头贴近地面的时候,会变得很模糊,但Torque会在这时贴上细节纹理(参见后面的截图),一个叫detail1.png的图片文件(还是只有1张,但效果很好),这是另一个技术了,在此不表。图中,凡是黄色区域都来自sand.jpg。我们看那个左边有“稀疏的草地”的方形区域,这个区域用的是patchy.jpg和sand.jpg两张纹理混合的,“地”字就刚好位于混合边界,所以模糊了。混合因子不是顶点diffuse的alpha吗?所以这个区域里面,要有更多的顶点,没问题,Torque使用四叉树来创建地形,这个方形区域里面被细分为更小的方形区域,而且不是平衡的(LOD技术),所以有足够的顶点,同时看上去混合边界是扭曲的。这个Demo可以切换为线框渲染模式,我好好观察了那些顶点的分布,确实跟Alpha混合的分布相一致。
    再来一张截图:
     
    图3
    从这个截图里面看出,阴影的存在确实起到了丰富视觉效果的作用。看左边那个方形区域,几乎全是沙地,但有阴影的存在,效果就好多了。你可能觉得它的阴影很细致,但别忘了这是一个全3D的FPS游戏,我是在很高的空中俯拍的。
    另一个游戏《极限滑雪》,这是欧洲某个国家制作的商业游戏。虽是商业游戏,它的纹理文件也没有打包,赤裸裸的jpg、tga,所以我把这些纹理都替换为只有一个颜色的图片,再勾勒出图片的四条边,打上文件名。由于是个滑雪游戏,所以场景中最常见的颜色就是白色了,所以大范围内只使用同一张纹理用得理直气壮。
     
    图4
    当然要加上阴影,不然真的会灼伤玩家的眼睛呢。有了阴影,效果好一些了。再加上彩色的光影,还蛮令人着迷的,看图:
     
    图5
    游戏中的山头和公路都需要别的纹理来混合。
     
    图6
    看图6的阴影,尤其是左边的,有较为明显的梯级,右边的呈矩形,应该是那棵树的影子,但却很涣散,很不对劲,跟顶点光照的效果十分相像,可能是场景编辑器把计算出来的影子信息存储到顶点的diffuse中去了。
    这个游戏的雪地纹理只有2张,另一张出现的频率较小。

    附:Torque的细节纹理
     
    图7


    <<图片均在上传rar文件里。>>

               

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

    展开全文
  • 1.前言 公司的项目进入真机调试阶段,体验了一个月的996模式正式结束,放假第一天来写篇博客  2.... 1.积雪的实现 ...一般由模型的纹理贴图和一张积雪的纹理图混合而成。...//2个采样结果的差值(1....color.rgb = lerp...

    1.前言

    公司的项目进入真机调试阶段,体验了一个月的996模式正式结束,放假第一天来写篇博客

     2.实现思路

    1.积雪的实现

    一般由模型的纹理贴图和一张积雪的纹理图混合而成。

    //2个采样结果的差值(1.模型纹理,2.积雪纹理/颜色)
    color.rgb = lerp(color, _SnowColor, SnowThreshold);

    不过因为没找到比较合适的积雪纹理图,作为一名实习生也不好意思让公司的美术大佬帮我量身定做,所以退而求其实选择使用颜色-白色作为纹理的替代。

    _SnowColor ("Snow Color", Color) = (1.0, 1.0, 1.0, 1.0)

    以世界法线和垂直方向夹角点积作为积雪厚度判断标准,积雪的程度由参数SnowLevel,SnowDepth来共同控制。

    float _SnowLevel;
    float _SnowDepth;
    
    //计算阈值,以世界法线和垂直方向夹角点积作为积雪厚度判断标准,参数Snowlevel,SnowDepth一起控制积雪程度
    //一般来说,夹角越小(点积值越大)积雪越厚
    half SnowThreshold = dot(i.worldNormal, float3(0, 1, 0)) - lerp(1, -1, _SnowLevel);
    SnowThreshold = saturate(SnowThreshold / _SnowDepth);

    2.光照

    还是使用Lambert漫反射光照模型,上次没介绍,这里简单介绍一下公式吧

    C_{LambertDiffuse} = (C_{Light} \cdot M_{Diffuse})Max(0,\widehat{n}\cdot \widehat{l})

    其中:

     C_{Light} 光源颜色

    M_{Diffuse} 材质漫反射颜色

    Max(0,\widehat{n}\cdot \widehat{l})  法线与光源方向点积的正数值

     

     3.代码实现

    以下是完整的shader代码

    Shader "Unlit/SnowShader"
    {
    	Properties
    	{
    		_MainTex ("Texture", 2D) = "white" {}
    		_SnowColor ("Snow Color", Color) = (1.0, 1.0, 1.0, 1.0)
    		_SnowLevel ("Snow Level", Range(0, 1)) = 0
    		_SnowDepth ("Snow Depth", Range(0, 0.5)) = 0.1
    	}
    	
    	SubShader{
    
    		Tags {"RenderType" = "Opaque"}
    
    		CGINCLUDE
    		#include "UnityCG.cginc"
    		#include "Lighting.cginc"
    		#include "AutoLight.cginc"
    
    		sampler2D _MainTex;
    		float4 _MainTex_ST;
    		float4 _SnowColor;
    		float _SnowLevel;
    		float _SnowDepth;
    		
    		struct a2v{
    			float4 vertex : POSITION;
    			float3 normal : NORMAL;
    			float2 texcoord : TEXCOORD0;	
    		};
    
    		struct v2f{
    			float4 pos : SV_POSITION;
    			float2 uv : TEXCOORD0;
    			float3 worldNormal : TEXCOORD1;
    			float3 worldPos : TEXCOORD2;
    			SHADOW_COORDS(3)
    		};
    
    		v2f vert(a2v v) {
    			v2f o;
    			
    			o.pos = UnityObjectToClipPos(v.vertex);
    			o.worldNormal = UnityObjectToWorldNormal(v.normal);
    			o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    			o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    			
    			TRANSFER_SHADOW(o);
    			return o;
    		}
    
    		fixed4 frag(v2f i) : SV_Target{
    
    			//使用Lambert光照模型
    
    			//材质漫反射颜色
    			fixed3 albedo = tex2D(_MainTex, i.uv).rgb;
    			//入射光方向
    			fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    			//世界法线
    			fixed3 worldNormal = normalize(i.worldNormal);
    			//环境光
    			fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    			//漫反射光照
    			fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, -worldLightDir));
    			//统一光照衰减和阴影
    			UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
    			//混合光照
    			fixed3 lightColor = diffuse * atten + ambient;
    			//纹理采样
    			fixed4 color = tex2D(_MainTex, i.uv);
    
    			//计算阈值,以世界法线和垂直方向夹角点积作为积雪厚度判断标准,参数Snowlevel,SnowDepth一起控制积雪程度
    			//一般来说,夹角越小(点积值越大)积雪越厚
    			half SnowThreshold = dot(i.worldNormal, float3(0, 1, 0)) - lerp(1, -1, _SnowLevel);
    			SnowThreshold = saturate(SnowThreshold / _SnowDepth);
    			// SnowThreshold = saturate(_SnowDepth / SnowThreshold);
    			color.rgb = lerp(color, _SnowColor, SnowThreshold);
    			//混合颜色 输出,这里把插值函数第三个值置为1,可以得到一种类似卡通风格的渲染(也就是只有color作为输出)
    			fixed3 finalColor = lerp(lightColor, color, SnowThreshold);
    
    			return float4(finalColor, 1);
    
    		}
    
    		ENDCG
    
    
    		Pass{
    
    			CGPROGRAM
    
    			#pragma vertex vert
    			#pragma fragment frag
    
    			ENDCG
    
    		}
    
    	}
    
    	FallBack "Diffuse"
    }
    

    4.实现效果

    写在最后

    项目链接:我的GitHub

    展开全文
  • Sleepless Footsteps是一种可以轻松应用于预制件的脚本和技术。该技术适用于人形机器人,但如果您在足迹平面上应用不同的纹理,也可以很容易地应用于动物。 一个简单而逼真的足迹效果,可以很容易地应用于所有移动的...
  • 先、unity 灯光烘焙 :Unity 3D FBX模型导入、选项Model 不导入资源球、Rig 不导入骨骼、Animations 不导入动画。在Model选项勾选 Generate Linghtmap UVs 。否则、灯光烘焙、会出现阴影错乱。灯光烘焙时FBX ...
  • UE4 树木积雪效果

    2017-12-21 11:20:00
    Unreal Engine 树木积雪效果1....若是单独针对雪景创建场景,则工作量就会翻倍,有什么简便的办法,能够自动将当前场景附加上积雪效果呢,网上找了好久,UE4倒没有示例,不过找到一片Unity3d的教程:...
  • 本篇blog简单记录了一下最近一两年一直在读的一系列书目。《Gpu Gems》1-3三部,《Gpu Pro》1-7七部,《Gpu Zen》一部。针对每一项渲染技术,进行全系列书的总结,从这个角度来看,可以看到一项技术,近十五六年来的...
  • 在这篇文章中,我们选择了过去一周Unity官方社区交流群中比较有代表性的几个问题,总结在这里和大家进行分享。主要涵盖了IL2CPP、Scripting、Virtual Reality、Graphics、Editor、Terrain、Plugins 、Education等...
  • 柏林噪音生成地形 沙砾闪烁效果 网格生成 首先用c#生成指定尺寸的网格(Mesh)。参照Catlike Coding的Procedural Grid教程完成。 每个3D模型都有Mesh Filter和Mesh Renderer这两个组件。其中Mesh Filter指向希望...
  • NavMeshAgent

    2016-11-17 13:33:22
    原文http://docs.Unity3D.com/ScriptReference/NavMeshAgent.html   继承自Behaviour Variables acceleration  类型:float。 代理的最大加速度。代理并不是精确的按照被navigation ...
  • shader思路以及解决方案汇总: 手游性能指标 三角形数上限 的建议是 200K --------------------------------------- #0.... Nsight调试 Adreno Profiler --------------------------------------- ...
  • 前言最近看书看很慢,过了好久也才看到shader的纹理混合与压缩这块儿,纹理混合与压缩,在游戏中是比较常见的技术,例如在一些简易的地形贴图中便使用了纹理混合,通常在shader中加载一个填充了灰度图像的混合纹理,...
  • 除战斗范围设定外,说到SLG中最有趣而经典的算法莫过于角色可移动范围的测算与寻路。当前成熟的SLG商业游戏中,以《火焰纹章》、《高级大战争》等系列新作为代表,它们在传统的基础上将可移动范围进行了拓展,组合上...
  • 斜视角的讨论

    2015-04-15 14:48:58
    斜视角的讨论(转) http://school.ogdev.net/listshow.asp?page=4&typeid=0&categoryid=5&id=0&ListType=2 http://www.docin.com/p-391446142.html&key=%E6%96%9C%E8%A7%86%E6%80%8E%E4%B9%88%E6%B2%BB ...
1 2
收藏数 21
精华内容 8
关键字:

unity3d雪地地形