Unity大面积草地渲染——1、Shader控制一棵草的渲染

101 篇文章 93 订阅
订阅专栏

目录
1、Shader控制一棵草的渲染
2、草地的动态交互
3、使用GPUInstancing渲染大面积的草
4、对大面积草地进行区域剔除和显示等级设置

大家好,我是阿赵。
这里开始讲大面积草地渲染的第一个部分,一棵草的渲染。按照惯例,完整shader在最后。前面是原理的介绍。

一、准备的资源

在这里插入图片描述

这里我自己随便做了一个草的模型,主要是用几个面片搭建的一个简单模型。
在这里插入图片描述
在这里插入图片描述

然后我准备了一张草的贴图,带有透明通道的。
在这里插入图片描述

把贴图赋予给模型后,在3DsMax里面草是这个样子,只是简单的几个直草。

二、控制草的形态

把草的模型和贴图放到Unity引擎里面,写一个最简单的漫反射加上Cutout的shader,会看到草是这个样子:
在这里插入图片描述

这里我们需要根据草的顶点坐标,做2个范围的控制:

1.从底部到顶部的顶点渐变
在这里插入图片描述

由于我做模型的时候,模型的中心点就在草的根部,所以我可以拿模型中心点作为一个基准,然后计算其他顶点的坐标离根部的Y坐标差,算出一个渐变。上图是越高的地方颜色越白。
通过这个,我们在写Shader的时候,就可以根据顶点高度的不同,给草赋予不同的表现,比如颜色的变化,或者弯曲度的变化。
为了控制黑白渐变的范围,我一般会加一个smoothstep来控制。
2.以底部为圆心,求扩散的范围
在这里插入图片描述

这个计算和刚才的高度计算效果不一样,离圆心越近的点越黑,离得越远的点越白。这个渐变的范围,可以用于我们计算时,草离中心不一样,表现不一样。
同样的,为了控制黑白渐变的范围,我会加smoothstep控制。

有了以上2个渐变之后,下面就开始来计算草的外观了。

1、草的颜色变化

一棵植物,一般会在不同的生长部位表现出颜色不一样,比如一棵草,按道理可能会根部的颜色较深,而顶部的地方颜色较浅。
这里先实现一下这个效果,根据刚才的高度渐变计算结果,可以把草本身的贴图颜色再混合2个颜色:一个根部颜色和一个顶部颜色。
混合之后,结果如下:
在这里插入图片描述

2、草的弯曲度变化

之前在3DsMax里面做的草模型,是直挺挺的草,完全没有弯曲度的,但实际上的草,会因为受到重力的原因,而到了一定的长度和角度之后出现弯曲。
这里我用到了上面计算的高度渐变和圆心渐变,来做这个效果。
首先,根据实际情况,离圆心越远的叶子,由于他倾斜度会越大,所以受到重力之后他应该往下弯曲得更多,然后,究竟从哪个高度开始才应该弯曲呢?这里就可以用高度渐变来控制了。
最后得到的结果是这样:
在这里插入图片描述

三、关于阴影

由于我是用顶点片段程序来写这个shader的,所以阴影需要用单独一个pass来绘制。
怎样使用动态阴影,之前我有介绍过,要在shader里面加入影子三剑客。
不过这里由于使用了顶点变化的控制,所以在这个专门绘制影子的pass里面,我们需要把顶点程序也照抄一份。
还有一个需要注意的是,在顶点程序里面照抄完控制顶点的代码之后,不是给v2f结构体赋值转换到裁剪空间的顶点坐标,而是直接赋值给输入顶点程序的appdata结构体的vertex。这是比较特殊的地方。

其实也可以不用影子三剑客来做,在不要#pragma multi_compile_shadowcaster、TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)和SHADOW_CASTER_FRAGMENT(i)的情况下,
为了让影子的顶点正常的动画,所以顶点程序直接复制正常pass。
然后片段程序改成最简单的clip透明度,也可以做到镂空的效果。

	half4 frag(v2f i) : SV_Target
	{
		half4 col = tex2D(_MainTex, i.uv);
		clip(col.a - 0.5);
		return col;
	}

不过产生影子的pass必须要加上标签

Tags { "LightMode" = "ShadowCaster" }

四、完整shader:

Shader "azhao/GrassBsse"
{
    Properties
    {
		_MainTex("MainTex", 2D) = "white" {}
		_hmin("hmin", Range(0 , 1)) = 0
		_hmax("hmax", Range(0 , 1)) = 1
		_hOffset("hOffset", Range(-1 , 1)) = 0
		_vmin("vmin", Range(0 , 1)) = 0
		_vmax("vmax", Range(0 , 1)) = 1
		_vOffset("vOffset", Range(-5 , 5)) = 0
		_topCol("topCol", Color) = (0,1,0,0)
		_bottomCol("bottomCol", Color) = (0,0,0,0)

    }
    SubShader
    {
		Tags{"Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" }
		Cull Off

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


			#include "UnityShaderVariables.cginc"
			#pragma target 3.0
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {                
                float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 centerPos : TEXCOORD1;
				float3 worldPos : TEXCOORD2;
				float3 hvVal : TEXCOORD3;

            };

			uniform float _hmin;
			uniform float _hmax;
			uniform float _vmin;
			uniform float _vmax;
			uniform float _vOffset;

			uniform float _hOffset;

			uniform sampler2D _MainTex;
			uniform float4 _MainTex_ST;
			uniform float4 _topCol;
			uniform float4 _bottomCol;
			SamplerState sampler_MainTex;

            v2f vert (appdata v)
            {
                v2f o;
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.centerPos = mul(unity_ObjectToWorld, float4(float3(0, 0, 0), 1)).xyz;
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				float hVal = smoothstep(_hmin, _hmax, o.worldPos.y - o.centerPos.y);
				float vVal = smoothstep(_vmin, _vmax, distance(o.worldPos.xz, o.centerPos.xz));
				float hvVal = hVal * vVal;
				o.hvVal = float3(hVal, vVal, hvVal);
				float hVertexOffset = hvVal * _hOffset;
				float2 vVertexOffset = (o.worldPos.xz - o.centerPos.xz)*hvVal*_vOffset;

				o.pos = UnityObjectToClipPos(v.vertex+float3(vVertexOffset.x, hVertexOffset, vVertexOffset.y));
                return o;
            }

            half4 frag (v2f i) : SV_Target
            {
                // sample the texture
                half4 col = tex2D(_MainTex, i.uv);
				half3 finalCol = col.rgb * _topCol.rgb*i.hvVal.z + col.rgb;
				finalCol = clamp(finalCol*i.hvVal.x + _bottomCol * (1 - i.hvVal.x)*finalCol,  half3(0, 0, 0), half3(1, 1, 1));
				half alpha = col.a;
				clip(alpha - 0.5);
                return half4(finalCol,alpha);
            }
            ENDCG
        }
		
		//为了产生影子,加多一个pass
		Pass {
			Name "ShadowCaster"
			Tags { "LightMode" = "ShadowCaster" }

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0
			#pragma multi_compile_shadowcaster
			#include "UnityCG.cginc"

			struct v2f {
				V2F_SHADOW_CASTER;
			};
			uniform float _hmin;
			uniform float _hmax;
			uniform float _vmin;
			uniform float _vmax;
			uniform float _vOffset;

			uniform float _hOffset;
			uniform sampler2D _MainTex;
			uniform float4 _MainTex_ST;
			uniform float4 _topCol;
			uniform float4 _bottomCol;
			SamplerState sampler_MainTex;
			v2f vert(appdata_base v)
			{
				v2f o;
				float3 centerPos = mul(unity_ObjectToWorld, float4(float3(0, 0, 0), 1)).xyz;
				float3 worldPos = mul(unity_ObjectToWorld, v.vertex);
				float hVal = smoothstep(_hmin, _hmax, worldPos.y - centerPos.y);
				float vVal = smoothstep(_vmin, _vmax, distance(worldPos.xz, centerPos.xz));
				float hvVal = hVal * vVal;
				float hVertexOffset = hvVal * _hOffset;
				float2 vVertexOffset = (worldPos.xz - centerPos.xz)*hvVal*_vOffset;

				v.vertex = v.vertex + float4(vVertexOffset.x, hVertexOffset, vVertexOffset.y,1);
				TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
				return o;
			}

			float4 frag(v2f i) : SV_Target
			{
				SHADOW_CASTER_FRAGMENT(i)
			}
			ENDCG

		}

    }
	FallBack "VertexLit"
}
草地渲染-使用Unity实现逼真的实时草地渲染-附项目源码-优质项目实战.zip
05-18
草地渲染_使用Unity实现逼真的实时草地渲染_附项目源码_优质项目实战
unity常用坪贴图材质包
05-02
unity3d常用材质球,包括多种不同坪贴图材质 / unity3d游戏开发常用材质。
渲染理论
最新发布
qq_41061477的博客
08-02 834
Unity引擎提供了基础的terrain工具,可以制作地形,在上面刷树刷。对于,Unity是支持带的Prefab,,效果还不错。对于Unity支持两种方式来刷,一种是,一种是。第一种实际上就是放一张图片,可以支持billboard,目的是营造一片的错觉,这个只能远看,但是离得近,就穿帮了,尤其是在俯视的情况下,如下图。第二种是Add Detail Mesh,类似刷树,但是不支持LOD。1.使用面片+贴图 性能好但效果不好。
Unity大面积草地渲染——3、使用GPUInstancing渲染大面积
阿赵的博客
05-10 3692
大面积草地渲染的第三个部分,使用GPU Instancing来渲染大面积
Unity】建片草地
沙师弟专栏
10-25 6501
文章目录1、简述2、创建2.1、创建项目2.2、进入开发窗体3、建个地面3.1、新建地面3.2、调整地面大小3.3、添加草地3.3.1、初识Unity图片资源3.3.2、添加图片资源3.3.3、修改图片在场景中大小 1、简述 前一章我们已经学会 下载安装 了,接下来和我一起一步一步开始操作,做第一个实例吧~ 2、创建 2.1、创建项目 第一步打开Hub,点击新建项目。然后选择合适的项目和项目位置(如图),然后点击创建(搭建过程要拷贝比较多的文件和库,稍微要等上一小会儿) 2.2、进入开发窗体 第一步成功后
探索高效草地渲染UnityGrassRenderingIndirectExample
gitblog_00093的博客
06-12 564
探索高效草地渲染UnityGrassRenderingIndirectExample 项目地址:https://gitcode.com/EricHu33/UnityGrassIndirectRenderingExample 在游戏开发中,逼真的环境细节往往是提升沉浸感的关键因素之一,而茂盛的草地则是自然场景中的重要组成部分。今天,我们向您推荐一款开源项目——UnityGrassRendering...
Unity大面积草地渲染——2、草地的动态交互
阿赵的博客
05-08 1850
大面积草地渲染的第二个部分,草地动态交互
Shader之——花动画shader
baicaishisan的博客
02-01 1945
今天 ,接到了个需求,花的动画。谈到花动画,立马就想到顶点动画,让顶点动起来就可以实现了。但是有个问题,所有的都往一个方向运动,这个就麻烦了。因为在shader里没有随机这种概念,提到最多的是用一张噪声图来模拟。在网上搜索了一下,发现有更好的办法,就是用每个顶点到一个点的距离来控制动画的开始,毕竟每个顶点到同一个点的距离很少是一样的。 float dis = distance ...
Unity URP】风格化草地01:实现方法概述
qq_41835314的博客
03-09 3655
简单总结一下常见的草地渲染思路。
Unity草地/坪案例分享(完整代码)
盖子的博客
08-23 4726
老规矩先上图 最近又开始继续操刀我的新独立游戏啦,网上看了很多草地的案例受益匪浅。但是嘛最近还是选择用自己的方式去实现。 主要是因为这种方式可以更好的贴合我前后的需求。还有很多有意思的技术点,有时间一点点拿来和大家一起分享吧。 这次先来说说草地的实现方式: 由于草地需要贴合模型表面,所以这里是从附着的模型表面开始的: 一、循环Mesh三角型数值,以三角型为单位记录一组数据,内容为三个顶点位置及其法线信息。 代码如下: private List<GlassPoint> myData;
VIRTOOLS VT 草地Shader
06-21
个人收集 很好的一个shader 可作动态草地
Grass.shader
08-30
对应《UnityShader_使用几何着色器实现坪效果(简易)》中的shader,文中仅仅提炼出了大部分代码,完整代码可自行下载
(八)unity shader基础之——————渲染平台差异问题
cgy56191948的博客
10-08 2373
unity的优点之一是强大的跨平台性,本篇文章给出了一些常见的因为平台不同而造成的差异。 1.渲染纹理的坐标差异 之前提到过OPenGL和DirectX的屏幕空间坐标的差异。在水平方向上,两者的数值变化方向是相同的,但在竖直方向上,两者是相反的。在OpenGL中,(0,0)点对应了屏幕的左下角,而在DirectX中,(0,0)点对应了左上角。 需要注意的是,我们不仅可以把渲染结果输出到屏...
(三)unity Shader之——————surface shader转变为自己写的vertex&fragment Shader不受unity的动态实时点光源的影响解决方案
cgy56191948的博客
08-28 1261
在写环境、植物的Shader时,原来使用的是Surface shader,出于性能的考虑要转变成效果一致的vertex&fragment Shader,转变中遇到了一个问题。 首先我加了一个unity的标准点光源,如果都换成unity的standard shader,或者其他的surface shader(包括现在使用的环境和植物的surface shader),你会发现环境都是受点光源...
Unity Shader】使用Geometry Shader进行大片草地的实时渲染
weixin_44422550的博客
03-28 4535
效果预览图 0.前言 笔者最近阅读学习了知乎大神@陈嘉栋所写的这篇文章:《利用GPU实现无尽草地的实时渲染》,这篇文章写得非常好,给出了实时生成一片草地的核心思路和基本流程,非常清晰……但可惜的是,如果读者没有一定Shader基础(尤其是关于GeometryShader)的话,在读了这篇文章后很难直接着手去做,许多代码需要自己去下工程来解读。 笔者在下载工程并较为完整地学习/制作,并在此基础上做...
(二)unity shader基础之——————shader一些专业术语的解释(OpenGL/DirectX、HLSL/GLSL/Cg、Draw Call、固定管线渲染等)
cgy56191948的博客
10-02 1080
一、什么是OpenGL/DirectX 我们直接访问GPU是一件非常麻烦的事情,可能需要各自寄存器、显存打交道而图像编程接口在这些硬件的基础上实现了一层抽象。 OpenGL和DirectX就是这些图像应用编程接口,这些接口用于渲染二维或三维图形。这些接口架起了上层应用程序和底层GPU的沟通桥梁。一个应用程序向这些接口发送渲染接口发送渲染命令,而这些接口会依次向显卡驱动发送渲染命令,这些显卡驱动...
Unity】从零使用ShaderGraph - 花简单摇曳效果
sylardie的博客
04-02 1246
顶点偏移可以用于实现许多类似于摇曳、摆动等动画。控制顶点位置则可以使用顶点色贴图。Position节点、Time节点、Noise节点是实现该效果的核心节点。
普通的Shader_草地效果
suixinger_lmh的随笔
06-06 486
unity 草地shader效果
Unity3D 制作绿草地,坪,模型表面生成草地,草地效果Shader实现 着色器 Brute Force - Grass Shader
CTangZe的博客
06-16 4464
适用于 PC/Mac/Linux/Nintendo Switch 和移动设备的 Brute Force 交互式着色器 与渲染管线 Standard ,URP 与 HDRP 兼容 - 简单: 拖放材料 - 优化: 每种材料的自定义 LoD 距离衰减 - 动态自定义阴影: 可以接收和投射阴影的 - 交互性: 使用简单的粒子系统,您可以创建交互效果,例如鼠标/玩家位置上的轨迹 - 定制: 完全可定制的 - 灯光支持: 4x 点灯和聚光灯支持 - 地形: 使用纹理 Splat Map 绘制。 - VR 支持
unity,根据相机渲染变化的shader
06-01
可以使用Unity内置的Shader中的"Unlit/Texture" Shader来实现这个功能。该Shader不受光照影响,只显示贴图颜色,因此可以用于实现根据相机距离变化的效果。 具体操作如下: 1. 在Unity中创建一个新的材质,并为其选择"Unlit/Texture" Shader。 2. 将需要渲染的纹理贴图赋值给该材质的贴图属性。 3. 在Shader中添加一个"Camera"节点,用于获取相机的属性。 4. 使用"CameraDepth"属性来获取相机渲染的深度值,将其映射到对应的颜色值上。 5. 在Shader中使用映射好的颜色值来渲染材质。 具体代码实现可参考以下示例: ``` Shader "Custom/DistanceColorShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags {"Queue"="Transparent" "RenderType"="Opaque"} LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UNITY_PROJ_COORD(i.vertex))); float4 color; color.r = depth; color.g = depth; color.b = depth; color.a = 1.0; return color; } ENDCG } } } ``` 这样就可以根据相机距离渲染出一张深度颜色变化的图片了。
写文章

热门文章

  • 2019年第一次画画,顺便评价一下ipadPro和Surface的画画优劣 34786
  • 面向对象的概念介绍 22125
  • 解决部分手机读取obb失败的问题 17804
  • unity自带寻路Navmesh入门教程(一) 17693
  • MaterialPropertyBlock 17337

分类专栏

  • ZBrush使用 15篇
  • 虚幻引擎(UE) 45篇
  • 系列文章目录 9篇
  • Unity引擎Shader效果 101篇
  • Unity屏幕后处理 10篇
  • TA通用技术 19篇
  • MaxScript 20篇
  • Unity功能与问题解决 47篇
  • Unity资源管理相关 8篇
  • 程序基础 13篇
  • 寻路和智能 9篇
  • 3D打印 22篇
  • 行业杂谈 49篇

最新评论

  • 阿赵UE学习笔记——30、HUD简单介绍

    阿赵3D: 关于UE的暂时只写了2个系列,一个是基础学习笔记,另一个是C++的学习笔记

  • 阿赵UE学习笔记——30、HUD简单介绍

    不想当咸鱼i: 表情包好文,还有后续吗,感觉UE知识点太多了,看官方文档看不懂都表情包

  • Unity引擎在UI上渲染粒子播放

    阿赵3D: 不用导出啊,先理解一下用法,然后shader需要是支持UI的

  • Unity引擎在UI上渲染粒子播放

    TVstart: 导出没效果

  • 关于写简历的趣事

    阿赵3D: 40出头

最新文章

  • FDM3D打印系列——黑悟空打印
  • Unity引擎绘制多边形属性图
  • FDM3D打印系列——大面积水性漆手涂效果测试
2024
09月 10篇
08月 18篇
07月 18篇
06月 16篇
05月 16篇
04月 17篇
03月 19篇
02月 5篇
01月 20篇
2023年151篇
2022年1篇
2020年4篇
2019年5篇
2018年64篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家宁夏玻璃钢雕塑仿真牛江西公园玻璃钢雕塑供应商金华景观玻璃钢雕塑泰州商场主题美陈扬州定做玻璃钢雕塑上海人物玻璃钢雕塑销售厂家花朵玻璃钢卡通雕塑加工服务好的玻璃钢花盆外贸桃子玻璃钢雕塑厂浙江商业商场美陈多少钱淮北人物玻璃钢雕塑丰都玻璃钢仿铜雕塑重庆仿铜玻璃钢雕塑市场甘肃大型玻璃钢雕塑多少钱鼓楼商场新年美陈成都市玻璃钢雕塑厂电话银川仿真玻璃钢雕塑安装泡沫校园玻璃钢雕塑公司抚州玻璃钢雕塑人物聚脂玻璃钢雕塑哪种好玻璃钢雕塑营造南阳镂空不锈钢校园玻璃钢雕塑暴力熊玻璃钢雕塑淮安玻璃钢动漫卡通雕塑设计泥塑及玻璃钢雕塑设计加工西安玻璃钢雕塑树玻璃钢动物雕塑参考价泡泡玛特玻璃钢雕塑如何上色绵阳玻璃钢卡通雕塑价格上饶玻璃钢雕塑背景香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化