Hey,

since my methond only works with AGKv2, I made a new thread for it and provide a Demo with normalmapping for "real" sprites.

**New Demo:**
2D Normalmapping Demo
**Old Thread where it started(AGKv1):**
[AGKv1] Normal mapping
**Here it was discussed at the same time:**
OMG look what i found
**Old Demo:**
2D Normalmapping Demo
**Picture:**
**2D Normalmapping DynamicLightCount.ps**
#version 120
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texture0;
uniform sampler2D texture1;
varying vec2 uvVarying;
varying vec2 posVarying;
uniform vec4 LightPos;
uniform vec4 LightColor;
uniform vec4 LightPos2;
uniform vec4 LightColor2;
uniform vec4 LightPos3;
uniform vec4 LightColor3;
uniform vec4 LightPos4;
uniform vec4 LightColor4;
uniform vec4 LightPos5;
uniform vec4 LightColor5;
uniform vec4 LightPos6;
uniform vec4 LightColor6;
uniform vec4 LightPos7;
uniform vec4 LightColor7;
uniform vec4 LightPos8;
uniform vec4 LightColor8;
uniform vec4 Resolution;
uniform vec4 AmbientColor;
uniform vec3 Falloff;
uniform float LightCount;
vec3 light(vec4 TLightPos, vec4 TLightColor)
{
TLightPos.y = Resolution.y - TLightPos.y;
vec3 normal = texture2D(texture1, uvVarying.xy).rgb;
vec3 LightDir = vec3(TLightPos.xy - gl_FragCoord.xy, TLightPos.z);
vec3 LDIR=normalize(LightDir);
normal = normal * 2.0 - 1.0;
vec3 NDIR=normalize(normal);
float distance = length(LightDir);
float Attenuation = clamp((1.0 / (Falloff.x +(Falloff.y * distance) +(Falloff.z * distance * distance))) * TLightPos.w,0.0,1.0);
return TLightColor.rgb * max(dot(NDIR, LDIR), 0.0) * Attenuation;
}
void main()
{
vec4 LightPosArray[8] = vec4[8](LightPos,LightPos2,LightPos3,LightPos4,LightPos5,LightPos6,LightPos7,LightPos8);
vec4 LightColorArray[8] = vec4[8](LightColor,LightColor2,LightColor3,LightColor4,LightColor5,LightColor6,LightColor7,LightColor8);
vec4 diffuse = texture2D(texture0, uvVarying.xy);
vec3 PLight;
for(int i=0; i<int(LightCount); i++)
PLight = PLight + light(LightPosArray[i],LightColorArray[i]);
gl_FragColor = diffuse * (AmbientColor + vec4(PLight,0.0));
}

AGK Code:

SetDisplayAspect( 1024.0/640.0 )
SetVirtualResolution(1024,640)
SetSyncRate(0,0)
setprintsize(16)
SetScissor(0,0,0,0)
//loadspriteshader(1,"2D Normalmapping.ps")
loadspriteshader(1,"2D Normalmapping DynamicLightCount.ps")
loadimage(1,"Diffuse.png")
loadimage(2,"Normal.png")
loadimage(3,"pizza_d.png")
loadimage(4,"pizza_n.png")
createsprite(1,1)
SetSpriteAdditionalImage(1,2,1)
SetSpriteAdditionalImage(1,3,2)
setspriteshader(1,1)
SetSpritePositionByOffset(1,512,320)
SetShaderConstantByName( 1, "LightColor", 1.0,0.8,0.6, 1.0 )
SetShaderConstantByName( 1, "LightColor2", 1.0,0.0,0.0, 1.0 )
SetShaderConstantByName( 1, "LightColor3", 0.0,0.0,1.0, 1.0 )
SetShaderConstantByName( 1, "LightColor4", 0.2,0.6,0.8, 1.0 )
SetShaderConstantByName( 1, "LightColor5", 1.0,0.0,0.1, 1.0 )
SetShaderConstantByName( 1, "LightColor6", 1.0,1.0,0.0, 1.0 )
SetShaderConstantByName( 1, "LightColor7", 0.0,1.0,1.0, 1.0 )
SetShaderConstantByName( 1, "LightColor8", 0.8,0.6,0.2, 1.0 )
SetShaderConstantByName( 1, "Resolution", GetVirtualWidth(),GetVirtualHeight(),0.0, 0.0 )
SetShaderConstantByName( 1, "AmbientColor", 0.1,0.1,0.1, 1.0 )
SetShaderConstantByName( 1, "Falloff", 0.1,0.01,0.001, 0.0 )
String$="Inverted y normal and Illumination Mapping"
VirtualMidX#=(GetVirtualWidth()*0.5)
VirtualMidY#=(GetVirtualHeight()*0.5)
Radius#=120
LightCount=4
do
print("Press the mouse/Touch the screen to change the Image: "+String$)
print("Light Count: "+str(LightCount))
print("FPS: "+str(screenfps(),2))
if getpointerpressed()=1
Switch=Switch+1
if Switch>1 then Switch=0
if Switch=0
String$="The Ghost"
setspriteimage(1,1)
SetSpriteAdditionalImage(1,2,1)
endif
if Switch=1
String$="The Brick"
setspriteimage(1,3)
SetSpriteAdditionalImage(1,4,1)
endif
endif
if GetRawKeyPressed(49) then LightCount=LightCount-1
if GetRawKeyPressed(50) then LightCount=LightCount+1
SetShaderConstantByName( 1, "LightCount", LightCount,0.0,0.0, 0.0 )
LightX#=getpointerx()
LightY#=getpointery()
LightZ#=10.0
SetShaderConstantByName( 1, "LightPos",LightX#,LightY#,LightZ#, 100.0 )
Angle#=Angle#+60.0*GetFrameTime()
SetShaderConstantByName( 1, "LightPos2",VirtualMidX#+cos(Angle#)*Radius#,VirtualMidY#+sin(Angle#)*Radius#,LightZ#, 10.0 )
SetShaderConstantByName( 1, "LightPos3",VirtualMidX#,VirtualMidY#,LightZ#+sin(Angle#)*LightZ#, 10.0 )
SetShaderConstantByName( 1, "LightPos4",VirtualMidX#+cos(-Angle#)*Radius#,VirtualMidY#+sin(-Angle#)*Radius#,LightZ#, 10.0 )
SetShaderConstantByName( 1, "LightPos5",VirtualMidX#+cos(Angle#*0.5)*Radius#,VirtualMidY#+sin(Angle#*0.5)*Radius#,LightZ#, 10.0 )
SetShaderConstantByName( 1, "LightPos6",VirtualMidX#+cos(Angle#)*Radius#,VirtualMidY#+sin(Angle#*0.5)*Radius#,LightZ#, 10.0 )
SetShaderConstantByName( 1, "LightPos7",VirtualMidX#+cos(Angle#*0.5)*Radius#,VirtualMidY#+sin(Angle#)*Radius#,LightZ#, 10.0 )
SetShaderConstantByName( 1, "LightPos8",VirtualMidX#+cos(Angle#*0.5)*Radius#,VirtualMidY#+sin(Angle#*0.5)*Radius#,LightZ#, 10.0 )
sync()
loop

**2D Normalmapping.ps**
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texture0;
uniform sampler2D texture1;
varying vec2 uvVarying;
varying vec2 posVarying;
uniform vec4 LightPos;
uniform vec4 LightColor;
uniform vec4 LightPos2;
uniform vec4 LightColor2;
uniform vec4 LightPos3;
uniform vec4 LightColor3;
uniform vec4 Resolution;
uniform vec4 AmbientColor;
uniform vec3 Falloff;
vec3 light(vec4 TLightPos, vec4 TLightColor)
{
TLightPos.y = Resolution.y - TLightPos.y;
vec3 normal = texture2D(texture1, uvVarying.xy).rgb;
vec3 LightDir = vec3(TLightPos.xy - gl_FragCoord.xy, TLightPos.z);
vec3 LDIR=normalize(LightDir);
normal = normal * 2.0 - 1.0;
vec3 NDIR=normalize(normal);
float distance = length(LightDir);
float Attenuation = clamp((1.0 / (Falloff.x +(Falloff.y * distance) +(Falloff.z * distance * distance))) * TLightPos.w,0.0,1.0);
return TLightColor.rgb * max(dot(NDIR, LDIR), 0.0) * Attenuation;
}
void main()
{
vec4 diffuse = texture2D(texture0, uvVarying.xy);
vec3 PLight = light(LightPos,LightColor) + light(LightPos2,LightColor2) + light(LightPos3,LightColor3);
gl_FragColor = diffuse * (AmbientColor + vec4(PLight,0.0));
}

**2D NormalmappingIY.ps**
Some Normal Maps have inverted y normals here is my solution

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texture0;
uniform sampler2D texture1;
varying vec2 uvVarying;
varying vec2 posVarying;
uniform vec4 LightPos;
uniform vec4 LightColor;
uniform vec4 LightPos2;
uniform vec4 LightColor2;
uniform vec4 LightPos3;
uniform vec4 LightColor3;
uniform vec4 Resolution;
uniform vec4 AmbientColor;
uniform vec3 Falloff;
vec3 light(vec4 TLightPos, vec4 TLightColor)
{
TLightPos.y = Resolution.y - TLightPos.y;
vec3 normal = texture2D(texture1, uvVarying.xy).rgb;
vec3 LightDir = vec3(TLightPos.x - gl_FragCoord.x,gl_FragCoord.y - TLightPos.y, TLightPos.z);
vec3 LDIR=normalize(LightDir);
normal = normal * 2.0 - 1.0;
vec3 NDIR=normalize(normal);
float distance = length(LightDir);
float Attenuation = clamp((1.0 / (Falloff.x +(Falloff.y * distance) +(Falloff.z * distance * distance))) * TLightPos.w,0.0,1.0);
return TLightColor.rgb * max(dot(NDIR, LDIR), 0.0) * Attenuation;
}
void main()
{
vec4 diffuse = texture2D(texture0, uvVarying.xy);
vec3 PLight = light(LightPos,LightColor) + light(LightPos2,LightColor2) + light(LightPos3,LightColor3);
gl_FragColor = diffuse * (AmbientColor + vec4(PLight,0.0));
}

**2D Normalmapping Illuminationmapping.ps**
Provide a third texture as Illumination Map

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 uvVarying;
varying vec2 posVarying;
uniform vec4 LightPos;
uniform vec4 LightColor;
uniform vec4 LightPos2;
uniform vec4 LightColor2;
uniform vec4 LightPos3;
uniform vec4 LightColor3;
uniform vec2 Resolution;
uniform vec3 AmbientColor;
uniform vec3 Falloff;
uniform float Threshold;
vec3 light(vec4 TLightPos, vec4 TLightColor)
{
TLightPos.y = Resolution.y - TLightPos.y;
vec3 normal = texture2D(texture1, uvVarying.xy).rgb;
vec3 LightDir = vec3(TLightPos.x - gl_FragCoord.x,gl_FragCoord.y - TLightPos.y, TLightPos.z);
vec3 LDIR=normalize(LightDir);
normal = normal * 2.0 - 1.0;
vec3 NDIR=normalize(normal);
float distance = length(LightDir);
float Attenuation = clamp((1.0 / (Falloff.x +(Falloff.y * distance) +(Falloff.z * distance * distance))) * TLightPos.w,0.0,1.0);
return TLightColor.rgb * max(dot(NDIR, LDIR), 0.0) * Attenuation;
}
void main()
{
vec4 diffuse = texture2D(texture0, uvVarying.xy);
vec3 illumination = texture2D(texture2, uvVarying.xy).rgb;
vec3 lightcolor;
if (illumination.r<Threshold)
{
gl_FragColor = diffuse * vec4(AmbientColor + light(LightPos,LightColor) + light(LightPos2,LightColor2) + light(LightPos3,LightColor3), 1.0);
}
else
{
gl_FragColor = diffuse * vec4(illumination + AmbientColor + light(LightPos,LightColor) + light(LightPos2,LightColor2) + light(LightPos3,LightColor3), 1.0);
}
}

</div>