Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: spotLight

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    6

    spotLight

    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;
    }

  2. #2
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    6

    Re: spotLight

    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?

  3. #3
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    899

    Re: spotLight

    First, please edit your post and put the code into the '['code']' tags (without ''). Code of this length is painful to read without formatting.

  4. #4
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    6

    Re: spotLight

    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;
    Code :
    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 [img:center]/http://postimage.org/image/ylk7xyd4z/[/img]

    Point Light:
    changes:
    set linear attenuation to 0.02;
    set position to 10.0,10.0,15.0;
    Code :
    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
    [img:center]http://postimage.org/image/hjlevzu3b/[/img]
    Spot Light:
    direction = (0.0,0.0,-1.0);
    position = (0.0,0.0,10.0);
    spotCutoff = 2.0; degrees
    spotExpoent = 0.0;
    Code :
    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
    [img:center]http://postimage.org/image/7wxix010h/[/img]
    --------------------------------------------------------
    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;">
    Code :
    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,modelview);
    	//output texture coordinates
    	textureCoord0 = a_textureCoord0;
    }
    [/QUOTE]</div>
    frag shader
    Code :
    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 ?

  5. #5
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,882

    Re: spotLight

    Quote Originally Posted by franciscoBiaso
    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.

  6. #6
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    6

    Re: spotLight

    Thank you very much!
    I write the code on fragment shader and obtained result.
    My implementation.
    Code :
    ****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:
    [img:center]http://postimage.org/image/ewli4sf3b/[/img]
    Only other question: why fragment is better than vertex shader?

  7. #7
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    899

    Re: spotLight

    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.

  8. #8
    Junior Member Regular Contributor Kopelrativ's Avatar
    Join Date
    Apr 2011
    Posts
    212

    Re: spotLight

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •