wow!!!! Nice water effect!
Code archives/3D Graphics - Effects/Aqua Effect on 3D Cube
This code has been declared by its author to be Public Domain code.
Download source code
| Aqua is nice ! Test it ! The Code writing water hight fields in a Buffer and copy them to a texture that is on a cube that simply rotate in a 3D World . It has automatic rains drops but you can hold down the left mouse button and move it ! The gray Pixel in the texture on the cube it your mouse pointer . What you need is a Texture.bmp file in the same directory as the Code . If you have a CPU <= 400 MHz you need a Texture with size 128x128 . The Texture you need must have the same x and y size . First test it in debug mode (very very very slow) , when it works disable the debug mode to run it fast . |
; Aqua Effect (C) 2002 by M.Rauch from Germany ; If DebugMode = True Then it is very slow ! ; MR 03.11.2002 .Top Graphics3D 640,480,16,1 SetBuffer BackBuffer() ;------------------------------------------------------------------------- Camera .Cam Global Camera =CreateCamera() PositionEntity Camera,0,0,-10 CameraClsColor Camera,0,20,0 ;------------------------------------------------------------------------- Texture .Texture ;a Texture size 128 x 128 is very fast Global ReflectImage=LoadTexture("Texture.bmp") ;<--- Global ReflectImageB=TextureBuffer(ReflectImage) Global Output=CreateTexture(TextureWidth(ReflectImage),TextureHeight(ReflectImage),1) ;The same size Global OutputB=TextureBuffer(Output) ;------------------------------------------------------------------------- .Entitys Global Cube=CreateCube() ScaleMesh Cube,3,3,3 EntityTexture Cube,Output ;-------------------------------------------------------- .Light Global Light1 =CreateLight(1) Global Light2 =CreateLight(1) Global Light3 =CreateLight(1) LightRange Light1 ,50 LightRange Light2 ,50 LightRange Light3 ,50 LightColor Light1, 64, 64, 64 LightColor Light2,255,255,255 LightColor Light3, 64, 64, 64 PositionEntity Light1 ,-10, 10,-10 PositionEntity Light2 , 0, 0,-10 PositionEntity Light3 , 10,-10,-10 AmbientLight 0,0,0 ;------------------------------------------------------------------------- WaterSettings .WaterSettings Global WATERSIZE=TextureWidth(ReflectImage) ;like 128 or 256 Global RainCount=0 Global DripRadius = 12 Global DripRadiusSqr = DripRadius * DripRadius Global DampingFactor# = 0.04 ;Values For damping from 0.04 - 0.0001 look pretty good (the Buffer must in float) .WaterBuffers Global BufferSize=(WATERSIZE * WATERSIZE) Dim ReadBuffer #(BufferSize) Dim WriteBuffer#(BufferSize) Dim TempBuffer #(BufferSize) Local i For i = 0 To BufferSize TempBuffer (i) = 0 ReadBuffer (i) = 0 WriteBuffer(i) = 0 Next ;------------------------------------------------------------------------- MainLoop .MainLoop While Not KeyHit(1) ; 1=Escape Local ti# ti=MilliSecs() SwapBuffers Show CheckMouse ;<- Press left Button and move the Mouse TurnEntity Cube,1,-1.5,0 RenderWorld Rain ;<- automatic ProcessWater While Abs(MilliSecs()-ti)<10 Wend Flip Wend End ;------------------------------------------------------------------------- .Buffers ;------------------------------------------------------------------------- Function SetBufferR(x,y,value#) ReadBuffer(x+y*WATERSIZE)=value End Function ;------------------------------------------------------------------------- Function SetBufferW(x,y,value#) If value > 32 Then value = 32 If value < -32 Then value = -32 WriteBuffer(x+y*WATERSIZE)=value End Function ;------------------------------------------------------------------------- Function GetBufferR#(x,y) Return ReadBuffer(x+y*WATERSIZE) End Function ;------------------------------------------------------------------------- Function GetBufferW#(x,y) Return WriteBuffer(x+y*WATERSIZE) End Function ;------------------------------------------------------------------------- Function SwapBuffers() Local i ;Swap the buffers ! For i = 0 To BufferSize TempBuffer(i) =ReadBuffer(i) ReadBuffer(i) =WriteBuffer(i) WriteBuffer(i)=TempBuffer(i) Next End Function ;------------------------------------------------------------------------- .RenderTexture Function Show() Local x,y Local xoff,yoff Local xm,ym Local pix,pix2 Local r,g,b,a Local bu xm=GraphicsWidth() /2-WATERSIZE/2 ym=GraphicsHeight()/2-WATERSIZE/2 ;----------------------------------------------- LockBuffer ReflectImageB LockBuffer OutputB Local cnt=0 y=0 While y < WATERSIZE x=0 While x < WATERSIZE xoff = x If x > 0 And x < WATERSIZE - 1 Then xoff =xoff- (ReadBuffer(cnt - 1)) xoff =xoff+ (ReadBuffer(cnt + 1)) EndIf yoff = y If y > 0 And y < WATERSIZE - 1 Then yoff =yoff- ReadBuffer(cnt - WATERSIZE) yoff =yoff+ ReadBuffer(cnt + WATERSIZE) EndIf If xoff < 0 Then xoff = 0 If yoff < 0 Then yoff = 0 If xoff > WATERSIZE-1 Then xoff = WATERSIZE-1 If yoff > WATERSIZE-1 Then yoff = WATERSIZE-1 pix=ReadPixelFast(xoff,yoff,ReflectImageB) r=(pix And $ff0000)/$10000 g=(pix And $ff00)/$100 b=(pix And $ff) ;r=128 ;<- only color ;g=128 ;b=128 bu=ReadBuffer(cnt) r = r + bu g = g + bu b = b + bu If r < 0 Then r = 0 If g < 0 Then g = 0 If b < 0 Then b = 0 If r > 255 Then r = 255 If g > 255 Then g = 255 If b > 255 Then b = 255 pix2=ARGB(r,g,b) WritePixelFast x,y,pix2,OutputB cnt=cnt+1 x=x+1 Wend y=y+1 Wend UnlockBuffer OutputB UnlockBuffer ReflectImageB End Function ;------------------------------------------------------------------------- .Helpers Function ARGB(r,g,b) ;Return ((128 * $1000000) Or (r * $10000) Or (g * $100) Or b) Return ((r * $10000) Or (g * $100) Or b) End Function ;------------------------------------------------------------------------- Function SquaredDist(sx, sy, dx, dy) ;Find the Squared distance between two 2D points Return ((dx - sx) * (dx - sx)) + ((dy - sy) * (dy - sy)) End Function ;------------------------------------------------------------------------- .MouseInput Function CheckMouse() Local mx,my mx=MouseX() my=MouseY() If mx<0 Then mx=0 If my<0 Then my=0 If mx>WATERSIZE-1 Then mx=WATERSIZE-1 If my>WATERSIZE-1 Then my=WATERSIZE-1 WritePixel mx,my,ARGB(128,128,128),OutputB If MouseDown(1) Then MakeDrip mx,my,4 EndIf End Function ;------------------------------------------------------------------------- .RainInParadise Function Rain() Local mx,my Local i RainCount=RainCount+1 If RainCount > 10 Then RainCount=0 SeedRnd MilliSecs() mx=Rnd(0,WATERSIZE-1) my=Rnd(0,WATERSIZE-1) MakeDrip mx,my,4 EndIf End Function ;------------------------------------------------------------------------- .WaterDrip Function MakeDrip(xm , ym , depth) ;Creates an initial drip in the water Field ;DebugLog "MakeDrip "+x+" "+y+" "+depth Local x,y Local dist,finaldepth# y=ym - DripRadius While y < ym + DripRadius x=xm - DripRadius While x < xm + DripRadius If x => 0 And y => 0 And x < WATERSIZE And y < WATERSIZE Then dist = SquaredDist(x,y,xm,ym) If dist < DripRadiusSqr Then finaldepth = (depth * DripRadius - Sqr(dist))/DripRadius If finaldepth > 127 Then finaldepth = 127 If finaldepth < -127 Then finaldepth = -127 SetBufferW x,y,finaldepth EndIf EndIf x=x+1 Wend y=y+1 Wend End Function ;------------------------------------------------------------------------- .WaterInAction Function ProcessWater() ;Calculate New values For the water height Field Local x,y Local v# y=2 While y < WATERSIZE-2 x=2 While x < WATERSIZE-2 ;Sample a "circle" around the center point v =0 v = v + GetBufferR(x-2,y) v = v + GetBufferR(x+2,y) v = v + GetBufferR(x ,y-2) v = v + GetBufferR(x ,y+2) v = v + GetBufferR(x-1,y) v = v + GetBufferR(x+1,y) v = v + GetBufferR(x ,y-1) v = v + GetBufferR(x ,y+1) v = v + GetBufferR(x-1,y-1) v = v + GetBufferR(x+1,y-1) v = v + GetBufferR(x-1,y+1) v = v + GetBufferR(x+1,y+1) v = v / 6.0 v = v - GetBufferW(x,y) v = v - (v * DampingFactor) SetBufferW (x,y,v) x=x+1 Wend y=y+1 Wend End Function ;------------------------------------------------------------------------- |
Comments
One more "WOW" :) - Really nice !
Nice effect mate :)
WOW :) nice effect
Heh, I don't think I ever saw that one before - very cool.
Finding the right texture is the key.
Finding the right texture is the key.
In fact, this is quite amazing.
This was done 4 years ago - my PC is well capable of running this quite fast.
You can even create pixel-shader-esqe water ripples like in Morrowind - like when you move through water and turn around to see the waves you created behind you. Disable the rotation of the cube to look at this.
Very nice.
This was done 4 years ago - my PC is well capable of running this quite fast.
You can even create pixel-shader-esqe water ripples like in Morrowind - like when you move through water and turn around to see the waves you created behind you. Disable the rotation of the cube to look at this.
Very nice.
i am working on a water eingine like your one with a bump mapping texture ("wateranim.png")...wait until first release :)