2012-04-02 54 views
0

可以說我們紋理四(兩個三角形)。我認爲這個問題是什麼類同質地潑灑像下面的例子GLSL混合基底紋理與貼花紋理在需要的地方

precision lowp float; 

uniform sampler2D Terrain; 
uniform sampler2D Grass; 
uniform sampler2D Stone; 
uniform sampler2D Rock; 

varying vec2 tex_coord; 

void main(void) 
{ 
vec4 terrain = texture2D(Terrain, tex_coord); 
vec4 tex0 = texture2D(Grass, tex_coord * 4.0); // Tile 
vec4 tex1 = texture2D(Rock, tex_coord * 4.0); // Tile 
vec4 tex2 = texture2D(Stone, tex_coord * 4.0); // Tile 

tex0 *= terrain.r; // Red channel - puts grass 
tex1 = mix(tex0, tex1, terrain.g); // Green channel - puts rock and mix with grass 
vec4 outColor = mix(tex1, tex2, terrain.b); // Blue channel - puts stone and mix with others 

gl_FragColor = outColor; //final color 
} 

,但我想只要將在需要的地方基礎四紋理貼圖1。
算法是一樣的,但我認爲我們不需要額外的紋理和1個填充圖層來保存貼圖的位置(例如紅色層!= 0),我們必須生成自己的「terrain.r」(這是浮動嗎?)變量並混合基礎紋理和貼花紋理。

precision lowp float; 

uniform sampler2D base; 
uniform sampler2D decal; 
uniform vec2 decal_location; //where we want place decal (e.g. 0.5, 0.5 is center of quad) 

varying vec2 base_tex_coord; 
varying vec2 decal_tex_coord; 

void main(void) 
{ 
vec4 v_base = texture2D(base, base_tex_coord); 
vec4 v_decal = texture2D(Grass, decal_tex_coord); 
float decal_layer = /*somehow get our decal_layer based on decal_position*/ 

gl_FragColor = mix(v_base, v_decal, decal_layer); 
} 

如何實現這樣的事情?
或者我可能只是在opengl一側生成splat紋理並將其傳遞給第一個着色器?這會給我爲什麼要在四4個不同的貼花,但會經常更新慢(如機槍打牆)

回答

1

是的,decal_layer是一個浮動,如你所描述的。它的範圍是0到1.但是你沒有足夠的信息,在這裏你已經指定了decal_location但沒有貼圖的大小。您也不知道這個片段在四邊形中的位置,如果您想知道這個片段與正在渲染的四邊形的相對位置,則需要使用varying vec2 quad_coord;或來自頂點着色器的類似輸入。

但讓我們嘗試一種不同的方法。編輯您的第二個例子的頂部包括這些制服:

uniform vec2 decal_location; // Location of decal relative to base_tex_coord uniform float decal_size; // Size of decal relative to base_tex_coord

現在,在main(),你應該能夠計算decal_layer像這樣的東西:

float decal_layer = 1.0 - smoothstep(decal_size - 0.01, decal_size, max(abs(decal_location.x - base_tex_coord.x), abs(decal_location.y - base_tex_coord.y)));

基本上你正在試圖讓decal_layer在decal中達到1.0,在decal之外達到0.0。我在邊界上添加了一個0.01的模糊邊緣,您可以使用它。祝你好運!

2
float decal_layer = /*somehow get our decal_layer based on decal_position*/ 

嗯,這是你的,你如何解釋decal_position。我認爲一個簡單的距離度量就足夠了。但是這也需要四分之一的大小。假設你通過一個額外的統一decal_radius來提供這個。然後我們可以使用

decal_layer = clamp(length(decal_position - vec2(0.5, 0.5))/decal_radius, 0., 1.); 
+0

你的也不錯,只比66多30.8k,新手需要幫助新手。 – Aristarhys 2012-04-03 19:04:22