Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在OpenGL中更好地制作2D照明_C++_Opengl_Glsl_Draw - Fatal编程技术网

C++ 如何在OpenGL中更好地制作2D照明

C++ 如何在OpenGL中更好地制作2D照明,c++,opengl,glsl,draw,C++,Opengl,Glsl,Draw,我想问一个关于我在OpenGL中的照明效果的问题 我正在尝试添加灯光,但我认为这不好,我看到了一些2D灯光图片,它们比我的要好得多 问:我做了一个聚光灯,但我希望它变暗,因为它的光线范围越来越小,更像自然光,但我想不出解决方案 我使用(800600)作为窗口大小的正交矩阵,并使用真实的x,y坐标制作网格。我将lightPos和PlayerPos发送到片段着色器,并使用顶点作为网格的宽度和高度,以便为每个像素生成照明 灯光只是一个基本的圆圈,我不知道如何使它看起来更好。这里有一些图片。在片段着色器

我想问一个关于我在OpenGL中的照明效果的问题

我正在尝试添加灯光,但我认为这不好,我看到了一些2D灯光图片,它们比我的要好得多

问:我做了一个聚光灯,但我希望它变暗,因为它的光线范围越来越小,更像自然光,但我想不出解决方案

我使用(800600)作为窗口大小的正交矩阵,并使用真实的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);
}

}
#版本330
输出vec4颜色;
均匀取样器;
在vec2tcoord0中;
均匀vec3单色;
均匀vec2-lightPos;
均匀vec2xypos;
在vec2 VPO中;
void main(){
vec4 textureColor=texture2D(采样器,tCoord0);
vec3环境光=vec3(0.3f,0.3f,0.3f);
浮点数dx=lightPos.x-(xyPos.x+vPos.x);
float dy=lightPos.y-(xyPos.y+vPos.y);
浮动距离=sqrt(dx*dx+dy*dy);
如果(距离>0&&dist<50){
环境光=vec3(0.7f,0.7f,0.7f)*0.6f;
}
否则,如果(距离>50和距离<70){
环境光=vec3(0.4f,0.4f,0.4f)*0.6f;
}
否则{
丢弃;
}
if((textureColor.x==0&&textureColor.y==0&&textureColor.z==0)| | textureColor.a isDraw(){
(*it)->getShader().bind();
int color=getColor(static_cast(*it)->getColor());
int r=(颜色>>16)&0xff;
int g=(颜色>>8)&0xff;
intb=(颜色)&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(“采样器”,1);
if(static_cast(*it)->getLight()!=NULL){
静态_cast(*it)->getLight()->update();
}
//(*it)->getShader().setUniform(“环境光”,静态投影(*it)->getAmbientLight());
玻璃结构(GL_纹理1);
if((*it)->getTexture()!=NULL)
(*it)->getTexture()->bind();
(*it)->getMesh().draw();
if((*it)->getTexture()!=NULL)
(*it)->getTexture()->unbind();
(*it)->getShader().unbind();
}
}
}
int Drawer::getColor(colorType颜色){
int col=0;
如果(颜色==GE_颜色_蓝色){
col=0
但是,如果中心周围有一个尖锐的点,你可能会觉得这有点难看。我们可以用指数曲线代替,如下所示:

...
percent *= percent;
ambientLight = vec3(percent, percent, percent);
要使其更“圆”,可以再次乘法:

...
percent *= percent * percent;
ambientLight = vec3(percent, percent, percent);
如果这与您想要的视觉效果相反,您可以尝试
sqrt

float percent = clamp(1.0f - dist / max_dist, 0.0, 1.0f);
percent = sqrt(percent);
因为我不知道你在视觉上到底想要什么,所以在开始的时候有一些东西可以尝试。试着用这两个,看看你是否喜欢你得到的

如果您真的想最大限度地控制效果,三次贝塞尔曲线插值可能会派上用场:

float bezier4(float p1, float p2, float p3, float p4, float t)
{
    const float mum1 = 1.0f - t;
    const float mum13 = mum1 * mum1 * mum1;
    const float mu3 = t * t * t;
    return mum13 * p1 + 3 * t * mum1 * mum1 * p2 + 3 * t * t * mum1 * p3 + mu3 * p4;
}
...
float percent = clamp(1.0f - dist / max_dist, 0.0, 1.0f);

// Can play with the first four arguments to achieve the desired effect.
percent = bezier4(0.0f, 0.25f, 0.75f, 1.0f, percent);
ambientLight = vec3(percent, percent, percent);
这会让你对效果有很大的控制力,但可能有些过分。先试试其他方法

但是,如果中心周围有一个尖锐的点,你可能会觉得这有点难看。我们可以用指数曲线代替,如下所示:

...
percent *= percent;
ambientLight = vec3(percent, percent, percent);
要使其更“圆”,可以再次乘法:

...
percent *= percent * percent;
ambientLight = vec3(percent, percent, percent);
如果这与您想要的视觉效果相反,您可以尝试
sqrt

float percent = clamp(1.0f - dist / max_dist, 0.0, 1.0f);
percent = sqrt(percent);
因为我不知道你在视觉上到底想要什么,所以在开始的时候有一些东西可以尝试。试着用这两个,看看你是否喜欢你得到的

如果您真的想最大限度地控制效果,三次贝塞尔曲线插值可能会派上用场:

float bezier4(float p1, float p2, float p3, float p4, float t)
{
    const float mum1 = 1.0f - t;
    const float mum13 = mum1 * mum1 * mum1;
    const float mu3 = t * t * t;
    return mum13 * p1 + 3 * t * mum1 * mum1 * p2 + 3 * t * t * mum1 * p3 + mu3 * p4;
}
...
float percent = clamp(1.0f - dist / max_dist, 0.0, 1.0f);

// Can play with the first four arguments to achieve the desired effect.
percent = bezier4(0.0f, 0.25f, 0.75f, 1.0f, percent);
ambientLight = vec3(percent, percent, percent);

这将为您提供对效果的大量控制,但可能有些过分。请先尝试其他方法。

在片段着色器中计算距离灯光中心的距离,并使用该距离混合灯光量。在片段着色器中计算距离灯光中心的距离,并使用该距离混合灯光量。谢谢非常感谢!你是一个神:D非常感谢!你是一个神:D