Archive: OK ---- I GIVE UP! I'll take my chances and ask...


9th November 2005 22:24 UTC

OK ---- I GIVE UP! I'll take my chances and ask...
For a really long time, I've been looking at what AVSers like UnConeD, EL-VIS, Tuggummi, et al. do and ask myself the simple question:


:eek:HOW DO THEY DO IT???:eek:


Now before you start the ruthless screaming and puffing and fury, hear me out. I want no details (cuz I've seen the charred remains of thus who foolishly did). I want to know what level of learning is involved in this line of expertise. Is it higher-order calculus, vector math, advanced programming, or just long hours spent at a computer screen??? Betray to us suckers the true road to mastry.


9th November 2005 22:46 UTC

I personally learned how to do it by spending long hours in front of the computer, reading how everything works, looking at everyone else's code. Sooner or later, things just clicked and began to make sense.

Most recently, I've begun taking higher-order math classes, and this has helped a little bit. Sure, if you want to create something like UnConeD's "Fiber Optics" or his Chmutov, it certainly helps to know what the hell you're trying to make, and how to draw it. But for my money, avs doesn't even really require much math skills. It's just understanding avs code.

For me, learning avs simply requires time.


10th November 2005 00:41 UTC

Ok, might I ask, are you what level of education are you in? I'm in high school and I've been messing around with AVS for about a year. I still don't get much, though.


10th November 2005 03:56 UTC

most of the effects i have seen in avs are well known computer graphics techniqes that have been adapted to avs. most good computer graphics techniques boil down to mathematics though.

for example, i beleve that unconed's fiber optics preset was based on ray tracing, which is itself based on the physical model of light but needs some reasonably complicated maths to make it work right.

i think a lot of presets are made with just messing about though, trying to get cirtain effects but ending up with something diffirent.


10th November 2005 04:00 UTC

I'm in my second year of college, currently taking pre-calculus algebra, and am signed up to the end of the math courses this college offers, which is calculus 3, which is multiple independent variables, partial derivatives, multiple integrations and vector analysis.

I don't know, or even care, if this will help me in my avs hobby. I'm taking these classes because I not only enjoy math, but it will hopefully further me in my career later in life.


10th November 2005 04:13 UTC

I'm a junior in high school, and I have absolutely no knowledge of calc, slight knowledge of trig. Your opinion is kinda comforting, but I figured that the more complex presets used such maths.

Another important aspect that I have noticed in lots of peoples' presets is the use of slick render and effect combinations. There is such a diversity of effects that they achieve that there has to be a basic understanding of how the image is drawn on the screen. This could also be worth consideration...


10th November 2005 04:55 UTC

Well again, for me at least, a lot of the slick render and effect combos are just tips and tricks I've picked up along the way by looking at some other presets for inspiration, talking to some other artists in the community (come to #avs on freenode for irc sometime, a lot of the "biggies" hang out there).

If I could recommend one artist, who may not have slick renders, but uses real slick and original effects, is framesofreality. For some of my more stylish and slick presets, it's a lot of experimentation. For any preset where I use effect lists, I try every different combination of input and output blendings. However, as time has progressed, I am pretty certain what will happen when I do this.

Try applying some of the different trans effects, especially in areas where you would not normally think they would work well.

By the way, do you have any presets that I could take a look at? If you're willing, I'll try and remix some of them or spiff them up a little bit, try and give you a few ideas if you would like.


10th November 2005 14:21 UTC

I can't even figure out why something like


r=i*$pi*2 ; d=0.5+v*0.5 ; x=sin(r)*d ; y=cos(r)*d


Produces a oscilliscope ring, i just know that it does.

This is the result of about 6 years of experimenting with avs. (6 years coming this christmas to be exact, so were not only celebrating Jesus Christs birth, Santa Claus or Hanuka or whatever weird thing you worship, but my AVS career's birth aswell :p)

10th November 2005 14:28 UTC

There certainly is no shortage of documantation to guide one along the way, and then there are always the presets ehemselves one can disassemble for insight. Thing is that even if one does not "get it" right off, 3, 6, 9, days, weeks, months (perhaps years) on down the line, things will come into focus... that's life, not just AVS presets. Good luck and have fun.


10th November 2005 18:49 UTC

Yeah it really depends on what type of stuff you're looking to do. The real high tech stuff is usually college level math and computer science. For instance, if you're looking at the famous Chmutov presets then you're looking at knowledge of basic raytracing setup (computer graphics course), approximation methods (a numerical methods course), and gradients (multidimensional calculus course) to say the least. On top of that years of experience with AVS and probably plenty of other related fields help. Of course you could learn this stuff on your free time, but you're not gonna get the same well rounded knowledge of the related topics which could be used in other presets.

If you want to do "tech" stuff then you're looking at a lot of math and a lot of programming... There's just no way around it.


10th November 2005 21:24 UTC

everyone says the math is really bad. but if you have an aptitude for it you can learn the neccessary pieces as you go along.

raytracing is no more complicated than equation solving like ax+b=0 or ax^2+bx+c=0 etc.. which you have probably learned some of. and vectors are very simple too, they just dont get taught early because they arent useful for school maths.

a lot of the time just knowing something works is good enough, and understanding isnt always needed. a lot of the best stuff comes from random experimentation. a lot of the 'tech' stuff even boils down to a pile of hacks.

good luck with this...


10th November 2005 22:47 UTC

Originally posted by Tuggummi
I can't even figure out why something like

r=i*$pi*2 ; d=0.5+v*0.5 ; x=sin(r)*d ; y=cos(r)*d


Produces a oscilliscope ring, i just know that it does.

As far as that's concerned, a parametric circle is a compilation of every possible right triangle. See here:

Circle - Sine Animation

Ok, so its scetchy, but you get the image. Draw a circle around the origin and draw a line to any point on the circle from the origin. EGAD!!! A right triangle!!! Trig explains the rest.

11th November 2005 00:33 UTC

raytracing no more hard than equasion solving? o_O i realise that raytracing is basically equasion solving but its like compairing pushing a pebble over a slight bump in the road to that greek guy who was forever pushing that bolder up the mountin. maths can be a lot like that if you arn't mathematically minded.


11th November 2005 02:52 UTC

well you really aren't doing anything more than solving for the intersection of a line and a sphere. It really is basic algebra.


11th November 2005 11:57 UTC

Originally posted by JFASI
Trig explains the rest.
I don't understand Trig.

11th November 2005 14:21 UTC

Originally posted by UIUC85
well you really aren't doing anything more than solving for the intersection of a line and a sphere. It really is basic algebra.

Huh? I was thinking more like a plane and a sphere.

11th November 2005 21:19 UTC

what's also useful is to take an interesting effect, not too easy, but not brain-breaking difficult either, rip it to shreds in notepad or something and start by watching how it changes when you alter a variable, a sine to a cosine or anything. Later on, you'll learn why it happens by experience. (note that I'm saying ripping apart, not ripping the preset to claim you coded it, but let that be obvious)

Also, browsing math websites can also give you some ideas (or totally wreck your brain)


11th November 2005 22:04 UTC

Still, dissecting is tough, since it's much easier to build a system than to crack it open.

What good math websites are there?
Apart from mathworld, I mean.


11th November 2005 22:13 UTC

Quote:


12th November 2005 13:53 UTC

Cool


12th November 2005 17:20 UTC

I usually just google


12th November 2005 18:24 UTC

Google?

I just flip through the big guys' works...

Which I need some more of. Is there any place other than Winamp.com that everyone posts their stuff? Because this they post here once in a blue moon.

Besides, they're cool to watch.

By the way, what signature plugin do you use to show your songs? I can't find any that actually work.


12th November 2005 18:32 UTC

For more presets go to: www.deviantart.com
You'll definitely find more good stuff there!


13th November 2005 01:44 UTC

The thing that sucks about AVS is its learning curve. If you open up a Wacko pack or Extra Dimension, there's no way you're going to understand all the crap that's going on in the equations. In fact, I rarely know what's going on in my own code, let alone anyone else's. If you're trying to emulate your effects to get to the point where the big guys are, don't try emulating their presets directly. The most successful AVS artists take some time to develop. I'd like to think that their skills are primed outside the world of AVS. If you can't imagine how to spot all the points of a 3-d sphere, perhaps you should concern yourself with making a good circle. Hopefully, you'll develop an understanding for all the code that goes into some of the really high-end stuff. But this takes experience.

And that's just if you want to be a copy-cat. Being an original AVS artist is going to take lots and lots of practice figuring out what you want to make. So much trial and error will be involved, you'll either love it or hate it (most of us do both). It's very easy to conceptualize "I want to make a preset just like Tugg/UCD." Or "Amphirion/Zamuz is my idol." When you start thinking on the level of "I want to make a really cool preset that reminds me of this poster I saw" you'll be in another realm altogether. Best of luck to you.


13th November 2005 05:02 UTC

Good post Nemo! Might I add that AVS isn't all about equations too. There are a lot of amazing things you can do just by knowing how to use the filters right. And even if you do know equations like nobody's business, that doesn't mean you can make an preset that actually looks good. There are many artists who are successful just because they know how to add the right touch with effects not equations. I mean look at the bulk of Tuggummi's presets. He even said in this post he doesn't understand tech stuff, but he's got more style in one preset than I could muster in a year. That's skill.


14th November 2005 02:57 UTC

Yeah, I see that in a lot of presets. Sometimes, if I get the perfect equation going, it still doesn't look quite right for me. It's still missing <<something>>. I totally agree.

Sometimes when I see a cool effect in an ad or on TV, I have a rough idea how to replicate it, but I still can't the finer points right, and the whole project falls apart.


16th November 2005 21:01 UTC

Originally posted by NemoOrange
... When you start thinking on the level of "I want to make a really cool preset that reminds me of this poster I saw" ...
90% of the presets I make come from that sort of reasoning, posters, cool effects on TV shows and films etc..

16th November 2005 21:06 UTC

Originally posted by PAK-9
TV shows and films etc..
Must... resist... pr0n... joke...

16th November 2005 22:30 UTC

Eeeeeeeew...

I still can't take my ideas and turn them into a cool looking effect. I just can't. Needless to say, I have ideas, but...


16th November 2005 23:04 UTC

I just remembered a great preset that used no fancy math at all, but was still awesome. mir's Hyper*******ce. Tres awesome.


25th November 2005 12:04 UTC

Stuff like that MAYBE looks cool, but usually the artist has got no idea what he is doing. Using stuff because it looks nice is a lot less effective than making something because it does exactly what you want.

You dont need fancy math to make stuff look good yourself either. In fact that maths for constructing specific stuff is usually the most trivial sort, except in the case of DM.

I would iterate a list of tips for constructing superscopes.... but I have done it before enough times...

The 'fancy' stuff like rotation matrices and raytracing, are only half understood by most who use them. So don't feel down if you don't understand them properly or at all, neither do Tuggummi or PAK-9 or most of the rest... and they still make a ton of awesome presets.


25th November 2005 17:42 UTC

Originally posted by jheriko
Stuff like that MAYBE looks cool, but usually the artist has got no idea what he is doing. Using stuff because it looks nice is a lot less effective than making something because it does exactly what you want.

You dont need fancy math to make stuff look good yourself either. In fact that maths for constructing specific stuff is usually the most trivial sort, except in the case of DM.

I would iterate a list of tips for constructing superscopes.... but I have done it before enough times...

The 'fancy' stuff like rotation matrices and raytracing, are only half understood by most who use them. So don't feel down if you don't understand them properly or at all, neither do Tuggummi or PAK-9 or most of the rest... and they still make a ton of awesome presets.
Hey! I understand fancy stuff!

25th November 2005 18:55 UTC

Jheriko is right...
I can do fancy iterative (whittaker/newton)-raytracing,
but i cant figure out how to do raytracing the way Pak-9 does.
And Pak-9 doesnt like/understand the raytracing i do.


25th November 2005 23:06 UTC

I know all the code that I'm using when it comes to SSC's.
But most of it I learned from ripping the sourcecodes from El-Vis en Nic01 to notepad, and then strip it down to the bit to figure them out. Then I tried to re-assemble them using my own variable names, shape, rotation, movement, colors etc.

Also, I can't create the main core of it by heart though, I usually use some of my (rather messy) templates.

The next thing is to know how to use the 'basic' modules of AVS (i.e. don't use invert and clear every frame at the same time). Old doesn't necessarily mean they're outdated. Experimentate and find out how to use a Water Bump and not make it kill the preset for instance.
Also, don't hesitate to experimentate. Before I created my first 3D SSC, I had created at least 50-60 not-working versions. Set a goal and go for it, one step at a time.


26th November 2005 01:37 UTC

I could never get the craxy DM work that some do, since I'm better with a SSC or a Texer than with something like a DM. I guess some people are better with some bits than others.


30th November 2005 08:05 UTC

Originally posted by JFASI
I'm better with a SSC or a Texer than with something like a DM.
SSC and Texer are naturally easier since you position points naturally. DM is hard becasuse you have to manipulate texture co-ordinates... which is pretty unnatural. Its like tying a load of stones to a flexible sheet in a grid, then deciding how far you have to move each stone to warp the sheet so it looks how you want. I advise ignoring it to start with if its not easy for you to work with...

30th November 2005 22:24 UTC

Ok, the issue comes down to being able to find ways to tye stones to a map. It's so abstract, and all or most of the guides I have read only scratch the surface, and leave all the discovering to the reader, not even like the good discovery, where you invent methods and such, but you have to figure out what every-single-thing does.


1st December 2005 11:30 UTC

Originally posted by JFASI
Ok, the issue comes down to being able to find ways to tye stones to a map. It's so abstract, and all or most of the guides I have read only scratch the surface, and leave all the discovering to the reader, not even like the good discovery, where you invent methods and such, but you have to figure out what every-single-thing does.
Its not hard to work out what DM does. If you look at any of the examples or experiment with simple stuff like x=x+1 x=x*2 etc... then you can work it out with out much head scratching. It basically allows you to slide/zoom/spin/warp the image depending on how each grid point's code evaluates.

There are plenty of guides for DMS floating around, i think very few of them really explain why it works... but they are good enough. PAK-9's programming guide has an excellent section on DM which describes how it functions and provides plenty of example code...

1st December 2005 16:20 UTC

If you have any specific examples that you've been trying to figure out, maybe we could help you with those.


1st December 2005 23:23 UTC

I'm fighting to resist the temptation to place UnconeD's famous line of brand name mazes...


2nd December 2005 00:51 UTC

So you're interested in 3D DM's then? I can help with that probably better than I can with 2D ones.


2nd December 2005 01:47 UTC

Really? That's very good news, since I kinda sorta get what the 2d Dm's are all about.


2nd December 2005 16:17 UTC

Well let me know what you need and I'll gladly explain somethings as best as I can.


2nd December 2005 21:55 UTC

Ok, I'm not quite sure if it's 3D or otherwise, but the nice metal blob effects that so many use:

Init

c=6.1 ; sza=0.15 ; r=0.9 ; szb=1.5 ;

Frame

asp=reg03 ; sec=reg00 ; vol=reg01 ; f1=1-sec*(0.5+vol*0.1) ;
spd=vol*sec*0.03 ;

g1=g1*0.9+getspec(0.05,0.5,0) ; g2=g2*0.9+getspec(0.1,0.5,0) ;
g3=g3*0.9+getspec(0.15,0.5,0) ; g4=g4*0.9+getspec(0.2,0.5,0) ;
g5=g5*0.9+getspec(0.25,0.5,0) ; g6=g6*0.9+getspec(0.3,0.5,0) ;
sz1=szb-g1*sza ; sz2=szb-g2*sza ; sz3=szb-g3*sza ;
sz4=szb-g4*sza ; sz5=szb-g5*sza ; sz6=szb-g6*sza ;

xts1=xts1*f1 ; yts1=yts1*f1 ; xts2=xts2*f1 ; yts2=yts2*f1 ;
xts3=xts3*f1 ; yts3=yts3*f1 ; xts4=xts4*f1 ; yts4=yts4*f1 ;
xts5=xts5*f1 ; yts5=yts5*f1 ; xts6=xts6*f1 ; yts6=yts6*f1 ;
xt1=xt1+xts1 ; yt1=yt1+yts1 ; xt2=xt2+xts2 ; yt2=yt2+yts2 ;
xt3=xt3+xts3 ; yt3=yt3+yts3 ; xt4=xt4+xts4 ; yt4=yt4+yts4 ;
xt5=xt5+xts5 ; yt5=yt5+yts5 ; xt6=xt6+xts6 ; yt6=yt6+yts6 ;
sxt1=sin(xt1)*r ; syt1=sin(yt1)*r ; sxt2=sin(xt2)*r ; syt2=sin(yt2)*r ;
sxt3=sin(xt3)*r ; syt3=sin(yt3)*r ; sxt4=sin(xt4)*r ; syt4=sin(yt4)*r ;
sxt5=sin(xt5)*r ; syt5=sin(yt5)*r ; sxt6=sin(xt6)*r ; syt6=sin(yt6)*r ;

Beat

xts1=(rand(131)-75)*spd ; yts1=(rand(131)-75)*spd ;
xts2=(rand(131)-75)*spd ; yts2=(rand(131)-75)*spd ;
xts3=(rand(131)-75)*spd ; yts3=(rand(131)-75)*spd ;
xts4=(rand(131)-75)*spd ; yts4=(rand(131)-75)*spd ;
xts5=(rand(131)-75)*spd ; yts5=(rand(131)-75)*spd ;
xts6=(rand(131)-75)*spd ; yts6=(rand(131)-75)*spd ;

Pixel

ax1=x*asp+sxt1 ; ay1=y+syt1 ; ad1=sqrt(sqr(ax1)+sqr(ay1))*sz1 ;
ax2=x*asp+sxt2 ; ay2=y+syt2 ; ad2=sqrt(sqr(ax2)+sqr(ay2))*sz2 ;
ax3=x*asp+sxt3 ; ay3=y+syt3 ; ad3=sqrt(sqr(ax3)+sqr(ay3))*sz3 ;
ax4=x*asp+sxt4 ; ay4=y+syt4 ; ad4=sqrt(sqr(ax4)+sqr(ay4))*sz4 ;
ax5=x*asp+sxt5 ; ay5=y+syt5 ; ad5=sqrt(sqr(ax5)+sqr(ay5))*sz5 ;
ax6=x*asp+sxt6 ; ay6=y+syt6 ; ad6=sqrt(sqr(ax6)+sqr(ay6))*sz6 ;
alpha=-ad1*ad2*ad3*ad4*ad5*ad6*0.75+1 ;

This is an effect that I see all the time. It comes from the below attachment (many thanks to Tuggummi for such a sweet pack):


3rd December 2005 01:51 UTC

Eeh, I wouldn't take my code as a example for study...

Im sure PAK-9 can tell you why :rolleyes:


3rd December 2005 03:57 UTC

Yeah this example of metaballs isn't 3D though unconed did do a 3D metaballs preset. Basically metaballs is a lot like simulating electrical charges. So in concept you create several points that will produce a charge dependent on the distance to the origin of the charge. No matter how far the point being calculated is away from the center of the charge, there is still some amount of charge there. Then when you add in multiple charges you'll end up with a net charge from multiple charges.

Now for some mathy stuff. The equation of a circle (your charge radiates in a circle) is x^2+y^2=r^2. Now if you know the equation for the charge of an electron, 1/r^2, you can plug in the circle equation to get 1/(x^2+y^2)! Yay!

So now how do we make that idea useful. Well we can evaluate this equation for each point on the screen (or DM grid). So assume (x0,y0) is the origin of your point and (x,y) is the point you are evaluating. Simply take the difference and plug it in. 1/((x-x0)^2+(y-y0)^2)

Now if you want to do this for multiple charges you just evaluate the same point for all the charges and then add them together. You MIGHT need a scalar for this depending on how big of blobs you want. Any questions?


3rd December 2005 13:15 UTC

A very good explanation with the charges! I never considered metablobs this way but it's really logic!

btw: for a deeper insight in electrical charges and the resulting potential see the Coulomb's Law ;)


3rd December 2005 13:40 UTC

Originally posted by Tuggummi
Eeh, I wouldn't take my code as a example for study...

Im sure PAK-9 can tell you why :rolleyes:
nothing wrong with that code...

3rd December 2005 13:43 UTC

Wow. That really explains a lot. Now can someone take a SSC and make a mass of points, like I see some do, or a Texer and make them dance around and fuse, or, like Tug does it, a DM that in some strange way (I still find DM a tad cryptic) make the image act like blobs?


3rd December 2005 13:48 UTC

TUG-MAGIC-SUPER-VOODOO-CODE!

It makes, absolutlynosensewhatsoever, but in some miraculous way it works!


3rd December 2005 15:32 UTC

I think its pretty slick, nut I think I might lose that impression with time, if you insist...

Anyway, the mose I look at it, the more I realize how the thing works.

Now for something that's really nuts, the smooth watery turbulent effect.

Init

--

Frame

x1=x1*0.9+x1a*1.1;
y1=y1*0.9+y1a*1.1;
x2=x2*0.9+x2a*1.1;
y2=y2*0.9+y2a*1.1;
s=s*0.9+s1*0.9;
c=c+0.02

Beat

x1a=(rand(1000)/5500)*2+x1a*0.5;
y1a=(rand(1000)/5500)*2+y1a*0.5;
x2a=(rand(1000)/5500)*2+x2a*0.5;
y2a=(rand(1000)/5500)*2+y2a*0.5;
s1=getspec(0,1,0)*0.2;

Pixel

x=x+sin(y*$PI+c-x1+s-cos(y*cos(c+s-y2)+x*sin(c+s-x2))-sin(r)*d)*(s*0.08);
y=y+cos(x*$PI+c-y1+s-sin(x*sin(c+s-x2)+y*cos(c+s-y2))-cos(r)*d)*(s*0.08);
d=sqrt(sqr(x)+sqr(y));
r=atan2(y,x)+cos(d*s+c)*0.02;
x=cos(r)*d*1.02;
y=sin(r)*d*1.02


3rd December 2005 15:35 UTC

Sorry this is coming from WFC1:


3rd December 2005 18:36 UTC

Ok so I'll try my best at parsing through that code. A lot of the times it's hard to figure out what's really math and what's just some random handwaving Tug-ish magic. And I can't actually look at the preset cause I'm working but I just imagine that it's the usual swirls.

Frame:
This section is just interpolating between old and new points. (x1,y1) and (x2,y2) is your old points and (x1a,y1a) and (x2a,y2a) are your destination points. .9 and 1.1 are pretty much percentages though in this case they don't exactly add up to 1. But if you try this with a scope you'll notice that the points don't move in linear time. It's not always the same increment. Interpolating is used (this may not be all reasons, but they are good ones) because it's easy to implement as seen, and it's a lot smoother than linear movement. The c variable I'm just assuming is for added rotation on the trig functions. And the s variable is to get in a little beat detection in the swirl too (I think).

Beat:
This section is where (x1a,y1a) and (x2a,y2a) are chosen. So these points are going to be the destination points. s1 is going to be your destination s.

Pixel:
Ok so this part looks little hand-wavey magic to me. There might be more math behind it than I'm aware of though. Sometimes in order to simulate some randomness in the waves or swirls, you can throw in a bunch of sines and cosines and wierd ways to get more randomness. Like I said, it's kinda just mathemagic to get the right effect. The line where they set d is to find the distance to the origin. Then they set r (radius) as the angle from the origin (atan2(y,x)) and then add on what looks like a bit more mathemagic.

Ok so that's as much about this code as I can sift through. If someone else might enlighten us on the few parts that I don't really understand that'd rock. Anymore? You haven't posted any 3D problems. ;) I think I said this before but I'm better at 3D if you have anything from that neck of the woods. Basic raytracing? Approximation methods for quartics or other shapes? Other crazy methods (ie the one I used to make the 3D shape in my icon)?


3rd December 2005 20:17 UTC

Oh yeah and about the metaballs stuff. I know you see everyone doing blobs from point charges, but really nothing is stopping you from doing lines or other crazy shapes besides a bit of algebra and trig. You could do metacircles or metalines or whatever. I guess I'll explain how I would imagine someone going about doing this. So before we had x^2+y^2=r^2 right? Well is we take the square root of both sides of the equation we get sqrt(x^2+y^2)=r. So you might notice now that r just is the distance to the point. Well this is where I think we have some room to roam in the world of math. The basic concept is that if you can find the distance between your point and the closest point on the shape, then you have your r and you plug it right back in to the equation 1/r^2. (bare with me cause I'm winging this as best I can) So say we want to do circles. The equations for parametric equations for variable size and position are {x0+r1*cos(t),y0+r1*sin(t)}. Now for this we would know (x0,y0} cause we would specify where the circle would be just like the points. r1 would also be specified. This leaves t as the variable. Now we want to find the distance between those equations and our point (x,y) so we can plug and chug. So we need to solve for t! If you just set x=x0+r1*cos(t) and bring some stuff to the other side you get (x-x0)/r1=cos(t) and (y-y0)/r1=sin(t). Now the problem I see right now is that if (x,y) isn't exactly on the circle or at least within r1 of the (x0,y0) we're gonna run into problems taking the acos() and asin(). But if we think about our circle, if we normalize our distance to be equal to 1 then we we'll get the same value of t!

If you understood that last little leap skip this paragraph cause I'm just gonna explain it better. So we're looking for t. acos() and asin() work for the interval [-1,1] because thats all cos() and sin() map to. So what we need to do is shrink this value down but retain the same angle so as not to mess with t. Make sense?

Ok so lets normalize! We need to divide by the distance to the origin so we get l=sqrt((x-x0)^2+(y-y0)^2). Then we just divide the distance (x-x0) and (y-y0) by l to normalize it! So we get cos(t)=(x-x0)/(l*r1) and sin(t)=(y-y0)/(l*r1). Now we can take the acos() or asin() of both sides to get t=acos((x-x0)/(l*r1)) and t=asin((y-y0)/(l*r1). You could use either one of these to get t and then plug this back into your parametric equations x1=x0+r1*cos(t) and y1=y0+r1*sin(t) etc to get the point on the circle closest to your point. Then use the distance formula r=sqrt((x-x1)^2+(y-y1)^2 and plug it into the original 1/r^2 equation! Rock! So that's a basic parametric curve implementation. I showed this method just so you can see the work with a parametric curve so you can try other ones and maybe know what you're doing.

However (for fun and efficiency), we can actually the do the above example a lot faster. t is really just the angle! So we know that the slope of the line from our point to the origin is just (y-y0)/(x-x0)=tan(t) right? Solve for t and you can just do atan2(y-y0,x-x0)=t which is better than regular atan() anyways. Now you have t so you can plug and chug like last time. Any questions?

Yeah metaballs (though they look nice) are over done so maybe some people can make some new blob objects after this?? Anyone?


4th December 2005 00:00 UTC

Ok, if you want 3D dm's, UnconeD's ZeroGMaze is really what I wanted to decypher.

Init

t=0;rx=1.57;ry=1.57;rx=0;ry=0;rz=0;rxo=0;ryo=0;rzo=0;rxt=0;ryt=0;rzt=0;

Frame

t=t+0.2;
rx=rx+rxo-0.03*cos(t/9)*cos(t/20)*sin(sin(t/9));
ry=ry+ryo+0.03*sin(t/10)*cos(t/22)*sin(cos(t/31));
rz=rz+rzo+0.03;
cx=cos(rx);sx=sin(rx);cy=cos(ry);sy=sin(ry);cz=cos(rz);sz=sin(rz);
rxo=(rxo+rxt)*.5;
ryo=(ryo+ryt)*.5;
rzo=(rzo+rzt)*.5;
ox=sin(t*.5)*.5;
oy=sin(t*.53)*.5;
oz=sin(t*.57)*.5;

Beat

rxt=(rand(80)/320)*sign(-rxt);
ryt=(rand(80)/320)*sign(-ryt);
rzt=(rand(80)/320)-0.125;

Pixel

x=sin(r)*d;y=-cos(r)*d;
dx=x;dy=y;dz=0.6;
dx1=dx*cz-dy*sz;
dy1=dx*sz+dy*cz;
dy2=dy1*cx-dz*sx;
dz2=dy1*sx+dz*cx;
dx3=dx1*cy-dz2*sy;
dz3=dx1*sy+dz2*cy;
k1=abs((-1-oy)/dy2);
k1=if(below(k1*dy2,0),abs((1-oy)/dy2),k1);
k2=abs((-1-ox)/dx3);
k2=if(below(k2*dx3,0),abs((1-ox)/dx3),k2);
k3=abs((-1-oz)/dz3);
k3=if(below(k3*dz3,0),abs((1-oz)/dz3),k3);
k=min(min(max(k1,k2),max(k2,k3)),max(k1,k3));
ix=dx3*k-ox;iy=dy2*k-oy;iz=dz3*k-oz;
x=if(equal(k,k1),-ix,if(equal(k,k2),-iy,-ix));
y=if(equal(k,k1),iz,if(equal(k,k2),iz,iy));
ix=ix+ox;iy=iy+oy;iz=iz+oz;
d=sqrt(ix*ix+iy*iy+iz*iz);
alpha=2/d-0.4;
x=asin(sin(x*2.7))*.5;
y=asin(sin(y*2.7))*.5;
alpha=if(above(alpha,1),1,if(below(alpha,0),0,alpha));




What I realize that most 3D DMs do is take a texer or an image that resembles blur an syncronizing this with the DM. (I know this because I screwed around :D) I'm expecting a lot of the DM to be just that.


4th December 2005 17:40 UTC

Ok well I'm not quite sure I'm capable of making it through all of his code. But I'll give it a try and if I can't figure out exactly what's going on I'll just explain the concept.

So I take it you're still a little confused about DM's. The best way I can explain it is, a dynamic movement moves the screen dynamically. Haha, ok so in other words you can shift, skew, rotate, scale, and a lot of other things with DM. All you do to make the DM do whatever you want is take the coordinates you are given, and set x and y to the coordinates of the texture you want. So in UnConeD's ZeroGMaze, he's just finding the new texture coordinates for each (x,y) point on the screen.

Ok so code:

Init:
Just reseting variables.

Frame:
This part is just setting up the camera movement and rotation. Note the cx,cy,cz and sx,sy,sz variables. These are used for 3D rotation. The rest of this jargon is just UnConeD's camera work which I can't really pick through. The ox,oy,oz is the actually position of the camera and the rest is rotation.

Beat:
This is adding beat detection to the rotations and movements of the camera. You can see they are added up in the frame section.

Pixel:
Ok so here's the fun part. This is actually where we start raytracing! So the idea of raytracing is just like it sounds. Instead of light coming from a light source and bouncing into your eyes, you trace all the needed light rays out from your eyes to the objects and light sources. So we have to setup rays that goes from our camera, through each point we are working with. That's what he does with the first too lines of code. So we define our lines with these equations: x=ox+dx*k; y=oy+dy*k; z=ox+dz*k; where (ox,oy,oz) is our camera's position, (dx,dy,dz) is the vector from the camera, to the cooresponding point on the screen we are working with, and k is a variable scalar that we need to find. Our task right now is to find the specific value of k, where our line defined by those equation's above , intersects our shape. So since we already setup the camera in the frame section the vector setup is next. We want our vector to be from the camera to the point on the screen we are working with. Remember that vectors contain nothing about position. Just speed and direction. You'll notice if you take out the first line of code, the rendering still works without it. So for our vector, we can just say that the dx and dy values just equal the point on the screen. Then dz can just be set depending on how you want your view to look like. Try variable sizes of dz!

Ok so we setup or vector and camera. Now we rotate the camera. This can be accomplished by just rotating the vectors since the vectors really define our field of view anyways. That's what lines 3-8 are doing. You can look up 3D rotation on TONS of sites so I won't explain it here.

Now we have the line exactly how we want it so it's time to find where our line intersects our object. The shape UnConeD is using is actually 6 planes. To be more specific the planes are defined as: x=-1; x=1; y=-1; y=1; z=-1; z=1; so we want to find where our shape intersects with these planes. Lines 9-14 are doing just that. In order to find the intersection we set our equations for our line equal to the equation for the planes. -1=ox+dx*k; 1=ox+dx*k; -1=oy+dy*k; 1=oy+dy*k; -1=oz+dz*k; -1=oz+dz*k; then we solve for our unknown k and get: (-1-ox)/dx=k; (1-ox)/dx=k; (-1-oy)/dy=k; (1-oy)/dy=k; (-1-oz)/dz=k; (1-oz)/dz=k; Lines 10, 12, and 14 choose which value of k to work with depending on where the intersection was for each set of planes. This is how he combines multiple planes into 1 dm. So once we narrowed all our options for k down to the one we want, we plug it back into our equations for our lines to get the point in 3D space where our line intersects! This value is stored into (ix,iy,iz). We can use this to get our texture coordinates. The next 3 lines are just messing with the texture coordinates a bit. d is set to the distance from the point of intersection to the camera. Then it is used in the alpha blending to blend out the texture if the point is too far from the camera. He does this because if you showed the texture all the way down one of those tunnels, it'd look really ugly and distorted since there's only so many rays headed down there. Try taking out blending and you'll see what I mean.

So that's pretty much the deep, dark, and cryptic workings of that preset. Does that help?


4th December 2005 20:29 UTC

Well, it does, a lot, but I still would not be able to contruct it from scratch... Not that I expected to in the first place, but I get what some of these things are doing, but the nitty gritty still evades me. Any way, could you go over raytracing a bit more detail, cuz I figure that that's probably going to show up in other presets.

Here's another:


Init

dv=3; pfs=.15; pfz=0; pf=0; pbx=0; pby=0; pbz=0; water=0;

Frame

pfx=pfx+pbx; xc=cos(pfx/dv); xs=sin(pfx/dv);
pfy=pfy+pby; yc=cos(pfy/dv); ys=sin(pfy/dv);
pfz=pfz+pbz-(pfz*.1);
pf=pf+pfs;

Beat

pbx=rand(50)/500;
pby=rand(50)/400;
pbz=rand(50)/500-.01;

Pixel

mw=pfz+.6;
x=x/(1.2+y)*mw;
y=y/(1.2+y)*mw;
x1=x*xs-y*xc;
y1=x*xc+y*xs;
x2=y1*yc+x1*ys;
y2=y1*ys-x1*yc;
z1=sqr(y2*y2+sqr(y2+pfz));
z2=max(z1,sqrt(z1+z1))+sqr(z1*sin(xs*.1));
water=if(below(mw,.7),rand(5)/90,0);
z3=z1/z2;
x=x2+(x2*z3)-pf+water;
y=y2+(y2*z3)+water;
alpha=z1/z2+.5;


Coming from Duo


4th December 2005 20:59 UTC

Sorry again...


5th December 2005 01:44 UTC

As far as I can tell this really isn't raytracing at all. It looks to me like it's just a semi 3D skew with rotation and some alpha blending to fake 3D.

I'll explain why I believe it's just a skew. First tip is that he divides (x,y) by (y+1.2) in lines 2-3 of the pixel code. Notice how (y+1.2) is always above 0? Try switching that 1.2 to 1 and you'll see that it gets really ugly at top of the screen. Normally if you were transforming from 3D to 2D you would divide by z. Another hint is that he's only rotating in 2D instead of 3D. Notice in the last preset there were 6 lines for rotation. This only has the 4.

I think I covered raytracing pretty well in the last post. Are there any specifics that you are confused with? I'm more than will to fill in any gaps, but I thought I spelled most of it our pretty clearly the last time except for rotation which is easily googled. Be careful what presets you're looking through. Some may not be straight forward raytracing and it might make you more confused. There are a lot of examples like this one that really aren't raytracing at all and there are many examples that use tricks. For example, in UnConeD's/Jheriko's chmutov preset, an approximation method is used to raytrace the quartic shape. That preset is raytracing, but it's more advanced and not exactly a place to learn basic raytracing from. If we get to that bridge I can help you cross it, but don't worry about that stuff now.


5th December 2005 21:23 UTC

What about the 3D-2D conversion in the 3D SSC's?
I'm wondering how that works...

Init

n=7;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p

Frame

rx=rx+rdx;
ry=ry+rdy;
rz=rz+rdz;

xs=sin(rx/p3);
ys=sin(ry/p3);
zs=sin(rz/p3);

xc=cos(rx/p3);
yc=cos(ry/p3);
zc=cos(rz/p3)

Beat

rdx=rand(3)+1;
rdy=rand(3)+1;
rdz=rand(3)+1

Point

x1=r*sin(p2*i);
y1=0;
z1=r*cos(p2*i);

y2=y1*xc-z1*xs;
z2=y1*xs+z1*xc;
x2=z2*ys+x1*yc;

z3=z2*yc-x1*ys;
x3=x2*zcy2*zs;
y3=y2*zc+x2*zs;

x4=mx+x3;
y4=my+y3;
z4=mz+z3;

x=x4/(1+z4/dst);
y=y4/(1+z4/dst)


6th December 2005 03:43 UTC

I'd like to note that code like this is in just about every tutorial on AVS/superscopes. I'm assuming you looked up those already because of their wide accessability and that you are having problems conceptually. So instead of parsing through this code I'll offer some webpages that can explain all of this better than I can. Here is one great example:
http://www.gamedev.net/reference/art...article795.asp
http://www.gamedev.net/reference/art...article796.asp
http://www.gamedev.net/reference/art...article797.asp
This series offers all the math you need to know to create the preset you posted.


9th December 2005 03:22 UTC

Ok. After a few days of deep thought and study, I do believe I get it. Thanks. How about the sphere DM in UnconeD's Nuke Warfare? I think that could be simpler example of raytracing than any of these other DMs.

Thanks to UnconeD fot the single greatest preset saga ever...You know which one I mean...


9th December 2005 06:22 UTC

Originally posted by UIUC85
This only has the 4.
He rotates in 3d, is just only in two axes. 2d rotation is two lines, one of the pairs used for 3d on its own.

Anyway...

If you think the sphere is going to be simpler, then you don't really get it yet ;)


Here is another explanation... again (I have written this before I am sure...). I'll use unconeds variable name conventions so you can compare to his dms

the idea of raytracing is that you find the distance to the object being 'traced' by projecting a line from the camera, through a point (defined by our frustrum) and out into the world. this sounds horribly abstract... but is pretty simple if we use vectors (read as three numbers in a row, if 'vector' scares you).

we represent our camera position as (ox,oy,oz)

dm uses a grid from 1 to -1 of x and y values which we recycle into our 45 degree view frustrum with lines like this:

dx=x;
dy=y;
dz=1;

these define the directions out of the eye we look into the world for each grid. where 0,0,1 is forward, 1,0,0 is right, 0,1,0 is down etc... usual avs stuff. in a square window this would give us a square pyramid view with a 90 degree fov. you can rotate the frustrum vectors to get the effect of rotating the camera.

we then trace along each of these directions from the camera and find where it intersects the model by using simultaneous equations and some other simple maths. first we use the vector equation for a line to find our 'ray' that goes along the direction from the camera:

(x,y,z)=(ox+dx*k,oy+dy*k,oz+dz*k) (k is a parameter which allows us to 'travel along the ray')

we want to find k where there is an intersection with our geometry. for our example lets use a plane z = 1, then from the above we can see that z = oz+dz*k = 1 and so k = (1-oz)/dz.

now we know how far down the ray the intersection point is we can mangle our texture coordinates to make it look right. the normal way to do this is with a planar projection:

x=ox+dx*k;
y=oy+dy*k;

looks deceptively simple in this case, but here is how it works: everything samples from a 0-1 grid of texture coordinates, with wrap it auto clamps all the x's and y's to 0-1. since z=1 has is x component and y component describing the plane at right angles and ox+dx*k and oy+dy*k are these components in world space, then hopefully you can see that we are simply projecting the existing texture coordinate grid onto the plane (with or without wrap). if we used the plane x = 1 then we would use the y and Z component for this instead, e.g. x=oy+dy*k;y=oz+dz*k; (yes 'y' not 'z')

so drawing a shape with raytracing involves two problems:

finding 'k' which means you need an equation for the shape which you can solve.

finding a suitable texture projection (trivial for planes)

the first is a lot easier than the second, but you cant really do anything that great in terms of applying texture coordinates to most of the more powerful shapes anyway....

hope this helps

9th December 2005 13:38 UTC

Aha. I get it. I'll go mess around with it later...


9th December 2005 21:34 UTC

Good call Jheriko.


11th December 2005 14:34 UTC

I'm sure I posted this before... i must have forgot to submit it :P

But... raytracing and the '3d ssc' are related. If you ignore rotation for a minute and raytrace from a 0,0,0 through any point x1,y1,z1 onto the plane z=1 and find the local plane coordinates (x,y) at this intersection then you get the perpective transformation everyone loves to use. The reason we use z = 1 is that the 0..1 in x and y define the intersection area with a pyramidal view frustrum, in this case it is a 90 degree frustrum since the pyramid has a base length 1 and height 1.

Putting this into effect you get:

ox,oy,oz = 0,0,0
dx,dy,dz = x1,y1,z1
(because the direction from ox,oy,oz to the point x1,y1,z1 = x1-ox,y1-oy,z1-oz)

.: k = 1/z1 (oz=0, from plane equation dz*k+oz = 1)

.: x = x1*k; y = y1*k; (remember ox,oy are 0)

which is just the same as the usual code at the end of a superscope, after the rotation...


this helps understand one of the fundamental differences between ssc and dm presets, which is that when you rotate in a superscope you are normally rotating the point around the origin, when you rotate in a dm you are rotating the view frustrum. this is why rotations and shifts have to be done differently in the superscope to the dm.


11th December 2005 14:41 UTC

Quick detail. Do the points in the DM keep their r and d value when the rectangular coords are turned on, and vice versa?


11th December 2005 17:29 UTC

no. rectangular coordinates only enables x and y. otherwise only d and r are enabled. you need to backwards work them out if you want them, using something like:

x=d*cos(r);
y=d*sin(t);

d=sqrt(sqr(x)+sqr(y);
r=atan2(-y,x);

This is mentioned else where on the forums...


11th December 2005 17:33 UTC

So if rect is turned on, then a pint has only (x,y) and if polar is on then it only has (r,d)?


11th December 2005 18:46 UTC

Right, either (x,y) OR (r,d) are sufficient to exactly define where a point is located in an coordinate system (or: on the screen, in our case).

For more info about coordinates you can read
this wikipedia article.


11th December 2005 18:50 UTC

Ok. Cool. This explains a lot.


11th December 2005 19:12 UTC

Good, cause imo it's essential to understand that polar (r,d) and cartesian (x,y) coordiantes are two different things. But that doesn't mean that you cannot "translate" coordinates between both systems (as Jheriko already mentioned)!!

For example, take a random point: you can either describe it with (r,d) or (x,y) values. If you chose polar you can translate these values into cartesion and vice versa. now the dynamic movement does exactly the same: using either polar or cartesian values.

/sorry if this was too much of a repetition, but i'm in an 'explainatory' mood at,! ;)


11th December 2005 21:50 UTC

Im in a mood at which in i... kick your ass and then... something, oh fuck... im just drunk so that's my mood :D


11th December 2005 22:54 UTC

But that isn't your mood just at the moment. Unfortunately it's the mood you're always in...
...except while you're asleep. :p

Anyway, didn't we agree to restrict this kind of conversation to the bin? :confused:


11th December 2005 23:10 UTC

Oh you're right, as always utterly unpronouncable ^..^ :p

Okay, so what i want to say is that maybe JFASI needs to stop asking so many questions and start learning things by himself, i dunno, but if i were the one giving him tutoring lessons, i would pretty much freak out by now :D


12th December 2005 00:10 UTC

Heeeeeeey...I'm learning. It's not like you give actual lines of code and I use them blindly!


12th December 2005 01:12 UTC

to Tug:
Well it's a good thing I'm not drunk then. :)


12th December 2005 16:18 UTC

Originally posted by JFASI
Heeeeeeey...I'm learning. It's not like you give actual lines of code and I use them blindly!
Yeah, but learning for yourself is much more effective than being taught.

12th December 2005 19:11 UTC

best way of learning is reading plain code


12th December 2005 21:07 UTC

I had no idea what raytracing was about, or how certain DM worked. I came and found out. That's ok.
Now, if I had gone and just asked you for code and used it without any analysis, then it would be different.


12th December 2005 23:05 UTC

Just cause there's a lot about raytracing on here and I was playing around with some stuff I decided to post this up here. Something fun for other tech-heads to look at maybe? Maybe it's been done and I didn't know but I haven't seen it so enjoy.


13th December 2005 01:03 UTC

Originally posted by JFASI
I had no idea what raytracing was about, or how certain DM worked. I came and found out. That's ok.
Now, if I had gone and just asked you for code and used it without any analysis, then it would be different.
Yeah, and if you looked up raytracing on the internet, and then looked up the things you didnt understand on those pages... etc... it would be different again. The information is out there, and if you can't get it for yourself, you will only be able to go as far as other people take you.

13th December 2005 02:20 UTC

True. But don't condemn me for this little foray into explanation...


13th December 2005 03:20 UTC

Any thoughts on my tech preset? (not in terms of it being a music visualization but just a tech demo)


13th December 2005 21:35 UTC

I've never seen anything like this before, and I think it's pretty nifty! :)
I especially like that slick and polished look of it.

review resolution[s]: 172x172 & 344x344


13th December 2005 21:37 UTC

That texture on the sphere is pretty awesome. I like it. Oh, yeah, technical...its cool...


13th December 2005 22:13 UTC

It's indeed cool!
But unfortunately not the first such thing! Jheriko has already made a pretty similar sphere tech-demo preset before:

http://www.deviantart.com/deviation/13908660


13th December 2005 22:33 UTC

Awww...
It's still cool, though.


13th December 2005 23:51 UTC

i made some thing similar to this preset tho, using texture sources to do normal mapping. you can break the lighting down into stuff you can do with blend modes and unique tones etc..

But yeah, using the superscope looks better i think... and its faster for a lot of stuff too


14th December 2005 00:53 UTC

You did a dm that does specular highlights and bump mapping? I'd like to see that. I knew you did the ssc version but I wanted to do it with dm's instead.


Here's another neat tech demo that I whipped up today. Like I said in the comment, I know UnConeD did a reflection dm but this has both objects reflecting and textures on the objects that are reflecting as well. I made a few comments about other things in the preset if you're interested. Good stuff :)


14th December 2005 03:54 UTC

i used the old trick of rendering low res light directions to r,g,b and dotting them with a normal map on the plane.. i lost it a while ago tho, i didnt make it on this computer... it was slow though. didnt have spec, just normal based directional lighting...

besides, dms are ugly. triangle is the way to go.

i dunno how to tell you how bad that reflection preset looks... it just looks bad.


14th December 2005 05:01 UTC

this is how to do a reflection effect...

its not a hack or anything, honest :)


14th December 2005 05:58 UTC

i'm not post pumping honest...


here is what i was talking about with blending stuff together... its hella slow, and doesnt even use a dm, it just assumes the picture is .1 away from the light in z... whatever that means :)

its a bit poo. try enabling the last effect list to see what it looks like when the diffuse stage is blended.. its not perfect either, definately some bug... but i just threw this together so you could see what i mean... its very hax :)


oh.. and i didnt steal these textures, i made them from scratch...

EDIT: updated attachment so its more fixed... altho... no one dled it... yet


14th December 2005 07:47 UTC

That sure is a lot of effects for a emulated bump, but it's resolution fixed, yay! Now someone do that to the original bump effect :)


14th December 2005 07:54 UTC

it is really crap, but the excessive amount of stuff is to do the dot product as blends. since avs can only use positive colors in its buffers i need to work out the positives*positives, positives*negatives and negatives*negatives and add and subtract them from each other to get the result. very slow. it can be optimised... but its a flawed method anyway..

although, it can let you do 3d stuff

updated preset, one with spec hax...

http://jheriko.kicks-ass.net/avs_projects/textures.zip


14th December 2005 23:03 UTC

I know my reflection preset looks like total crap. The purpose was more to have two reflecting objects. I agree that triangle is the way to go when it comes to making solid shapes and what not, but dm's let you have textures. You can't really have textures on objects made from triangles (unless tomylobo threw in (u,v) texture mapping *dream*). Heck if we could speficy 3 colors to blend over the triangle we could do gouraud shading which would rock...

Yeah it is too bad there's only positive colors allowed.

Anymore cool demos to post?


14th December 2005 23:33 UTC

you can use textures with triangles if you use gvm... i made something ages ago that did it.. and pak has done it too. its not that big a deal. i think there is some info on this thread:

http://forums.winamp.com/showthread....hreadid=211772

also i made a spiffy tool with ui and shit using .net which is on this thread:

http://forums.winamp.com/showthread....hreadid=231934

interesting and vaguely related demos:

http://jheriko.kicks-ass.net/avs_pro...ity%20shit.rar

prolly the most complicated example:

(slightly broken dynamic lights.. this is quite old now)

http://jheriko.kicks-ass.net/avs_pro...0intro_old.rar

i did an animated shadow mapping of a stereotypical fan in a metal room... but it came out crappy and i cant find it...

there is also:

ftp://jheriko.kicks-ass.net:69/AVS/J...ter%20demo.avs


15th December 2005 02:26 UTC

Oh man there's so many new apes I'm not knowledgable in and no time to learn yet. The global vars ape you made looks pretty dang nice btw.


15th December 2005 04:09 UTC

I'm confused, I think I'll go and discover invaluable AVS experience now...



Originally posted by JFASI
Huh? I was thinking more like a plane and a sphere. Regardless, you're still just plugging in an equation and solving for a variable using algebra.