Chiếu sáng dựa trên pixel là một vấn đề phổ biến trong nhiều ứng dụng OpenGL, vì ánh sáng OpenGL tiêu chuẩn có chất lượng rất kém.Đèn chiếu sáng GLSL chung
Tôi muốn sử dụng chương trình GLSL để có ánh sáng dựa trên mỗi pixel trong chương trình OpenGL của tôi thay vì cho mỗi đỉnh. Chỉ cần khuếch tán ánh sáng, nhưng với sương mù, kết cấu và texture-alpha ít nhất.
tôi bắt đầu với this shader:
texture.vert:
varying vec3 position;
varying vec3 normal;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
normal = normalize(gl_NormalMatrix * gl_Normal);
position = vec3(gl_ModelViewMatrix * gl_Vertex);
}
texture.frag:
uniform sampler2D Texture0;
uniform int ActiveLights;
varying vec3 position;
varying vec3 normal;
void main(void)
{
vec3 lightDir;
float attenFactor;
vec3 eyeDir = normalize(-position); // camera is at (0,0,0) in ModelView space
vec4 lightAmbientDiffuse = vec4(0.0,0.0,0.0,0.0);
vec4 lightSpecular = vec4(0.0,0.0,0.0,0.0);
// iterate all lights
for (int i=0; i<ActiveLights; ++i)
{
// attenuation and light direction
if (gl_LightSource[i].position.w != 0.0)
{
// positional light source
float dist = distance(gl_LightSource[i].position.xyz, position);
attenFactor = 1.0/(gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * dist +
gl_LightSource[i].quadraticAttenuation * dist * dist);
lightDir = normalize(gl_LightSource[i].position.xyz - position);
}
else
{
// directional light source
attenFactor = 1.0;
lightDir = gl_LightSource[i].position.xyz;
}
// ambient + diffuse
lightAmbientDiffuse += gl_FrontLightProduct[i].ambient*attenFactor;
lightAmbientDiffuse += gl_FrontLightProduct[i].diffuse * max(dot(normal, lightDir), 0.0) * attenFactor;
// specular
vec3 r = normalize(reflect(-lightDir, normal));
lightSpecular += gl_FrontLightProduct[i].specular *
pow(max(dot(r, eyeDir), 0.0), gl_FrontMaterial.shininess) *
attenFactor;
}
// compute final color
vec4 texColor = gl_Color * texture2D(Texture0, gl_TexCoord[0].xy);
gl_FragColor = texColor * (gl_FrontLightModelProduct.sceneColor + lightAmbientDiffuse) + lightSpecular;
float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; // Intensität berechnen
fog = clamp(fog, 0.0, 1.0); // Beschneiden
gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); // Nebelfarbe einmischen
}
Bình luận là Đức bởi vì nó là một trang web tiếng Đức nơi mã này đã được đăng , lấy làm tiếc.
Nhưng tất cả công cụ đổ bóng này đều làm mọi thứ rất tối. Không có hiệu ứng ánh sáng ở tất cả - nhưng các mã đổ bóng biên dịch. Nếu tôi chỉ sử dụng GL_LIGHT0 trong trình đổ bóng phân đoạn thì có vẻ như nó hoạt động, nhưng chỉ hợp lý đối với các đa giác đối diện với máy ảnh và đa giác sàn của tôi cực kỳ tối. Ngoài ra quads với RGBA kết cấu cho thấy không có dấu hiệu của sự minh bạch. Tôi sử dụng tiêu chuẩn glRotate/Dịch cho ma trận Modelview và glVertex/Normal cho đa giác của tôi. OpenGL chiếu sáng hoạt động tốt ngoài thực tế là nó trông xấu xí trên bề mặt rất lớn. Tôi gấp ba lần kiểm tra các tiêu chuẩn của tôi, họ ổn.
Có điều gì sai trong mã ở trên không? HOẶC Hãy cho tôi biết lý do tại sao không có Shader ánh sáng chung cho tác vụ thực tế này (điểm dựa trên ánh sáng với khoảng cách từ xa: nến nếu bạn muốn) - không nên chỉ có một cách chính xác để thực hiện việc này? Tôi không muốn bump/normal/parallax/toon/blur/bất kỳ hiệu ứng nào. Tôi chỉ muốn ánh sáng của tôi hoạt động tốt hơn với các đa giác lớn hơn.
Tất cả các hướng dẫn tôi tìm thấy chỉ hữu ích khi chiếu sáng một đối tượng khi máy ảnh ở vị trí 0,0,0 đối diện trực giao với đối tượng. Ở trên là người duy nhất thấy rằng ít nhất là trông giống như điều tôi muốn làm.
Điều đầu tiên: bạn có ràng buộc một mẫu, là các kết cấu và đường chuẩn của bạn đúng không, liệu nó có hiển thị hình học nếu bạn đặt gl_FragColor thành màu cố định không?Với shaders tôi thấy dễ dàng hơn để có được đầu của tôi xung quanh họ bằng cách sử dụng và thêm các tính năng nhỏ tại một thời điểm, trong trường hợp không có khả năng bước vào và theo dõi qua chúng: p. – Robinson
Sampler là TEXTURE_2D và nó bị ràng buộc các polys kết xuất. Texture coords là chính xác, vì ánh sáng openGL bình thường thực hiện hoàn hảo. Normals là hoàn hảo (như đã nêu). Có nó cho thấy hình học khi thiết lập gl_FragColor thành một màu cố định hoặc chỉ để texColor. – Rock