update 20 feb 2014
After much faffing about I've managed to get my light shader to work on my android tablet and phone (but may not work on all devices such as the Galaxy S3). I've updated the code snippet and the download.
update:
Thanks to lilpissywilly I managed to get my shaders working and have combined them into a single shader which allows: 1 texture, 1 directional light, 2 point lights, ambient light and allows the object to be affected by the setObjectColor command:
vertex shader:
// vertex shader
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
varying vec2 uvVarying;
varying vec3 normalVarying;
varying vec3 posVarying;
uniform vec4 uvBounds0;
uniform vec4 startUV;
uniform vec4 endUV;
uniform mat4 agk_World;
uniform mat4 agk_ViewProj;
uniform mat3 agk_WorldNormal;
void main()
{
vec4 pos = agk_World * vec4(position,1);
gl_Position = agk_ViewProj * pos;
vec3 norm = agk_WorldNormal * normal;
posVarying = pos.xyz;
normalVarying = norm;
uvVarying = uv * uvBounds0.xy + uvBounds0.zw;
}
updated 20 feb 2014
Pixel shader:
// pixel shader
// 1 texture and 1 directional light and 2 point lights
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texture0;
varying vec2 uvVarying;
varying vec3 normalVarying;
varying vec3 posVarying;
uniform vec3 DLightDir;
uniform vec3 DLightCol;
uniform vec4 PLightPos1;
uniform vec4 PLightCol1;
uniform vec4 PLightPos2;
uniform vec4 PLightCol2;
uniform float Ambient;
uniform vec4 agk_ObjColor;
void main()
{
vec3 norm = normalize(normalVarying);
// point light 1
vec3 dir1 = PLightPos1.xyz - posVarying;
float atten1 = dot(dir1,dir1);
atten1 = clamp(PLightPos1.w/atten1,0.0,1.0);
float intensity1 = dot(normalize(dir1),norm);
intensity1 = clamp(intensity1,0.0,1.0);
vec3 color1 = PLightCol1.rgb * intensity1 * atten1;
// light 2
vec3 dir2 = PLightPos2.xyz - posVarying;
float atten2 = dot(dir2,dir2);
atten2 = clamp(PLightPos2.w/atten2,0.0,1.0);
float intensity2 = dot(normalize(dir2),norm);
intensity2 = clamp(intensity2,0.0,1.0);
vec3 color2 = PLightCol2.rgb * intensity2 * atten2;
// directional light
vec3 nDLightDir = normalize(DLightDir);
vec3 fDLightCol = DLightCol/255;
vec3 color3 = clamp(dot(-nDLightDir.xyz,norm)*fDLightCol.rgb,0.0,1.0);
// add the three light together
vec4 finalColor = clamp(vec4(color1,1) + vec4(color2,1) + vec4(color3,1),Ambient,1.0);
gl_FragColor = texture2D(texture0, uvVarying) * finalColor * agk_ObjColor;
}
AGK tier 1 code:
`point light 1
setShaderConstantByName(1,"PLightPos1", x position, y position, z position, radius)
setShaderConstantByName(1,"PLightCol1", red, green, blue, 0)
`point light 2
setShaderConstantByName(1,"PLightPos2", x position, y position, z position, radius)
setShaderConstantByName(1,"PLightCol2", red, green, blue, 0)
`directional light
setShaderConstantByName(1,"DLightDir", x direction, y direction, z direction, 0)
setShaderConstantByName(1,"DLightCol", red, green, blue, 0)
`ambient light
setShaderConstantByName(1,"Ambient",ambient level, 0,0,0)
positions, radius and directions are floats
red, green, blue and integers with a range of 0 thru 255
ambient level is a float with a range of 0 thru 1
In the download of this post is a simple project that uses this shader.
+++++++
Original post:
As the title suggest, I've been having a go at learning shaders. With people posting some simple examples and explanations, namely Cliff Mellangard, lilpissywilly and Paul, which has been really helpful so thanks guys, it seemed like a good time to learn.
What I've managed to do is create a shader for a texture and two point lights:
vertex shader:
// vertex shader
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
varying vec2 uvVarying;
varying vec3 normalVarying;
varying vec3 posVarying;
uniform vec4 uvBounds0;
uniform vec4 startUV;
uniform vec4 endUV;
uniform mat4 agk_World;
uniform mat4 agk_ViewProj;
uniform mat3 agk_WorldNormal;
void main()
{
vec4 pos = agk_World * vec4(position,1);
gl_Position = agk_ViewProj * pos;
vec3 norm = agk_WorldNormal * normal;
posVarying = pos.xyz;
normalVarying = norm;
uvVarying = uv * uvBounds0.xy + uvBounds0.zw;
}
pixel shader:
// pixel shader
// one texture and 2 pointlights
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texture0;
varying vec2 uvVarying;
varying vec3 normalVarying;
varying vec3 posVarying;
uniform vec4 PLightPos1;
uniform vec4 PLightCol1;
uniform vec4 PLightPos2;
uniform vec4 PLightCol2;
void main()
{
// light 1
vec3 dir1 = PLightPos1.xyz - posVarying;
vec3 norm1 = normalize(normalVarying);
float atten1 = dot(dir1,dir1);
atten1 = clamp(PLightPos1.w/atten1,0.0,1.0);
float intensity1 = dot(normalize(dir1),norm1);
intensity1 = clamp(intensity1,0.0,1.0);
vec3 color1 = PLightCol1.rgb * intensity1 * atten1;
// light 2
vec3 dir2 = PLightPos2.xyz - posVarying;
vec3 norm2 = normalize(normalVarying);
float atten2 = dot(dir2,dir2);
atten2 = clamp(PLightPos2.w/atten2,0.0,1.0);
float intensity2 = dot(normalize(dir2),norm2);
intensity2 = clamp(intensity2,0.0,1.0);
vec3 color2 = PLightCol2.rgb * intensity2 * atten2;
// add the two lights together
vec4 finalColor = clamp(vec4(color1,1) + vec4(color2,1),0.0,1.0);
gl_FragColor = texture2D(texture0, uvVarying) * finalColor;
}
AGK Tier 1 code to set position, range and colour:
setShaderConstantByName(id,"PLightPos1",xpos,ypos,zpos,range)
setShaderConstantByName(id,"PLightCol1",red,green,blue,0)
I'm sure there's a better way to code the pixel shader but I've never done this before so I'm just pleased it works.
I then tried to do a shader for 1 texture and a directional light but it doesn't work as intended. I simply tried to make it work in the same way as the default shader but the colours come out wrong.
vertex shader:
// vertex shader
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
varying vec2 uvVarying;
varying vec3 normalVarying;
uniform vec4 uvBounds0;
uniform mat4 agk_WorldViewProj;
uniform mat3 agk_WorldNormal;
void main()
{
gl_Position = agk_WorldViewProj * vec4(position,1);
normalVarying = agk_WorldNormal * normal;
uvVarying = uv * uvBounds0.xy + uvBounds0.zw;
}
pixel shader:
// pixel shader
// 1 texture and 1 directional light
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D texture0;
varying vec2 uvVarying;
varying vec3 normalVarying;
uniform vec3 DLightDir;
uniform vec4 DLightCol;
uniform vec4 agk_ObjColor;
void main()
{
vec3 norm = normalize(normalVarying);
vec3 color = dot(-DLightDir.xyz,norm)*DLightCol.rgb;
color = clamp(color,DLightCol.w,1.0);
gl_FragColor = texture2D(texture0, uvVarying) * vec4(color,1);
}
AGK Tier 1 code to set direction and colour:
setShaderConstantByName(id,"DLightDir",xdirection,ydirection,zdirection,0)
setShaderConstantByName(id,"DLightCol",red,green,blue,0)
edit: this project has been replaced
I've attached a project as an example of how it all works, or doesn't as the case may be, so if someone could help me out I'd really appreciate it.