0

スペキュラー ライティングに問題があります。アンビエントとディフューズがありますが、見栄えの良いモデルを作成するためにスペキュラーを検討しています。

vertexShader には次のものがあります。

#version 330

layout (location = 0) in vec3 Position;
layout (location = 1) in vec3 Normal;

out vec4 Colour0;

// Transforms
uniform mat4 gModelToWorldTransform;
uniform mat4 gWorldToViewToProjectionTransform;

// Ambient light parameters
uniform vec3 gAmbientLightIntensity;

// Directional light parameters
uniform vec3 gDirectionalLightIntensity;
uniform vec3 gDirectionalLightDirection;

// Material constants
uniform float gKa;
uniform float gKd;
uniform float gKs;
uniform float gKsStrength;

                                                                   
void main()
{  
    // Transform the vertex from local space to homogeneous clip space 
    vec4 vertexPositionInModelSpace = vec4(Position, 1);
    vec4 vertexInWorldSpace = gModelToWorldTransform * vertexPositionInModelSpace;
    vec4 vertexInHomogeneousClipSpace = gWorldToViewToProjectionTransform * vertexInWorldSpace;
    gl_Position = vertexInHomogeneousClipSpace;

    // Calculate the directional light intensity at the vertex
    // Find the normal in world space and normalise it
    vec3 normalInWorldSpace = (gModelToWorldTransform * vec4(Normal, 0.0)).xyz;
    normalInWorldSpace = normalize(normalInWorldSpace);

    // Calculate the ambient light intensity at the vertex
    // Ia = Ka * ambientLightIntensity
    vec4 ambientLightIntensity = gKa * vec4(gAmbientLightIntensity, 1.0);

    // Setup the light direction and normalise it
    vec3 lightDirection = normalize(-gDirectionalLightDirection);
    
    //lightDirection = normalize(gDirectionalLightDirection);
    // Id = kd * lightItensity * N.L
    // Calculate N.L
    float diffuseFactor = dot(normalInWorldSpace, lightDirection);
    diffuseFactor = clamp(diffuseFactor, 0.0, 1.0);

    // N.L * light source colour * intensity
    vec4 diffuseLightIntensity = gKd * vec4(gDirectionalLightIntensity, 1.0f) * diffuseFactor;

    vec3 lightReflect = normalize(reflect(gDirectionalLightDirection, Normal));

    //Calculate the specular light intensity at the vertex
    float specularFactor = dot(normalInWorldSpace, lightReflect);
    specularFactor = pow(specularFactor, gKsStrength);
    vec4 specularLightIntensity = gKs * vec4(gDirectionalLightIntensity, 1.0f) * specularFactor;
   
    // Final vertex colour is the product of the vertex colour
    // and the total light intensity at the vertex 

    vec4 colour = vec4(0.0, 1.0, 0.0, 1.0);
    Colour0 = colour * (ambientLightIntensity + diffuseLightIntensity + specularLightIntensity);
}

次に、私の main.cpp には、これを一緒に機能させるためのコードがいくつかあります。鏡面反射光は、モデルを光沢のあるものに見せるのではなく、明らかに何かを行っています。詳細が表示されません。

次の変数を作成します。

// Lighting uniforms location

GLuint gAmbientLightIntensityLoc;
GLuint gDirectionalLightIntensityLoc;
GLuint gDirectionalLightDirectionLoc;
GLuint gSpecularLightIntensityLoc;

// Materials uniform location
GLuint gKaLoc;
GLuint gKdLoc;
GLuint gKsLoc;
GLuint gKsStrengthLoc;

renderSceneCallBack()次に、メインで呼び出される関数で変数を次のように設定します。

// Set the material properties
glUniform1f(gKaLoc, 0.2f); 
glUniform1f(gKdLoc, 0.9f);
glUniform1f(gKsLoc, 0.5f);
glUniform1f(gKsStrengthLoc, 0.5f);

initLights()次に、すべての照明を処理する関数を作成します。これはメインでも呼び出されます。

static void initLights()
{
    // Setup the ambient light
    vec3 ambientLightIntensity = vec3(0.2f, 0.2f, 0.2f);
    glUniform3fv(gAmbientLightIntensityLoc, 1, &ambientLightIntensity[0]);
    
    // Setup the direactional light
    vec3 directionalLightDirection = vec3(0.0f, 0.0f, -1.0f);
    normalize(directionalLightDirection);
    glUniform3fv(gDirectionalLightDirectionLoc, 1, &directionalLightDirection[0]);

    vec3 directionalLightIntensity = vec3(0.8f, 0.8f, 0.8f);
    glUniform3fv(gDirectionalLightIntensityLoc, 1, &directionalLightIntensity[0]);

    //Setup the specular Light
    vec3 specularLightIntensity = vec3(0.5f, 0.5f, 0.5f);
    glUniform3fv(gSpecularLightIntensityLoc, 1, &specularLightIntensity[0]);
}

誰かが私が間違っているかもしれないことを見ることができますか?私はいくつかの計算が間違っている可能性があります. アンビエント/拡散照明の両方が正しく機能しています。この写真は、現在何が起こっているかを示しています。左側がアンビエント、中央がディフューズ、右側が強度を 30 に設定したスペキュラーです。

ここに画像の説明を入力

答え

この値をメインに渡すのを忘れていました:

gKsStrengthLoc = glGetUniformLocation(shaderProgram, "gKsStrength");
    //assert(gDirectionalLightDirectionLoc != 0xFFFFFFFF);

選択した回答を使用してすべてが機能するようになりました

4

1 に答える 1

3

の値がgKsStrength小さすぎます:

glUniform1f(gKsStrengthLoc, 0.5f);

この値はオブジェクトの光沢の度合いを制御し、値が高いほど光沢が増します。これは、シェーダーでの計算を見ると理にかなっています。

specularFactor = pow(specularFactor, gKsStrength);

指数が大きいほど、値が急速に低下します。これは、スペキュラ ハイライトがより狭くなることを意味します。

典型的な値は、適度に光沢がある場合は 10.0f、非常に光沢がある場合は 30.0f、非常に光沢のあるマテリアルの場合はさらに高くなります。

値を 0.5f にすると、非常に広い鏡面反射光の「ハイライト」が得られます。鏡面反射強度の値もかなり高い (0.5) ため、ハイライトはオブジェクトの大部分をカバーし、大きな部分の色を飽和させます。

于 2014-12-02T17:25:03.070 に答える