"Signed Distance Functions" heyya technique bech t'rendri des objets w des volumes Ɛla surface.
SDFs mostaƐmlin barcha f'el volumes (eg. smoke fi counter-strike) w el complex shaders (kima ShaderToy).
~~! Q̈bal ma nq̈admou f'el ħkeya hedhi lezem ykoun Ɛandek base f'el Shaders
w taƐraf chnouwa el Ray tracing, aƐmel gacha
w'arjaƐ !~~
Awel etape bech ennejmou n'rendriw el scene,
lezem nefhmou el concept mteƐ el Raymarching.
"Raymarching" houma kelmtin:
1. "ray" (fr: rayon)
2. "marching" (yemchi/yq̈addem).
Houni, el ray yq̈addem mel camera w ychouf chƐand'na f'el scene.
Ken yelq̈a objet, ylawwén el pixela f'el écran b'couleur l'objet.
"Ray tracing" y'traci ligne waħda kol marra,
par contre el "Ray marching" y'traci b'sphere kemla w ychouf el distance bin el centre mtaƐ el sphere
w aq̈rab object.
Kol marra yelq̈a object, yƐawed y'traci mel limite mtaƐ el'sphere (el distance eli lq̈aha).
Function mtaƐ el raymarching:
float raymarch (vec3 cameraPosition, vec3 cameraDirection)
{
// N'initializew el depth(profondeur) mtaƐ el ray (houni MIN_DIST = 0)
float depth = MIN_DIST;
// Kol marra nqadmou chwaya (men 0 lel max steps: MAX_MARCHING_STEPS = 20)
for (int i = 0; i < MAX_MARCHING_STEPS; i++) {
// Nthabtou el distance l'aq̈rab point f'el scene mteƐna
float dist = sceneSDF (cameraPosition + depth * cameraDirection);
// Idha ken el distance asghar m'el epsilon, (houni EPSILON = 0.001)
if (dist < EPSILON) {
// Fi west el surface!
return depth;
}
// Qaddem el depth ħasb el distance
depth += dist;
if (depth >= MAX_DIST) {
// BƐiid yecer, zeyed, nrajƐou el distance maximale eli wselnelha (houni MAX_DIST = 100)
return MAX_DIST;
}
}
// Une fois kammelna m'el raymarching loop, n'returniew MAX_DIST
return MAX_DIST;
}
Binnesba lel "sceneSDF", heya juste function elli t'representi el scene mteƐna.
El scene tnajem tkoun 1 object wela barcha objects. Kol object howa formule tmathel des distances.
Kol objet yaƐtina distance(float) binnesba l'position eli naƐaddiwhelou.
Example bech n'ajoutiew sphere lel scene:
float sceneSDF (vec3 p)
{
return sdSphere (p);
}
Fama ħaja essemha "SDF operators" eli heya tkhallina nzidou akthar men object weħed lel scene.
Bech nfasrouhom baƐd ama tnajem telq̈a el objects w'el operators el'kol
houni.
Hedhi el Sphere function:
float sdSphere (vec3 p)
{
return length (p) - 1.;
}
Kobr el sphere "1.0" f'hal example.
Ken nħebbou n'akhtarou el size, nƐaddiwah comme parameter, kima hak:
float sdSphere (vec3 p, float size)
{
return length (p) - size;
}
Tnajjem tenzel Ɛal taswira ken t'ħeb e'testi w tabaddel el code.
El transform heya el transformation eli bech tsiir l'el objet proportionellement l'el scene.
YaƐni kifeh nħarkou el objet mteƐna. Généralement el transform fiha 3 modifications ysiirou Ɛal objet:
- Location (el position mtaƐ l'objet f'el scene)
- Rotation
- Scale (Kobr el object f'el scene)
Généralement, ki testaƐmel engine, bech telq̈a el transform en tant que structure men 3 vectors.
Kol vector fih 3 values: Location(x, y, z)
, Rotation(x, y ,z)
, Scale(x, y, z)
.
F'el 3D famma 3 axes, donc:
- Location: yħot el object yetzaħlaq̈ Ɛla axe (axis) specifique.
- Rotation: yħot el object ydour Ɛla axe (axis) specifique.
- Scale: yħot el object yekber ħasb axe (axis) specifique.
Binnesba l'el location, kima fassarna, heya Ɛibara Ɛla offset l'el position actuelle mtaƐ el sphere.
Donc bech nħarkou el sphere, yelzem nzidou wela ennaq̈sou values m'el position mtaƐ el ray.
float sceneSDF (vec3 p)
{
// Nħadhrou el offset mteƐna. F'el cas hedha, nzaħlq̈ouha Ɛal Y-axis
vec3 offsetPos = vec3 (0.0, cos (iTime), 0.0);
p = p + offsetPos;
return sdSphere (p);
}
l'el rotation, yosƐeb chwayya bech nchoufouha puisque el sphere Ɛand'ha nafs el mandhar m'el jihét el kol.
Donc ennajmou nestaƐmlou texture uniform, win naƐtiw l'el shader texture, w baƐd, nestaƐmlou el texture bech nbadlou el shape mtaƐ el sphere.
float sceneSDF(vec3 p)
{
// Nzidou texture fel iChannel0, w nsampliwha b' XY mtaƐ position el ray
vec3 textureMask = texture (iChannel0, p.xy).xyz;
// Nraq̈Ɛouh chwaya (ennaq̈sou f'el intensity w n'invertiw el mask b technique "1-x")
textureMask = 1.0 - (textureMask * 0.5);
return sdSphere(p * textureMask);
}
Taw ki ennajmou nchoufou el objet mteƐna wadhaħ men kol el jihét, ennajmou ndawrouh.
Houwa sħiih todhor el rotation eli heyya juste 3 values, ama f'el ħq̈iiq̈a, hiiya matrice(matrix) 3 par 3 eli nedhrbouha f'el position mteƐna (position mtaƐ el ray houni).
Matkhafech el chay easy peasy, tabbaƐ mƐaya!
Bech ennajmou ndawrou el objet mteƐna Ɛal X (ħasb angle nƐaddiwah f'el parameter), il suffit ntalƐou el matrix, w nedhrbouha:
mat3 rotateX (float a)
{
float sa = sin (a);
float ca = cos (a);
return mat3 (vec3 (1., .0, .0), vec3 (.0, ca, sa), vec3 (.0, -sa, ca));
}
Binnesba l'el Y:
mat3 rotateY (float a)
{
float sa = sin (a);
float ca = cos (a);
return mat3 (vec3 (ca, .0, sa), vec3 (.0, 1., .0), vec3 (-sa, .0, ca));
}
Wa akhiiran, el Z:
mat3 rotateZ (float a)
{
float sa = sin (a);
float ca = cos (a);
return mat3 (vec3 (ca, sa, .0), vec3 (-sa, ca, .0), vec3 (.0, .0, 1.));
}
Taw njarbou nedhrbou waħda fihom f'el p
w nchoufou el resultat:
// Nħadhrou el rotation matrix (ndawrouha ħasb el waq̈t)
mat3 rotationMatrix = rotateY (iTime);
// Nedhrbou el rotation matrix f'el p
p = p * rotationMatrix;
(Kima el Ɛada, tnajjem tenzel Ɛal code)
Finally, el takbiir w'el tasghiir.
Fi engine Ɛadi, l'implementation mtaƐ el scale sehla: Juste nbadlou values f'el transform matrix.
Par contre, f'el SDF, yelzem naq̈smou p / scale
w nedhrbou el sdf kemla f'el scale
:
// Nħottou el scale yetzed w yonq̈os ħasb el waq̈t
float scale = abs (sin (iTime));
// Nedhrbou f'el ray position w naq̈smou
return sdSphere (p / scale) * scale;
Hedhi el implementation de base mteƐ l'SDF. Taw, l'étape el jéya, bech nebniw fouq̈ minha bech nsawrou el scene mteƐna.
El page el jéya (SDF shading) twarrik kifeh tlawwén el sphere.
Pagèt okhrin: SDF - Shading | Shaders | Home