2016-07-04 12 views
0

編集: 実際のところ、これらの画像はベクターの違いを示しているだけなので正しいかもしれません。したがって、正しいと仮定すると、実際にBRDFに関するコードのどこかに問題があります。私は完全なシェーダコードを追加しました。私は見ているアーティファクトを示す新しいスクリーンショットを添付しています。それは特定の角度で飽和しているようです。 問題は潜在的に分布にあります。ベックマン分布モデルも試しましたが、同じタイプの問題を示しました。BRDF計算の過飽和度

光源が下に移動するのを見てくださいこれは、右側に飽和する上でだ..から地形..

light at horizon

light just above horizon

上で、私は頂点シェーダで方向を計算するいくつかの問題を抱えている、方向は一角に偏っています(原点) インスタンス化を使用して地形を作成しますが、静的平面を使用するだけで同じ問題が発生します。

私の頂点シェーダは、(ogre3d使用して)このよう

# version 330 compatibility 
# define MAP_HEIGHT_FACTOR 50000 
# define MAP_SCALE_FACTOR 100 
# 

// attributes 
in vec4 blendIndices; 
in vec4 uv0; 
in vec4 uv1; 
in vec4 uv2; 
in vec4 position; 
in vec2 vtx_texcoord0; 

uniform mat4 viewProjMatrix; 
uniform mat4 modelMatrix; 
uniform mat4 modelViewMatrix; 
uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 
uniform mat4 worldMatrix; 
uniform vec3 cameraPosition; 
uniform vec3 sunPosition; 

out vec4 vtxPosWorld; 
out vec3 lightDirection; 
out vec3 viewVector; 

uniform sampler2D heightmap; 
uniform mat4 worldViewProjMatrix; 

void main() 
{ 
    vec4 vtxPosWorld = vec4((gl_Vertex.x * MAP_SCALE_FACTOR) + uv0.w, 
         (gl_Vertex.y * MAP_SCALE_FACTOR) + uv1.w, 
         (gl_Vertex.z * MAP_SCALE_FACTOR) + uv2.w, 
         1.0) * worldMatrix; 

    l_texcoord0 = vec2((vtxPosWorld.x)/(8192*MAP_SCALE_FACTOR), (vtxPosWorld.z)/(8192*MAP_SCALE_FACTOR)); 

    vec4 hmt = texture(heightmap, l_texcoord0); 
    height = (hmt.x * MAP_HEIGHT_FACTOR); 

    // take the height from the heightmap 
    vtxPosWorld = vec4(vtxPosWorld.x, height, vtxPosWorld.z, vtxPosWorld.w); 

    lightDirection = vec4(normalize(vec4(sunPosition,1.0)) * viewMatrix).xyz; 

    viewVector = normalize((vec4(cameraPosition,1.0)*viewMatrix).xyz-(vtxPosWorld*viewMatrix).xyz); 

    l_Position = worldViewProjMatrix * vtxPosWorld; 

} 

フラグメントシェーダを探します。私はワールド空間など、viewspaceを使用してみました

#version 330 compatibility 
#define TERRAIN_SIZE 8192.0 
#define HEIGHT_SCALE_FACTOR 50000 
#define MAP_SCALE_FACTOR 100 
#define M_PI 3.1415926535897932384626433832795 

in vec2 l_texcoord0; 
in vec4 vtxPosWorld; 
in vec3 viewVector; 

uniform vec3 sunPosition; 
uniform vec3 cameraPosition; 
uniform sampler2D heightmap; 

float G1V(float dotP, float k) 
{ 
    return 1.0f/(dotP*(1.0f-k)+k); 
} 

float calcBRDF(vec3 normal, float fresnel, float MFD, vec3 sunColor) { 

    float F = fresnel; 

    vec3 Nn = normalize(normal.xyz); 
    vec3 Vn = viewVector; 
    vec3 Ln = lightDirection; 
    vec3 Hn = normalize(viewVector + lightDirection); 

    float NdotV = max(dot(Nn,Vn),0.0); 
    float NdotL = max(dot(Nn,Ln),0.0); 
    float NdotH = max(dot(Nn,Hn),0.1); 
    float VdotH = max(dot(Vn,Hn),0.0); 
    float LdotH = max(dot(Ln,Hn),0.0); 

    // Microfacet Distribution 
    float denom, alpha, beckmannD, GGXD; 
    float NdotHSqr = NdotH * NdotH; 
    float alphaSqr = MFD*MFD; 

    // GGX distribution (better performance) 
    denom = NdotHSqr * (alphaSqr-1.0) + 1.0f; 
    GGXD = alphaSqr/(M_PI * pow(denom,2)); 

    float k = MFD/2.0f; 
    float GGX = G1V(NdotL,k) * G1V(NdotV,k); 

    return GGXSpecular = F * GGXD * GGX; 

} 

float calcFresnel(float R) { 
    vec3 Hn = normalize(viewVector + lightDirection); 
    vec3 Vn = viewVector; 
    vec3 Ln = lightDirection; 
    float VdotH = dot(Vn,Hn); 
    float NdotL = dot(Hn,Vn); 
    float fresnel = R + (1-R)*pow((1-NdotL),5); 
    return fresnel; 
} 

vec3 calcNormal(sampler2D heightmap, vec2 texcoord) { 

    const vec2 size = vec2(MAP_SCALE_FACTOR,0.0); 
    vec3 off = ivec3(1,0,1)/TERRAIN_SIZE; 

    float hL = texture2D(heightmap, texcoord - off.xy).x*HEIGHT_SCALE_FACTOR; 
    float hR = texture2D(heightmap, texcoord + off.xy).x*HEIGHT_SCALE_FACTOR; 
    float hD = texture2D(heightmap, texcoord - off.yz).x*HEIGHT_SCALE_FACTOR; 
    float hU = texture2D(heightmap, texcoord + off.yz).x*HEIGHT_SCALE_FACTOR; 

    vec3 va = normalize(vec3(size.xy,(hL-hR))); 
    vec3 vb = normalize(vec3(size.yx,(hD-hU))); 

    return vec3(1.0,1.0,1.0); 
    return normalize(cross(va,vb)/2 + 0.5); 

} 

void main() 
{ 
    vec3 normal = calcNormal(heightmap, l_texcoord0); 

    float N = 1.69; 
    float microFacetDistribution = 1.5; 
    vec3 sunColor = vec3(1.0,1.0,1.0); 
    float Rfactor = calcFresnelReflectance(N); 
    float fresnel = calcFresnel(Rfactor); 
    float brdf = calcBRDF(normal,fresnel,microFacetDistribution,sunColor); 
    float conservedBrdf = clamp(brdf,0.0,fresnel); 

    gl_FragColor.rgb = vec4(0.5,0.5,0.5,1.0)*conservedBrdf; 
} 

...それは、単純な/愚かな問題のように思えるが、私はそれを把握することはできません。| 何か提案が高く評価されました..

+0

'l_lightDirection'と' viewVector'は宣言されておらず、コード内の何にも使われません。 – derhass

+0

シェイダーをもっと完全に更新しました..!ビュー方向とライト方向の画像は、フラグメントシェーダ(gl_FragColor.rgb = dot(normal、viewVector))に直接出力されました。他の問題のようです... –

答えて

0

もちろん答えは馬鹿なものでした。 まず最初に法線が正しくありませんでした。それは、光を一方向だけに当てているように見せる光の方向に歪みを生じさせた。

第2に、光の方向自体を無効にする必要がありました。

関連する問題