Normal map filters help needed

I am new to corona and maybe i have missed something. I am trying to use either directional or point light filter on an object, animating the poinLightPosition or dirLightDirection property so that light moves in a circle atound the object. However, regardless the value, light is always appears to fall towards bottom right corner. Is there any way to control the light rotation/orientation? I will some code and screenshots when near a computer.
Thanks.

This is right up my alley.   Send some code and I’ll take a look.  I have a suspicion that you will have time implement some trigonometry to make the light land in the proper quadrant. 

Hi sporkfin, I know - you da man!  :) 

In fact, everything I was doing is based on you invaluable input in this post.

I also looked at your dynamic shader plugin, but I am just testing the waters with corona at the moment and not ready to commit to any plugins or the engine itself.

Here is a screenshot of the test scene, the light (point light here) is orbiting the image, what I want is for it to always point towards the center.

Attaching the test project and a screenshot.

Here is the relevant code:

-- calculate rotation local lightTimer = timer.performWithDelay( 100, function() -- inline function repeats 10x/sec --local physicsState = physics.getPhysicsState() -- get current physics state -- I cannot find property physicsState - getting an error --if (physicsState == "play") then -- if physics state is "play" e.i. not paused if (1) then -- if physics state is "play" e.i. not paused --local sunX, sunY = sun.moveSun() --[[-- calls the moveSun() method from the sun module (require file) which: -- 1) rotates the sun around the center by a set number of degrees -- 2) compares the position of the sun to the center (in degrees) -- 3) converts postion degrees to radians and gets quadrant info for +/- values -- 4) math.cos(radians) = sunX -- 5) math.sin(radians) = sunY -- 6) returns sunX, sunY --]] -- --local rot = math.mod(testPlate.rotation,360) --local rot = testPlate.rotation local rot = system.getTimer() / 10 print("rot:"..rot) local rotrad = math.rad(rot) -- I don't understand how to implement quadrant stuff the sporkfin mentioned in his post. --local quad = math.floor(rotrad / 1.570796) -- --local multX -- X -/+ switch --local multY -- Y -/+ switch (multiplier) -- --if quad == 1 or quad == 2 then -- multX = 1 --else -- multX = 1 --end -- --if quad == 0 or quad == 1 then -- multY = 1 --else -- multY = 1 --end -- print("quad:"..quad ) -- normalizaton ? local Remap = function(value, from1, to1, from2, to2) return (value - from1) / (to1 - from1) \* (to2 - from2) + from2; end local origX = 0.5 local origY = 0.5 -- standard rotation formula local posX = origY \* math.sin(rotrad) + origX \* math.cos(rotrad) local posY = origY \* math.cos(rotrad) - origX \* math.sin(rotrad) posX = Remap(posX, -1,1,0,1) posY = Remap(posY, -1,1,0,1) --local posX = math.sin(rotrad) --local posY = math.cos(rotrad) --print("rot rad:"..rot) --print("posX:"..math.round(posX\*100)/100) --print("posY:"..math.round(posY\*100)/100) -- testPlate.fill.effect = "composite.normalMapWith1PointLight" -- testPlate.fill.effect.dirLightDirection = { 1, 0, 0 } --testPlate.fill.effect.pointLightColor = { 1, 1, 1, 1 } --testPlate.fill.effect.ambientLightIntensity = 0.2 --if (testPlate.alive == true) then -- if the object is not dead -- testPlate.fill.effect.dirLightDirection = { 0.7, 0.3, 0.5 } -- x, y, z values for the Normal Map ; applied to each object -- pointLightPos testPlate.fill.effect.pointLightPos = { posX, posY, 0 } -- x, y, z values for the Normal Map ; applied to each object --testPlate.fill.effect.pointLightPos = { 0.1, 0.2, 0 } -- x, y, z values for the Normal Map ; applied to each object --end end end, 0) -- end inline function and set repeat to infinite

I also tried to write a custom shader to address my needs, but the vector math and GLSL is out of my depth at the moment. Corona Shader Playground link: https://goo.gl/q9jjD3

EDIT:

I wouldn’t mind using directional light instead, I think it would serve my purpose better. it’s just that the point light demonstrates the issue better.

Preview of effect I am after.

Yeah, it’s always best to have your own code for tweaking.  A plugin is just a timesaver.

I notice that you use a conceptual value for the light distance value.

[lua]local origX = 0.5

local origY = 0.5[/lua]

This will give you accurate lighting effects but try making the light an actual object so you can more readily play around with it and then you can reference its actual x and y positions.

Also, use directional light for your initial testing.  I find that one point light has some unpredictability to it, such as highlights, that might make you misinterpret the accuracy of your code or the position of the light.

@sporkfin: I still cannot workout what is going on with shading, something to do with normal map space (object vs camera) and quadrants that you mentioned. In the sample project file there are 2 normal maps:

test image RGBA

normal map rendered with blender internal (camera space)

normal map rendered with cycles (object (or world?) space)

I am attaching 4 screen captures (2 for each - point and directional light), there is clearly something wrong. I can see the quadrant devision in shading. Any ideas on how to solve this?

Hey Adrei,

How familiar are you with Corona?  If I asked you to make an object and then attach a touch joint to it, would that make sense to you?

This is definitely a solvable problem by the way.

I’m digging into your code a little bit and a few things pop out at me.  I’m not quite sure what the logic is behind your Remap functions [lua] posX = Remap(posX, -1,1,0,1)

posY = Remap(posY, -1,1,0,1)[/lua]

It seems like it might be better to use raw trig functions anchored by physical positions (making the light a display object to you can observe it better) rather than relative positions.  With relative positions the math might seem like it’s working but then quadrant issues pop up and there is no way to see why (without an observable object that lets you say - "Oh!, the computer thinks the light is here!).

Your normal maps look a little odd to me but I might just be used to my own workflow.  I use Sprite Illuminator, what are you using?

I totally understand wanting your own codebase for shading but just in case you throw in the towel, I recently changed the Dynamic Shader to a subscription to encourage more people to try it.

Another tip, use real life objects and a ton of drawing calculations to help you figure out all the trig.

More thoughts. . . 

I find that it’s easy to come up with calculations that are trig approximations but they inevitably fail at some point.  In all the mess of calculations, keep in mind the following:

  1. The y axis is reversed in Corona

  2. Rotation is measured clockwise and starts at 12 o’clock

  3. trig angles calculations go counter-clockwise and start at 3’clock

If any of these three things is overlooked, the calculations will fall apart in one quadrant or another.

Not very familiar, just started using it about a week ago.

I’m digging into your code a little bit and a few things pop out at me.  I’m not quite sure what the logic is behind your Remap functions

  1. posX = Remap(posX, -1,1,0,1)
  2. posY = Remap(posY, -1,1,0,1)

This supposed to normalize the value from [-1,1] to [0,1] range - corona texture space.

Your normal maps look a little odd to me but I might just be used to my own workflow.  I use Sprite Illuminator, what are you using?

I use 3D applications like Cinema4D, or Blender. I used Blender for this one.

I am definitely considering your plugin. How do they work anyway? Since they are on the server, does this mean I can only apply it during build and not in simulator?

Thanks for looking into this, by the way.

You actually got me thinking on inverted Y axis, and since I got the desired light motion there is probably nothing to do in my code anymore. The issue is with normal data that affects the actual shading / light casting.

I made this normal map by baking in onto another plane using object space and setting Y normal to -Y, guess what? The point light result is exactly what I was after! the directional light is still off - instead of going full circle around the plane, it appears to bounce from 0 to 90 degrees. Getting closer! :slight_smile:

Point light, correct! 

Directional light, not so :frowning:

I think I got satisfactory result with point light for now, will post back if I find anything new on directional light normals.

Thanks for input.

  

Yeah, I thought those normal maps looked funky!

You were using the same normal map for the point and directional lighting?  If so, that doesn’t really make sense to me unless it’s a normal map setting issue again.  Try adjust the directional z value as well.

@sporkfin: Yes, same map, I used constant value for Z coordinate, thought it only affects the “height” of the light from the surface. Hmm…

--dirLightDirection testPlate.fill.effect.pointLightPos = { posX, posY, 0.2}

There is a follow up topic on this matter here: normal-map-lighting-effects-with-image-sheets

This is right up my alley.   Send some code and I’ll take a look.  I have a suspicion that you will have time implement some trigonometry to make the light land in the proper quadrant. 

Hi sporkfin, I know - you da man!  :) 

In fact, everything I was doing is based on you invaluable input in this post.

I also looked at your dynamic shader plugin, but I am just testing the waters with corona at the moment and not ready to commit to any plugins or the engine itself.

Here is a screenshot of the test scene, the light (point light here) is orbiting the image, what I want is for it to always point towards the center.

Attaching the test project and a screenshot.

Here is the relevant code:

-- calculate rotation local lightTimer = timer.performWithDelay( 100, function() -- inline function repeats 10x/sec --local physicsState = physics.getPhysicsState() -- get current physics state -- I cannot find property physicsState - getting an error --if (physicsState == "play") then -- if physics state is "play" e.i. not paused if (1) then -- if physics state is "play" e.i. not paused --local sunX, sunY = sun.moveSun() --[[-- calls the moveSun() method from the sun module (require file) which: -- 1) rotates the sun around the center by a set number of degrees -- 2) compares the position of the sun to the center (in degrees) -- 3) converts postion degrees to radians and gets quadrant info for +/- values -- 4) math.cos(radians) = sunX -- 5) math.sin(radians) = sunY -- 6) returns sunX, sunY --]] -- --local rot = math.mod(testPlate.rotation,360) --local rot = testPlate.rotation local rot = system.getTimer() / 10 print("rot:"..rot) local rotrad = math.rad(rot) -- I don't understand how to implement quadrant stuff the sporkfin mentioned in his post. --local quad = math.floor(rotrad / 1.570796) -- --local multX -- X -/+ switch --local multY -- Y -/+ switch (multiplier) -- --if quad == 1 or quad == 2 then -- multX = 1 --else -- multX = 1 --end -- --if quad == 0 or quad == 1 then -- multY = 1 --else -- multY = 1 --end -- print("quad:"..quad ) -- normalizaton ? local Remap = function(value, from1, to1, from2, to2) return (value - from1) / (to1 - from1) \* (to2 - from2) + from2; end local origX = 0.5 local origY = 0.5 -- standard rotation formula local posX = origY \* math.sin(rotrad) + origX \* math.cos(rotrad) local posY = origY \* math.cos(rotrad) - origX \* math.sin(rotrad) posX = Remap(posX, -1,1,0,1) posY = Remap(posY, -1,1,0,1) --local posX = math.sin(rotrad) --local posY = math.cos(rotrad) --print("rot rad:"..rot) --print("posX:"..math.round(posX\*100)/100) --print("posY:"..math.round(posY\*100)/100) -- testPlate.fill.effect = "composite.normalMapWith1PointLight" -- testPlate.fill.effect.dirLightDirection = { 1, 0, 0 } --testPlate.fill.effect.pointLightColor = { 1, 1, 1, 1 } --testPlate.fill.effect.ambientLightIntensity = 0.2 --if (testPlate.alive == true) then -- if the object is not dead -- testPlate.fill.effect.dirLightDirection = { 0.7, 0.3, 0.5 } -- x, y, z values for the Normal Map ; applied to each object -- pointLightPos testPlate.fill.effect.pointLightPos = { posX, posY, 0 } -- x, y, z values for the Normal Map ; applied to each object --testPlate.fill.effect.pointLightPos = { 0.1, 0.2, 0 } -- x, y, z values for the Normal Map ; applied to each object --end end end, 0) -- end inline function and set repeat to infinite

I also tried to write a custom shader to address my needs, but the vector math and GLSL is out of my depth at the moment. Corona Shader Playground link: https://goo.gl/q9jjD3

EDIT:

I wouldn’t mind using directional light instead, I think it would serve my purpose better. it’s just that the point light demonstrates the issue better.

Preview of effect I am after.

Yeah, it’s always best to have your own code for tweaking.  A plugin is just a timesaver.

I notice that you use a conceptual value for the light distance value.

[lua]local origX = 0.5

local origY = 0.5[/lua]

This will give you accurate lighting effects but try making the light an actual object so you can more readily play around with it and then you can reference its actual x and y positions.

Also, use directional light for your initial testing.  I find that one point light has some unpredictability to it, such as highlights, that might make you misinterpret the accuracy of your code or the position of the light.

@sporkfin: I still cannot workout what is going on with shading, something to do with normal map space (object vs camera) and quadrants that you mentioned. In the sample project file there are 2 normal maps:

test image RGBA

normal map rendered with blender internal (camera space)

normal map rendered with cycles (object (or world?) space)

I am attaching 4 screen captures (2 for each - point and directional light), there is clearly something wrong. I can see the quadrant devision in shading. Any ideas on how to solve this?