QB64 Phoenix Edition
Shadowing - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Prolific Programmers (https://qb64phoenix.com/forum/forumdisplay.php?fid=26)
+---- Forum: MasterGy (https://qb64phoenix.com/forum/forumdisplay.php?fid=45)
+---- Thread: Shadowing (/showthread.php?tid=994)

Pages: 1 2


Shadowing - MasterGy - 10-21-2022

Back when I made the "tree house" game, a few years ago. It's 3D and you can only walk around. At that time, I remember Galleon rewrote the program and added something to the display part to shade the textures. Everything got darker in proportion to the distance. I didn't understand then. I looked for the code, but I couldn't find it, and the old forum is not available. Since then, I have solved the distance-proportional darkening of games by generating lots of textures. That's a lot of memory, and it doesn't work on a large surface, because if one vertex of a triangle is close to you and another vertex is far away, then what shade should it get? So it's only good for displaying small textures.

In the past few days, I've been thinking about how Galleon solved the problem of placing a texture of any size on the screen in any way. Then he told me that a black mask with an alpha distance proportional to the texture should be drawn. That's when I understood that by switching _depthbuffer on and off, it can be solved by dragging the alpha texture after each texture. And I understood why I didn't use it then. Very good, fast, practical, only switching the z-buffer on and off slows down the program significantly.

I was wondering how it could be solved without switching on the z-buffer.

Suppose _maptriangle gets a 3d point. be x,y,z. it should be 20,10,30. This point in the plane will be where, for example, 200,100,300 or 2,1,3 or 40,20,60. This simple realization helped. Simply, after drawing the texture, x,y,z must be multiplied by 0.999999, and then the mask can be drawn on it. That way, you don't have to switch on the z-buffer.
I thank Galleon several times already! If it doesn't show it then, I won't think about how it could be operated faster.



[Image: qb-2.jpg]

[Image: qb-1.jpg]


Code: (Select All)
picture$ = "" '<-------- enter an image or leave the field blank



'texture
If _FileExists(picture$) Then
    text = _LoadImage(picture$, 33)
Else
    temp = _NewImage(1, 1, 32): _Dest temp: Cls , _RGB32(255, 255, 255): text = _CopyImage(temp, 33): _FreeImage temp
End If

'window
monx = 800: mony = Int(monx / _DesktopWidth * _DesktopHeight): monm = monx * .008: mon = _NewImage(monx, mony, 32): Screen mon: _FullScreen: _DisplayOrder _Hardware , _Software

Const pip180 = 3.141592 / 180
Dim Shared me(9), cosrotz, sinrotz, cosrotx, sinrotx, sinrot_cs, cosrot_cs

'cube locations, sizes
Randomize Timer
cube_res = 1000: cube_deep = 1000
temp = _NewImage(cube_res - 1, cube_deep - 1, 32): _Dest temp: For t = 0 To cube_res - 1: For t2 = 0 To cube_deep - 1
    PSet (t, t2), _RGBA32(0, 0, 0, Int(255 / (cube_deep - 1) * t2) - 3)
Next t2, t: cube_text = _CopyImage(temp, 33): _FreeImage temp

'mask distance behind texture
Dim shdw_m(15000): For t = 0 To 15000: shdw_m(t) = Interpolate(.999, .97, 1 / 15000 * t): Next t


mapdim = 1000

'make cubes
obj_c = 200
Dim obj(obj_c - 1, 9): _Source deep_text: For t = 0 To obj_c - 2: For t2 = 0 To 2: obj(t, t2) = mapdim * Rnd: obj(t, t2 + 3) = 10 + 40 * Rnd: Next t2, t

For t = 0 To 2: obj(obj_c - 1, 3 + t) = mapdim / 2: obj(obj_c - 1, t) = mapdim / 2: Next t
For t = 0 To 2: me(t) = mapdim / 2: Next t: light = .2: me(4) = -.2: ut_me4 = -.2: ylook_limit = 80 'radian

_Dest mon
Locate 1, 1: Print "moving:WASD       looking:mouse        light adjust : mousewheel"
Dim p(3, 2), p2(3, 2), pc(7, 9)
Do: _Limit 30
    'control
    mouse_sens_xy = .01: mouse_sens_z = .01
    mousex = 0: mousey = 0: mousew = 0: While _MouseInput: mousex = mousex + _MouseMovementX: mousey = mousey + _MouseMovementY: mousew = mousew + _MouseWheel: Wend
    me(3) = me(3) + mousex * mouse_sens_xy: me(4) = me(4) + mousey * mouse_sens_z

    ylook_deg = ((me(4) / pip180) + 90): If Abs(ylook_deg) > ylook_limit Then me(4) = ut_me4 Else ut_me4 = me(4)
    rot_cs = (rot_cs + mousex * .001 * Abs(Sin(me(4)))) * .9
    light = light - mousew * 0.005: If light < 0 Then light = 0 Else If light > 1 Then light = 1
    Locate 2, 1: Print "light:"; Int(light * 100); "%   "
    position_speed = 5
    kw = _KeyDown(119): ks = _KeyDown(115): ka = _KeyDown(97): kd = _KeyDown(100): new_direction = (Abs(ka Or kd Or kw) Or -Abs(ks)) * position_speed
    deg_XY = -90 * Abs(ka) + 90 * Abs(kd): szog_xy = me(3) + deg_XY * pip180: szog_z = me(4)
    me(0) = me(0) - Sin(szog_xy) * (1 - Cos(szog_z)) * new_direction
    me(1) = me(1) - Cos(szog_xy) * (1 - Cos(szog_z)) * new_direction
    me(2) = me(2) - Cos(szog_z + _Pi) * new_direction

    cosrotz = Cos(me(3)): sinrotz = Sin(me(3)): cosrotx = Cos(me(4)): sinrotx = Sin(me(4)): cosrot_cs = Cos(rot_cs): sinrot_cs = Sin(rot_cs) 'to rotating angles

    'draw cubes
    px1 = cube_res / 2: px2 = cube_res - 2
    dl = cube_deep - 3: c_dis = Interpolate(50, 2500, light): temp = cube_deep / c_dis
    For a_obj = 0 To obj_c - 1: For t = 0 To 7
        For t2 = 0 To 2: pc(t, t2) = (obj(a_obj, 3 + t2) * (Sgn(t And 2 ^ t2) * 2 - 1) + (obj(a_obj, t2) - me(t2))): Next t2
            rotate pc(t, 0), pc(t, 1), pc(t, 2)
            pc(t, 3) = Sqr(pc(t, 0) * pc(t, 0) + pc(t, 1) * pc(t, 1) + pc(t, 2) * pc(t, 2))
            sm = shdw_m(Abs(Int(pc(t, 2))))
            For t2 = 0 To 2: pc(t, 4 + t2) = pc(t, t2) * sm: Next t2
        Next t

        For t = 0 To 5: For t2 = 0 To 3: side(t2) = Val(Mid$("024623673175105445670123", 1 + t * 4 + t2, 1)): For t3 = 0 To 2: p(t2, t3) = pc(side(t2), t3): p2(t2, t3) = pc(side(t2), t3 + 4): Next t3, t2

            'texture
            _MapTriangle (0, 0)-(_Width(text) - 1, 0)-(0, _Height(text)), text To(p(0, 0), p(0, 1), p(0, 2))-(p(1, 0), p(1, 1), p(1, 2))-(p(2, 0), p(2, 1), p(2, 2)), , _Smooth
            _MapTriangle (_Width(text), _Height(text))-(_Width(text) - 1, 0)-(0, _Height(text)), text To(p(3, 0), p(3, 1), p(3, 2))-(p(1, 0), p(1, 1), p(1, 2))-(p(2, 0), p(2, 1), p(2, 2)), , _Smooth

            'shadow mask
            For t2 = 0 To 3: py(t2) = Int(temp * pc(side(t2), 3)): If py(t2) > dl Then py(t2) = dl
            Next t2
            _MapTriangle (1, py(0))-(px1, py(1))-(px2, py(2)), cube_text To(p2(0, 0), p2(0, 1), p2(0, 2))-(p2(1, 0), p2(1, 1), p2(1, 2))-(p2(2, 0), p2(2, 1), p2(2, 2)), , _Smooth
            _MapTriangle (1, py(3))-(px1, py(1))-(px2, py(2)), cube_text To(p2(3, 0), p2(3, 1), p2(3, 2))-(p2(1, 0), p2(1, 1), p2(1, 2))-(p2(2, 0), p2(2, 1), p2(2, 2)), , _Smooth
    Next t, a_obj

    _Display

Loop
Function Interpolate (a, b, x): Interpolate = a + (b - a) * x: End Function
Sub rotate (px, py, pz2): px3 = px * cosrotz - py * sinrotz: py2 = px * sinrotz + py * cosrotz: py3 = py2 * cosrotx - pz2 * sinrotx: pz3 = py2 * sinrotx + pz2 * cosrotx
px4 = px3 * cosrot_cs - py3 * sinrot_cs: py4 = px3 * sinrot_cs + py3 * cosrot_cs: px = -px4: py = -py4: pz2 = -pz3: End Sub



RE: Shadowing - bplus - 10-21-2022

(10-21-2022, 06:31 PM)MasterGy Wrote: Back when I made the "tree house" game, a few years ago. It's 3D and you can only walk around. At that time, I remember Galleon rewrote the program and added something to the display part to shade the textures. Everything got darker in proportion to the distance. I didn't understand then. I looked for the code, but I couldn't find it, and the old forum is not available. Since then, I have solved the distance-proportional darkening of games by generating lots of textures. That's a lot of memory, and it doesn't work on a large surface, because if one vertex of a triangle is close to you and another vertex is far away, then what shade should it get? So it's only good for displaying small textures.

In the past few days, I've been thinking about how Galleon solved the problem of placing a texture of any size on the screen in any way. Then he told me that a black mask with an alpha distance proportional to the texture should be drawn. That's when I understood that by switching _depthbuffer on and off, it can be solved by dragging the alpha texture after each texture. And I understood why I didn't use it then. Very good, fast, practical, only switching the z-buffer on and off slows down the program significantly.

I was wondering how it could be solved without switching on the z-buffer.

Suppose _maptriangle gets a 3d point. be x,y,z. it should be 20,10,30. This point in the plane will be where, for example, 200,100,300 or 2,1,3 or 40,20,60. This simple realization helped. Simply, after drawing the texture, x,y,z must be multiplied by 0.999999, and then the mask can be drawn on it. That way, you don't have to switch on the z-buffer.
I thank Galleon several times already! If it doesn't show it then, I won't think about how it could be operated faster.



[Image: qb-2.jpg]

[Image: qb-1.jpg]


Code: (Select All)
picture$ = "" '<-------- enter an image or leave the field blank



'texture
If _FileExists(picture$) Then
    text = _LoadImage(picture$, 33)
Else
    temp = _NewImage(1, 1, 32): _Dest temp: Cls , _RGB32(255, 255, 255): text = _CopyImage(temp, 33): _FreeImage temp
End If

'window
monx = 800: mony = Int(monx / _DesktopWidth * _DesktopHeight): monm = monx * .008: mon = _NewImage(monx, mony, 32): Screen mon: _FullScreen: _DisplayOrder _Hardware , _Software

Const pip180 = 3.141592 / 180
Dim Shared me(9), cosrotz, sinrotz, cosrotx, sinrotx, sinrot_cs, cosrot_cs

'cube locations, sizes
Randomize Timer
cube_res = 1000: cube_deep = 1000
temp = _NewImage(cube_res - 1, cube_deep - 1, 32): _Dest temp: For t = 0 To cube_res - 1: For t2 = 0 To cube_deep - 1
    PSet (t, t2), _RGBA32(0, 0, 0, Int(255 / (cube_deep - 1) * t2) - 3)
Next t2, t: cube_text = _CopyImage(temp, 33): _FreeImage temp

'mask distance behind texture
Dim shdw_m(15000): For t = 0 To 15000: shdw_m(t) = Interpolate(.999, .97, 1 / 15000 * t): Next t


mapdim = 1000

'make cubes
obj_c = 200
Dim obj(obj_c - 1, 9): _Source deep_text: For t = 0 To obj_c - 2: For t2 = 0 To 2: obj(t, t2) = mapdim * Rnd: obj(t, t2 + 3) = 10 + 40 * Rnd: Next t2, t

For t = 0 To 2: obj(obj_c - 1, 3 + t) = mapdim / 2: obj(obj_c - 1, t) = mapdim / 2: Next t
For t = 0 To 2: me(t) = mapdim / 2: Next t: light = .2: me(4) = -.2: ut_me4 = -.2: ylook_limit = 80 'radian

_Dest mon
Locate 1, 1: Print "moving:WASD       looking:mouse        light adjust : mousewheel"
Dim p(3, 2), p2(3, 2), pc(7, 9)
Do: _Limit 30
    'control
    mouse_sens_xy = .01: mouse_sens_z = .01
    mousex = 0: mousey = 0: mousew = 0: While _MouseInput: mousex = mousex + _MouseMovementX: mousey = mousey + _MouseMovementY: mousew = mousew + _MouseWheel: Wend
    me(3) = me(3) + mousex * mouse_sens_xy: me(4) = me(4) + mousey * mouse_sens_z

    ylook_deg = ((me(4) / pip180) + 90): If Abs(ylook_deg) > ylook_limit Then me(4) = ut_me4 Else ut_me4 = me(4)
    rot_cs = (rot_cs + mousex * .001 * Abs(Sin(me(4)))) * .9
    light = light - mousew * 0.005: If light < 0 Then light = 0 Else If light > 1 Then light = 1
    Locate 2, 1: Print "light:"; Int(light * 100); "%   "
    position_speed = 5
    kw = _KeyDown(119): ks = _KeyDown(115): ka = _KeyDown(97): kd = _KeyDown(100): new_direction = (Abs(ka Or kd Or kw) Or -Abs(ks)) * position_speed
    deg_XY = -90 * Abs(ka) + 90 * Abs(kd): szog_xy = me(3) + deg_XY * pip180: szog_z = me(4)
    me(0) = me(0) - Sin(szog_xy) * (1 - Cos(szog_z)) * new_direction
    me(1) = me(1) - Cos(szog_xy) * (1 - Cos(szog_z)) * new_direction
    me(2) = me(2) - Cos(szog_z + _Pi) * new_direction

    cosrotz = Cos(me(3)): sinrotz = Sin(me(3)): cosrotx = Cos(me(4)): sinrotx = Sin(me(4)): cosrot_cs = Cos(rot_cs): sinrot_cs = Sin(rot_cs) 'to rotating angles

    'draw cubes
    px1 = cube_res / 2: px2 = cube_res - 2
    dl = cube_deep - 3: c_dis = Interpolate(50, 2500, light): temp = cube_deep / c_dis
    For a_obj = 0 To obj_c - 1: For t = 0 To 7
        For t2 = 0 To 2: pc(t, t2) = (obj(a_obj, 3 + t2) * (Sgn(t And 2 ^ t2) * 2 - 1) + (obj(a_obj, t2) - me(t2))): Next t2
            rotate pc(t, 0), pc(t, 1), pc(t, 2)
            pc(t, 3) = Sqr(pc(t, 0) * pc(t, 0) + pc(t, 1) * pc(t, 1) + pc(t, 2) * pc(t, 2))
            sm = shdw_m(Abs(Int(pc(t, 2))))
            For t2 = 0 To 2: pc(t, 4 + t2) = pc(t, t2) * sm: Next t2
        Next t

        For t = 0 To 5: For t2 = 0 To 3: side(t2) = Val(Mid$("024623673175105445670123", 1 + t * 4 + t2, 1)): For t3 = 0 To 2: p(t2, t3) = pc(side(t2), t3): p2(t2, t3) = pc(side(t2), t3 + 4): Next t3, t2

            'texture
            _MapTriangle (0, 0)-(_Width(text) - 1, 0)-(0, _Height(text)), text To(p(0, 0), p(0, 1), p(0, 2))-(p(1, 0), p(1, 1), p(1, 2))-(p(2, 0), p(2, 1), p(2, 2)), , _Smooth
            _MapTriangle (_Width(text), _Height(text))-(_Width(text) - 1, 0)-(0, _Height(text)), text To(p(3, 0), p(3, 1), p(3, 2))-(p(1, 0), p(1, 1), p(1, 2))-(p(2, 0), p(2, 1), p(2, 2)), , _Smooth

            'shadow mask
            For t2 = 0 To 3: py(t2) = Int(temp * pc(side(t2), 3)): If py(t2) > dl Then py(t2) = dl
            Next t2
            _MapTriangle (1, py(0))-(px1, py(1))-(px2, py(2)), cube_text To(p2(0, 0), p2(0, 1), p2(0, 2))-(p2(1, 0), p2(1, 1), p2(1, 2))-(p2(2, 0), p2(2, 1), p2(2, 2)), , _Smooth
            _MapTriangle (1, py(3))-(px1, py(1))-(px2, py(2)), cube_text To(p2(3, 0), p2(3, 1), p2(3, 2))-(p2(1, 0), p2(1, 1), p2(1, 2))-(p2(2, 0), p2(2, 1), p2(2, 2)), , _Smooth
    Next t, a_obj

    _Display

Loop
Function Interpolate (a, b, x): Interpolate = a + (b - a) * x: End Function
Sub rotate (px, py, pz2): px3 = px * cosrotz - py * sinrotz: py2 = px * sinrotz + py * cosrotz: py3 = py2 * cosrotx - pz2 * sinrotx: pz3 = py2 * sinrotx + pz2 * cosrotx
px4 = px3 * cosrot_cs - py3 * sinrot_cs: py4 = px3 * sinrot_cs + py3 * cosrot_cs: px = -px4: py = -py4: pz2 = -pz3: End Sub

cool!


RE: Shadowing - Pete - 10-21-2022

Re-title this...

What can you do in 100 lines or less?

Very cool 3-D effects. Somehow I managed the clear the screen with random use of WASD buttons, and I couldn't get anything to display again. Sorry, I have no clue exactly what I did to make that happen. Anyway, I get it , the post is a demo, and it's a really neat one to see. Oh, and it doesn't even use OpenGL.

I'd recommend everyone give it a spin.

Pete


RE: Shadowing - James D Jarvis - 10-22-2022

That is interesting. Thanks for sharing.


RE: Shadowing - OldMoses - 10-22-2022

That was amazing. Very cool effect.


RE: Shadowing - james2464 - 10-22-2022

Amazing what can be done with QB64

I was reading the code and trying to see what the least understandable portion is (to me), and I believe this is it: 

Code: (Select All)
side(t2) = Val(Mid$("024623673175105445670123", 1 + t * 4 + t2, 1))

I looked up mid$ on the wiki and it's about selecting part of a string.  That makes this even more interesting...

Anyway thanks for sharing this.  Great work.


RE: Shadowing - MasterGy - 10-22-2022

(10-22-2022, 05:17 PM)james2464 Wrote: Amazing what can be done with QB64

I was reading the code and trying to see what the least understandable portion is (to me), and I believe this is it: 

Code: (Select All)
side(t2) = Val(Mid$("024623673175105445670123", 1 + t * 4 + t2, 1))

I looked up mid$ on the wiki and it's about selecting part of a string.  That makes this even more interesting...

Anyway thanks for sharing this.  Great work.

Thanks for the comments!

I invented it to draw the cube. This is what the number line "024623673175105445670123" means. It must be interpreted with 4 essays. Smile
[Image: box.jpg]


RE: Shadowing - Pete - 10-22-2022

Cube smube. Where's my decahedron!

Hell, it's always something. What's cool is concepts are concepts. Get enough of a team together to use them, and eventually you get a 3-D game engine. Since I've only worked on two team project in my entire 30+ years of coding, I can't imagine myself going very far in 3-D gaming apps. If I could program one, up to today's standards, in a year, I might feel differently. I like stuff like Chivalry II. Oh, I don't play it, I just think it would be fascinating to be able to code it, but what MG gave use as a graphical 3-D motion concept here, in under 100-lines, is truly inspiring.

Pete


RE: Shadowing - bplus - 10-22-2022

So how many lines when Double Parking colons, :, removed?

Anyone got a quick app? Eh, has to distinguish a single line IF with block IF to insert END IF's in correct place.


RE: Shadowing - james2464 - 10-22-2022

(10-22-2022, 05:41 PM)MasterGy Wrote:
(10-22-2022, 05:17 PM)james2464 Wrote: Amazing what can be done with QB64

I was reading the code and trying to see what the least understandable portion is (to me), and I believe this is it: 

Code: (Select All)
side(t2) = Val(Mid$("024623673175105445670123", 1 + t * 4 + t2, 1))

I looked up mid$ on the wiki and it's about selecting part of a string.  That makes this even more interesting...

Anyway thanks for sharing this.  Great work.

Thanks for the comments!

I invented it to draw the cube. This is what the number line "024623673175105445670123" means. It must be interpreted with 4 essays. Smile
[Image: box.jpg]

So...sort of like READ and DATA but selecting the data from a string of data using variables to adjust where the data is within the string?

Very interesting invention!   Almost like a data keyboard, the mid$ allows you to press different keys and you just start by listing them all.

(I might have misunderstood but that's what it seems like it's doing)