2016-09-29 155 views
0

我試圖在OpenGL中實現多紋理。使用的紋理基於給定頂點的曲面法線 - 越是垂直,第二個紋理的可見度越高。GLSL多紋理混合紋理

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

} 
+0

爲什麼你覆蓋'out_Color'多次? – ybungalobill

+0

我是GLSL和OpenGL的新手。我只是試驗不同的東西,看看會發生什麼 –

回答

0

混合兩個紋理底座d在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); 
+0

非常感謝。這正是我所期待的。它完美的作品:) –