

Genel Bakış #
Bu doku, örneğin araba boyası benzeri malzemeler için kullanılabilen, prosedürel bir pul normal haritası oluşturur. Malzemenin kabartma yuvası içinde normal harita olarak kullanılmak üzere tasarlanmıştır. Haritanın herhangi bir filtreleme yapmadığını, bu nedenle küçük pulların temizlenmesi için çok sayıda AA örneği gerektiğini unutmayın.
Shader kodu burada:
3ds Max için örnek bir sahne burada:
Çıktılar #
sonuç – pul normal haritası rengi
alfa – pullar için siyah beyaz bir maske
Girişler #
Yonga ölçeği – tüm yonga yapısını yukarı veya aşağı ölçeklendirir. Daha büyük değerler haritadan uzaklaştırır.
Pul boyutu – pulların göreceli boyutu.
Pul boyutu varyansı – pul boyutunun rastgeleliğini belirler. 0,0, tüm pulların belirtilen boyutta olduğu anlamına gelir.
Pul normal yönelimi – rastgele pul normali ile pürüzsüz yüzey normali arasında bir karışım.

Gölgelendirici kodu #
İşte shader kodu:
</p>
<div>shader</div>
<div>flakes</div>
<div>(</div>
<div>float flake_scale = 10.0 [[ string description = "Smaller values zoom into the flake map, larger values zoom out" ]],</div>
<div>float flake_size = 0.5 [[ string description = "Relative size of the flakes" ]],</div>
<div>float flake_size_variance = 0.0 [[ string description = "0.0 makes all flakes the same size, 1.0 assigns random size between 0 and the given flake size" ]],</div>
<div>float flake_normal_orientation = 0.0 [[ string description = "Blend between the flake normals (0.0) and the surface normal (1.0)" ]],</div>
<div></div>
<div>output color result = 1.0,</div>
<div>output float alpha = 1.0</div>
<div>)</div>
<div>{</div>
<div>float safe_flake_size_variance = clamp(flake_size_variance, 0.1, 1.0);</div>
<div>vector cellCenters[9] = {</div>
<div>vector( 0.5, 0.5, 0.0),</div>
<div>vector( 1.5, 0.5, 0.0),</div>
<div>vector( 1.5, 1.5, 0.0),</div>
<div>vector( 0.5, 1.5, 0.0),</div>
<div>vector(-0.5, 1.5, 0.0),</div>
<div>vector(-0.5, 0.5, 0.0),</div>
<div>vector(-0.5, -0.5, 0.0),</div>
<div>vector( 0.5, -0.5, 0.0),</div>
<div>vector( 1.5, -0.5, 0.0)</div>
<div>};</div>
<div></div>
<div>point position = vector(u, v, 0.0);</div>
<div>position = flake_scale * position;</div>
<div></div>
<div>point base = floor(position);</div>
<div></div>
<div>point nearestCell = point(0.0, 0.0, 1.0);</div>
<div>int nearestCellIndex = -1;</div>
<div>for(int cellIndex = 0; cellIndex < 9; ++cellIndex){</div>
<div>point cellCenter = base + cellCenters[cellIndex];</div>
<div></div>
<div>vector centerOffset = cellnoise(cellCenter) * 2.0 - 1.0;</div>
<div>centerOffset[2] *= safe_flake_size_variance;</div>
<div>centerOffset = normalize(centerOffset);</div>
<div></div>
<div>cellCenter += 0.5 * centerOffset;</div>
<div>float cellDistance = distance(position, cellCenter);</div>
<div>if(cellDistance < flake_size && cellCenter[2] < nearestCell[2]) {</div>
<div>nearestCell = cellCenter;</div>
<div>nearestCellIndex = cellIndex;</div>
<div>}</div>
<div>}</div>
<div></div>
<div>result = color(0.5, 0.5, 1.0);</div>
<div>alpha = 0.0;</div>
<div></div>
<div>if (nearestCellIndex != -1) {</div>
<div>vector randomNormal = cellnoise(base + cellCenters[nearestCellIndex] + vector(0.0, 0.0, 1.5));</div>
<div>randomNormal = 2.0 * randomNormal - 1.0;</div>
<div>randomNormal = faceforward(randomNormal, I, randomNormal);</div>
<div>randomNormal = normalize(mix(randomNormal, vector(0.0, 0.0, 1.0), flake_normal_orientation));</div>
<div></div>
<div>result = color(0.5*randomNormal[0]+0.5, 0.5*randomNormal[1]+0.5, randomNormal[2]);</div>
<div>alpha = 1.0;</div>
<div>}</div>
<div>}</div>
<p data-v-97f42bc7="" data-v-c6e36616="">
