View Full Version : spotLight
franciscoBiaso
01-14-2012, 12:53 AM
I got results with directional light but I can't see what is wrong with spot light.Do you know?thanks!
vertex shader---
----
uniform mat4x4 modelview;
uniform mat4x4 projection;
in vec3 a_vertex;
in vec3 a_normal;
in vec2 a_textureCoord0;
varying out vec2 textureCoord0;
varying out vec4 color;
//estruturas
struct tLight{
uniform vec4 position;
uniform vec4 ambient;
uniform vec4 diffuse;
uniform vec4 specular;
vec4 spotDirection;
float spotCutoff;
float spotCosCutoff;
float spotExpoent;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
struct tMaterial{
uniform vec4 ambient;
uniform vec4 diffuse;
uniform vec4 specular;
uniform vec4 emissive;
uniform float shininess;
};
uniform struct tLight light0;
uniform struct tMaterial material;
void main(){
//vetor que armazenará os resultados finais da luz, inicialmente sem luz
vec4 finalColor = light0.ambient + material.ambient;
//transformando normal nas coordenadas do word -> eye
mat3x3 normalMatrix = mat3x3(modelview);
vec3 normal = normalMatrix * a_normal;
//transformação da posição do word -> eye
vec4 position = modelview * vec4(a_vertex,1.0);
vec3 lightPosition = (modelview * light0.position).xyz;
//vetores
vec3 lightVector = (lightPosition - position.xyz).xyz;
float dist = length(lightVector);
vec3 eye = -(position.xyz);
//cálculo do angulo do termo diffuso, modelo de luz (phong)
float lambertTerm = max(dot(normalize(normal),normalize(lightVector.xy z)),0.0);
//cálculo da atenuação
float attenuation = 1.0;
//se cos(ângulo) > 0 então superfíce está recebendo luz
if(lambertTerm > 0.0){
//a luz na superfície está dentro do cone spot ?
float spotEffect = dot(normalize(-lightVector),normalize(light0.spotDirection.xyz));
if(spotEffect > light0.spotCosCutoff){
//computa termo diffuso
finalColor += light0.diffuse * material.diffuse * lambertTerm;
//cálculos speculares
vec3 HV = eye + lightVector;
float NdotHV = max(dot(normalize(normal),normalize(HV)),0.0);
//computa termo specular
finalColor += light0.specular * material.specular * pow(NdotHV,material.shininess);
//computa atenuação
attenuation = spotEffect/(light0.constantAttenuation +
light0.linearAttenuation * dist +
light0.quadraticAttenuation * dist * dist);
}
}
finalColor *= attenuation;
color = finalColor;
gl_Position = projection * position;
textureCoord0 = a_textureCoord0;
}
---
frag shader
----
uniform sampler2D texture0;
in vec2 textureCoord0;
in vec4 color;
void main(){
vec4 texColor = texture2D(texture0,textureCoord0.st);
gl_FragColor = texColor * color;
}
franciscoBiaso
01-15-2012, 12:06 PM
My implementations :
uniform mat4 modelview;
uniform mat4 projection;
in vec3 a_normal;
in vec3 a_vertex;
in vec2 a_textureCoord0;
varying out vec2 textureCoord0;
varying out vec4 color;
struct tLight{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 spotDirection;
float spotCutoff;
float spotCosCutoff;
float spotExpoent;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
struct tMaterial{
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 emissive;
float shininess;
};
uniform struct tLight light0;
uniform struct tMaterial material;
vec4 DirectionalLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightDirection = (MVm * vec4(light.position.xyz,0.0)).xyz;
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
if(lambertTerm > 0.0){
float diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
return finalColor;
}
vec4 PointLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
if(lambertTerm > 0.0){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
float attenuation = 1.0/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
return finalColor * attenuation;
}
vec4 SpotLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
float attenuation = 0.0;
if(lambertTerm > 0.0){
float spotEffect = dot(normalize(-lightDirection),normalize(light.spotDirection.xyz) );
if(spotEffect > cos(light.spotCutoff)){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
spotEffect = pow(spotEffect,light.spotExpoent);
attenuation = spotEffect/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
}
}
return finalColor * attenuation;
}
void main(){
vec4 position = modelview * vec4(a_vertex,1.0);
//output position
gl_Position = projection * position;
//output color
color = SpotLight(material,light0,a_vertex,a_normal,modelv iew);
//output texture coordinates
textureCoord0 = a_textureCoord0;
}
My spotLight isn't working.What can I do?
thokra
01-16-2012, 01:32 AM
First, please edit your post and put the code into the '['code']' tags (without ''). Code of this length is painful to read without formatting.
franciscoBiaso
01-16-2012, 02:48 PM
My implementation of lights:
Directional Light
*light features
position of light: (0.0,0.0,100.0,0.0);
constante = linear = quadratic attenuation = 0.0;
specular = diffuse = (1.0,1.0,1.0,1.0);
ambient = (0.0,0.0,0.0,0.0);
normal = (0.0,0.0,1.0);
*material features
diffuse = specular = (1.0,1.0,1.0,1.0);
ambient = (0.2,0.2,0.2,0.0);
shininess = 15;
vec4 DirectionalLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightDirection = (MVm * vec4(light.position.xyz,0.0)).xyz;
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
if(lambertTerm > 0.0){
float diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
return finalColor;
}
image of directional light /http://postimage.org/image/ylk7xyd4z/
Point Light:
changes:
set linear attenuation to 0.02;
set position to 10.0,10.0,15.0;
vec4 PointLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
if(lambertTerm > 0.0){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
float attenuation = 1.0/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
return finalColor * attenuation;
}
image of point light
http://postimage.org/image/hjlevzu3b/
Spot Light:
direction = (0.0,0.0,-1.0);
position = (0.0,0.0,10.0);
spotCutoff = 2.0; degrees
spotExpoent = 0.0;
vec4 SpotLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
float attenuation = 0.0;
if(lambertTerm > 0.0){
float spotEffect = dot(normalize(-lightDirection),normalize(light.spotDirection.xyz) );
if(spotEffect > cos(light.spotCutoff)){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
spotEffect = pow(spotEffect,light.spotExpoent);
attenuation = spotEffect/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
finalColor += diffuse;
finalColor += specular;
}
}
return finalColor * attenuation;
}
image of spot light
http://postimage.org/image/7wxix010h/
--------------------------------------------------------
vertex shader
<div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
uniform mat4 modelview;
uniform mat4 projection;
in vec3 a_normal;
in vec3 a_vertex;
in vec2 a_textureCoord0;
varying out vec2 textureCoord0;
varying out vec4 color;
struct tLight{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 spotDirection;
float spotCutoff;
float spotCosCutoff;
float spotExpoent;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
struct tMaterial{
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 emissive;
float shininess;
};
uniform struct tLight light0;
uniform struct tMaterial material;
vec4 DirectionalLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightDirection = (MVm * vec4(light.position.xyz,0.0)).xyz;
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
if(lambertTerm > 0.0){
float diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
return finalColor;
}
vec4 PointLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
if(lambertTerm > 0.0){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
float attenuation = 1.0/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
return finalColor * attenuation;
}
vec4 SpotLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0. 0);
float attenuation = 0.0;
if(lambertTerm > 0.0){
float spotEffect = dot(normalize(-lightDirection),normalize(light.spotDirection.xyz) );
if(spotEffect > cos(light.spotCutoff)){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
spotEffect = pow(spotEffect,light.spotExpoent);
attenuation = spotEffect/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
finalColor += diffuse;
finalColor += specular;
}
}
return finalColor * attenuation;
}
void main(){
vec4 position = modelview * vec4(a_vertex,1.0);
//output position
gl_Position = projection * position;
//output color
color = SpotLight(material,light0,a_vertex,a_normal,modelv iew);
//output texture coordinates
textureCoord0 = a_textureCoord0;
}
[/QUOTE]</div>
frag shader
uniform sampler2D texture0;
in vec2 textureCoord0;
in vec4 color;
void main(){
vec4 texColor = texture2D(texture0,textureCoord0.st);
gl_FragColor = texColor * color;
}
I don't know why spot light don't do a circle.Do you you know whats wrong with my implementation ?
Dark Photon
01-16-2012, 06:39 PM
I don't know why spot light don't do a circle.Do you you know whats wrong with my implementation ?
Looks like you're doing all your lighting calcs in the vertex shader.
So it ends up being important what the vertex density of your mesh is. How many verts are you using across and down the mesh that's visible in your pics?
This annoying dependence on the vertex count is one of the reasons that moves folks to calc lighting in the frag shader.
franciscoBiaso
01-16-2012, 11:17 PM
Thank you very much!
I write the code on fragment shader and obtained result.
My implementation.
****vertex shader****
varying mat4 modelview;
uniform mat4 modelviewMatrix;
uniform mat4 projectionMatrix;
in vec3 a_normal;
in vec3 a_vertex;
in vec2 a_textureCoordinate0;
varying out vec2 textureCoordinate0;
varying float distance;
varying vec4 position;
varying vec3 normal;
void main(){
modelview = modelviewMatrix;
position = modelviewMatrix * vec4(a_vertex,1.0);
gl_Position = projectionMatrix * position;
normal = mat3x3(modelviewMatrix) * a_normal;
textureCoordinate0 = a_textureCoordinate0;
}
****fragment****
uniform sampler2D texture0;
in vec2 textureCoordinate0;
varying vec3 normal;
varying float distance;
varying vec4 position;
varying mat4 modelview;
struct tLight{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 spotDirection;
float spotCutoff;
float spotCosCutoff;
float spotExpoent;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
struct tMaterial{
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 emissive;
float shininess;
};
uniform struct tLight light0;
uniform struct tMaterial material;
vec4 SpotLight(struct tMaterial material,struct tLight light,vec4 position,vec3 normal,float distance,
mat4 modelviewMatrix){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
vec3 lightDirection = (modelviewMatrix * light.position).xyz - position.xyz;
distance = length(lightDirection);
float lambertTerm = max(dot(normalize(normal),normalize(lightDirection )),0.0);
float attenuation = 0.0;
if(lambertTerm > 0.0){
float spotEffect = dot(normalize(-lightDirection),normalize(light.spotDirection.xyz) );
if(spotEffect > light.spotCosCutoff){
vec4 diffuse = material.diffuse * light.diffuse * lambertTerm;
vec3 eye = -position.xyz;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
spotEffect = pow(spotEffect,light.spotExpoent);
attenuation = spotEffect/(light.constantAttenuation +
light.linearAttenuation * distance +
light.quadraticAttenuation * distance * distance);
finalColor += diffuse;
finalColor += specular;
}
}
return finalColor * attenuation;
}
void main(){
vec4 textureColor = texture(texture0,textureCoordinate0.st);
gl_FragColor = material.emissive + SpotLight(material,light0,position,normal,distance ,modelview) * textureColor;
}
image of result:
http://postimage.org/image/ewli4sf3b/
Only other question: why fragment is better than vertex shader?
thokra
01-17-2012, 02:41 AM
Only other question: why fragment is better than vertex shader?
Because when shading at the vertices only you're interpolating the resulting values at the vertices across the primitive. This is also known as Gouraud shading or per-vertex shading.
If, however, you're shading is done per-fragment you can correctly calculate the light contribution for every fragment of the primitive which is far more realistic and allows for way more sophisticated lighting models.
Kopelrativ
01-20-2012, 03:09 PM
Or to take an example:
If you only have one big triangle, the vertex shader would only do three calculations in total. That would give correct lighting at the three corners of the single triangle.
These three lighting results would then automatically be interpolated all over the pixels of the triangle. The final result is only good if the sizes of the triangles are small enough.
On the other hand, the fragment shader executes for every pixel. That allows for perfect resolution. The disadvantage is that it may take a longer time, given that there are usually many more pixels than vertices.
That is why the general recommendation is to do as much as possible in the vertex shader. Not only that, but the fragment shader can be executed more than once for every pixel if the triangles are overlapping and not sorted on increasing distance.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.