none
Rendering shadows on shapes RRS feed

  • Question

  • Hey Guys!

    I was hoping one of you would have a clever way of rendering shadows on shape images. Basically here's what I need to do:

    I currently have images with shadows added previously in gimp. I can then add them to the scene I'm working on and it all looks pretty good. The issue I'm running into is that I then can't rotate the building images, or the shadows will be pointing in a wrong direction.

    I was hoping that there was a way to add just the house image, at any angle I choose, and then render the shadows afterwards (in the Graphics Window)

    To currently create shadows, I use a script I made for gimp. Here is how I do it

    First, I duplicate the image layer and motion blur it:

    Next, I mess with the transparency threshold to get the image to be consistently transparent:

    After that, I add the shadow layer under the house image and it is finished.

    So what do you all think? Can this be done in SB?


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Sunday, October 16, 2016 4:28 PM
    Answerer

Answers

  • Now that's a challenge!

    I doubt any kind of detailed image manipulation at the pixel level will be fast enough for images that are rotating.

    Ideas:

    1] Use a generic circlar type shadow

    2] Maybe use a very low res mage that you do manipulate in a simalar way to the Gimp at the pixel level, eg 8x8 image zoomed

    3] Have say 20 shadows for different angles all stored and Hide/Show as needed

    Sunday, October 16, 2016 5:41 PM
    Moderator
  • The normal mapping is effectively what the 3D lighting model does deep down in the OpenGL or Directx - if you are interested this is programming GPUs using HSLS shaders.  I had a go at writing GPU shaders to do fun stuff a few months ago.

    So as a 4th option: to show a 3D look map with shadows, maybe do it in a 3D view directly, moving the camera at a fixed height over the scene.

    You will need the 3D geometry for the objects in the map - but you would also need this for 'normal maps'.

    The other ways are to process or generate a whole bunch of 2D shadow images manually in some way (GIMP) or directly in SB.  Probaly easier in GIMP since there is currenly nohing like motion blur etc in SB extensions as far as I know.

    Or even do the game in 3D?
    Wednesday, October 19, 2016 6:23 PM
    Moderator
  • I am specifically refuring to normal maps on 2d images. It gives the image a '3d' look. Check out this video I found: https://m.youtube.com/watch?v=DoSl10i4oX4

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Yes I know, but you need a height map or normal map (that is X,Y,Z 3D information to do it) - you cannot do it just starting from a flat image I think, unless the flat image colour represents height (i.e. the image is already a height map).

    So by the time you have created a 3D height or normal map you will have created a 3D geometry is all I was saying.  Also my guess is that normal maps will work best for complex curved surfaces with texture, basically where the normals all point in different directions, flat vertical walls less good.

    Thursday, October 20, 2016 5:59 PM
    Moderator
  • There is a GIMP normal map plugin for the most recent 64 bit GIMP
    Thursday, October 20, 2016 6:51 PM
    Moderator

All replies

  • Now that's a challenge!

    I doubt any kind of detailed image manipulation at the pixel level will be fast enough for images that are rotating.

    Ideas:

    1] Use a generic circlar type shadow

    2] Maybe use a very low res mage that you do manipulate in a simalar way to the Gimp at the pixel level, eg 8x8 image zoomed

    3] Have say 20 shadows for different angles all stored and Hide/Show as needed

    Sunday, October 16, 2016 5:41 PM
    Moderator
  • I like the multiple image idea! I forgot to mention though that there would be no real time limit for the time it would take to render. Since they would be used in a map, they wouldn't need to update (they would be static shadows)

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Sunday, October 16, 2016 11:14 PM
    Answerer
  • How would I render a shadow, and store it for future use? I would guess I would have to create an image and modify it. How would you do it?

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Wednesday, October 19, 2016 1:28 AM
    Answerer
  • I just took a look at normal maps. The are AMAZING! Any chance we could apply them to SB shapes?

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Wednesday, October 19, 2016 4:36 AM
    Answerer
  • The normal mapping is effectively what the 3D lighting model does deep down in the OpenGL or Directx - if you are interested this is programming GPUs using HSLS shaders.  I had a go at writing GPU shaders to do fun stuff a few months ago.

    So as a 4th option: to show a 3D look map with shadows, maybe do it in a 3D view directly, moving the camera at a fixed height over the scene.

    You will need the 3D geometry for the objects in the map - but you would also need this for 'normal maps'.

    The other ways are to process or generate a whole bunch of 2D shadow images manually in some way (GIMP) or directly in SB.  Probaly easier in GIMP since there is currenly nohing like motion blur etc in SB extensions as far as I know.

    Or even do the game in 3D?
    Wednesday, October 19, 2016 6:23 PM
    Moderator
  • I am specifically refuring to normal maps on 2d images. It gives the image a '3d' look. Check out this video I found: https://m.youtube.com/watch?v=DoSl10i4oX4

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Thursday, October 20, 2016 5:34 PM
    Answerer
  • I am specifically refuring to normal maps on 2d images. It gives the image a '3d' look. Check out this video I found: https://m.youtube.com/watch?v=DoSl10i4oX4

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Yes I know, but you need a height map or normal map (that is X,Y,Z 3D information to do it) - you cannot do it just starting from a flat image I think, unless the flat image colour represents height (i.e. the image is already a height map).

    So by the time you have created a 3D height or normal map you will have created a 3D geometry is all I was saying.  Also my guess is that normal maps will work best for complex curved surfaces with texture, basically where the normals all point in different directions, flat vertical walls less good.

    Thursday, October 20, 2016 5:59 PM
    Moderator
  • There is a GIMP normal map plugin for the most recent 64 bit GIMP
    Thursday, October 20, 2016 6:51 PM
    Moderator
  • I have created a demo Normal mapping program. This is what I was hoping to do to shapes. 

    It needs to be optimized though, because it's pretty slow.

    Normal map:

    Result:

    Give it a minute to load, then move the mouse around.

    GraphicsWindow.MouseMove = OnMouseMove
    
    specularity = 128
    shiny = 1
    ambient = 80
    
    
    ImgShape = Shapes.AddImage("http://sean.alyrica.net/Blank.png")
    LDShapes.Centre(ImgShape,200,200)
    
    PrintImg = ImageList.LoadImage("http://sean.alyrica.net/Blank.png")
    NormalImage = ImageList.LoadImage("http://sean.alyrica.net/NM_4.png")
    
    LDImage.OpenWorkingImage(NormalImage)
    
    SubRunning = "True"
    'collect the normal map data, normalize it, and store it in an array
    For px = 1 To ImageList.GetWidthOfImage(NormalImage)
      For py = 1 To ImageList.GetHeightOfImage(NormalImage)
        pixRGB = LDImage.GetWorkingImagePixelARGB(NormalImage,px,py)
        tface_x = (pixRGB["R"]/128)-1
        tface_y = (pixRGB["G"]/128)-1
        tface_z = (pixRGB["B"]/128)-1
        
        magInv = Math.SquareRoot(tface_x*tface_x + tface_y*tface_y + tface_z*tface_z)
        face_x[px][py] = tface_x / magInv
        face_y[px][py] = tface_y / magInv
        face_z[px][py] = tface_z / magInv
        
      EndFor
    EndFor
    SubRunning = "False"
    
    
    Sub OnMouseMove
      If SubRunning <> "True" Then
        SubRunning = "True"
        mx = GraphicsWindow.MouseX
        my = GraphicsWindow.MouseY
        
        FL_distx = GraphicsWindow.MouseX-200
        FL_disty = 200-GraphicsWindow.MouseY
        FL_distz = 40
        LDImage.OpenWorkingImage(PrintImg)
        
        
        For px = 1 To ImageList.GetWidthOfImage(NormalImage) Step 2
          For py = 1 To ImageList.GetHeightOfImage(NormalImage) Step 2
            
            L_distx = FL_distx
            L_disty = FL_disty 
            L_distz = FL_distz
            
            'Normalize the light vector
            magInv = Math.SquareRoot(L_distx*L_distx + L_disty*L_disty + L_distz*L_distz)
            L_distx = L_distx / magInv
            L_disty = L_disty / magInv
            L_distz = L_distz / magInv
           
            'Get the dot product of the two normalized vectors
            dot = (face_x[px][py]*L_distx)+(face_y[px][py]*L_disty)+(face_z[px][py]*L_distz)
    
            
            spec = dot*specularity
            spec = spec + dot*shiny
            
            If spec < 0 Then 
              spec = 0
            EndIf
            
            ' spec + ambient
            intensity = spec + 128
            If intensity > 255 Then
              intensity = 255
            EndIf
            
            LDImage.SetWorkingImagePixel(PrintImg,px,py,GraphicsWindow.GetColorFromRGB(intensity,intensity,intensity))
           LDImage.SetWorkingImagePixel(PrintImg,px,py+1,GraphicsWindow.GetColorFromRGB(intensity,intensity,intensity))
            
          EndFor
          
        EndFor
    
        LDImage.CloseWorkingImage(PrintImg)
        LDShapes.SetImage(ImgShape,PrintImg)
        SubRunning = "False"
        
      EndIf
    EndSub


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Saturday, November 19, 2016 11:11 PM
    Answerer
  • Interesting and nice idea!

    .....  It needs to be optimized though, because it's pretty slow.

    Here's a shorter and hopefully faster version using SBVector extension (based on Vector3 by R. Potter  ,  github)

    The difference is, that in all the SBVector methods i used default SB Arrays for 2D or 3D vectors - not the generic methods as in Vector3, so probably speed might suffer slightly lower.
    But it's useable in 3D for vector translation, euclidian color distance and that kind, although somewhat more cumbersome to handle than Vector3's functions. And .. all the xml help text is in german, but that should be easy to translate to good english, esp. with a look at the mentioned CP site above.

    ID: HML729            SBVector_1-2.zip (6.15KB)

    Sunday, November 20, 2016 11:47 AM
    Answerer
  • Added a method to do this in code, uploaded to beta extension.

    Test code:

    normImg = ImageList.LoadImage(Program.Directory +"\img\NM_4.png") ' 88x88
    w = ImageList.GetWidthOfImage(normImg)
    h = ImageList.GetHeightOfImage(normImg)
    image1 = Shapes.AddImage(normImg)
    image = Shapes.AddImage(normImg)
    Shapes.Move(image,300-w/2,300-h/2)
    GraphicsWindow.PenWidth = 0
    GraphicsWindow.BrushColor = "Yellow"
    light = Shapes.AddEllipse(10,10)
    
    For i = 1 To 360
      x = Math.Cos(i*Math.Pi/180)
      y = Math.Sin(i*Math.Pi/180)
      LDImage.Shadow(image,x,y,1)
      Shapes.Move(light,300+100*x-5,300+100*y-5)
    EndFor

    Sunday, November 20, 2016 5:23 PM
    Moderator
  • Holy smokes litdev! How did you get it to render so fast? It's perfectly seamless!

    Would it be possible to edit it so you can apply a normal map shadow to another image? (not just to itself)

    I have two Images here. A normal map:

    And a texture image:

    Both the same width and height. Would it be possible to apply the shading from the normal map onto the texture image?


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Sunday, November 20, 2016 5:59 PM
    Answerer
  • Yes.

    What kind of algorithm do think to combine the rgb from the normal map (grag scale) and texture image. 

    Perhaps experimant a bit and post an idea to test.

    Of course anything complex may slow it a bit.

    Sunday, November 20, 2016 6:08 PM
    Moderator
  • The following (uploaded beta using your car images) just multiplies all r,g,b by grayscale value

    'normImg = ImageList.LoadImage(Program.Directory +"\img\NM_4.png") ' 88x88
    normImg = ImageList.LoadImage(Program.Directory +"\car_normalmap.png") ' 88x88
    textureImg = ImageList.LoadImage(Program.Directory +"\car_texture.png") ' 88x88
    w = ImageList.GetWidthOfImage(normImg)
    h = ImageList.GetHeightOfImage(normImg)
    image1 = Shapes.AddImage(normImg)
    image2 = Shapes.AddImage(textureImg)
    image = Shapes.AddImage(normImg)
    Shapes.Move(image2,100,0)
    Shapes.Move(image,300-w/2,300-h/2)
    GraphicsWindow.PenWidth = 0
    GraphicsWindow.BrushColor = "Yellow"
    light = Shapes.AddEllipse(10,10)
    
    For i = 1 To 360*10
      x = Math.Cos(i*Math.Pi/180)
      y = Math.Sin(i*Math.Pi/180)
      LDImage.Shadow(image,x,y,1,textureImg)
      Shapes.Move(light,300+100*x-5,300+100*y-5)
    EndFor

    Sunday, November 20, 2016 6:32 PM
    Moderator
  • That works well! Would you mind giving me a brief overview on how you did it? I'm very curious how you made it so fast.

    Also, could you make the light intensity adjustable?


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Sunday, November 20, 2016 8:07 PM
    Answerer
  • I experimented a bit with light intensity and found the best approach seems to be alter the Z value.

    This is the c# code i wrote, the first (Shadow constructor) sets up the normal vectors and the second (Update) modifies the image based on light source direction, basically just the code you were using, but optimised to not keep opening and closing images etc to alter pixels.

        public class Shadow
        {
            System.Windows.Controls.Image image;
            private Bitmap bNormal;
            private Bitmap bTexture = null;
            private int width;
            private int height;
            private Vector3[,] vectors;
            private Type GraphicsWindowType = typeof(GraphicsWindow);
            public bool bValid = false;
    
            public Shadow(string shapeName, string texture)
            {
                Type ImageListType = typeof(Microsoft.SmallBasic.Library.ImageList);
                Dictionary<string, BitmapSource> _savedImages;
                BitmapSource img;
                Dictionary<string, System.Windows.UIElement> _objectsMap;
                System.Windows.UIElement obj;
    
                try
                {
                    _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null);
                    _objectsMap = (Dictionary<string, System.Windows.UIElement>)GraphicsWindowType.GetField("_objectsMap", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null);
                    if (!_objectsMap.TryGetValue(shapeName, out obj)) return;
                    if (obj.GetType() != typeof(System.Windows.Controls.Image)) return;
                    bValid = true;
    
                    InvokeHelper ret = new InvokeHelper(delegate
                    {
                        try
                        {
                            image = (System.Windows.Controls.Image)obj;
                            bNormal = LDImage.getBitmap((BitmapSource)image.Source);
    
                            width = bNormal.Width;
                            height = bNormal.Height;
                            vectors = new Vector3[width, height];
    
                            if (_savedImages.TryGetValue(texture, out img))
                            {
                                bTexture = LDImage.getBitmap(img);
                                if (width != bTexture.Width || height != bTexture.Height) bTexture = null;
                            }
    
                            Color c;
                            for (int i = 0; i < width; i++)
                            {
                                for (int j = 0; j < height; j++)
                                {
                                    c = bNormal.GetPixel(i, j);
                                    vectors[i, j] = new Vector3(c.R - 128f, c.G - 128f, c.B - 128f);
                                    vectors[i, j].Normalize();
                                }
                            }
    
                            if (null != bTexture) bNormal = new Bitmap(bTexture); //to handle alpha channel
                        }
                        catch (Exception ex)
                        {
                            Utilities.OnError(Utilities.GetCurrentMethod(), ex);
                        }
                    });
                    MethodInfo method = GraphicsWindowType.GetMethod("Invoke", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase);
                    method.Invoke(null, new object[] { ret });
                }
                catch (Exception ex)
                {
                    Utilities.OnError(Utilities.GetCurrentMethod(), ex);
                }
            }
    
            public void Update(float x, float y, float z)
            {
                if (!bValid) return;
    
                InvokeHelper ret = new InvokeHelper(delegate
                {
                    try
                    {
                        double scale;
                        byte rgb;
                        Color c;
                        Vector3 source = new Vector3(x, -y, z);
                        source.Normalize();
                        for (int i = 0; i < width; i++)
                        {
                            for (int j = 0; j < height; j++)
                            {
                                scale = 0.5 * (1 + Vector3.Dot(source, vectors[i, j]));
                                scale = System.Math.Max(0, System.Math.Min(1, scale));
    
                                if (null != bTexture)
                                {
                                    c = bTexture.GetPixel(i, j);
                                    bNormal.SetPixel(i, j, Color.FromArgb(c.A, (byte)(c.R * scale), (byte)(c.G * scale), (byte)(c.B * scale)));
                                }
                                else
                                {
                                    rgb = (byte)(255 * scale);
                                    bNormal.SetPixel(i, j, Color.FromArgb(255, rgb, rgb, rgb));
                                }
                            }
                        }
                        image.Source = LDImage.getBitmapImage(bNormal);
                    }
                    catch (Exception ex)
                    {
                        Utilities.OnError(Utilities.GetCurrentMethod(), ex);
                    }
                });
                MethodInfo method = GraphicsWindowType.GetMethod("Invoke", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase);
                method.Invoke(null, new object[] { ret });
            }
        }


    Sunday, November 20, 2016 8:14 PM
    Moderator
  • Added ambient and intensity to try to control the effect

    'normImg = ImageList.LoadImage(Program.Directory +"\img\NM_4.png") ' 88x88
    GraphicsWindow.BackgroundColor = "Black"
    normImg = ImageList.LoadImage(Program.Directory +"\car_normalmap.png") ' 88x88
    textureImg = ImageList.LoadImage(Program.Directory +"\car_texture.png") ' 88x88
    w = ImageList.GetWidthOfImage(normImg)
    h = ImageList.GetHeightOfImage(normImg)
    image1 = Shapes.AddImage(normImg)
    image2 = Shapes.AddImage(textureImg)
    image = Shapes.AddImage(normImg)
    Shapes.Move(image2,100,0)
    Shapes.Move(image,300-w/2,300-h/2)
    GraphicsWindow.PenWidth = 0
    GraphicsWindow.BrushColor = "Yellow"
    light = Shapes.AddEllipse(10,10)
    
    For i = 1 To 3600
      x = Math.Cos(i*Math.Pi/180)
      y = Math.Sin(i*Math.Pi/180)
      LDImage.Shadow(image,x,y,0,textureImg,0.3,2)
      Shapes.Move(light,300+100*x-5,300+100*y-5)
    EndFor

    scale = Vector3.Dot(source, vectors[i, j]);

    scale = ambient + (intensity - ambient) * System.Math.Max(0, scale); c = bTexture.GetPixel(i, j); bNormal.SetPixel(i, j, Color.FromArgb(c.A, LDImage.range(c.R * scale), LDImage.range(c.G * scale), LDImage.range(c.B * scale)));


    Sunday, November 20, 2016 9:30 PM
    Moderator
  • Thats awesome.

    I did notice that the function will edit the normal map shape, not the texture shape. This may make it difficult to apply a shadow to shapes that are already coded into programs. So right now, if I want to rotate the lighted shape, I have to rotate the normal map shape: 

    For i = 1 To 3600
      x = Math.Cos(i*Math.Pi/180)
      y = Math.Sin(i*Math.Pi/180)
      LDImage.Shadow(image,x,y,0.5,textureImg,0.5,2)
      Shapes.Move(light,300+100*x-5,300+100*y-5)
    
      Shapes.Rotate(image,-i) 
    EndFor
    It might make more sense if you had to rotate the textureImg instead.


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Monday, November 21, 2016 12:13 AM
    Answerer
  • The two images normalMap and texture are both loaded into ImageList and neither are modified.

    When the image Shape is created using the normalMap image it is copied from the ImageList to the image shape.  It is the copy inside the image shape that is first read to get the normal vectors (hence loading with the normalMap image), then this shape copy is altered using the normal vectors and the texture image in ImageList.  So both the ImageList versions are not modified at all.

    Rotating the shape is just rotating the modified shape image and the fact that it was originally created from the normalMap image is irrelevant.

    The one thing I could change is that if the ImageList texture image changes between updates then this is taken into account.  I just took a copy of the original ImageList texture on the first load to keep the internal manipulations to a minimum.

    Monday, November 21, 2016 12:19 PM
    Moderator
  • Uploaded the ability to change the texture, press a key in my sample below, where the car also rotates andthe light moves with the mouse.

    'normImg = ImageList.LoadImage(Program.Directory +"\img\NM_4.png") ' 88x88
    GraphicsWindow.BackgroundColor = "Black"
    'normImg = ImageList.LoadImage(Program.Directory +"\car_normalmap.png") ' 88x88
    'textureImg = ImageList.LoadImage(Program.Directory +"\car_texture.png") ' 88x88
    normImg = ImageList.LoadImage("https://social.msdn.microsoft.com/Forums/getfile/965521") ' 88x88
    textureImg = ImageList.LoadImage("https://social.msdn.microsoft.com/Forums/getfile/965522") ' 88x88
    w = ImageList.GetWidthOfImage(normImg)
    h = ImageList.GetHeightOfImage(normImg)
    image1 = Shapes.AddImage(normImg)
    image2 = Shapes.AddImage(textureImg)
    image = Shapes.AddImage(normImg)
    Shapes.Move(image2,100,0)
    Shapes.Move(image,300-w/2,300-h/2)
    GraphicsWindow.PenWidth = 0
    GraphicsWindow.BrushColor = "Yellow"
    light = Shapes.AddEllipse(10,10)
    GraphicsWindow.KeyDown = OnKeyDown
    
    While ("True")
      start = Clock.ElapsedMilliseconds
      
      angle = angle+1
      Shapes.Rotate(image,angle)
    
      x = GraphicsWindow.MouseX
      y = GraphicsWindow.MouseY
      Shapes.Move(light,x-5,y-5)
      rotate = LDMath.Rotate(300,300,x,y,-angle)
      x = rotate[1]
      y = rotate[2]
      LDImage.Shadow(image,x-300,y-300,20,textureImg,0.1,2)
      
      delay = 20-(Clock.ElapsedMilliseconds-start)
      If (delay > 0) Then
        Program.Delay(delay)
      EndIf
    EndWhile
    
    Sub OnKeyDown
      If (textureImg = "") Then
        textureImg = textureImgSave
      Else
        textureImgSave = textureImg
        textureImg = ""
      EndIf
    EndSub



    Monday, November 21, 2016 7:55 PM
    Moderator
  • I had an idea for optimizing it that I thought i'd run by you. What if instead of looping through the pixels in an image, we looped through the colors in an image. This would mean, that if we only had four colors in an image, say like this image: 

    We would only have to loop four times. Then we could just apply the color change to all pixels of the same color. I'm not sure how we could go about finding an array of colors in an image, but I think it can be done.

    PS. Try these normal map images. They look great!

     


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Monday, November 21, 2016 8:29 PM
    Answerer
  • Any method will ultimately change pixel by pixel internally.

    The tanks look great in the last sample I gave.

    How do you create the normal maps?

    Monday, November 21, 2016 8:37 PM
    Moderator
  • @litdev

    ok i find it:

    line:   LDImage.Shadow(image,x-300,y-300,20,textureImg,0.1,2)

    i think it is the 0.1 value,

    again may be for my regional settings keyboard and decimal separator ? 

    Monday, November 21, 2016 10:27 PM
    Answerer
  • I have been using Sprite Illuminator: https://www.codeandweb.com/spriteilluminator

    The reason I suggested trying to optimize is because my CPU currently runs at 45% just from the test program :D

    I'm wondering how the game engines do it with so little processing...


    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11


    Monday, November 21, 2016 10:31 PM
    Answerer
  • @Zock - faster using C++ and GPUs, kinda beyond SB!

    EDIT - also C# .Net pixel setting can be speeded e.g.

    http://stackoverflow.com/questions/24701703/c-sharp-faster-alternatives-to-setpixel-and-getpixel-for-bitmaps-for-windows-f#34801225

    The lower level you go the faster, but more work and care - can't edit smething while it is being rendered etc.

    @YLed - commenting this line out prevents the shadow effect method so you only see the normal map image.

    I've made a few uploads so try again to be sure, and to test you can replace the last 2 args with "" to use defaults as a test.

    LDImage.Shadow(image,x-300,y-300,20,textureImg,"","")

    If it is the localisation confirmed I will try to fix.

    Monday, November 21, 2016 11:11 PM
    Moderator
  • @YLed,

    Perhaps try this simple test first.

    normImg = ImageList.LoadImage("https://social.msdn.microsoft.com/Forums/getfile/966180") ' 88x88
    image = Shapes.AddImage(normImg)
    LDImage.Shadow(image,100,100,20,"","","")

    Then with texture

    normImg = ImageList.LoadImage("https://social.msdn.microsoft.com/Forums/getfile/966180") ' 88x88
    textureImg = ImageList.LoadImage("https://social.msdn.microsoft.com/Forums/getfile/966181") ' 88x88
    image = Shapes.AddImage(normImg)
    LDImage.Shadow(image,100,100,20,textureImg,0.1,2)
    Tuesday, November 22, 2016 6:27 PM
    Moderator
  • @litdev

    Something news, may be will help ! i hope !!

    you know that i am a work-around in programming.

    so i try to LDimage.copy the normal image, and put a LDimage.effectgray , why ? i don't know , just to try some variants like in Chess. :)

    with that no more error:

    so i introduce this:

    __________________________________________

    ximg=LDImage.Copy(image1)
    LDImage.EffectGray(ximg)

    __________________________________________

    into this program:  LRT473

    image1 is copy to ximg and i use the ximg in the LDshadow command. in line 42

     LDImage.Shadow(ximg,x-300,y-300,20,textureImg,0.1,2)

    Tuesday, November 22, 2016 8:15 PM
    Answerer
  • I uploaded a debug test to get some idea where the problem may be - it may take a few tries.

    Test code:

    normImg = ImageList.LoadImage("https://social.msdn.microsoft.com/Forums/getfile/966180") ' 88x88
    image = Shapes.AddImage(normImg)
    LDImage.DebugNormalMap(image,100,100,20,"","","")
    What do you get in TextWindow before crash?

    Tuesday, November 22, 2016 8:16 PM
    Moderator
  • Thanks, and again new test upload with more debug statements, same Small Basic test code.

    Tuesday, November 22, 2016 9:12 PM
    Moderator
  • see December Challenge suggestion:

    program HTT158



    • Edited by YLedEditor Wednesday, November 23, 2016 4:19 PM
    Tuesday, November 22, 2016 9:26 PM
    Answerer
  • Nice picture effects!

    And another test upload same again - getting there I hope - thanks for your patience.

    Tuesday, November 22, 2016 9:40 PM
    Moderator
  • see my email !
    Tuesday, November 22, 2016 9:56 PM
    Answerer
  • Unfortunately Ximg is an ImageList image, not an image in the shape so the problem code is bypassed.

    I assume these results ending at Shaow 2A were with the version upoaded following your email.

    Tuesday, November 22, 2016 10:32 PM
    Moderator
  • Ok i suggest to  take a break :)

    i'm going to supper, and after it's the soccer game on Tv, MLS semi-final.

    thanks very much , i'm sure you will find it another day !!!

    Tuesday, November 22, 2016 10:42 PM
    Answerer
  • Thanks for your help and have a good evening.

    If you want to try again sometime I have had some ideas and uploaded yet another version - no debug stuff this time, so try

    normImg = ImageList.LoadImage("https://social.msdn.microsoft.com/Forums/getfile/966180") ' 88x88
    image = Shapes.AddImage(normImg)
    LDImage.NormalMap(image,100,100,20,"","","")
    Or LQV688 where I was also playing with creating normal maps from height maps which may be good for 3D terrains in 2D games.

    • Proposed as answer by YLedEditor Saturday, November 26, 2016 5:26 PM
    Tuesday, November 22, 2016 11:41 PM
    Moderator
  • @litdev

    Yes !!!! this time it work !!

    i get this for the 3 lines code above

    Wednesday, November 23, 2016 2:27 PM
    Answerer
  • @litdev

    now for the big test: program LQV688

    it work !! :)

    i see 4 images, and one is rotating , great 3D effect !

    and i can move with the mouse the little yellow light and the light angle change in real time.

    i have change the background color to dark gray  "#222222"



    • Edited by YLedEditor Wednesday, November 23, 2016 2:46 PM
    Wednesday, November 23, 2016 2:33 PM
    Answerer
  • I think I have speeded all the image manipulations including normalMaps by a factor of 10 to 20.
    Wednesday, November 23, 2016 10:34 PM
    Moderator
  • Very nicely done!! This greatly improves the graphical look of a lot of SB games ;D

    It is written: "'As surely as I live,' says the Lord, 'every knee will bow before me; every tongue will acknowledge God.'" Romans 14:11

    Friday, November 25, 2016 9:32 PM
    Answerer
  • (translated by Google translator)

    Hi guys.
    I am sure that all beginners who are learning Small Basic, very grateful to you for what you are showing these examples.

    If you did not do the job, then we would not have all this knowledge.

    Thank you very very much!..

    Saturday, November 26, 2016 8:25 AM