UnityShader 基於網格頂點的草叢

2021-09-17 01:25:09 字數 4445 閱讀 8621

發現了一篇寫草叢的文章,自己跟著寫了遍,並新增了自定義的形狀和密度。

思路:1、利用幾何著色器,將每個頂點轉為乙個葉片網格

2、利用曲面細分生成新頂點控制草叢密度

3、貼圖加clip決定葉片形狀

4、利用旋轉矩陣完成動態和隨機效果

shader檔案

shader "custom/grassshaderwithtexture"

[header(shape)]

[space]

[toggle(_use_grass_texture)]_usetexture("使用紋理形狀",float)=0

[noscaleoffset]_grasstexture("草葉形狀(a)",2d)="white"{}

_bladewidthbase("基礎寬度",float)=0.5

_bladewidthrandom("寬度擾亂",float)=0.5

_bladeheightbase("基礎高度",float)=0.5

_bladeheightrandom("高度擾亂",float)=0.5

[header(wind)]

[space]

_windmap("風向貼圖",2d)="white"{}

_windspeed("風速(xy)",vector)=(0.05,0.05,0,0)

_windstrength("風力",float)=1

[header(bend)]

[space]

_bendstrength("bend strength",range(0,1))=0.4

_bladeforward("blade forward amount", float) = 0.38

_bladecurve("blade curvature amount", range(1, 4)) = 2

}cginclude

#include "unitycg.cginc"

#include "autolight.cginc"

#include "lighting.cginc"

#include "assets/shaders/grasstessellationwithtexture.cginc"

#pragma shader_feature _use_grass_texture

float rand(float3 co)

float3x3 angleaxis3x3(float angle, float3 axis)

struct gout;

gout vertexoutput(float3 pos,float2 uv,float3 normal)

gout generategrasspoint(float3 pos,float width,float forward,float height,float2 uv,float3x3 transform)

float _bendstrength;

float _bladewidthbase,_bladewidthrandom,_bladeheightbase,_bladeheightrandom;

sampler2d _windmap;

float4 _windmap_st;

float2 _windspeed;

float _windstrength;

float _bladeforward,_bladecurve;

#ifdef _use_grass_texture

sampler2d _grasstexture;

#endif

#define blade_segments 3

#ifdef _use_grass_texture

[maxvertexcount(blade_segments*2+2)]

#else

[maxvertexcount(blade_segments*2+1)]

#endif

void geo(point vout i[1],inout ********streamstream)

#ifdef _use_grass_texture

#else

#endif

}endcg

subshader

cull off

cgprogram

#pragma target 4.6

#pragma multi_compile_fwdbase

#pragma vertex vert

#pragma hull hull

#pragma domain domain

#pragma geometry geo

#pragma fragment frag

float4 _bottomcol,_topcol;

float _translucentgain;

float4 frag(gout i,fixed facing : vface):sv_target

endcg

}pass

cgprogram

#pragma vertex vert

#pragma geometry geo

#pragma fragment frag

#pragma hull hull

#pragma domain domain

#pragma target 4.6

#pragma multi_compile_shadowcaster

float4 frag(gout i) : sv_target

endcg}}

fallback "diffuse"

}

grasstessellationwithtexture.cginc 

#ifndef grass_tessellation_texture_include

#define grass_tessellation_texture_include

struct vin;

struct vout;

struct tessellationfactors

;//--------------------vertex------------------------

vin vert(vin v)

//---------------------hull-----------------------

float _tessellationuniform,_texturestrength;

sampler2d _densitytexture;

float4 _densitytexture_st;

tessellationfactors patchconstantfunction(inputpatchpatch)

[unity_domain("tri")]

[unity_outputcontrolpoints(3)]

[unity_outputtopology("********_cw")]

[unity_partitioning("integer")]

[unity_patchconstantfunc("patchconstantfunction")]

vin hull(inputpatchpatch,uint id:sv_outputcontrolpointid)

//gpu進行曲面細分操作 in->out

//-----------------------domain-------------------

vout tessvert(vin v)

#define my_domain_program_interpolate(fieldname) v.fieldname = \

patch[0].fieldname * barycentriccoordinates.x + \

patch[1].fieldname * barycentriccoordinates.y + \

patch[2].fieldname * barycentriccoordinates.z;

[unity_domain("tri")]

vout domain(tessellationfactors factors,outputpatchpatch,float3 barycentriccoordinates : sv_domainlocation)

#endif

UnityShader3 網格漸現效果

效果圖 1.首先就是簡單的漸現效果,同時要注意,在出現網格時,需要用到透明度混合 shader custom mesh meshtex meshtex 2d white thresholdy thresholdy range 8,0 8 除錯出來的範圍 2.上面的是手動拖動 thresholdy的情...

Unity Shader 基於物理的渲染技術

光是一種電磁波,由光源發射出來,與物體相交,一部分被吸收轉化為其他能量,而另一些被散射,最後被感應器 如眼睛 吸收成像 吸收 改變光的能量,不改變光的方向 散射 不改變光的能量,改變光的方向 影響光的乙個重要的特質就是物體材質的折射率 drdf可以用f l,v 來表示,l是入射方向,v是觀察方向 乙...

建立接近最優的導航網格以及基於導航網格的尋路演算法

一種接近最優的導航網格生成演算法以及基於導航網格的尋路演算法 a 尋路 3d 環境中的尋路 提出背景 長距離尋路會出現掉幀現象,為了提高尋路速度,並為 3d環境中的尋路方案提供基礎演算法實現。目前狀況 由於 3d遊戲對幀率要求很高,而在遊戲中進行一次長距離的尋路可能要花費 8 10 幀的時間,在地圖...