GLSL 多纹理 - 混合纹理
Posted
技术标签:
【中文标题】GLSL 多纹理 - 混合纹理【英文标题】:GLSL multi-texturing- blending textures 【发布时间】:2016-09-29 20:57:33 【问题描述】:我正在尝试在 OpenGL 中实现多纹理。使用的纹理基于给定顶点的表面法线 - 垂直度越高,第二个纹理的可见度就越多。
Here 是我目前所拥有的。
我现在想将边缘融合在一起,而不是拥有那种硬边缘。是否可以以这种方式混合纹理?如果是这样,我该怎么做?
这是我的片段着色器代码:
#version 150
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCamera;
in vec3 playerPosition;
in vec4 vertexPosition;
in float blendPosition;
in float visibility;
out vec4 out_Color;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform vec3 skyColour;
uniform vec3 light_colour;
uniform float shineDamper;
uniform float reflectivity;
void main(void)
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDot1 = dot(unitNormal,unitLightVector);
float brightness = max(nDot1,0.2);
vec3 diffuse = brightness * light_colour;
vec3 unitToCamera = normalize(toCamera);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection,unitNormal);
float specular = dot(reflectedLightDirection, unitToCamera);
specular = max(specular,0.0);
float damped = pow(specular,shineDamper);
vec3 finalSpecular = damped * reflectivity * light_colour;
out_Color = (vec4(diffuse,1.0) * texture(texture0,pass_textureCoords)) + vec4(-20,-20,0.0,0.0);
out_Color = (vec4(diffuse,1.0) * texture(texture0,pass_textureCoords));
out_Color = mix(vec4(skyColour,1.0),out_Color,visibility);
if(vertexPosition.y < -6.1 || surfaceNormal.y < 0.6)
out_Color = (vec4(diffuse,1.0) * texture(texture1,pass_textureCoords)) + vec4(-20,-20,0.0,0.0);
out_Color = (vec4(diffuse,1.0) * texture(texture1,pass_textureCoords));
out_Color = mix(vec4(diffuse,1.0) * texture(texture0,pass_textureCoords),out_Color,1);
out_Color = mix(vec4(skyColour,1.0),out_Color,visibility);
if(playerPosition.y < -6.1)
out_Color = mix(vec4(0.0,0.3,0.5,1.0),out_Color,0.1);
编辑:
这是任何感兴趣的人的新片段着色器代码
更新片段着色器代码:
#version 150
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCamera;
in vec3 playerPosition;
in vec4 vertexPosition;
in float blendPosition;
in float visibility;
out vec4 out_Color;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform vec3 skyColour;
uniform vec3 light_colour;
uniform float shineDamper;
uniform float reflectivity;
void main(void)
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDot1 = dot(unitNormal,unitLightVector);
float brightness = max(nDot1,0.2);
vec3 diffuse = brightness * light_colour;
vec3 unitToCamera = normalize(toCamera);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection,unitNormal);
float specular = dot(reflectedLightDirection, unitToCamera);
specular = max(specular,0.0);
float damped = pow(specular,shineDamper);
vec3 finalSpecular = damped * reflectivity * light_colour;
out_Color.a = 1;
vec4 fog = vec4(skyColour,1.0);
vec4 diffusion = vec4(diffuse,1.0);
float a = clamp((unitNormal.y - .6)*5 + .5, 0, 0.7);
vec3 texture0_colour = (mix(fog,diffusion * texture(texture0,pass_textureCoords),visibility)).rgb;
vec3 texture1_colour = (mix(fog,diffusion * texture(texture1,pass_textureCoords),visibility)).rgb;
out_Colour.rgb = mix(texture1_colour,texture0_colour,a);
【问题讨论】:
为什么要多次覆盖out_Color
?
我是 GLSL 和 OpenGL 的新手。我只是在尝试不同的东西,看看会发生什么
【参考方案1】:
要根据值 a
混合两种纹理,您可以这样做:
float a = ...;
vec3 color0 = texture(texture0, pass_textureCoords).rgb;
vec3 color1 = texture(texture1, pass_textureCoords).rgb;
out_Color.rgb = mix(color0, color1, a);
假设您的unitNormal = (0,1,0)
是向上的方向,如代码所示,则值为
float a = clamp(unitNormal.y, 0, 1);
将导致两个纹理之间的平滑过渡。但是,您可能想要更清晰的过渡,在这种情况下,您可以移动并缩放 unitNormal.y
值以调整过渡的开始和结束位置:
float a = clamp((unitNormal.y - .6)*5 + .5, 0, 1);
【讨论】:
非常感谢。这正是我一直在寻找的。它完美地工作:)以上是关于GLSL 多纹理 - 混合纹理的主要内容,如果未能解决你的问题,请参考以下文章