编写PBR着色器时高光区域出现黑斑问题求助
PBR着色器问题:高光区域出现黑斑,粗糙度参数完全失效
模型本该最亮的区域出现了黑斑,熬夜调试毫无进展。

我参考了LearnOpenGL的PBR光照教程,同时对照了Nadrin的PBR HLSL代码示例。
我确认自己使用的数学运算和参考内容一致,但就是得不到预期结果。除了黑斑问题,粗糙度参数完全不影响最终效果——尽管我在多个关键位置都用到了这个参数。
以下是我使用的代码,所有输入均为世界空间坐标:
vec3 gammaCorrect(vec3 color) { color = color / (color + vec3(1.0)); return pow(color, vec3(1.0/2.2)); } vec3 shadeDiffuse(vec3 color, vec3 position, vec3 normal) { vec3 lightHue = vec3(0,0,0); for(uint i = 0; i < plb.numLights; ++i) { float sqrdist = distance(plb.lights[i].position, position); sqrdist *= sqrdist; float b = max(0, dot(normalize(plb.lights[i].position - position), normal) * max(0, plb.lights[i].color.a * (1 / sqrdist))); lightHue += plb.lights[i].color.xyz * b; } color *= lightHue; return gammaCorrect(color); } #ifndef PI const float PI = 3.14159265359; #endif float DistributionGGX(vec3 normal, vec3 viewVec, float roughness) { float a2 = pow(roughness, 4); float NdotH = max(dot(normal, viewVec), 0.0); float denom = (NdotH*NdotH * (a2 - 1.0) + 1.0); return a2 / (PI * denom * denom); } float GeometrySchlickGGX(float dotp, float roughness) { return dotp / (dotp * (1.0 - roughness) + roughness); } float GeometrySmith(vec3 normal, vec3 viewVec, vec3 lightVec, float roughness) { float r = (roughness + 1.0); float k = (r * r) / 8.0; return GeometrySchlickGGX(max(dot(normal, viewVec), 0.0), k) * GeometrySchlickGGX(max(dot(normal, lightVec), 0.0), k); } vec3 fresnelSchlick(float cosTheta, vec3 F0) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); } vec3 shadePBR(vec3 albedo, vec3 position, vec3 cameraPos, vec3 normal, float roughness, float metallic) { vec3 viewVec = normalize(cameraPos - position); const vec3 F0 = mix(vec3(0.03), albedo, metallic); vec3 lightHue = vec3(0); for(uint i = 0; i < plb.numLights; ++i) { // radiance vec3 lightVec = normalize(plb.lights[i].position - position); vec3 halfVec = normalize(viewVec + lightVec); float distance = length(plb.lights[i].position - position); float attenuation = 1.0 / (distance * distance); vec3 radiance = plb.lights[i].color.xyz * attenuation * max(plb.lights[i].color.a, 0); // brdf float NDF = DistributionGGX(halfVec, normal, roughness); float G = GeometrySmith(normal, viewVec, lightVec, roughness); vec3 F = fresnelSchlick(max(dot(halfVec, viewVec), 0.0), F0); vec3 kD = mix(vec3(1)-F, vec3(0), metallic); float viewDot = max(dot(normal, viewVec), 0.0); float lightDot = max(dot(normal, lightVec), 0.0); vec3 specular = (NDF * G * F) / (4.0 * max(viewDot * lightDot, 0.000001)); // add to hue lightHue += (kD * albedo / PI + specular) * radiance * lightDot; } //Add in ambient here later vec3 color = lightHue; return gammaCorrect(color); }
我现在要去睡觉了,提前感谢各位的帮助。
内容的提问来源于stack exchange,提问作者WireWhiz
相关产品推荐
相关产品推荐

