LINUX.ORG.RU

[GLSL] Diffuse Light. Как переделать в directional?

 


0

1

Let’s take a look at our next example program, DiffuseLight. This program demonstrates a simple diffuse lighting shader on a blue sphere. It uses a point light source so you can also see how we determine this in a shader. Of course using a directional light source would be simpler since we’d already supply this vector, but we, as they say, leave that as an exercise for the reader. Listing 6.7 shows the complete DiffuseLight.vp vertex shader.

В openGL Superbible описывается шейдер диффузного затенения. На каждом проходе вычисляется вектор направления света по отношению к данной вершине. Как я понял, чтобы сделать источник света направленным, нужно вычислять вектор источника независимо от текущей вершины. Сделал нормализацию только самого вектора положения источника, но визуально это ничем не отличалось от первого варианта. Или нужно было вне шейдера взять среднюю точку сферы и отнять её от положения источника?

...
uniform vec4	diffuseColor;	
uniform vec3	vLightPosition;
uniform mat4	mvpMatrix;
uniform mat4	mvMatrix;
uniform mat3	normalMatrix;

// Color to fragment program
smooth out vec4 vVaryingColor;

void main(void) 
    { 
    // Get surface normal in eye coordinates
    vec3 vEyeNormal = normalMatrix * vNormal;

    // Get vertex position in eye coordinates
    vec4 vPosition4 = mvMatrix * vVertex;
    vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

    // Get vector to light source
    vec3 vLightDir = normalize(vLightPosition - vPosition3);
//я сделал vec3 vLightDir = normalize(vLightPosition);
...
★★★★

> Сделал нормализацию только самого вектора положения источника

Directional vector указывает не положение источника (т.к. положения попросту нету), он указывает направление падающих лучей, и этот вектор всегда постоянен.

Kirakishou
()
Ответ на: комментарий от Kirakishou

А как его найти? Положение источника света минус положение центра фигуры(в видовых координатах)?

wingear ★★★★
() автор топика
Ответ на: комментарий от Kirakishou

Понятно, но, кажется, в том варианте, что сейчас, положение у источника есть, т.е. лучи не параллельны. Если не учитывать координату вершины, то будет как раз то, что нужно?

UPD: Посмотрел, результат казался неотличимым из-за сферы и слишком далекого положения источника. Поставил тор, приблизил источник - оказывается, отличается. Теперь, если не учитывать положение вершины, только направление, то при любом значении всё выглядит так, как будто источник далеко в левом верхнем углу(не важно, в точке -1,1,1 или -100,100,100). А если отнимать координату вершины, то у источника сразу «появляется» положение.

Правда, всё равно не до конца понимаю, почему так. Нужно будет как-нибудь вручную посчитать простую сцену, умножая каждую матрицу

wingear ★★★★
() автор топика
Ответ на: комментарий от wingear

Вы оперируете только вектором направления света и вектором нормали в точке поверхности. Считаете косинус угла между ними, и исходя из него считаете цвет. В качестве примера можно посмотреть http://www.lighthouse3d.com/opengl/glsl/index.php/index.php?ogldir1

Kirakishou
()
Ответ на: комментарий от Kirakishou

Выходит, я сделал как раз то, что по ссылке:

// Simple Diffuse lighting Shader
// Vertex Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130

// Incoming per vertex... position and normal
in vec4 vVertex;
in vec3 vNormal;

// Set per batch
uniform vec4	diffuseColor;	
uniform vec3	vLightPosition;
uniform mat4	mvpMatrix;
uniform mat4	mvMatrix;
uniform mat3	normalMatrix;

// Color to fragment program
smooth out vec4 vVaryingColor;

void main(void) 
    { 
    // Get surface normal in eye coordinates
    vec3 vEyeNormal = normalMatrix * vNormal;
//было:  
    // Get vertex position in eye coordinates
    //vec4 vPosition4 = mvMatrix * vVertex;
    //vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

    // Get vector to light source
    //vec3 vLightDir = normalize(vLightPosition - vPosition3);
//стало:
    vec3 vLightDir = normalize(vLightPosition);
    // Dot product gives us diffuse intensity
    float diff = max(0.0, dot(vEyeNormal, vLightDir));

    // Multiply intensity by diffuse color
    vVaryingColor.rgb = diff * diffuseColor.rgb;
    vVaryingColor.a = diffuseColor.a;

    // Let's not forget to transform the geometry
    gl_Position = mvpMatrix * vVertex;
    }
А у автора источник света - точечный,т.е. всё правильно, или что-то другое подразумевалось под

Of course using a directional light source would be simpler since we’d already supply this vector, but we, as they say, leave that as an exercise for the reader

?

wingear ★★★★
() автор топика
Ответ на: комментарий от wingear

> А у автора источник света - точечный

Да, о чём он в общем-то и писал:

It uses a point light source

Kirakishou
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.