Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

How to add shadows to textures?
Started by ghost8bit Jul 23 2015 02:12 AM

17 replies to this topic
drop shadow texture shadow graphics effects
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

ghost8bit

[GLOBAL: userInfoPane.html]
ghost8bit
  • Observer

  • 1 posts
  • Corona SDK

Hey everybody!

 

I have some textures (.png) of different shape (for example, a ball, an airplain, a star) and I need to add shadows for them by coding, not by another texture. It's important because the game textures can be rotated and their shadows must save the direction.

 

I've been searching the topic over the Internet for 3 days, but haven't find the answer. Any help would be greatly appriciated.

 

Thanks in advance



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,263 posts
  • Enterprise

I wonder if a custom shader would do this?



[TOPIC: post.html]
#3

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 786 posts
  • Corona SDK

Do you have (or could you make) mockup images of the effect?

 

Does the shadow only affect the image, or does it cover the ground too?

 

I assume "save the direction" means the direction of the light source?



[TOPIC: post.html]
#4

Charles McKeever

[GLOBAL: userInfoPane.html]
Charles McKeever
  • Contributor

  • 116 posts
  • Alumni

@ghost8bit, you might want to take a look a the 2D shadow work that Rene Aye has done. He has created a 2D shadow library. Here are some resources on the topic.

 

2D Shadows Example

 

2D Shadow Library code:

https://bitbucket.org/reneaye/corona-2d-shadow-system/

 

Hangout Discussion with Rene Aye:

https://youtu.be/wtNuzLwFLxI?t=2364



[TOPIC: post.html]
#5

nasibullin.tz

[GLOBAL: userInfoPane.html]
nasibullin.tz
  • Observer

  • 4 posts
  • Corona SDK

Thanks guys for the answers,

 

@StarCrunch, sure, It must illustrate what I said about

image.png

As It shows, shadow affects the background. 

"Save the direction" means that the light source doesn't change it's position, so if you rotate an image the shadow doesn't change it's direction (from the up-right to rhe down-left or somehow).

 

@Rob, I thought about it, but it cant help fully, I mean, it would help with creation of a filter, but you cant apply the filter to that shape along the image.

 

@Charles, Yea, It's only the lib I could find when I looked for shadow creating but anfortunately it doesn't suit (the images above shows my case).

 

Now I think about applying image-shaped mask to a gradient filled square, how'd you think can it cope with the problem?



[TOPIC: post.html]
#6

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 786 posts
  • Corona SDK

Okay, I figured it might be something like that, or I'd have thrown Rene's (terrific) stuff your way too.  :)

 

No promises, but I've been considering decent multi-pass effects to show, if we have time, during the shader segment on Monday's Corona Geek. I'm not very satisfied with my current example, so I might try this. I have an idea that would build on the technique horacebury used here: Create a drop shadow



[TOPIC: post.html]
#7

nasibullin.tz

[GLOBAL: userInfoPane.html]
nasibullin.tz
  • Observer

  • 4 posts
  • Corona SDK

Oh, that sounds pretty cool, It'd be great if you show smth at Corona Geek!!! 



[TOPIC: post.html]
#8

nasibullin.tz

[GLOBAL: userInfoPane.html]
nasibullin.tz
  • Observer

  • 4 posts
  • Corona SDK

So, on this moment I have the following:

_W=display.contentWidth
_H=display.contentHeight

local background = display.newRect(_W/2,_H/2,_W, _H)
background:setFillColor(0.6, 0.6, 0.8)

--object we want to be with shadow
local ball = display.newImage('30_3@2x.png', _W/2, _H/2)
local size = 10

-- shadow object
local ballshadow = display.newImage( '30_3@2x.png', _W/2 - size+5, _H/2 + size-5)
ballshadow:setFillColor(0)--it fills our obj with black colour not touching the background of the image

--here's a trick for fill.effect, we just make shadow-image's canvas bigger
local r = display.newRect( ballshadow.x, ballshadow.y, ballshadow.width*2, ballshadow.height*2 )
r:setFillColor(0, 0)

--take black obj with extended canvas into the group
local g = display.newGroup()
g:insert(r)
g:insert(ballshadow)
  
--turn a groupObj into a displayObj	
local c = display.capture( g )
   
--apply blur filter and set alpha    
c.fill.effect = "filter.blurGaussian"
c.fill.effect.horizontal.blurSize = 10
c.fill.effect.horizontal.sigma = 128
c.fill.effect.vertical.blurSize = 10
c.fill.effect.vertical.sigma = 128	
c.alpha = 0.7

c.x = ballshadow.x 
c.y = ballshadow.y
  
  
display.remove( ballshadow )
c:toBack()


background:toBack()

BUT:

Corona windows simulator shows neither object nor it's shadow

Android app shows only the object

Corona mac simulator shows everything perthectly

Xcode ios simulator shows only the object

 

I wanna ask Corona labs: What the heck is going on???

image.png



[TOPIC: post.html]
#9

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 786 posts
  • Corona SDK

Hi.

 

My best guess, if that's your complete code, is that you're falling afoul of the "Capture on Launch" issue, as described in the gotchas here: display.capture() Try putting all the code after you load your group into a timer, as done there.

 

Or maybe g is still in the way? I see you removed ballshadow instead...

 

That said, it's looking pretty good so far! The main novelty I think I could introduce, where the shader would come in, would be a little directional steering.



[TOPIC: post.html]
#10

nasibullin.tz

[GLOBAL: userInfoPane.html]
nasibullin.tz
  • Observer

  • 4 posts
  • Corona SDK

Hello!

 

Yeah it was that issue, now it works perfectly good (and yes I had to remove the whole g instead of ballshadow, thanks for the point)

 

Thank you very very much! God bless you, good man!



[TOPIC: post.html]
#11

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 786 posts
  • Corona SDK

Okay, we'll see how it plays out today. Probably will be tight on time, but at any rate I ran with your code and made this:

 

Shadow Multi-Pass

 

The shadow breaks up a bit, which I think is fixable by averaging a few neighbors. As is, it would be worth making a talking point of that sort of thing anyway. (I tried rearranging the multi-pass order, since after all we are doing a blur, but got an error. It looks like filter.blurGaussian is already multi-pass itself and maybe there are some quirks!)



[TOPIC: post.html]
#12

DevilSquid – René

[GLOBAL: userInfoPane.html]
DevilSquid – René
  • Contributor

  • 157 posts
  • Corona SDK

@nasibullin The image is not working, so I guess you want to make something like a dropshadow like the Photoshop layer effects?

Furthermore in your code you are using the gaussianblur filter. I played a lot with it for my camera system with depth of field effects like here: http://devilsquid.com/how-a-2d-camera-system-makes-your-game-more-stylish-and-easier-to-develop-part-2/

All I can say is, that the gaussian blur filter does not work with mobile devices in real time. I don't know why, but the filter must be recalculated on every frame which slows everything down on mobile devices. On desktop the filter is working fine for me.

But as long as your sprites do fit on the screen, maybe you can capture the filtered sprite once, and then remove the filter.

Best
René

[TOPIC: post.html]
#13

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 786 posts
  • Corona SDK

@René Out of curiosity, how recent are the devices you're using? I've run into the same performance issues, but was unsure whether what I have isn't just too old. I should have followed up on this and mentioned the second capture.

 

@nasibullin Obviously just a basic shift in position is a pretty lame excuse for another shader, so I've thrown some color into my example too. But my purposes are intended for illustration, of course. Since you probably just need the shift, those calculations can of course all be done in Lua, say in an enterFrame handler.

 

Also, how was your own performance?



[TOPIC: post.html]
#14

DevilSquid – René

[GLOBAL: userInfoPane.html]
DevilSquid – René
  • Contributor

  • 157 posts
  • Corona SDK

I tested with a iPhone 5 not (5S). The FPS dropped that much, that I decided to not investigate into this technique. But since the desktop comnpilers are out now, the camera system might be interesting for desktop apps. Right now I'm on vacation any my internet connection is rather lame here. When I'm back home I can test it with an iPad Air 2, but I think the FPS will drop too. The docs also do not recommend to use the blur filter for realtime effects. So I think only workaround is to capture the blurred object into a new image and then kill the original gauss blur filter.

[TOPIC: post.html]
#15

DevilSquid – René

[GLOBAL: userInfoPane.html]
DevilSquid – René
  • Contributor

  • 157 posts
  • Corona SDK

I tested with iPad Air 2 and the FPS drops too. Not that much like on an iPhone 5 but definitely too much to use the blur filter on a mobile device in realtime.



[TOPIC: post.html]
#16

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,297 posts
  • Enterprise

this is such a simple/basic effect, that if performance is a concern, then i'd suggest just resorting to an "old tech" solution, and forget about any real-time gaussian blurs and such via shaders.

 

just precreate a monochrome mask of your sprite, blurred by some R.  then draw that under your sprite, offset by some XY, at partial transparency, possibly using multiply blend mode if normal doesn't look right (tho just normal blend mode will probably look right if your shadow mask is truly mono black with alpha -- use multiply if "faking it" with a grayscale-no-alpha bitmap).

 

now if you rotate them both synchronously, but keep the XY offset the same in global coords, it'll preserve the illusion of a constant light source direction.  plus photoshop preprocessed blur will probably look better than your real-time blur anyway AND cost no real-time cpu to generate, just a single additional bitmap to render underneath (which is "cheap" in relative performance terms).



[TOPIC: post.html]
#17

tastymushroom

[GLOBAL: userInfoPane.html]
tastymushroom
  • Enthusiast

  • 41 posts
  • Corona SDK

Old tech!

Exactly what I was thinking... but then I am old!

 

..... and if the image you are trying to shadow moves, then create a physics joint between the object and it's shadow.



[TOPIC: post.html]
#18

Strange Flight

[GLOBAL: userInfoPane.html]
Strange Flight
  • Enthusiast

  • 31 posts
  • Corona SDK

Also, depending on how you may want multiple objects/shadows to interact, you can add the main objects and shadows to two different display groups.

 

Place the shadow group below the objects group and they will appear in two distinct layers. All shadows in the 'background' layer.

 

That way if two objects are placed close to each other the shadows still fall behind them.




[topic_controls]
[/topic_controls]