If you put
DISABLE OBJECT ZWRITE iObj_count
after
point object iObj_count, 0, 0, 0
in function
wlCreateCloud, it may look at tad bit better.
After some web searching, it seems the alphablended 3d objects needs to be zwrite disabled and also have some way of doing your own z-sorting of those objects. I'm guessing and assuming that's why those unwanted lines are in the clouds like that.
So, with that idea in mind about zwrite disabled and needing zsorting... DBPro sprites came to mind. I have coded the example with using sprites that are positioned and sized according to where the objects are located at. For me, this method isn't practical as the more sprites, slower it gets. Plus, I had to use the Object Screen commands to help position the sprites. With that, when the objects go off the screen or go behind the camera... weird things can happen.
Bottom line is at least the cloud looks nicer
* I was trying to put in cloud density via using a 3d array to set a light scattering technique, but with the for/next/if statements, it was making the program come to a crawl. I might attempt a c++ dll.
// Volumetric clouds using 3D noise algorithm and sprites
rem iamge id's
#CONSTANT CLOUD_IMAGE_ID 1
#CONSTANT BACKDROP_IMAGE_ID 2
rem mesh id's
#CONSTANT MESH_OBJECT_LIMB_OFFSET_ID 1
rem object id's
#CONSTANT TEST_SPHERE_OBJECT_ID 10000
#CONSTANT FORGROUND_SPHERE_OBJECT_ID 10001
rem sprite id's
Rem Size of cloud
GLOBAL CloudWidth as INTEGER
GLOBAL CloudHeight as INTEGER
GLOBAL CloudDepth as INTEGER
CloudWidth = 10
CloudHeight =8
CloudDepth = 24
wlSetupScreen()
rem turn the camera's backdrop off so sprites can be seen after we call the 'draw sprites first' command
backdrop off
color backdrop rgb(0,68,128)
move camera -100
`
// Load the decal texture (has an alpha channel)
Load Image "ARGB_Dec.png", CLOUD_IMAGE_ID, 1
draw sprites first
` Create our own backdrop image that will be used by a sprite
create bitmap 1,screen width(),screen height()
cls rgb(0,68,128)
get image BACKDROP_IMAGE_ID,0,0,screen width(),screen height()
set current bitmap 0
delete bitmap 1
sprite 10000,0,0,BACKDROP_IMAGE_ID
Set sprite priority 10000,-10000 ` draw this backdrop sprite first
` create object to help determine the size of sprites
make object sphere TEST_SPHERE_OBJECT_ID, 1,8,8
make mesh from object MESH_OBJECT_LIMB_OFFSET_ID, TEST_SPHERE_OBJECT_ID
hide object TEST_SPHERE_OBJECT_ID
` As we use the 'draw sprites first' command to have the clouds in the background behind any 3d objects...
` we'll create an object to show this.
make object sphere FORGROUND_SPHERE_OBJECT_ID,24,8,8
// Create the cloud with our density settings
wlCreateCloud( 0.9, 0.5 )
Do
// Free flight camera control (speed setting)
wlControlCamera( 3.0 )
// Update the clouds particles (amount per frame)
wlUpdateCloud()
Sync
Loop
end
function wlSetupScreen()
sync on
sync rate 60
autocam off
set display mode 640, 480, 0
EndFunction
function wlControlCamera( speed as float )
LOCAL local_CameraAngleX as FLOAT
LOCAL local_CameraAngleY as FLOAT
LOCAL local_mmovex as INTEGER
LOCAL local_mmovex as INTEGER
local_mmovex = mousemovex()
local_mmovey = mousemovey()
` keep mouse centered when rotating camera
position mouse screen width()/2, screen height()/2
` Get Current Anlges
local_CameraAngleX = Camera Angle X()
local_CameraAngleY = Camera Angle Y()
` create a rotation axis based on controller movement
local_CameraAngleX = WrapValue ( local_CameraAngleX + (local_mmovey) )
local_CameraAngleY = WrapValue ( local_CameraAngleY + (local_mmovex) )
` rotate camera and lock x-axis between 0 and 90
if ((( local_CameraAngleX >= 0 ) and ( local_CameraAngleX <= 90 )) or (( local_CameraAngleX >= 270 ) and ( local_CameraAngleX < 360 )))
XRotate Camera local_CameraAngleX
endif
YRotate Camera local_CameraAngleY
if UpKey() then Move Camera speed
if DownKey() then Move Camera -speed
EndFunction
function wlCreateCloud( noise_per as float, noise_scale as float )
global iObj_count
local fVal#
local x, y, z
local nx#, ny#, nz#
local plain_size as integer
iObj_count = 0
for x=0 to CloudWidth-1
for y=0 to CloudHeight-1
for z=0 to CloudDepth-1
// get segments noise value
nx# = x : nx# = nx# / CloudWidth
ny# = y : ny# = ny# / CloudHeight
nz# = z : nz# = nz# / CloudDepth
fVal# = SIMPLEX SCALED 3D( 6, noise_per, noise_scale, -1.5, 1.0, nx#, ny#, nz# )
// is the value > 0.0
if ( fVal# > 0.0 )
// create the object
inc iObj_count
plain_size=32
make object plain iObj_count, plain_size, plain_size
set alpha mapping on iObj_count, 0
position object iObj_count, x*10, y*10, z*10
point object iObj_count, 0, 0, 0
rem create a limb for the object to help determine the size of the sprite
add limb iObj_count,1,MESH_OBJECT_LIMB_OFFSET_ID
offset limb iObj_count,1,plain_size/2,0,0
scale limb iObj_count,1,.5,.5,.5
hide limb iObj_count,1
rem Sprite will show the cloud particle where the object is at on screen...
sprite iObj_count,0,0,CLOUD_IMAGE_ID
hide sprite iObj_count
set sprite iObj_count,1,1
set sprite priority iObj_count,-100
set sprite alpha iObj_count,fVal# * 100.0
ENDIF
NEXT
NEXT
NEXT
EndFunction
function wlUpdateCloud()
local index_i as integer
local obj_x as float
local obj_y as float
local limb_x as float
local limb_y as float
for index_i=1 to iObj_count
rem face invisible cloud plains towards camera
point object index_i, camera position x(), camera position y(), camera position z()
obj_x=object screen X(index_i)
obj_y=object screen Y(index_i)
if object in screen(index_i)=1
` object in screen, show it's cloud particle
sprite index_i,obj_x,obj_y,CLOUD_IMAGE_ID
show sprite index_i
` the limb position helps us determine what size the sprite needs to be
position object TEST_SPHERE_OBJECT_ID,limb position x(index_i,1),limb position y(index_i,1),limb position z(index_i,1)
limb_x=object screen X(TEST_SPHERE_OBJECT_ID)
limb_y=object screen Y(TEST_SPHERE_OBJECT_ID)
if object in screen(TEST_SPHERE_OBJECT_ID)=1
size=(obj_x-limb_x)*2
rem make sure size is legal for teh size sprite command
if (size>0 and size<screen width())
size sprite index_i,size,size
endif
endif
else
`
hide sprite index_i
endif
next
EndFunction