Webgl Deferred Shading

Larrywayn

Mitglied
Hallo,
ich hab mal wieder Zeit gefunden an meiner kleinen WebGl Engine zu arbeiten.
Inzwischen bin ich schon recht weit gekommen, aber ich hab ein kleines Problem mit dem Licht.

Ich hab das deferred Shading aus dieser Demo nachgebaut
http://mrdoob.github.io/three.js/examples/webgldeferred_pointlights.html

Das funktioniert auch gut, bis auf die Berechnung meiner Lichtposition (wie es mir scheint).
Ich probier seit Tagen verschieden Matrixmultiplikationen und co aus ohne Ergebnis.
Hier die beiden Shader ich hebe die wichtigen Stellen hervor.
-->> sind die Stellen die sich unterschieden, !-> sind Testreste von mir.
Wenn ich es so mache wie in der Demo ist einfach alles schwarz bei mir bis auf die Lichter.
Manchmal scheint das Licht auch korrekt zu sein, jedoch dreht es sich dann mit der Kamera mit.
Vielleicht hat jemand so etwas schon mal gehabt oder hat einfach ein besseres mathematisches Verständnis als ich, danke.

Hier die aktuelle Demo dazu:
http://tunnistava.systemcloud.de/
(Bewegen mit den Pfeiltasten)

VertexShader
(Die Zeile 14 ist von mir, damit ich überhaupt etwas sehe, Zeile 13 wäre die korrekte laut Demo)
Code:
precision highp float;
precision highp int;

attribute vec3 vertexPosition;
uniform mat4 modelviewMatrix;
uniform mat4 projektionsMatrix;
uniform mat4 transformationsMatrix;
uniform mat4 inverseMVMatrix;
uniform mat4 inverseProjMatrix;

void main() { 
   vec4 mvPT = inverseMVMatrix  * vec4(vertexPosition, 1.0);
-->>   gl_Position =  projektionsMatrix * mvPT;
-->>   gl_Position = vec4(sign( ( vec4(vertexPosition, 1.0)).xy), 1.0, 1.0 );
}

Hier das eigentliche Problemkind:
Zeilen 53 und 56 müssen dabei das Problem sein oder die Werte welche die variablen dort haben.
Code:
precision highp float;
precision highp int;

uniform sampler2D uSampler;
uniform sampler2D nSampler;

struct LichtQuelle {
    vec4 Position;
    vec4 Richtung;
    vec4 AmbientFarbe;
    vec4 DiffusFarbe;
    vec4 SpecularFarbe;
    vec4 Attenuation;
    float OuterCutoff;
    float InnerCutoff;
    float Exponent;
};
uniform LichtQuelle licht0;

vec3 float_to_vec3(float data) {
    vec3 uncompressed;
    uncompressed.x = fract(data);
    float zInt = floor(data / 255.0);
    uncompressed.z = fract(zInt / 255.0);
    uncompressed.y = fract(floor(data - (zInt * 255.0)) / 255.0);
    return uncompressed;
}

uniform mat4 inverseProjMatrix;
uniform mat4 projektionsMatrix;
uniform mat4 transformationsMatrix;
uniform mat4 modelviewMatrix;
uniform mat4 inverseMVMatrix;
void main() {
!->    mat4 tmp =  modelviewMatrix;
!->    float x = licht0.Position.x;
!->    float y = licht0.Position.y;
!->    float z2 = licht0.Position.z;
!->    float w = licht0.Position.w;
!->    tmp[3][0] = 0.0;
!->    tmp[3][1] = 0.0;
!->    tmp[3][2] = 0.0;

    float lightradius = 40.0;
    float viewHeight = 1024.0;
    float viewWidth = 1024.0;
    vec2 texCoord = gl_FragCoord.xy / vec2(viewWidth, viewHeight);
    vec4 normalDepth = -texture2D(nSampler, texCoord);
    float z = normalDepth.w;
    if (z == 0.0) discard;
    vec2 xy = texCoord * 2.0 - 1.0;
    vec4 vertexPositionProjected = vec4(xy, z, 1.0);
-->>    vec4 vertexPositionVS  = inverseProjMatrix * vertexPositionProjected;
    vertexPositionVS.xyz /= vertexPositionVS.w;
    vertexPositionVS.w = 1.0;
-->>  vec4 lposition = inverseProjMatrix * licht0.Position;
!->   /* vec4( tmp[0][0] * x + tmp[1][0] * y + tmp[2][0] * z2 + tmp[3][0] * w,
!->    tmp[0][1] * x + tmp[1][1] * y + tmp[2][1] * z2 + tmp[3][1] * w,
!->    tmp[0][2] * x + tmp[1][2] * y + tmp[2][2] * z2 + tmp[3][2] * w,
!->    tmp[0][3] * x + tmp[1][3] * y + tmp[2][3] * z2 + tmp[3][3] * w);
    vec3 lightVector2 = ((lposition.xyz - vertexPositionVS.xyz));
    float distance = length(lightVector2);
    if (distance > lightradius) discard;
    vec3 normal = normalDepth.xyz * 2.0 - 1.0;
    vec4 colorMap = texture2D(uSampler, texCoord);
    vec3 albedo = float_to_vec3(abs(colorMap.x));
    vec3 specularColor = float_to_vec3(abs(colorMap.y));
    float shininess = abs(colorMap.z);
    float wrapAround = sign(colorMap.z);
    float additiveSpecular = sign(colorMap.y);
    vec3 lightVector = normalize(lightVector2.xyz);
    float dotProduct = dot(normal, lightVector);
    float diffuseFull = max(dotProduct, 0.0);
    vec3 diffuse;
    if (wrapAround < 0.0) {
        float diffuseHalf = max(0.5 * dotProduct + 0.5, 0.0);
        const vec3 wrapRGB = vec3(1.0, 1.0, 1.0);
        diffuse = mix(vec3(diffuseFull), vec3(diffuseHalf), wrapRGB);
    } else {
        diffuse = vec3(diffuseFull);
    }
    vec3 halfVector = normalize(lightVector - normalize(vertexPositionVS.xyz));
    float dotNormalHalf = max(dot(normal, halfVector), 0.0);
    float specularNormalization = (shininess + 2.0001) / 8.0;
    vec3 schlick = specularColor + vec3(1.0 - specularColor) * pow(1.0 - dot(lightVector, halfVector), 5.0);
    vec3 specular = schlick * max(pow(dotNormalHalf, shininess), 0.0) * diffuse * specularNormalization;
    float cutoff = 0.3;
    float denom = distance / lightradius + 1.0;
    float attenuation = 1.0 / (denom * denom);
    attenuation = (attenuation - cutoff) / (1.0 - cutoff);
    attenuation = max(attenuation, 0.0);
    attenuation *= attenuation;
    vec3 light = licht0.Exponent * licht0.AmbientFarbe.rgb;
    gl_FragColor = vec4(light * (albedo * diffuse + specular), attenuation);
}

Grüße
Lattywayn
 
Zuletzt bearbeitet: