Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL从定向/点到聚光灯的转换_Opengl_Glsl_Phong - Fatal编程技术网

OpenGL从定向/点到聚光灯的转换

OpenGL从定向/点到聚光灯的转换,opengl,glsl,phong,Opengl,Glsl,Phong,因此,我目前正在尝试在我的顶点着色器中创建聚光灯,目前我可以使用Phong照明模型生成方向光和/或点光 我发现很难计算出聚光灯的正确角度,基本上只需要一个从眼睛空间0,0,0的聚光灯,并向下看Z坐标 我试着让圆锥体里的一切(现在)都变成亮白色,而外面的一切都变成黑色 #version 130 uniform mat4 model_view_matrix; uniform mat4 projection_matrix; uniform mat3 normal_matrix; uniform in

因此,我目前正在尝试在我的顶点着色器中创建聚光灯,目前我可以使用Phong照明模型生成方向光和/或点光

我发现很难计算出聚光灯的正确角度,基本上只需要一个从眼睛空间0,0,0的聚光灯,并向下看Z坐标

我试着让圆锥体里的一切(现在)都变成亮白色,而外面的一切都变成黑色

#version 130

uniform mat4 model_view_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
uniform int light_mode;

uniform vec4 light_pos;
uniform vec3 light_ambient;
uniform vec3 light_diffuse;
uniform vec3 light_specular;

uniform vec3 mtl_ambient;
uniform vec3 mtl_diffuse;
uniform vec3 mtl_specular;
uniform float mtl_shininess;

// Spotlight test
const float spotCutOff = 100.00f;

in vec3 position;
in vec3 normal;
in vec2 texCoord;

out vec2 st;
out vec4 litColour;


vec3 phongLight(in vec4 position, in vec3 norm)
{
    // s is the direction from the light to the vertex
    vec3 s;
    if (light_pos.w == 0.0) {
        s = normalize(light_pos.xyz);
    }
    else {
        s = normalize(vec3(light_pos - position));
    }

    // v is the direction from the eye to the vertex
    vec3 v = normalize(-position.xyz);

    // r is the direction of light reflected from the vertex
    vec3 r = reflect(-s, norm);

    vec3 ambient = light_ambient * mtl_ambient;

    // The diffuse component
    float sDotN = max(dot(s,norm), 0.0);
    vec3 diffuse = light_diffuse * mtl_diffuse * sDotN;

    // Specular component
    vec3 spec = vec3(0.0);
    if (sDotN > 0.0)
        spec = light_specular * mtl_specular * pow(max(dot(r,v), 0.0), mtl_shininess);

    return ambient + diffuse + spec;
}

vec3 spotLight(in vec4 position, in vec3 norm)
{
    vec3 ambient = vec3(0.2, 0.2, 0.2);

    vec3 lightDir = normalize(vec3(light_pos - position));
    vec3 spotDir = vec3(0.0, 0.0, -1.0);



    float angle = degrees(acos(dot(spotDir, lightDir)));
    //angle = max (angle, 0);

    if ((angle) < spotCutOff) {
        return vec3(1.0, 1.0, 1.0);
    }

    float dist = sqrt(positon.x * position.x + position.y + position.y + position.z * position.z);

    if (dist < 1) {
        return vec3(1.0,1.0,0.0);
    }

    return vec3(0.2, 0.2, 0.2);
}

void main(void)
{
    // Convert normal and position to eye coords
    vec3 eyeNorm = normalize(normal_matrix * normal);
    vec4 eyePos = model_view_matrix * vec4(position, 1.0);

    // No lighting effect
    if (light_mode == 0)
    {
        litColour = vec4(1.0, 1.0, 1.0, 1.0);
    }
    // Directional overhead light
    else if (light_mode == 1)
    {
        litColour = vec4(phongLight(eyePos, eyeNorm), 1.0);
    }
    // Point light
    else if (light_mode == 2)
    {
        litColour = vec4(phongLight(eyePos, eyeNorm), 1.0);
    }
    else if (light_mode == 3)
    {
        litColour = vec4(spotLight(eyePos, eyeNorm), 1.0);
    }

    //litColour = vec4(normal*1000, 1.0);

    gl_Position = projection_matrix * eyePos;
    st = texCoord;
}
#版本130
统一mat4模型\视图\矩阵;
一致mat4投影矩阵;
一致mat3正规矩阵;
均匀内光模式;
均匀vec4灯位置;
均匀的vec3光照环境;
均匀的vec3光漫射;
均匀vec3光镜;
均匀vec3 mtl_环境;
均匀vec3mtl_扩散;
均匀vec3 mtl_镜面反射;
均匀浮动mtl_亮度;
//聚光灯试验
恒浮点截止=100.00f;
在vec3位置;
vec3正常;
在vec2 texCoord;
第2街;
外显颜色;
vec3 phongLight(处于vec4位置,处于vec3标准)
{
//s是从灯光到顶点的方向
vec3s;
如果(灯位置w==0.0){
s=标准化(灯光位置xyz);
}
否则{
s=标准化(vec3(灯光位置));
}
//v是从眼睛到顶点的方向
vec3 v=标准化(-position.xyz);
//r是从顶点反射的光的方向
vec3 r=反射(-s,标准);
vec3环境=灯光环境*mtl环境;
//漫反射组件
浮动sDotN=最大值(点(s,标准),0.0);
vec3漫反射=灯光漫反射*mtl漫反射*sDotN;
//镜面反射分量
vec3规范=vec3(0.0);
如果(sDotN>0.0)
规格=光照镜面反射*mtl镜面反射*功率(最大值(点(r,v),0.0),mtl镜面反射亮度);
返回环境光+漫反射光+等级库;
}
vec3聚光灯(处于vec4位置,处于vec3标准)
{
vec3环境=vec3(0.2,0.2,0.2);
vec3 lightDir=规格化(vec3(灯光位置));
vec3-spotDir=vec3(0.0,0.0,-1.0);
浮动角度=度(acos(点(spotDir,lightDir));
//角度=最大值(角度,0);
如果((角度)
聚光灯由位置(ps)和方向(ds)定义。因此,对于位置vp处的每个顶点,可以计算d=vp ps,将其规格化为dn=normalize(d),然后点(dn,ds)将给出聚光灯中的角度。只需将其缩放或将其与截断进行比较即可获得标量

或者,从长远来看,更好的办法是将聚光灯视为一台照相机。对摄影机执行相同的操作:模型和视图矩阵!将每个顶点变换到该空间,并将其从x,y,z,w投影到x,y,z。z是距离,该距离始终适用于照明,x,y可用于在具有圆形形状(或任何其他形状)的纹理中查找

使用这两种技术需要注意的一点是反向投影:确保检查灯光是否只指向前方!检查z或点积的符号