2012-04-02 13 views
0

Lets sagen wir Texturing Quad (zwei Dreiecke). Ich denke, was diese Frage Textur splatting wie in nächstem Beispiel ähnlich istGLSL Mischbasis Textur mit Abziehbild Textur am benötigten Platz

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 
} 

Aber ich mag nur einen 1 Aufkleber auf Textur in gewünschtem Ort Basis Quad platzieren.
Algorithmus ist genau der gleiche, aber ich denke, wir brauchen keine zusätzliche Textur mit 1 gefüllten Schicht zu halten Positionen (zB wo rote Schicht! = 0) von Abziehbild, einige, wie wir müssen unsere eigenen "terrain.r" (Ist das Float?) variabel und mische Grundtextur und Stickerentextur damit.

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

Wie erreichen Sie so etwas?
Oder ich erzeuge nur Splat Textur auf OpenGL-Seite und übergibt es an den ersten Shader? Das wird mir zu 4 verschiedenen Aufklebern auf Quad gibt aber für häufiges Updates langsam sein (zum Beispiel Maschinengewehr trifft Wand)

Antwort

1

Ja, decal_layer ist ein Schwimmer wie Sie beschrieben haben. Sein Bereich ist 0 bis 1. Aber Sie haben nicht genug Informationen, hier haben Sie decal_location aber keine Größe für das Abziehbild angegeben. Sie wissen auch nicht, wo dieses Fragment in den Quadranten fällt, Sie benötigen eine varying vec2 quad_coord; oder eine ähnliche Eingabe vom Vertex-Shader, wenn Sie wissen wollen, wo dieses Fragment relativ zum gerenderten Quad ist.

Aber lass uns einen anderen Ansatz versuchen. Bearbeiten Sie die oben in Ihrem zweiten Beispiel enthalten diese Uniformen:

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

nun in main(), sollten Sie in der Lage zu berechnen decal_layer mit etwas wie folgt aus:

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

Grundsätzlich Du versuchst, decal_layer innerhalb des Decals auf 1.0 und außerhalb des Decals auf 0.0 zu bringen. Ich habe eine 0,01-fuzzy-Kante an der Grenze hinzugefügt, mit der Sie spielen können. Viel Glück!

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

Nun, es ist an Sie, wie Sie decal_position interpretieren. Ich denke, eine einfache Entfernungsmetrik würde ausreichen. aber dies erfordert auch die Größe des Quads. Nehmen wir an, Sie stellen dies durch einen zusätzlichen einheitlichen decal_radius zur Verfügung. Dann können wir verwenden

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

Ihr ist auch gut, nur 30.8k viel mehr als 66, Anfänger brauchen Hilfe Neuling. – Aristarhys