将 OpenGL 片段着色器设置为仅通过漫反射减少 vec4 色点的 RGB 值,而不是 alpha

     2023-02-22     244

关键词:

【中文标题】将 OpenGL 片段着色器设置为仅通过漫反射减少 vec4 色点的 RGB 值,而不是 alpha【英文标题】:Setting OpenGL fragment shader to reduce only the RGB values of the vec4 color points by the diffuse, not the alpha 【发布时间】:2020-09-09 16:28:17 【问题描述】:

在为我的 OpenGL 游戏设置片段着色器时,我发现当一个对象因远离灯光而变暗时,它也会失去不透明度,因为 gl_FragColor 计算会影响色点的所有四个成员:

GLES20.glEnable(GL_BLEND);
GLES20.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

final String Light1fragmentShader  = 
...
"varying vec4 v_Color;" +
...
"void main()" +""  +
...
"gl_FragColor = v_Color * diffuse * texture2D(u_Texture, v_TexCoordinate);" +
...

由于我的游戏通过 GL_BLEND 启用了透明度,因此当光线较暗或正常视线较高时,我的不透明纹理对象呈现为透明,因为 RGB 值也会降低 alpha。有没有一种优雅的方法可以将我的片段着色器设置为仅让每个 vec4 色点的前 3 个成员受漫反射影响?

【问题讨论】:

【参考方案1】:

您可以使用Swizzling 访问颜色通道。您可以使用xyzw,(分别为rgbaspq) 分别指第一个、第二个、第三个和第四个组件。您可以使用任意字母组合来创建向量(例如:texColor.rgb):

vec4 texColor = texture2D(u_Texture, v_TexCoordinate);
gl_FragColor = v_Color * vec4(diffuse * texColor.rgb, texColor.a);

如果在相同类型的向量之间使用二元运算符(如 *),它们将按组件工作(如 v_Color * vec4(...))。 二元运算符还可用于对向量的所有分量进行浮点值运算(例如diffuse * texColor.rgb)。 (进一步查看GLSL Programming/Vector and Matrix Operations)

向量可以由其他向量或向量和标量的组合构成(例如vec4(vec3(...), texColor.a))。见Vector constructors。


或者,您可以从 diffuse 创建一个 3 分量向量并构造一个 4 分量向量,其中第 4 个分量是 1 (vec4(vec3(diffuse), 1.0)):

gl_FragColor = 
    v_Color * vec4(vec3(diffuse), 1.0) * texture2D(u_Texture, v_TexCoordinate);

【讨论】:

两个优雅的解决方案,带有示例。这就是我喜欢 *** 的原因。我很久以前学习的 OpenGL 教程应该使用您的片段着色器方法。

OpenGL漫反射照明着色器错误?

】OpenGL漫反射照明着色器错误?【英文标题】:OpenGLDiffuseLightingShaderBug?【发布时间】:2010-03-1309:42:40【问题描述】:橙皮书第16.2节列出了实现漫反射照明:voidmain()vec3N=normalize(gl_NormalMatrix*gl_Normal);vec4V=gl_ModelViewMatrix*gl_vertex;vec3L=... 查看详情

OpenGL片段着色器不照亮场景

】OpenGL片段着色器不照亮场景【英文标题】:OpenGLfragmentshadernotlightingthescene【发布时间】:2016-06-3011:09:38【问题描述】:我是OpenGL的一个新手,我已经为一个场景实现了光照,其中实例化的小行星环绕着一个行星。出于某种原因... 查看详情

实现每个顶点的漫反射着色器,不起作用

...【发布时间】:2012-09-2118:28:51【问题描述】:我正在实现OpenGL4.0ShadingLanguageCookbook中的逐顶点漫反射着色器,但为了适合我的项目,我做了些许修改。这是我的顶点着色器代码:layout(location=0)invec4vertexCoord;l 查看详情

OpenGL/C++:将多个纹理传递给一个着色器的问题

】OpenGL/C++:将多个纹理传递给一个着色器的问题【英文标题】:OpenGL/C++:Problempassingmultipletexturestooneshader【发布时间】:2019-05-0220:29:31【问题描述】:我按照https://learnopengl.com/Lighting/Lighting-maps上的教程进行操作,在使用多个纹理... 查看详情

OpenGL 3着色器错误[关闭]

】OpenGL3着色器错误[关闭]【英文标题】:OpenGL3Shaderbug[closed]【发布时间】:2020-11-2220:25:25【问题描述】:我们的任务是为球体创建漫反射照明,但我们认为我们的着色器存在错误。当我们这样放置着色器时:顶点着色器:#version3... 查看详情

此像素着色器中的漫反射和镜面反射

】此像素着色器中的漫反射和镜面反射【英文标题】:DiffuseandSpecularreflectioninthispixelshader【发布时间】:2011-03-0414:20:52【问题描述】:#version150uniformfloatshade;invec3cshade;invec3v_o;invec3locallight_o;invec3n;infloatshadescale_o;outvec4pixelcolour;v 查看详情

OpenGL中的延迟着色?

】OpenGL中的延迟着色?【英文标题】:DeferredshadinginOpenGL?【发布时间】:2014-04-0613:00:53【问题描述】:我的延迟着色实现有一个奇怪的问题。我通过MRT将所需的信息渲染到一个FBO,目前在世界空间中的漫反射、位置和法线,如下... 查看详情

从固定管线到可编程管线:十段代码入门opengl(代码片段)

文章目录1.最简单的OpenGL应用程序2.视点系统和投影矩阵3.深度缓冲区和深度测试4.模型的旋转和平移5.VBO和顶点混合数组6.纹理映射和纹理坐标7.光照和法向量计算8.最简单的着色器程序9.着色器中的MVP矩阵10.着色器中的漫反射、镜... 查看详情

OpenGL:为啥我不能将单个浮点数从顶点着色器传递到片段着色器?

】OpenGL:为啥我不能将单个浮点数从顶点着色器传递到片段着色器?【英文标题】:OpenGL:Whycan\'tIpassasinglefloatfromvertexshadertofragmentshader?OpenGL:为什么我不能将单个浮点数从顶点着色器传递到片段着色器?【发布时间】:2014-08-1407... 查看详情

OpenGL着色器没有将变量从顶点传递到片段着色器

】OpenGL着色器没有将变量从顶点传递到片段着色器【英文标题】:OpenGLshadernotpassingvariablefromvertextofragmentshader【发布时间】:2014-11-0716:44:44【问题描述】:我遇到了一些非常非常奇怪的事情。我有一个非常简单的程序,它使用以... 查看详情

GLSL PBS 实现,奇怪的着色器行为

】GLSLPBS实现,奇怪的着色器行为【英文标题】:GLSLPBSimplementation,weirdshaderbehaviour【发布时间】:2015-08-1809:40:53【问题描述】:我正在使用Cook-Torrance镜面反射BRDF+Disney的漫反射BRDF光模型,如果单独应用,它们可以正常工作。不幸... 查看详情

计算机图形学(opengl):基础光照

参考技术A本文同时发布在我的个人博客上:https://dragon_boy.gitee.io  光往往不来源于单一的光源,而是多个光源将光线散射到我们周围。光线可以散射和四处反射,这样会直接或间接影响物体的颜色。基于这种理论的算法... 查看详情

[unityshader]逐顶点光照和逐片元光照

...。  前一种算法是根据漫反射公式计算顶点颜色(顶点着色器),对颜色插值(光栅化过程)返回每个像素的颜色值(片元着色器)。  第二种算法是获得顶点的法线(顶点着色器),对法线插值(光栅化过程),根据漫反... 查看详情

opengles着色语言-光照效果之散射光(代码片段)

  OpenGL光照模型,在固定管线中,主要是调用OpenGL函数实现,如果使用着色器,该怎么实现。本文的例子是移植OpenGL4.0ShadingLanguageCookbook中第二章的例子。代码已经移植到Android上。  散射光计算主要涉及到两个... 查看详情

opengles着色语言-光照效果之散射光(代码片段)

  OpenGL光照模型,在固定管线中,主要是调用OpenGL函数实现,如果使用着色器,该怎么实现。本文的例子是移植OpenGL4.0ShadingLanguageCookbook中第二章的例子。代码已经移植到Android上。  散射光计算主要涉及到两个... 查看详情

OpenGL GLSL 插值

】OpenGLGLSL插值【英文标题】:OpenGLGLSLinterpolation【发布时间】:2010-11-0220:15:48【问题描述】:我尝试使用GLSL在OpenGL中实现点光源。我将所有需要的数据发送到着色器。为简单起见,我在这里只使用漫反射光。我的示例显示了一... 查看详情

通过多个类传递 OpenGL 3.0 制服的问题

】通过多个类传递OpenGL3.0制服的问题【英文标题】:ProblemspassingOpenGL3.0uniformsthroughmultipleclasses【发布时间】:2015-05-2515:55:40【问题描述】:我正在松散地遵循www.learnopengl.com上的教程,我目前正在将多个灯光传递到我的片段着色... 查看详情

光照漫反射光照(代码片段)

step1.在片段着色器中声明一个静态变量uniform作为光源位置:uniformvec3lightPos,step2.在渲染循环中(渲染循环的外面也可以,因为它不会改变)更新uniform。lightingShader.setVec3("lightPos",lightPos);step3.片段的位置... 查看详情