OpenGL의 조명 시스템을 사용하지 않고 멋진 조명을 구현하기위한 탐구를 시작했습니다. Phong 확산 조명을 성공적으로 구현했습니다. Specular가 내게 문제가되고있다.GLSL/OpenGL 2.1 : 유니폼을 사용한 반사 조명
내가 사용하고있는 OpenGL 상수가 차지하는 공간이 무엇인지 알아야합니다. 오정렬 된 것처럼 보이고 조명 글리치가 발생하기 때문입니다.
성공적으로 Phong 확산 쉐이더를로드하고 실행하여 C++ 코드에 문제가 없음을 확인했습니다. 그러나 C++ 코드는 무의미한 데이터를 쉐이더에 전달할 수 있습니다. 이는 내가 염려하는 것 중 하나입니다. 나는 쉐이더에 관한 모든 C++ 코드뿐만 아니라 쉐이더에 주석을 붙여 넣을 것이다. (문제는 쉐이더에 90 % 확신한다.)
이 이미지에서 광원은 큰 포인트이며 축이 표시됩니다. 조명은 icosphere 주변에서 y = 0에서 회전합니다. 당신이 모델이 무엇인지 생각 ... 내가 당 픽셀 아직 수행하지 않은 주 ... 소스와 같이
여기, 프레 넬 조명입니다 수 있도록여기, 확산이다. .. 점등 얼굴 빛과 카메라 여기
사이하지 어딘가에 빛을 직면하는 방법 참고 다시 나는 30를 곱해야했던 Blinn을-퐁 ... 주의의 방법 조명 된면이 광원을 향하고 내가
const int MAXLIGHTS = 4;
uniform bool justcolor = false;
uniform int lightcount;
uniform vec4 lightposs[MAXLIGHTS];
uniform vec4 lightdirs[MAXLIGHTS];
uniform vec4 lightdifs[MAXLIGHTS];
uniform vec4 lightambs[MAXLIGHTS];
//diffuse
vec4 D;
//specular, normaldotlight
float S, NdotL[MAXLIGHTS];
//normal, eyevec, lightvecs, halfvecs
vec3 N, E, L[MAXLIGHTS], H[MAXLIGHTS];
void main() {
//if(lightcount > MAXLIGHTS) lightcount = MAXLIGHTS;
D = vec4(0.0, 0.0, 0.0, 0.0);
S = 0.0;
N = gl_Normal;
E = normalize(vec3(-gl_Vertex));
for(int i = 0; i < lightcount; i++)
{
//calculating direction to light source
L[i] = normalize(vec3(lightposs[i] - gl_Vertex));
//normal dotted with direction to light source
NdotL[i] = max(dot(N, L[i]), 0.0);
//diffuse term, works just fine
D += gl_Color * lightdifs[i] * NdotL[i];
if(NdotL[i] >= 0.0)
{
//halfvector = normalize(lightdir + eyedir)
H[i] = normalize(L[i] + E);
//Blinn-Phong, only lights up faces whose normals
//point directly to the light source for some reason...
//S += max(0.0, dot(H[i], N));
//Fresnel, lights up more than Blinn-Phong
//but the faces still point directly to the light source,
//not somewhere between the lightsource and myself, like they should.
S += pow(max(0.0, dot(reflect(L[i], N), E)), 50.0);
}
else
{
H[i] = vec3(0.0, 0.0, 0.0);
}
}
//currently only showing specular. To show diffuse add D.
gl_FrontColor = justcolor ? gl_Color : vec4(S * 0.3, S * 0.3, S * 0.3, 1.0);
gl_Position = ftransform();
}
조각 쉐이더 소스 (dirlight "에서로드 ("dirlight.vs "에서로드)이
버텍스 쉐이더 소스를 달성하기 위해 (30)에 의해 하나 뿐인 인자 (S)를 곱해야한다고도 사실 .fs ") C++의 주요 초기화에서
void main()
{
gl_FragColor = gl_Color;
}
발췌 ...
//class program manages shaders
Program shaders = Program();
//attach a vertex shader, compiled from source in dirlight.vs
shaders.addShaderFile(GL_VERTEX_SHADER, "dirlight.vs");
//attach a fragment shader compiled from source in dirlight.fs
shaders.addShaderFile(GL_FRAGMENT_SHADER, "dirlight.fs");
//link program
shaders.link();
//use program
shaders.use();
//Program::getUniformLoc(const char* name) grabs the location
//of the uniform specified
GLint sTime = shaders.getUniformLoc("time");
GLint lightcount = shaders.getUniformLoc("lightcount");
GLint lightdir = shaders.getUniformLoc("lightdirs");
GLint lightdif = shaders.getUniformLoc("lightdifs");
GLint lightamb = shaders.getUniformLoc("lightambs");
GLint lightpos = shaders.getUniformLoc("lightposs");
GLint justcolor = shaders.getUniformLoc("justcolor");
glUniform1i(justcolor, 0);
glUniform1i(lightcount, 2);
//diffuse light colors
GLfloat lightdifs[] = {1.f, 1.f, 1.f, 1.f,
1.f, 1.f, 1.f, 1.f};
glUniform4fv(lightdif, 2, lightdifs);
glUniform4f(lightamb, 0.4f, 0.4f, 0.4f, 1.f);
Excer pt를 C++ 메인 루프에서 ...
//My lights rotate around the origin, where I have placed an icosphere
GLfloat lightposs[] = {-4 * sinf(newTime), lighth, -4 * cosf(newTime), 0.0f,
-4 * sinf(newTime + M_PI), lighth, -4 * cosf(newTime + M_PI), 0.0f};
glUniform4fv(lightpos, 2, lightposs);
기술적으로 꼭지점 셰이더가 아닌 조각 셰이더에서 조명 계산을 수행해야합니다. 이는 조각 쉐이더의 주요 목적 중 하나입니다. 조각 별 조명 모델을 구현합니다. – datenwolf
저는 버텍스 쉐이더에서 먼저 구현하고 있습니다. 그래서 모든 것을 같은 장소에 가질 수 있습니다. 나중에 픽셀 단위로 이동합니다. 그 둘 사이에 오류가 생기지 않기를 바랄뿐입니다. 그게 내가 다루는 유일한 것이 될 때까지는 아닙니다. – Miles