F
Fishman1175
Guest
Hey all,
I've been trying to learn shaders for a little bit, and now I've had a lot of trouble with a simple specular light shader.
I've been following this article series:
http://learnwebgl.brown37.net/09_lights/lights_specular.html
My code is pretty much copied from that article (with a bunch of stuff commented out... I was experimenting)
Vertex shader
Fragment
Draw code:
the shininess is 0.8
The little orange ball is the light source. As you can see, the well with water is totally dark (I'm only drawing specular light though). The sphere has nonsensical lighting.
I have a couple questions.
1. In the article, they use the "model view" matrix, but game maker has no such named thing. I've been using the "world" matrix in game maker. It worked for the diffuse shader. Is this the right matrix? I tried all of them but none of them worked.
2. I want to say that my problem comes from calculating the vector to the camera. I hardcoded a value in there, moved the camera in my game to that position, and the shader appeared to work. I'm not sure how to calculate the to_camera vector using the "world" matrix.
I've been trying to learn shaders for a little bit, and now I've had a lot of trouble with a simple specular light shader.
I've been following this article series:
http://learnwebgl.brown37.net/09_lights/lights_specular.html
My code is pretty much copied from that article (with a bunch of stuff commented out... I was experimenting)
Vertex shader
Code:
//
attribute vec3 in_Position; // (x,y,z)
attribute vec3 in_Normal; // (x,y,z)
attribute vec4 in_Colour; // (r,g,b,a)
attribute vec2 in_TextureCoord; // (u,v)
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec3 v_vNormal;
varying vec3 v_vVertex;
//varying vec3 v_vCameraVertex;
void main()
{
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
v_vColour = in_Colour;
v_vTexcoord = in_TextureCoord;
v_vVertex = vec3(gm_Matrices[MATRIX_WORLD] * vec4(in_Position, 1.0));
//v_vCameraVertex = vec3(gm_Matrices[MATRIX_WORLD_VIEW] * vec4(in_Position, 1.0));
v_vNormal = vec3(gm_Matrices[MATRIX_WORLD] * vec4(in_Normal, 0.0));
}
Code:
//
// Specular lighting
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec3 v_vNormal;
varying vec3 v_vVertex;
varying vec3 v_vCameraVertex;
uniform vec3 u_vLight;
uniform vec3 u_vAmbient;
uniform float u_fShin;
void main()
{
vec3 to_light;
vec3 vertex_normal;
vec4 col;
float cos_angle;
vec3 diffuse_light;
vec3 spec_light;
vec3 to_camera;
vec3 reflection;
float shine_alpha;
// Calculate a vector from the fragment location to the light source
to_light = u_vLight - v_vVertex;
to_light = normalize(to_light);
// The vertex's normal vector is being interpolated across the primitive
// which can make it un-normalized. So normalize the vertex's normal vector.
vertex_normal = normalize(v_vNormal);
// Calculate the cosine of the angle between the vertex's normal vector
// and the vector going to the light.
cos_angle = dot(vertex_normal, to_light);
cos_angle = clamp(cos_angle, 0.0, 1.0);
diffuse_light = vec3(v_vColour)*cos_angle;
reflection = (2.0 * dot(vertex_normal,to_light) * vertex_normal) - to_light;
// Calculate a vector from the fragment location to the camera.
// The camera is at the origin, so negating the vertex location gives the vector
to_camera = -1.0 * v_vVertex; //this seems to be the problem...
// Calculate the cosine of the angle between the reflection vector
// and the vector going to the camera.
reflection = normalize( reflection );
to_camera = normalize( to_camera );
cos_angle = dot(reflection, to_camera);
cos_angle = clamp(cos_angle, 0.0, 1.0);
shine_alpha = cos_angle;
cos_angle = pow(cos_angle, u_fShin);
col = vec4(/*u_vAmbient + diffuse_light + */ vec3(1.0,1.0,1.0) * cos_angle,1.0);
col = col * texture2D( gm_BaseTexture, v_vTexcoord );
//col.a = max(col.a,shine_alpha);
gl_FragColor = col;
}
the shininess is 0.8
Code:
var am = obj_ads_settings.ambient;
shader_set(shd_ads_light);
var shader_param = shader_get_uniform(shd_ads_light,"u_vLight");
var ambient_param = shader_get_uniform(shd_ads_light,"u_vAmbient");
var shin_param = shader_get_uniform(shd_ads_light,"u_fShin");
shader_set_uniform_f(shader_param,obj_light.x,obj_light.y,obj_light.z);
shader_set_uniform_f(ambient_param,am,am,am);
shader_set_uniform_f(shin_param,shin);
d3d_model_draw(model,0,0,z,background_get_texture(b_dblue));
shader_reset();
The little orange ball is the light source. As you can see, the well with water is totally dark (I'm only drawing specular light though). The sphere has nonsensical lighting.
I have a couple questions.
1. In the article, they use the "model view" matrix, but game maker has no such named thing. I've been using the "world" matrix in game maker. It worked for the diffuse shader. Is this the right matrix? I tried all of them but none of them worked.
2. I want to say that my problem comes from calculating the vector to the camera. I hardcoded a value in there, moved the camera in my game to that position, and the shader appeared to work. I'm not sure how to calculate the to_camera vector using the "world" matrix.