3
votes

I'm trying to implement multi-texturing in OpenGL. The texture used is based on the surface normal of a given vertex- The more vertical it is, the more of the second texture is visible.

Here is what I have so far.

I want to blend the edges together now rather than having that hard edge. Is it possible to blend the textures in this way? if so how do I do that?

This is my fragment shader code:

#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);
  }
}

EDIT:

This is the new fragment shader code for anyone interested

Updated fragment shader code:

#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);

}
1
Why do you overwrite out_Color multiple times?Yakov Galka
I'm new to GLSL and OpenGL in general. I was just experimenting with different stuff to see what happensAidan Haddon-Wright

1 Answers

4
votes

To mix two texture based on a value a you do:

float a = ...;
vec3 color0 = texture(texture0, pass_textureCoords).rgb;
vec3 color1 = texture(texture1, pass_textureCoords).rgb;
out_Color.rgb = mix(color0, color1, a);

Assuming that your unitNormal = (0,1,0) is the upwards direction, as it appears from the code, then the value of

float a = clamp(unitNormal.y, 0, 1);

will result in a smooth transition between the two textures. However, you probably want a sharper transition, in which case you shift and scale the unitNormal.y value to adjust where the transition starts and ends:

float a = clamp((unitNormal.y - .6)*5 + .5, 0, 1);