我正在尝试实施Blinn-Phong,Cool-Torrance和GGX灯光模型。我已经实现了前2个光模型,但现在我试图修复并弄清楚如何在漫反射和光泽之间进行插值。
我的场景将包含3行(每行是上面提到的灯光模型之一),其中10个球体,每个球体都有光泽因子.1更大,立方体贴图作为反射/漫反射纹理。
我正在尝试找到有关如何进行插值的有用信息,但我想我现在正在搜索错误的内容。
我的片段着色器代码现在看起来像这样。 PS,我很抱歉代码中留下的所有评论,但我相信它会帮助你看到我想要做的事情。
#version 410 core
#include "../Global/GlobalShader.inc"
#include "../Global/GlobalMesh.inc"
#include "../Global/GlobalLight.inc"
in vec3 Position;
in vec3 Normal;
in vec2 TexCoord;
uniform vec3 cameraPosition;
uniform samplerCube skybox;
uniform DirectionalLight directionalLight;
float specularStrength = 16.0; // to be implemented and be send at parameter
out vec4 gl_FragColor;
vec4 calculateDirectionalLight1(Light light, vec3 direction, vec3 normal, vec3 worldPosition, float specularIntensity, vec3 eyePosition, Material material, vec2 texCoord, vec4 diffuse)
{
vec3 diffuseFactor = (light.color * diffuse * (light.intensity * clamp(dot(normal, direction), 0.0, 1.0)));
vec3 viewDir = normalize(eyePosition - worldPosition);
vec3 reflectDir = normalize(reflect(-direction, normal));
float shininess = (material.shininess / 1000.0);
float specularFactor = pow(clamp(dot(viewDir, reflectDir), 0.0, 1.0), specularIntensity);
vec3 specularColor = (light.color * material.specular) * (specularFactor * shininess);
//return vec4(pow((diffuseFactor + specularColor + light.ambient), GAMMA), 1.0);
return vec4(pow((diffuseFactor + specularColor), GAMMA), 1.0);
//return specularColor;
//return diffuseFactor;
//return shininess;
//return diffuse;
}
void main() {
vec4 tempColor = vec4(0.2);
//vec4 tempColor = vec4(1.0, 0.0, 0.0, 0.0);
//vec4 diffuse = vec4(texture(material.texture.diffuse, TexCoord.st).rgb, 1.0); // *material.diffuse) - vec4(1.0 - material.specular);
vec3 I = normalize(Position - cameraPosition);
vec3 R = reflect(I, normalize(Normal));
vec4 reflection = texture(skybox, R);
// fix blending/interpolation for light
float shininess = (material.shininess / 1000.0);
//gl_FragColor = diffuse * (reflection * shininess) * material.specular;
//vec4 tempFinalDiffuse = mix(diffuse, reflection, shininess);
vec4 tempFinalDiffuse = mix(tempColor, reflection, shininess);
vec4 light = vec4(1.0);
light = calculateDirectionalLight1(directionalLight.light, directionalLight.position, Normal, Position, specularStrength, cameraPosition, material, TexCoord, tempFinalDiffuse);
//gl_FragColor = mix(tempFinalDiffuse, light, shininess);
//gl_FragColor = diffuse;
//gl_FragColor = vec4(shininess);
//gl_FragColor = tempFinalDiffuse * light;
//gl_FragColor = reflection;
gl_FragColor = light;
//gl_FragColor = tempFinalDiffuse;
}
答案 0 :(得分:0)
在阅读了Hammersley Points on the Hemisphere并了解它们之后,我设法使用了虚幻引擎4中Real Shading中提供的代码并对立方体贴图进行了采样,从而获得了更好的结果。
事情进展缓慢,但我最终到达那里,希望到目前为止,我正在做正确的事情。
这是我的功能结束的方式
vec4 brdf_GGX(Light light, vec3 direction, vec3 normal) {
float specular = 0.0;
float matShininess = 1.0 - (material.shininess / 1000.0);
vec2 randomPoint;
vec4 finalColor = vec4(0.0);
vec4 totalLambert = vec4(0.0);
const uint numberSamples = 32;
for (uint sampleIndex = 0; sampleIndex < numberSamples; sampleIndex++)
{
randomPoint = hammersley2d(sampleIndex, numberSamples);
vec3 H = ImportanceSampleGGX(randomPoint, matShininess, vec3(0.0, 1.0, 0.0));
vec3 L = 2.0 * dot(normal, H) * H - normal;
vec3 R = reflect(L, normalize(normal));
totalLambert += texture(skybox, L);
}
totalLambert = totalLambert / numberSamples;
float NdotL = max(dot(normal, direction), 0.0);
if (NdotL > 0.0)
{
vec3 eyeDir = normalize(cameraPosition);
// calculate intermediary values
vec3 halfVector = normalize(direction + eyeDir);
float NdotH = max(dot(normal, halfVector), 0.0);
float NdotV = max(dot(normal, eyeDir), 0.0);
float VdotH = max(dot(eyeDir, halfVector), 0.0);
float mSquared = clamp(matShininess * matShininess, 0.01, 0.99);
float geoAtt = G(NdotH, NdotV, VdotH, NdotL);
float roughness = D_Beckmann(NdotH, mSquared);
float fresnel = R_Fresnel(VdotH);
specular = (fresnel * geoAtt * roughness) / (NdotV * NdotL * PI);
}
vec3 finalValue = light.color * NdotL * (k + specular * (1.0 - k));
return vec4(finalValue, 1.0) * totalLambert;
}
vec3 finalValue = light.color * NdotL * (k + specular * (1.0 - k));
return vec4(finalValue, 1.0) * totalLambert;
}