照明双深度剥离

时间:2013-04-30 15:52:11

标签: opengl glsl

我正在进行双深度剥离。我想问你,如何正确。我有这样的算法。

glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);

    glBindFramebuffer(GL_FRAMEBUFFER, dualDepthFBOID);

    // Render targets 1 and 2 store the front and back colors
    // Clear to 0.0 and use MAX blending to filter written color
    // At most one front color and one back color can be written every pass
    glDrawBuffers(2, &drawBuffers[1]);
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    GL_CHECK_ERRORS

    // Render target 0 stores (-minDepth, maxDepth, alphaMultiplier)
    glDrawBuffer(drawBuffers[0]);   
    glClearColor(-MAX_DEPTH, -MAX_DEPTH, 0, 0); 
    glClear(GL_COLOR_BUFFER_BIT);
    glBlendEquation(GL_MAX);
    DrawScene(MVP, initShader);  

    // 2. Depth peeling + blending pass
    glDrawBuffer(drawBuffers[6]);
    glClearColor(bg.x, bg.y, bg.z, bg.w);
    glClear(GL_COLOR_BUFFER_BIT);

    int numLayers = (NUM_PASSES - 1) * 2;
    int currId = 0;
    for (int layer = 1; bUseOQ || layer < numLayers; layer++) {
        currId = layer % 2;
        int prevId = 1 - currId;
        int bufId = currId * 3;

        glDrawBuffers(2, &drawBuffers[bufId+1]);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawBuffer(drawBuffers[bufId+0]);
        glClearColor(-MAX_DEPTH, -MAX_DEPTH, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);

        // Render target 0: RG32F MAX blending
        // Render target 1: RGBA MAX blending
        // Render target 2: RGBA MAX blending
        glDrawBuffers(3, &drawBuffers[bufId+0]);
        glBlendEquation(GL_MAX);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_RECTANGLE, depthTexID[prevId]);

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_RECTANGLE, texID[prevId]);
        DrawScene(MVP, dualPeelShader, true,true);

        // Full screen pass to alpha-blend the back color
        glDrawBuffer(drawBuffers[6]);

        glBlendEquation(GL_FUNC_ADD);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        if (bUseOQ) {
            glBeginQuery(GL_SAMPLES_PASSED_ARB, queryId);
        }

        GL_CHECK_ERRORS

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_RECTANGLE, backTexID[currId]);
        blendShader.Use();       
             DrawFullScreenQuad();
        blendShader.UnUse();

        if (bUseOQ) {
            glEndQuery(GL_SAMPLES_PASSED);
            GLuint sample_count;
            glGetQueryObjectuiv(queryId, GL_QUERY_RESULT, &sample_count);
            if (sample_count == 0) {
                break;
            }
        } 
        GL_CHECK_ERRORS 
    } 

    GL_CHECK_ERRORS

    glDisable(GL_BLEND);

    // 3. Final render pass
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glDrawBuffer(GL_BACK_LEFT);

    glBindTexture(GL_TEXTURE_RECTANGLE, colorBlenderTexID);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_RECTANGLE, depthTexID[currId]);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_RECTANGLE, texID[currId]);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_RECTANGLE, colorBlenderTexID);
    finalShader.Use(); 
        DrawFullScreenQuad();
    finalShader.UnUse();

我正在使用dualPeelShader进行照明,每次通过都会点亮。这导致了极其明亮的物体。我应该在finalShader做照明吗?

--- ---- EDIT

剥离片段着色器

#version 330 core

layout(location = 0) out vec4 vFragColor0;
layout(location = 1) out vec4 vFragColor1;
layout(location = 2) out vec4 vFragColor2;  


uniform vec4 vColor;
uniform float isObject;
uniform vec3 LightPosition;

uniform sampler2DRect  depthBlenderTex;
uniform sampler2DRect  frontBlenderTex;

in vec4 vOutColor;
in vec3 position;
in vec3 normal;
in  vec3 eyeDirection;
in  vec3 lightDirection;

#define MAX_DEPTH 1.0

vec4 Lighted()
{
vec3 LightColor = vec3(1.0,1.0,1.0);
float LightPower = 50;

// Material properties

vec3 MaterialDiffuseColor = vOutColor.rgb;
vec3 MaterialAmbientColor = vec3(0.1,0.1,0.1) * MaterialDiffuseColor;
vec3 MaterialSpecularColor = vec3(0.3,0.3,0.3);

// Distance to the light
float distance = length( LightPosition - position );

// Normal of the computed fragment, in camera space
vec3 n = normalize( normal );
// Direction of the light (from the fragment to the light)
vec3 l = normalize( lightDirection);
// Cosvaryinge of the angle between the normal and the light direction,
// clamped above 0
//  - light is at the vertical of the triangle -> 1
//  - light is perpendicular to the triangle -> 0
//  - light is behvaryingd the triangle -> 0
float cosTheta = clamp( dot( n,l ), 0,1 );

// Eye vector (towards the camera)
vec3 E = normalize(eyeDirection);
// Direction in which the triangle reflects the light
vec3 R = reflect(-l,n);
// Cosvaryinge of the angle between the Eye vector and the Reflect vector,
// clamped to 0
//  - Lookvaryingg varyingto the reflection -> 1
//  - Lookvaryingg elsewhere -> < 1
float cosAlpha = clamp( dot( E,R ), 0,1 );

return vec4(MaterialAmbientColor + MaterialDiffuseColor * LightColor * LightPower * cosTheta / (distance*distance) +
MaterialSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance*distance),vOutColor.a);

}


void main(void)
{
float fragDepth = gl_FragCoord.z;
vec2 depthBlender = texture(depthBlenderTex, gl_FragCoord.xy).xy;
vec4 forwardTemp = texture(frontBlenderTex, gl_FragCoord.xy);

// Depths and 1.0-alphaMult always increase
// so we can use pass-through by default with MAX blending
vFragColor0.xy = depthBlender;

// Front colors always increase (DST += SRC*ALPHA_MULT)
// so we can use pass-through by default with MAX blending
vFragColor1 = forwardTemp;

// Because over blending makes color increase or decrease,
// we cannot pass-through by default.
// Each pass, only one fragment writes a color greater than 0
vFragColor2 = vec4(0.0);

float nearestDepth = -depthBlender.x;
float farthestDepth = depthBlender.y;
float alphaMultiplier = 1.0 - forwardTemp.w;

if (fragDepth < nearestDepth || fragDepth > farthestDepth) {
    // Skip this depth in the peeling algorithm
    vFragColor0.xy = vec2(-MAX_DEPTH);
    return;
}

if (fragDepth > nearestDepth && fragDepth < farthestDepth) {
    // This fragment needs to be peeled again
    vFragColor0.xy = vec2(-fragDepth, fragDepth);
    return;
}    

// If we made it here, this fragment is on the peeled layer from last pass
// therefore, we need to shade it, and make sure it is not peeled any farther
vFragColor0.xy = vec2(-MAX_DEPTH);

vec4 Color;
if(isObject == 0.0)
 Color = vColor;
else
 Color = Lighted();

if (fragDepth == nearestDepth) {
  vFragColor1.xyz += Color.rgb * Color.a * alphaMultiplier;
      vFragColor1.w = 1.0 - alphaMultiplier * (1.0 - Color.a);
} else {
    vFragColor2 += Color;
}
}

Blend Fragment Shader

 #version 330 core

 uniform sampler2DRect tempTexture; 

 layout(location = 0) out vec4 vFragColor;

 void main(void)
 {
vFragColor = texture(tempTexture, gl_FragCoord.xy); 
if(vFragColor.a == 0) 
    discard;
 }

0 个答案:

没有答案