Autor Wątek: [OpenGL] Skopany ambient?  (Przeczytany 1189 razy)

Offline NPS

  • Użytkownik

# Grudzień 25, 2009, 16:15:03
http://img96.imageshack.us/img96/2366/39120950.jpg
cube.vert:
varying vec3 normal;
varying vec3 lightPosition;
varying vec3 halfVector;

void main()
{
    normal = normalize(gl_NormalMatrix * gl_Normal);
    lightPosition = normalize(gl_LightSource[0].position.xyz);
    halfVector = normalize(gl_LightSource[0].halfVector.xyz);
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
cube.frag:
varying vec3 normal;
varying vec3 lightPosition;
varying vec3 halfVector;
uniform sampler2D texture;

void main()
{
    vec4 ambientColour = gl_FrontMaterial.ambient * gl_LightSource[0].ambient
                        + gl_FrontMaterial.ambient * gl_LightModel.ambient;
    vec4 diffuseColour = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
    vec4 specularColour = gl_FrontMaterial.specular * gl_LightSource[0].specular
                         * pow(max(dot(normal, halfVector), 0.0), gl_FrontMaterial.shininess);
    float diffuseValue = max(dot(normal, lightPosition), 0.0);
    vec4 lightColour = ambientColour + diffuseColour * diffuseValue + specularColour;
    gl_FragColor = texture2D(texture, gl_TexCoord[0].xy) * lightColour;
    gl_FragColor.a = 1.0;
}
ustawienia materiału i oświetlenia w kodzie:
float lightPosition[] = {0.0f, 100.0f, 0.0f, 0.0f};
float ambientLight[] = {1.0f, 1.0f, 1.0f};
float diffuseLight[] = {1.0f, 1.0f, 1.0f};
float specularLight[] = {1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition, 0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight, 0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight, 0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight, 0);
float shininess[] = {0.0f};
float ambientMaterial[] = {0.5f, 0.0f, 0.0f};
float diffuseMaterial[] = {0.5f, 0.0f, 0.0f};
float specularMaterial[] = {0.0f, 0.0f, 0.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientMaterial, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseMaterial, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularMaterial, 0);
Na pierwszym obrazku widać, że chociaż od góry oświetlenie działa dobrze, to z boku jest już zupełnie czarno (ciemno). Powinno być ciemniejsze, ale nie czarne (gdybym miał tylko diffuse light, to tak, ale mam jeszcze ambient). Ale tak jest tylko z kamerą pionowo od góry (i przy minimalnym odchyleniu od pionu). Przy większym odchyleniu od pionu ściany są już dobre (ciemniejsze niż góra, ale nie czarne). Ale dolne ścianki, niezależnie od ustawienia kamery, są zawsze czarne. Nie wiem czemu. Może skopałem coś z ambientem, może coś innego.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Witek9002

  • Użytkownik

# Grudzień 26, 2009, 00:34:49
A przerób to:
float ambientMaterial[] = {0.5f, 0.0f, 0.0f};
float diffuseMaterial[] = {0.5f, 0.0f, 0.0f};
float specularMaterial[] = {0.0f, 0.0f, 0.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientMaterial, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseMaterial, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularMaterial, 0);

na coś takiego:
float ambientMaterial[4] = {0.5f, 0.0f, 0.0f, 1.0f};
float diffuseMaterial[4] = {0.5f, 0.0f, 0.0f, 1.0f};
float specularMaterial[4] = {0.0f, 0.0f, 0.0f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientMaterial);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseMaterial);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularMaterial);

Tak samo zrób z właściwościami światła. Shadery wyglądają na dobre.
« Ostatnia zmiana: Grudzień 26, 2009, 00:36:53 wysłana przez Witek9002 »

Offline NPS

  • Użytkownik

# Grudzień 26, 2009, 02:22:51
Nie pomogło.

Offline Kos

  • Użytkownik
    • kos.gd

# Grudzień 26, 2009, 02:49:09
A próbowałeś narysować z samym tylko ambientem, bez oświetlenia i tekstury?

Offline NPS

  • Użytkownik

# Grudzień 26, 2009, 13:49:32
Powinienem zmienić tytuł topicu. Skopany specular. Konkretnie ta jego część:
* pow(max(dot(normal, halfVector), 0.0), gl_FrontMaterial.shininess);Jak ją usunę z mnożenia, to wyświetla się ładnie. Z nią jest błąd jak wyżej. Pytanie - dlaczego?
« Ostatnia zmiana: Grudzień 26, 2009, 13:53:15 wysłana przez NPS »

Offline Kos

  • Użytkownik
    • kos.gd

# Grudzień 26, 2009, 14:24:04
Myślałem, że dlatego, że nie normalizujesz normalnych varying w pixel shaderze (mogą afaik zyskać inną długość podczas interpolacji). Niemniej nie widzę, jak mógłbyś z tego powodu otrzymać gdziekolwiek ujemną wartość (?), więc to chyba nie to - ale spróbuj dorzucić na początku PS:
normal = normalize(normal);

Offline NPS

  • Użytkownik

# Grudzień 26, 2009, 14:46:04
Nie pomaga. W dodatku NetBeans (bo w nim działam) wywala mi ostrzeżenie:
Cytuj
warning C7565: assignment to varying in normal
Natomiast zauważyłem inną dziwną rzecz - dodanie na końcu fragment shadera czegoś takiego:
    if (pow(max(dot(normal, halfVector), 0.0), gl_FrontMaterial.shininess) > 0.0)
    {
        gl_FragColor = texture2D(texture, gl_TexCoord[0].xy);
    }
powoduje ten sam błąd, co wcześniej (tylko oczywiście nie ma żadnego koloru - jedynie czarnobiała tekstura. Ale jeśli zamiast tego dam samo:
    gl_FragColor = texture2D(texture, gl_TexCoord[0].xy);to błędu już nie ma. Teraz powiedzcie - jak obliczenie wartości wyrażenia w tym warunku może powodować błąd? :P

Offline Kos

  • Użytkownik
    • kos.gd

# Grudzień 26, 2009, 16:16:40
Hej, zaraz: nie ma tam czasem 0^0 = NaN ?

(e-> czy może = 1? Wariactwo z tym jest. W każdym razie shininess na 0 nie wydaje się być dobrym pomysłem.)
« Ostatnia zmiana: Grudzień 26, 2009, 16:20:49 wysłana przez Kos »

Offline NPS

  • Użytkownik

# Grudzień 26, 2009, 16:34:44
0^0 to symbol nieoznaczony i wygląda na to, że to tu tkwił błąd. Dzięki. Co nie zmienia faktu, że dalej nie wiem np., czemu obliczenie warunku wpływa na sposób wyświetlania czegoś w shaderze. :P Może błąd powoduje inne błędy? Nie wiem. :P

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Grudzień 26, 2009, 17:21:31
Zle liczys wogole specular :) nie uzywaj halfvectora bo czesto gesto zle dziala :) openGL ma swoj siwat :)

ja to robie tak i smiga az miło :) ew rob sobie swiatlo ambient jako att = 1/ambient^2;

vert:


varying vec3 normal;
varying vec3 position;
varying vec3 lightDir;

void main()
{
normal = normalize(gl_NormalMatrix * gl_Normal);
position = vec3(gl_ModelViewMatrix * gl_Vertex);
lightDir = gl_LightSource[0].position.xyz;

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}


frag:


uniform sampler2D myTexture;

varying vec3 normal;
varying vec3 position;
varying vec3 lightDir;

void main()
{
vec3 n,E,L,R;

n = normalize(normal);
    E = normalize(position);
    L = normalize(lightDir);
    R = reflect(-L,n);
   
vec4 Base = texture2D(myTexture,gl_TexCoord[0].xy);
vec4 Ambient  = (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
(gl_LightSource[0].ambient * gl_FrontMaterial.ambient);
vec4 Diffuse  = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * max(dot(n,L),0.0);
vec4 Specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(clamp(dot(R, E), 0.0, 1.0), gl_FrontMaterial.shininess );


gl_FragColor = (Base*ambient + Base * Diffuse) + Specular;
}