效果比較好的頭髮shader

2022-03-04 07:13:41 字數 4772 閱讀 2113

效果如下:

渲染頭髮時可能會遇到如下問題:

1. 因為頭髮本質上是乙個乙個的透明的麵片,理所當然會想到使用 blend 混合方式來渲染。

但當由於用 blend 時,要關閉z快取寫,即執行 zwirte off,不然透明的區域也會遮擋後面的畫素。

此時就會出現問題,頭髮之間的層級會完全混亂,因為頭髮是多個麵片穿插在一起的。

2. 因此不能使用blend的方式,就只能使用 alpha test 的方式來強制丟棄透明的畫素。

但 alpha test 的問題的邊緣部分不夠平滑,劇齒感明顯。

解決此問題的思路是,乙個通道執行 alpha test,把透明區域直接丟棄掉。

另乙個通道執行 blend 混合,把 alpha test 丟棄的畫素再重新渲染一遍。

示例**如下:

1 shader "

character/example-diffuse-hair"2

7 _cutoff( "

cutoff

", range (0,1)) = 0.58}

910subshader

1118 lod 200

1920

pass

2126

blend srcalpha oneminussrcalpha

27cull off

2829

cgprogram

30#pragma vertex vert

31#pragma fragment frag

32#pragma multi_compile_fwdbase

3334 #include "

unitycg.cginc

"35 #include "

autolight.cginc

"36 #include "

lighting.cginc"37

38fixed4 _color;

39sampler2d _maintex;

40float

_cutoff;

4142

struct43;

4849

struct

v2f50;56

5758

6667

fixed4 frag(v2f i) : sv_target

6882

83endcg84}

8586

pass

8792

blend srcalpha oneminussrcalpha

93zwrite off

9495

cgprogram

96#pragma vertex vert

97#pragma fragment frag

98#pragma multi_compile_fwdbase

99100 #include "

unitycg.cginc

"101 #include "

autolight.cginc

"102 #include "

lighting.cginc

"103

104fixed4 _color;

105sampler2d _maintex;

106float

_cutoff;

107108

struct

109;

114115

struct

v2f116

;122

123124

132133

fixed4 frag(v2f i) : sv_target

134148

149endcg

150}

151152

153}

154155 fallback "

diffuse

"156 }

以下是帶高光的頭髮shader,頭髮的高光比較特殊,是一圈一圈的高光,如下圖效果,故不能用普通的高光演算法。

**如下:

1 shader "

america/character/america-diffuse-specular-hair2"2

7 _ramp ("

toon ramp (rgb)

", 2d) = "

gray"{}

8 _cutoff( "

cutoff

", range (0,1)) = 0.5

910 _overlyingcolor("

overlying color

", color) = (0.5, 0.5, 0.5, 1)11

12 _speculargloss ("

specular gloss

", float) = 20

13 _anisotropybias("

anisotropy-bias

", range( -1 , 1)) = -1

14 _diffuserate ("

diffuse rate

", float) = 2

15 _specularrate ("

specular rate

", float) = 0.616}

1718

subshader

1926 lod 200

2728

pass

2934

blend srcalpha oneminussrcalpha

35cull off

3637

cgprogram

38#pragma vertex vert

39#pragma fragment frag

40#pragma multi_compile_fwdbase

4142 #include "

unitycg.cginc

"43 #include "

autolight.cginc

"44 #include "

lighting.cginc"45

46 #include "

../americacg.cginc"47

48fixed4 _color;

49sampler2d _maintex;

50sampler2d _ramp;

51float

_cutoff;

52fixed4 _overlyingcolor;

53float

_speculargloss;

54half _anisotropybias;

55float

_diffuserate;

56float

_specularrate;

5758

struct59;

6566

struct

v2f67;74

7576

9091

fixed4 frag(v2f i) : sv_target

92121

122endcg

123}

124125

pass

126131

blend srcalpha oneminussrcalpha

132zwrite off

133134

cgprogram

135#pragma vertex vert

136#pragma fragment frag

137#pragma multi_compile_fwdbase

138139 #include "

unitycg.cginc

"140 #include "

autolight.cginc

"141 #include "

lighting.cginc

"142

143 #include "

../americacg.cginc

"144

145fixed4 _color;

146sampler2d _maintex;

147sampler2d _ramp;

148float

_cutoff;

149fixed4 _overlyingcolor;

150float

_diffuserate;

151152

struct

153;

158159

struct

v2f160

;166

167168

176177

fixed4 frag(v2f i) : sv_target

178194

195endcg

196}

197198

199}

200201 fallback "

diffuse

"202 }

效果比較好的細化演算法

void cvthin cv mat src,cv mat dst,int intera 非原地操作時候,copy src到dst if dst.data src.data int i,j,n int width,height width src.cols 1 之所以減1,是方便處理8鄰域,防止越界...

還是 push 比較好

以前在 js 中往乙個陣列裡 放數 用的是 a i i 的形式,就像這樣 var testarray new array for var i 1 i m i 這樣寫可能會引起問題,看似 testarray 0 沒有被賦值,但是此時賦值完畢以後你會發現 testarray.length 的值為 m 1...

AsyncTask 比較好的解釋

package com.example.asynctask import android.os.asynctask import android.widget.progressbar import android.widget.textview 生成該類的物件,並呼叫execute方法之後 首先執行...