【发布时间】:2015-11-28 14:56:44
【问题描述】:
我想问一个关于我在 OpenGL 中的光照效果的问题。
我正在尝试添加照明,但我认为它不是很好,我看到一些 2D 照明图片比我的要好得多。
问题:我做了一个聚光灯,但我希望它变暗,因为它的光范围越来越小,更像自然光,但我不知道解决方案。
我正在使用以 (800, 600) 作为窗口大小的正交矩阵,并使用真实的 x、y 坐标制作网格。我将 lightPos 和 PlayerPos 发送到片段着色器,并使用顶点作为网格的宽度和高度,以便为每个像素生成光照。
灯光只是一个基本的圆圈,我不知道如何使它看起来更好。这里有一些图像。在片段着色器中,我使用勾股定理计算两点之间的距离。
这里是顶点和片段着色器
Vetex 着色器
#version 330
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 tCoord;
uniform mat4 mat;
out vec2 tCoord0;
out vec2 vPos;
void main(){
tCoord0 = vec2(tCoord.x, 1 - tCoord.y);
gl_Position = mat * vec4(pos, 1.0);
vPos = vec2(pos.x, pos.y);
}
片段着色器
#version 330
out vec4 color;
uniform sampler2D sampler;
in vec2 tCoord0;
uniform vec3 objColor;
uniform vec2 lightPos;
uniform vec2 xyPos;
in vec2 vPos;
void main(){
vec4 textureColor = texture2D(sampler, tCoord0);
vec3 ambientLight = vec3(0.3f, 0.3f, 0.3f);
float dx = lightPos.x - (xyPos.x + vPos.x);
float dy = lightPos.y - (xyPos.y + vPos.y);
float dist = sqrt(dx * dx + dy * dy);
if(dist > 0 && dist < 50){
ambientLight = vec3(0.7f, 0.7f, 0.7f) * 0.6f;
}
else if(dist > 50 && dist < 70){
ambientLight = vec3(0.4f, 0.4f, 0.4f) * 0.6f;
}
else{
discard;
}
if((textureColor.x == 0 && textureColor.y == 0 && textureColor.z == 0) || textureColor.a <= 0){
color = vec4(objColor, 1.0) * vec4(ambientLight, 1.0);
}
else{
color = textureColor * vec4(ambientLight, 1.0) * vec4(objColor, 1.0);
}
}
抽屉.cpp
#include <graphics\shader.h>
#include <graphics\texture.h>
#include <graphics\shape.h>
#include <GL\glew.h>
#include <graphics\light.h>
#include <core\TSAContainer.h>
#include <core\drawer.h>
namespace GE{
namespace core{
std::vector<graphics::GraphicComponent*> Drawer::drawables;
GLuint Drawer::buffer;
void Drawer::init(){
glGenFramebuffers(1, &buffer);
}
std::vector<graphics::GraphicComponent*>& Drawer::getAllGraphicComponents(){
return drawables;
}
void Drawer::addDrawable(graphics::GraphicComponent* drawable){
drawables.push_back(drawable);
}
void Drawer::destroy(){
for (unsigned int i = 0; i < drawables.size(); i++)
delete drawables[i];
drawables.clear();
}
void Drawer::render(){
for (std::vector<graphics::GraphicComponent*>::iterator it = drawables.begin(); it != drawables.end(); it++){
if ((*it)->isDraw()){
(*it)->getShader().bind();
int color = getColor(static_cast<graphics::Shape*>(*it)->getColor());
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = (color)& 0xff;
(*it)->getShader().setUniform("mat", (*it)->getTransformation().getTransformationMatrix());
(*it)->getShader().setUniform("objColor", r, g, b);
(*it)->getShader().setUniform("xyPos", (*it)->getTransformation().getPosition());
(*it)->getShader().setUniform("sampler", 1);
if (static_cast<graphics::Shape*>(*it)->getLight() != NULL){
static_cast<graphics::Shape*>(*it)->getLight()->update();
}
//(*it)->getShader().setUniform("ambientLight", static_cast<graphics::Shape*>(*it)->getAmbientLight());
glActiveTexture(GL_TEXTURE1);
if ((*it)->getTexture() != NULL)
(*it)->getTexture()->bind();
(*it)->getMesh().draw();
if ((*it)->getTexture() != NULL)
(*it)->getTexture()->unbind();
(*it)->getShader().unbind();
}
}
}
int Drawer::getColor(colorType color){
int col = 0;
if (color == GE_COLOR_BLUE){
col = 0 << 16 | 0 << 8 | 1;
}
else if (GE_COLOR_GREEN == color){
col = 0 << 16 | 1 << 8 | 0;
}
else if (GE_COLOR_RED == color){
col = 1 << 16 | 0 << 8 | 0;
}
else{
col = 1 << 16 | 1 << 8 | 1;
}
return col;
}
Drawer::Drawer(){
}
Drawer::~Drawer(){
}
}
}
【问题讨论】:
-
在片段着色器中计算到光中心的距离,并用它来混合光量。