Phong着色器中的非预期透明度 - GLSL

6
我正在尝试创建一个基本的Phong光照着色器来了解在着色器中的光照。同时,我正在使用openframeworks。我已经创建了三个立方体,它们周围有一个旋转的摄像机。灯光似乎正在工作(有点),但是立方体具有不需要的透明度,您可以在此处看到:

enter image description here

这是我的代码,它基于这个教程

testApp.h

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{

public:

ofCamera camera;
ofLight pointLight;
float camAngle;
float camX;
float camY;
float camZ;

ofShader lightShader;

ofBoxPrimitive box1;
ofBoxPrimitive box2;
ofBoxPrimitive box3;

void setup();
void update();
void draw();
};

testApp.cpp

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);

ofBackground(100, 100, 100);
ofSetFrameRate(30);

camera.setNearClip(0.1);
camera.setFarClip(1200);
camAngle = 0;
camX = 200;
camY = 150;
camZ = 200;

pointLight.setPointLight();

lightShader.load("shaders/lightShader");

//boxes setup here, not necessary to show

}

//--------------------------------------------------------------
void testApp::update()
{
camAngle += 0.01f;

if (camAngle >= 360)
{
    camAngle = 0;
}

camX = 300 * sin(camAngle);
camZ = 300 * cos(camAngle);


camera.lookAt(ofVec3f(0, 0, 0));
camera.setPosition(ofVec3f(camX, camY, camZ));

pointLight.setPosition(-50, -20, 200);
}

//--------------------------------------------------------------
void testApp::draw()
{
lightShader.begin();
    camera.begin();
    pointLight.enable();
        pointLight.draw();
        ofVec3f lightLocation = pointLight.getPosition();
        lightShader.setUniform3f("lightLocation", lightLocation.x, lightLocation.y, lightLocation.z);
        box1.draw();
        ofPushMatrix();
        ofTranslate(60, 50);
        ofRotate(45, 1.0, 0.0, 0.0);
        box2.draw();
        ofPopMatrix();
        ofPushMatrix();
        ofTranslate(-70,70);
        ofRotate(110, 1.0, 0.0, 0.6);
        box3.draw();
        ofPopMatrix();
    pointLight.disable();
    camera.end();
lightShader.end();
}

lightShader.vert

// vertex shader

#version 150

//these are passed in by openframeworks
uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec4 color;
in vec3 normal;
in vec2 texcoord;

out vec4 vertPosition;
out vec4 vertColor;
out vec3 vertNormal;
out vec2 texCoordVar;

void main()
{
texCoordVar = texcoord;
vertPosition = position;
vertColor = color;
vertNormal = normal;
gl_Position = modelViewProjectionMatrix * position;
}

lightShader.frag

// fragment shader

#version 150

uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform vec3 lightLocation;
uniform vec3 lightIntensity;

in vec2 texCoordVar;
in vec3 vertNormal;
in vec4 vertPosition;
in vec4 vertColor;

out vec4 outputColor;

void main()
{
//calculate normal in world coordinates
mat3 normalMatrix = transpose(inverse(mat3(modelViewMatrix)));
vec3 vertexNormal = normalize(normalMatrix * vertNormal);

//calculate the location of this pixel in world coordinates
vec3 fragPosition = vec3(modelViewMatrix * vertPosition);

//calculate the vector from this pixels surface to the light source
vec3 surfaceToLight = normalize(lightLocation - fragPosition);

//calculate the cosine of the angle of incidence (brightness)
float brightness = max(0.0, dot(vertexNormal, surfaceToLight));

//calculate final color of the pixel
outputColor = brightness * vec4(vertColor.rgb, 1.0);
}

通过一些实验,我发现如果我将片元着色器的最后一行更改为以下内容:

outputColor = brightness * (vec4(vertColor.rgb, 1.0) * modelViewProjectionMatrix);

我得到了这个:

enter image description here

颜色错误,光线变得非常黑暗,但物体是不透明的,正如它们应该的那样。也许我应该以某种方式使用modelViewProjectionMatrix?不确定如何使用。
1个回答

3
你需要通过alpha通道来增加亮度:
outputColor = brightness * vec4(vertColor.rgb, 1.0);

你可以像这样做:

您可以执行以下操作:

outputColor = brightness * vec4(vertColor.rgb, 1.0);

然后:
outputColor.a = 1.0;

不,您不必以这种方式使用modelViewProjectionMatrix
outputColor = brightness*(vec4(vertColor.rgb, 1.0) * modelViewProjectionMatrix);

您只需要使用modelViewProjectionMatrix就可以获取顶点的屏幕坐标。

2
或者只需将 outputColor = vec4(brightness * vertColor.rgb, 1.0); 输出。 - Dan
当然,那样更好 :) - Giobunny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接