gpt4 book ai didi

opengl - 当 NdotL <= 0 时,Cook-Torrance 着色器切断真的很奇怪

转载 作者:行者123 更新时间:2023-12-04 03:18:59 25 4
gpt4 key购买 nike

所以我一直在尝试在我正在从事的玩具项目中实现 Cook-Torrance 着色器模型,从正确的角度看它看起来相当不错: Normal但是,当您从浅角度观察时,您会看到明亮的伪像和截止点附近的视觉效果。

中断发生是因为我正在检查 NdotL 是否 > 0,但是如果我删除它,事情开始变得更加奇怪: Removed NdotL check颜色反转,在 NdotL == 0 处出现某种线条,在 NdotH < 0 处的每个片段都变成黑色,使其呈蛋形。

这是着色器代码:

#version 330 core
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoord;
in vec3 camPos;
in vec3 lightDir;

out vec4 color;

uniform sampler2D diffuseTexture;
uniform sampler2D glossTexture;
uniform sampler2D metalTexture;
uniform samplerCube cubemapTexture;
uniform vec3 lightPos;

float F(float ior, vec3 view, vec3 halfV) {
float F0 = abs((1.0 - ior) / (1.0 + ior));
F0 *= F0;
float VoH = dot(view,halfV);
float fresnel = F0+(1-F0) * pow(1 - VoH,5);
return fresnel;
}

float chiGGX(float v) {
return v > 0 ? 1 : 0;
}
float G(vec3 view, vec3 norm, vec3 halfV, float alpha) {
float VoH2 = clamp(dot(view,halfV),0.0,1.0);
float chi = chiGGX( VoH2 / clamp(dot(view,norm),0.0,1.0));
VoH2 = VoH2 * VoH2;
float tan2 = (1-VoH2) / VoH2;
return (chi*2)/(1+sqrt(1+alpha*alpha*tan2));

}
float D(float roughness, vec3 norm, vec3 halfV) {
float NdotH = max(dot(norm, halfV), 0.0);
float r1 = 1.0 / ( 4.0 * roughness * roughness * pow(NdotH, 4.0));
float r2 = (NdotH * NdotH - 1.0) / (roughness * roughness * NdotH * NdotH);
return r1 * exp(r2);
}
void main()
{
float gamma = 2.2f;
float roughnessValue = texture(glossTexture, TexCoord).r;
vec3 lightColor = vec3(1.0f, 0.8f, 1.0f)*4.0;

vec3 norm = normalize(Normal);

vec3 viewDir = normalize(camPos-FragPos);
vec3 halfVector = normalize(lightDir + viewDir);
float diff = max(dot(norm, lightDir), 0.0);

float NdotL = dot(norm, lightDir);

float spec = 0;
if(NdotL > 0.0) {
spec = ( F(1.45, viewDir, halfVector) * G(viewDir,norm,halfVector,roughnessValue) * D(roughnessValue,norm,halfVector)) / (3.14151828 * dot(norm, viewDir) * dot(norm, lightDir));
}
vec3 specular = spec * lightColor;
vec3 ambient = vec3(0.05);
vec3 diffuse = (1 - texture(metalTexture, TexCoord).r) * diff * lightColor + ambient;
vec3 finalcolor = (diffuse * pow(texture(diffuseTexture, TexCoord).rgb, vec3(gamma))) + specular;

color = vec4(finalcolor, 1.0f);
color.rgb = pow(color.rgb, vec3(1.0/gamma));

}

我知道有一些未使用的值,但那是因为着色器尚未完成。

最佳答案

我找到了出现这种暴力截断的原因。这个线程中的我们三个人在我们各自的独立实现中都犯了同样的错误。我们忘记了区域投影项,在最终的光照公式中: enter image description here

正确应用它可以解决这个问题:

enter image description here

进入这个:

enter image description here

所以就您的着色器而言,这意味着:

vec3 specular = spec * lightColor * NdotL;

同样适用于漫反射(环境光不适用,因为它来自各个方向,所以将漫反射和漫反射环境光分开)

来源: http://www.trentreed.net/blog/physically-based-shading-and-image-based-lighting/

关于opengl - 当 NdotL <= 0 时,Cook-Torrance 着色器切断真的很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39598160/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com