Probleme mit Wolkenrenderer



  • Hallo,

    ich versuche auf Basis dieser Demo einen Wolkenrenderer zu basteln. Ich denke nicht, dass es sinnvoll ist hier den ganzen Quellcode zu posten, worauf er aufbaut kann man ja auf der Seite nachlesen. Kurz zusammengefasst ist es einfach ein Raycaster.
    Im großen und ganzen aber stellen sich mir zwei Probleme.

    1. Die Wolken sind alle dunkel umrandet. Auf diesem Bild kann man gut erkennen was ich meine. Allerdings bekomme ich es nicht hin diesen Rand zu entfernen. Alle, wahrscheinlich naive, Ideen haben dazu geführt, dass die Wolken alle sehr künstlich aussahen, da die Kanten nicht mehr weich gezeichnet wurden, sondern alle sehr hart waren. Hat da jemand vielleicht eine Idee, was man tun könnte?

    2. Ich möchte, dass die Wolken korrekt aussehen, wenn die render-Boxen andere Objekte schneiden. Dazu benutze ich momentan folgende Methode (der depth test wurde deaktiviert):

    // Tiefeninformation linearisieren
    float convertZ(in float depthBufferValue)
    {
       float z = 2.0 * depthBufferValue - 1.0;
       float result = 2.0 * zNear * zFar / (zFar + zNear - z * (zFar - zNear));
    
       return result;
    }
    
    void main()
    {
        // Tiefe der bisher gerenderten Szene ermitteln
        float sceneDepth = texture(sceneDepthTexture, gl_FragCoord.xy / viewport.xy).r;
        // Tiefe der Szene und Tiefe des aktuellen Fragments linearisieren
        sceneDepth = convertZ(zNear, zFar, sceneDepth);
        float fragDepth = convertZ(zNear, zFar, gl_FragCoord.z);
        float depthDiff = sceneDepth - fragDepth;
        // Fragment wegclippen, wenn es hinter der bisherigen Szene liegt
        if (depthDiff < 0.0)
            discard;
    
        // ...
    
        // der for loop beinhalten unter anderem diese Zeile
        for (float dist = 0.0; dist < depthDiff; dist += stepSize)
    
        // ...
    
    }
    

    Das ganze funktioniert aber nicht richtig. Folgende zwei Bilder zeigen mein Problem ganz gut.
    Blick von "vorne"
    Blick um 90° nach rechts gedreht
    Wenn ich von vorne draufgucke wird quasi die komplette Wolke gerendert, eigentlich sollte viel weniger gerendert werden. Wenn ich dann von der Seite gucke sieht alles richtig aus, ich sehe deutlich weniger von der Wolke.
    Desweiteren sieht man auf den Bildern deutlich diese hässlichen Ringe. Wenn ich diese samplerate erhöhe, werden die Ringe dünner.
    Woran können diese beiden Sachen liegen?



  • Was den dunklen Rand angeht: wie sieht denn dein "lighting and absortion stuff" aus?

    Ad 2 sag ich mal nix, da müsste ich mich näher mit beschäftigen - hab ich zu wenig Plan von.



  • Der lighting and absorption stuff sieht so aus:

    // ...    
        float travel = min(distance(rayStart, rayStop), depthDiff);
        // ...
        for (int i = 0; i < numSamples && travel > 0.0; ++i, pos += step, travel -= stepSize) {
    
            float density = texture(Density, pos).x * densityFactor;
            if (density <= 0.0)
                continue;
    
            T *= 1.0 - density * stepSize * absorption;
            if (T <= 0.01)
                break;
    
            vec3 lightDir = normalize(LightPosition - pos) * lscale;
            float Tl = 1.0;
            vec3 lpos = pos + lightDir;
    
            for (int s = 0; s < numLightSamples; ++s) {
                float ld = texture(Density, lpos).x;
                Tl *= 1.0 - absorption * stepSize * ld;
                if (Tl <= 0.01) 
                lpos += lightDir;
            }
    
            vec3 Li = LightIntensity * Tl * LightColor;
            Lo += Li * T * density * stepSize;
        }
    

    und folgende Parameter wurden für die Screenshots verwendet:

    numSamples = 64;
    numLightSamples = 8;
    densityFactor = 10;
    absorption = 1;
    

    Wenn ich density und aborption weiter hochdrehe, sieht die Wolke nicht mehr echt aus, wenn ich die Parameter verringer, verhält sich alles wie erwartet. Die dunklen Ränder bleiben jedoch.


Anmelden zum Antworten