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

这篇具有很好参考价值的文章主要介绍了Unity大面积草地渲染——1、Shader控制一棵草的渲染。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

一、准备的资源

草的shader,Unity引擎Shader效果,unity,游戏引擎,草渲染

这里我自己随便做了一个草的模型,主要是用几个面片搭建的一个简单模型。
草的shader,Unity引擎Shader效果,unity,游戏引擎,草渲染
草的shader,Unity引擎Shader效果,unity,游戏引擎,草渲染

然后我准备了一张草的贴图,带有透明通道的。
草的shader,Unity引擎Shader效果,unity,游戏引擎,草渲染

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

二、控制草的形态

把草的模型和贴图放到Unity引擎里面,写一个最简单的漫反射加上Cutout的shader,会看到草是这个样子:
草的shader,Unity引擎Shader效果,unity,游戏引擎,草渲染

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

1.从底部到顶部的顶点渐变
草的shader,Unity引擎Shader效果,unity,游戏引擎,草渲染

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

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

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

1、草的颜色变化

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

2、草的弯曲度变化

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

三、关于阴影

由于我是用顶点片段程序来写这个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必须要加上标签文章来源地址https://www.toymoban.com/news/detail-658666.html

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大面积草地渲染——1、Shader控制一棵草的渲染的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ChatGPT扩展系列之解决ChatGPT 被大面积封号的终极方案

    本节介绍了一个解决ChatGPT在中国大陆无法使用和担心被封号的问题的方法。近期有很多亚洲用户被封号,原因是有人滥用API接口或者批量注册账号,不符合官方规定。对于这个问题,提出了一个解决方法,可以在中国大陆无需翻墙使用ChatGPT,并且不用担心被封号。 最近两天

    2024年02月03日
    浏览(49)
  • 技术旋风!快速采集建模装备、重建大师6.1版、大面积实景三维轻量化技术...

    实景三维模型应用广度和深度日益扩大,传统测绘技术体系和生产体系正经历数字化变革。 传统激光点云数据量大、空间点离散、缺少语义信息、直接应用困难 ;而 传统倾斜摄影采集与建模周期长、生产效率低下 。二者均已无法满足各细分行业 更快速、高效、精细化的建

    2024年02月09日
    浏览(38)
  • 关于4月2号OpenAI大面积封停亚洲(中国大陆)帐号的问题和应对策略

            此次OpenAI封的全部都是批量注册的号,这些一般都是具有一定编程能力的人,使用脚本注册的账号,目的是为了耗ChatGPT-API的5美元羊毛.         少部分受害者是刚出墙不久,没有自己的谷歌,微软账号,出墙时间太短,账号行为为高风险导致.         总的来说,此次封禁针对

    2024年02月02日
    浏览(56)
  • 【Unity Shader】Unity前向渲染

    ForwardBase Pass(优先渲染),渲染一个逐像素平行光和所有的顶点/球面调和光,阴影只和平行光有关系,那阴影应该是这个Pass中实现的 ForwardAdd Pass(需要和Base配合使用,否则不生效),渲染剩余全部逐像素灯光 Unity会根据场景中各个光源的设置以及这些光源对物体的影响程

    2024年02月08日
    浏览(59)
  • 实现草地Shader的物体互动效果

    我跟着教程:https://zhuanlan.zhihu.com/p/433385999 用Unity Shader实现了草地效果。 接下来我分享一下我在这篇文章的基础上实现简单的草地互动效果的经验。 如果需要实现互动效果,需要实现脚本向shader的传递参数。 脚本使用下面的代码: 在场景中创建一个胶囊体,挂上这个脚本。

    2024年02月07日
    浏览(45)
  • Unity中Shader编译目标渲染器

    Unity中Shader编译到目标渲染器 #pragma only_renderers 仅编译指定平台的Shader d3d11 - Direct3D 11/12 glcore - OpenGL 3.x/4.x gles - OpenGL ES 2.0 gles3 - OpenGL ES 3.x metal - iOS/Mac Metal vulkan - Vulkan d3d11_9x - Direct3D 11 9.x功能级别,通常在WSA平台上使用 xboxone - Xbox One ps4 - PlayStation 4 psp2 - PlayStation Vita n3ds -

    2024年02月05日
    浏览(52)
  • Unity shader 入门之渲染管线一、总览

     如下示意图 应用阶段(ApplicationStage):准备场景信息(视景体,摄像机参数)、粗粒度剔除、定义每个模型的渲染命令(材质,shader)——由开发者定义,不做讨论。 几何阶段(GemetryStage):顶点着色器、曲面细分着色器、几何着色器、裁剪、屏幕映射; 光栅化阶段(Rasterizer

    2024年02月11日
    浏览(49)
  • 【unity shader】水体渲染基础-水下透视效果

    接下来是水体渲染基础的最后一篇,通过水面看到水下的物体,并呈现深度效果。 我们直接搭一个小场景。 增加水面,赋予uv变形的水面材质,并增加透明度的设置。 水体会吸收光线,所以真实的水体并不是完全透明的。此外,水体对不同频率的光吸收率不同,蓝光被吸收

    2024年03月14日
    浏览(56)
  • 【Unity大气渲染】Unity Shader中实现大气散射(半成品)

    写在前面 这是之前在做天空盒的时候同步写的分析博客,结果后面写到一半就忘了继续了,这里先贴出当时写的半成品,有小伙伴问我怎么做的,这里只能尽力把之前的半成品先放出来了(写得很乱,勿怪orz),,后面有机会会完善好的!希望能帮到大家~ 前置知识学习 【

    2024年02月08日
    浏览(49)
  • unity build-in 渲染管线升级urp渲染 shader篇

            由于工作原因需要对项目进行升级,从build-in渲染管线升级到urp渲染管线,我自己对应的unity版本是2018.版本升级到2021.3.2版本,由于最近几年unity版本升级比较快,个体版本差异有所不同,如遇与版本不一致问题敬请谅解。以下是根据官网等系列网站整理的内容

    2023年04月16日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包