在OpenGL 3.2 / GLSL 1.50中写入纹理,然后将纹理写入屏幕

时间:2015-07-03 10:36:33

标签: opengl glsl fragment-shader vertex-shader fbo

我想在OpenGL中实现延迟着色。

我有一个支持OpenGL的框架。使用典型的顶点着色器和片段着色器进行前向着色可以正常工作,缩放和变换是没有问题的。

但实施延迟着色会导致我看不到任何问题而且我不知道是否在FBO中写入纹理。

在我的渲染方法中,我取消绑定FBO直接写入屏幕。它有效,一切看起来都很棒。但绑定FBO,写入纹理和尝试将纹理写入屏幕只会给我一个空白屏幕。

所以我的问题是:我是否正确处理不同纹理的并行写入?

initialize方法创建所有着色器程序并将VBO绑定到着色器的输入。

render方法分为延迟{}块和非延迟{}着色器块。非延迟着色是一个简单的前向着色概念。

我使用的是OpenGL 3.2 / GLSL 1.50。

由于GLSL 1.50不支持布局(位置),我认为应该将片段着色器输出绑定到不同的颜色(参见initialize()方法)。

创建缓冲区会导致GL_FRAMEBUFFER_COMPLETE成功。

下面你找到我的initialize()方法:

gettimeofday(&oldTime, NULL);

addLightToScene();

printError("Beginning of initialize");
/*
 * Enabling standard features in OpenGL
 */
glEnable(GL_DEPTH_TEST);
// Solange die Normalen nicht genutzt werden, sollte openGL nicht selber entscheiden dürfen in welche Richtung ein Vertex zeigt...
//glEnable(GL_CULL_FACE);

/*
 * Create ID for texturing
 */
glGenTextures(1, &texture_ID);

/*
 *  Loading pixel- and vertex shader program and compile and link them
 */
createProgram(vertex_ID, pixel_ID, program_ID,
              "shaders//VertexShader.glsl", "shaders//FragmentShader.glsl");

glBindFragDataLocation(program_ID, 0, "fragColor");

glLinkProgram(program_ID);

printProgramInfoLog(program_ID);

/*
 * Get vertex attribute IDs and uniform IDs
 */
getAttributeLocation(inPosition_ID, program_ID, "in_position");

getAttributeLocation(inColor_ID, program_ID, "in_color");

getAttributeLocation(inTexCoord_ID, program_ID, "in_texcoord");

getAttributeLocation(inNormal_ID, program_ID, "in_normal");

getUniformLocation(lightPos_ID, program_ID, "light_position");

getUniformLocation(lightInt_ID, program_ID, "light_intensity");

getUniformLocation(lightAmb_ID, program_ID, "light_ambient");

getUniformLocation(mvpMatrix_ID, program_ID, "MVPMatrix");

getUniformLocation(viewportMatrix_ID, program_ID, "ViewportMatrix");

getUniformLocation(samplerTexture_ID, program_ID, "myTexture");

/*
 * Create VAO and VBOs
 */
glGenVertexArrays (1 , &VAO); // Erzeugen des VAOs
glBindVertexArray(VAO); // Zustandsautomat: Aktiviere das VAO
glGenBuffers(4, &VBO[0]); // Erzeugen der 4 VBOs

// vertex position --> vec4
bindBuffer(VAO, VBO[0], inPosition_ID, 4);
// vertex color --> vec3
bindBuffer(VAO, VBO[1], inColor_ID, 3);
// vertex normal --> vec3
bindBuffer(VAO, VBO[2], inNormal_ID, 3);
// vertex texture coordinates --> vec2
bindBuffer(VAO, VBO[3], inTexCoord_ID, 2);

cam_c = QVector3D(0.f, 0.f, 1.f);
cam_n = QVector3D(0.f, 0.f, -1.f);
cam_v = QVector3D(0.f, -1.f, 0.f);

oldCamRotX = 0;
oldCamRotY = 0;
oldCamDist = 0;

printError("End of linking forward shading program");

/*
 * Deferred shading from here
 */

// First stage program
createProgram(firstStageVertex_ID, firstStageFragment_ID, firstStageProgram_ID,
              "shaders//FirstStageVertexShader.glsl",
              "shaders//FirstStageFragmentShader.glsl");

// Bind fragment shader outputs to the textures
glBindFragDataLocation(firstStageProgram_ID, 0, "out_diffuse");
glBindFragDataLocation(firstStageProgram_ID, 1, "out_position");
glBindFragDataLocation(firstStageProgram_ID, 2, "out_normal");

glLinkProgram(firstStageProgram_ID);

printProgramInfoLog(firstStageProgram_ID);

printError("End of linking first stage shader program");

/*
 * Get the attribute locations of the variables of the first stage vertex shader
 */
getAttributeLocation(in_normal_first_stage_ID, firstStageProgram_ID,
                     "in_normal", "first stage vertex shader");

getAttributeLocation(in_position_first_stage_ID, firstStageProgram_ID,
                     "in_position", "first stage vertex shader");

getAttributeLocation(in_color_first_stage_ID, firstStageProgram_ID,
                     "in_color", "first stage vertex shader");

getAttributeLocation(in_texCoord_first_stage_ID, firstStageProgram_ID,
                     "in_texCoord", "first stage vertex shader");

getAttributeLocation(in_intensity_first_stage_ID, firstStageProgram_ID,
                     "in_intensity", "first stage vertex shader");

getAttributeLocation(in_ambientLight_first_stage_ID, firstStageProgram_ID,
                     "in_ambientLight", "first stage vertex shader");

/*
 * Get the locations of the uniforms of the first stage vertex shader
 */
getUniformLocation(uniform_projectionMatrix_ID, firstStageProgram_ID,
                   "projectionMatrix", "first stage vertex shader");

getUniformLocation(uniform_modelMatrix_ID, firstStageProgram_ID,
                   "modelMatrix", "first stage vertex shader");

getUniformLocation(uniform_viewMatrix_ID, firstStageProgram_ID,
                   "viewMatrix", "first stage vertex shader");

getUniformLocation(uniform_mvpMatrix_first_stage_ID, firstStageProgram_ID,
                   "MVPMatrix", "first stage vertex shader");

getUniformLocation(uniform_viewportMatrix_first_stage_ID, firstStageProgram_ID,
                   "viewportMatrix", "first stage vertex shader");

/*
 * Create VAO_deferred and VBO_deffered
 */    
glGenVertexArrays (1 , &VAO_deferred); // Erzeugen des VAOs
glBindVertexArray(VAO_deferred); // Zustandsautomat: Aktiviere das VAO
glGenBuffers(4, &VBO_deferred[0]); // Erzeugen der 4 VBOs

bindBuffer(VAO_deferred, VBO_deferred[0], in_position_first_stage_ID, 4);
bindBuffer(VAO_deferred, VBO_deferred[1], in_color_first_stage_ID, 3);
bindBuffer(VAO_deferred, VBO_deferred[2], in_normal_first_stage_ID, 3);
bindBuffer(VAO_deferred, VBO_deferred[3], in_texCoord_first_stage_ID, 2);

printError("End of attaching VBO_deferred objects to first stage shader program");

// TODO: insert in_intensity and in_ambientLight into first stage vertex shader

/*
 * Deferred stage program from here
 */
createProgram(deferredStageVertex_ID, deferredStageFragment_ID, deferredStageProgram_ID,
              "shaders//DeferredStageVertexShader.glsl",
              "shaders//DeferredStageFragmentShader.glsl");

// Bind fragment shader outputs
glBindFragDataLocation(deferredStageProgram_ID, 0, "fragColor");

glLinkProgram(deferredStageProgram_ID);

printProgramInfoLog(deferredStageProgram_ID);

printError("End of linking deferred stage shader program");

getAttributeLocation(in_vertex_deferred_stage_ID, deferredStageProgram_ID,
                     "in_texture_vertex", "deferred stage vertex shader");

getUniformLocation(uniform_positionTexture_ID, deferredStageProgram_ID,
                   "positionTexture", "deferred stage vertex shader");

getUniformLocation(uniform_normalTexture_ID, deferredStageProgram_ID,
                   "normalTexture", "deferred stage vertex shader");

getUniformLocation(uniform_diffuseTexture_ID, deferredStageProgram_ID,
                   "diffuseTexture", "deferred stage vertex shader");

getUniformLocation(uniform_camera_ID, deferredStageProgram_ID, "viewMatrix", "deferred stage vertex shader");

printError("End of getting uniform locations of the deferred stage shader program");


glGenVertexArrays (1 , &VAO_texture);
glBindVertexArray(VAO_texture);
glGenBuffers(1, &VBO_texture[0]);

// vertex position --> vec4
bindBuffer(VAO_texture, VBO_texture[0], in_vertex_deferred_stage_ID, 4);

这是我的渲染方法:

doLightAnimationStep();

// Create matrices
//QMatrix4x4 modelMatrix = createMouseViewMatrix();
//QMatrix4x4 mouseViewMatrix = createViewMatrix();
//QMatrix4x4 projectionMatrix = createProjectionMatrix();
QMatrix4x4 mvpMatrix = createProjectionMatrix() * createMouseViewMatrix();
QMatrix4x4 viewportMatrix = MatrixHandler::createScaleMatrix(
            10.f / scaling, 10.f / scaling, 10.f / scaling);

if(deferredShading) {
    // Bind FBO to context and clear all buffers before rendering
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);
    //glViewport(0, 0, viewWidth, viewHeight);
    GLenum windowBufferSelector[] = {
        GL_COLOR_ATTACHMENT0,
        GL_COLOR_ATTACHMENT1,
        GL_COLOR_ATTACHMENT2 };
    glDrawBuffers(3, windowBufferSelector); // Select all buffers
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set everything to zero.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    printError("Bound FBO and depth buffer");
    // First render stage -> writing all data into the textures and the depth buffer
    glUseProgram(firstStageProgram_ID);

    // Set uniforms
    glUniformMatrix4fv(uniform_mvpMatrix_first_stage_ID, 1, GL_FALSE, mvpMatrix.data());
    glUniformMatrix4fv(uniform_viewportMatrix_first_stage_ID, 1, GL_FALSE, viewportMatrix.data());

    printError("Prepared buffer 0, 1 and 2 for writing");

    //DrawTheWorld(); // Will also produce depth data in the depth buffer
    glBindVertexArray(VAO_deferred); // VAO aktivieren
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
    glBindVertexArray(0);

    printError("Wrote into buffer 0, 1 and 2");

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // Deferred render stage -> read the data for all pixels from the textures and the depth buffer to calculate the color for the pixel

    // The depth buffer from stage 1 is not used now as the fbo is disabled.
    // Clearing the active buffer means clearing the screen
    glClearColor(255.0f, 255.0f, 255.0f, 0.0f); // Set everything to zero.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //EnableRenderProgramDeferredStage();
    glUseProgram(deferredStageProgram_ID);

    //SetupDeferredStageUniforms();
    printError("Setting uniforms for deferred stage vertex shader.");
    glBindTexture(GL_TEXTURE_2D, fDiffuseTexture);
    glUniform1i(uniform_diffuseTexture_ID, fDiffuseTexture);
    //glUniform1i(uniform_positionTexture_ID, fPositionTexture);
    //glUniform1i(uniform_normalTexture_ID, fNormalsTexture);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, fNormalsTexture);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, fPositionTexture);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, fDiffuseTexture);

    printError("Setted uniforms for deferred stage vertex shader.");

    glBindVertexArray(VAO_texture); // VAO aktivieren
    glDrawArrays(GL_TRIANGLES, 0, 2);
    glBindVertexArray(0);

    glBindTexture(GL_TEXTURE_2D, 0);

    glUseProgram(0);

    printError("End of deffered shading rendering");
} else {
    // Enable and disable z-buffering and backface culling
    if(zBuffering) {
        if(!(glIsEnabled(GL_DEPTH_TEST) == GL_TRUE)) {
            glEnable(GL_DEPTH_TEST);
        }
    } else {
        if(glIsEnabled(GL_DEPTH_TEST) == GL_TRUE) {
            glDisable(GL_DEPTH_TEST);
        }
    }

    if(backfaceCulling) {
        if(!(glIsEnabled(GL_CULL_FACE) == GL_TRUE)) {
            glEnable(GL_CULL_FACE);
        }
    } else {
        if(glIsEnabled(GL_CULL_FACE) == GL_TRUE) {
            glDisable(GL_CULL_FACE);
        }
    }

    glClearColor(255, 255, 255, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Use shader program
    glUseProgram(program_ID);

    glBindTexture(GL_TEXTURE_2D, texture_ID);
    glUniform1i(samplerTexture_ID, 0);

    if(textureMode == CLAMP) {
    // Werte auf kleiner 0 auf 0 beschränken , Werte größer 1 auf 1:
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    } else if(textureMode == REPEAT) {
        // Texturen wiederholen
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    } else if(textureMode == MIRRORED_REPEAT) {
        // Texturen wiederholen, die Koordinaten jedoch an den Grenzen ”spiegeln ”

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    } else {
        // Should never be reached!
        assert(false);
    }

    if(filterMode == NEAREST_NEIGHBOUR) {
        // Für Nearest−Neighbor Filterung (wie im Software−Renderer)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    } else if (filterMode == LINEAR) {
        // Für Lineare Filterung (qualitativhochwertiger)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    } else if (filterMode == MIPMAPPING) {
        // Mipmapping (weniger Aliasing Artefakte, aber höherer Speicherbedarf)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glGenerateMipmap(GL_TEXTURE_2D);
    } else {
        // Should never be reached!
        assert(false);
    }

    glUniformMatrix4fv(mvpMatrix_ID, 1, GL_FALSE, mvpMatrix.data());
    glUniformMatrix4fv(viewportMatrix_ID, 1, GL_FALSE, viewportMatrix.data());


    //float light_dist_f = (float)light_dist/100.f;
    //GLfloat lightPos__vec [3] = {light_dist_f*(float) cos(Math::toRadian(light_angle)), light_dist_f*(float) sin(Math::toRadian(light_angle)),light_dist_f};
    //glUniform3fv(lightPos_ID, 1, lightPos__vec);

    GLfloat lightPos__vec [3] = {lights[0].position.x(), lights[0].position.y(), lights[0].position.z()};
    glUniform3fv(lightPos_ID, 1, lightPos__vec);

    GLfloat intensity = ((GLfloat)light_intensity/(GLfloat)100);
    glUniform1fv(lightInt_ID, 1, &intensity);

    GLfloat ambient = ((GLfloat)light_ambient/(GLfloat)100);
    glUniform1fv(lightAmb_ID, 1, &ambient);

    glBindVertexArray(VAO); // VAO aktivieren
    glDrawArrays(GL_TRIANGLES, 0 , vertexCount);
    glBindVertexArray(0);

    glBindTexture(GL_TEXTURE_2D, 0);

    glUseProgram(0);
}

每次我改变框架的大小时,我都会改变视口大小和FBO +纹理。

sizeChanged()

// Prevent frame buffer objects to be corrupted
if(width <= 0 || height <= 0) {
    return;
}

if(origin_width == 0) {
    origin_width = width;
    origin_height = height;
}

multiplier_lr = (float)viewWidth/(float) origin_width;
multiplier_tb = (float)viewHeight/(float) origin_height;

viewWidth = width;
viewHeight = height;

screenVertices.clear();

screenVertices << 0.f << 0.f;
screenVertices << viewWidth << 0.f;
screenVertices << 0.f << viewHeight;

screenVertices << viewWidth << 0.f;
screenVertices << 0.f << viewHeight;
screenVertices << viewWidth << viewHeight;

glBindBuffer(GL_ARRAY_BUFFER, VBO_texture[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * screenVertices.size(), screenVertices.data(), GL_STATIC_DRAW);

glViewport(0,0,width,height);

/*
 * Generate framebuffer object, renderbuffer object and color buffers
 */
// Generate framebuffer object FBO
glGenFramebuffers(1, &FBO);

// The FBO does not have a depth buffer or anything else.
// Therefore it is necessary to implement a depth buffer and all the
// texture buffers in the initialize method
// Generate and adjust depth buffer
glGenRenderbuffers(1, &fDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, fDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);

printError("Generated frame buffer object and depth buffer");

// Generate diffuse buffer
generateTexture(fDiffuseTexture, GL_RGBA, width, height);
printError("Generated diffuse texture buffer");

// Generate and bind the texture for positions
generateTexture(fPositionTexture, GL_RGBA32F, width, height);
printError("Generated position texture buffer");

// Generate and bind the texture for normals
generateTexture(fNormalsTexture, GL_RGBA16F, width, height);
printError("Generated normal texture buffer");

// Bind the FBO so that the next operations will be bound to it.
glBindFramebuffer(GL_FRAMEBUFFER , FBO);

// Attach the depth buffer to the FBO
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fDepthBuffer);

// Attach the textures to the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fDiffuseTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fPositionTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, fNormalsTexture, 0);

printError("Bound all textures to the FBO");

// Check FBO for errors
GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fboStatus != GL_FRAMEBUFFER_COMPLETE) {
    printf("DeferredLighting::Init: FrameBuffer incomplete: 0x%x\n", fboStatus);
    exit(1);
}

// Unbind FBO
glBindFramebuffer(GL_FRAMEBUFFER , 0);

printError("Unbound all textures to the FBO");

Screenvertices是一个QVector,与我的前向阴影VAO和我的VAO_deferred相同的结构类型。

第一阶段顶点着色器:

#version 150

precision mediump float;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

uniform mat4 MVPMatrix;
uniform mat4 viewportMatrix;

in vec4 in_position;
in vec3 in_color;
in vec3 in_normal;
in vec2 in_texCoord;
in float in_intensity; // Sun light
in float in_ambient;

out vec4 position_varying;
out vec3 color_varying;
out vec3 normal_varying;
out vec2 texCoord_varying;
out float extIntensity_varying;
out float extAmbientLight_varying;


/*
 * The first stage shader program performs geometric calculations.
 * Light calculations are done in the second stage, the deferred stage shader
 * program.
 */

// Texture coordinates are applied to the first stage fragment shader.
// The normal vector is being transformed in world coordinates.
// gl_Position is being calculated with the MVP matrix in screen coordinates
// The intensity of the sun is in range [0;255], perhaps this has to be adjusted
// The ambient light is in the range of [0;255] aswell, perhaps this has to be
// adjusted too.

void main(void) {

    gl_Position = viewportMatrix * (MVPMatrix * in_position);
    color_varying = in_color;
    normal_varying = in_normal;
    texCoord_varying = in_texCoord;

    // Not used right now
    //extIntensity_varying = in_intensity;
    //extAmbientLight_varying = in_ambient;

    /*
    normal_varying = normalize((modelMatrix*vec4(in_normal, 0.0)));
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_vertex;
    position_varying = vec3(modelMatrix * in_vertex); // Copy position to the fragment shader
    extIntensity_varying = in_intensity/255.0; // Scale the intensity from [0..255] to [0..1].
    extAmbientLight_varying = in_ambientLight/255.0;
    */
}

第一阶段片段着色器:

#version 150

precision mediump float;

uniform sampler2D firstTexture;

in vec4 position_varying; // The model coordinate, as given by the vertex shader
in vec3 color_varying; // The interpolated color of the fragment
in vec3 normal_varying; // The interpolated normal of the fragment
in vec2 texCoord_varying; // The interpolated texture coordinates of the fragment

// To be written into texture buffers
out vec4 out_position;  // layout(location = 0)
out vec3 out_normal;    // layout(location = 1)
out vec3 out_diffuse;   // layout(location = 2)

/*
 * The first stage shader program performs geometric calculations.
 * Light calculations are done in the second stage, the deferred stage shader
 * program.
 */

// Output the model-transformed vertex-coordinates
// Output normal (normalized)
void main(void) {
    out_position = position_varying; // Position given by the vertext shader
    out_normal = normal_varying;
    out_diffuse = color_varying;

    /*
    // The blending is not necessary in calculation with the GDV framework
    // as there are no transparent models
    vec4 clr = texture(firstTexture, texCoord_varying);
    out_diffuse = clr;
    */
}

延迟阶段顶点着色器:

#version 150

precision mediump float;

in vec2 in_texture_vertex;

out vec2 texture_varying;

/*
 * The first stage shader program performs geometric calculations.
 * Light calculations are done in the second stage, the deferred stage shader
 * program.
 */

void main(void) {

    // Why is there a calculation in_vertex*2-1?
    gl_Position = vec4(in_texture_vertex.xy, 0.f, 0.f);

    // Copy position to the fragment shader. Only x and y is needed.
    texture_varying = in_texture_vertex;
}

延迟阶段片段着色器:

#version 150

precision mediump float;

uniform sampler2D positionTexture; // World position
uniform sampler2D normalTexture;   // Normals
uniform sampler2D diffuseTexture;  // The color information

// Not used?
//uniform vec3 camera;          // The coordinate of the camera

in vec2 texture_varying;     // The world position

out vec4 fragColor;           // layout(location = 0)

/*
 * The first stage shader program performs geometric calculations.
 * Light calculations are done in the second stage, the deferred stage shader
 * program.
 */

void main(void) {
    // Load data, stored in textures, from the first stage rendering.

    // Color
    fragColor = texture2D(diffuseTexture, texture_varying);
    //fragColor = vec4(0, 0, 0, 1);

    //vec4 worldPos = texture(positionTexture, texture_varying.xy);

    // Normals
    //fragColor = texture(normalTexture, texture_varying.xy);

    // Use information about lamp coordinate (not shown here), the pixel
    // coordinate (worldpos.xyz), the normal of this pixel (normal.xyz)
    // to compute a lighting effect.
    // Use this lighting effect to update 'diffuse'
    //vec4 preBlend = diffuse * lamp + specularGlare;
    //fragColor = (normal+1)/2;
    //fragColor = diffuse;
    //fragColor = worldPos; // Scaling may be needed to range [0,1]
    //fragColor = lamp*vec4(1,1,1,1);
}

0 个答案:

没有答案
相关问题