2016-02-06 31 views
0

我正在嘗試實現Blinn-Phong,Cool-Torrance和GGX light模型。我已經實現了前兩種燈光模型,但現在我試圖修復並找出如何在漫反射和光澤之間進行插值。在片段着色器中內插/混合反射和發亮

我的場景將由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; 
} 

enter image description here

+0

「漫和光澤之間的插值*。*」你爲什麼會之間插入「瀰漫」和「光澤」? –

+0

我不知道任何其他方式如何在改變光澤因子時混合/內插漫反射和鏡面反射。所以當材料很粗糙時,它不會反映任何東西,它什麼時候會反映更多。我在這裏做錯了什麼,或者我理解錯了什麼? –

回答

0

經過一番閱讀Hammersley Points on the Hemisphere和理解他們,我設法使用虛幻引擎4的真正陰影提供的代碼和樣本立方圖,從而得到更好的結果。

事情進展得非常緩慢,但我最終達到了目標,並希望迄今爲止我正在執行正確的事情。

這是我的職責是如何結束

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; 
    }