Pertanyaan Bagaimana saya bisa melewati beberapa tekstur ke shader tunggal?


Saya menggunakan freeglut, GLEW dan DevIL untuk membuat teko bertekstur menggunakan shader verteks dan fragmen. Ini semua berfungsi dengan baik di OpenGL 2.0 dan GLSL 1.2 pada Ubuntu 14.04.

Sekarang, saya ingin menerapkan peta benjolan ke teko. Pengajar saya ternyata tidak menyeduh tehnya sendiri, jadi mereka tidak tahu itu seharusnya halus. Bagaimanapun, saya menemukan tutorial yang bagus tentang pemetaan benjolan di sekolah tua itu termasuk shader fragmen yang dimulai:

uniform sampler2D DecalTex; //The texture
uniform sampler2D BumpTex; //The bump-map 

Apa yang tidak mereka sebutkan adalah bagaimana untuk melewati dua tekstur ke shader di tempat pertama.

Sebelumnya saya

//OpenGL cpp file
glBindTexture(GL_TEXTURE_2D, textureHandle);

//Vertex shader
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;

//Fragment shader
gl_FragColor = color * texture2D(DecalTex,gl_TexCoord[0].xy);

jadi sekarang saya

//OpenGL cpp file
glBindTexture(GL_TEXTURE_2D, textureHandle);
glBindTexture(GL_TEXTURE_2D, bumpHandle);

//Vertex shader
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;

//Fragment shader
gl_FragColor = color * texture2D(BumpTex,gl_TexCoord[0].xy);
//no bump logic yet, just testing I can use texture 1 instead of texture 0

tetapi ini tidak berhasil. Teksturnya hilang sepenuhnya (efektif teko berwarna putih). Saya sudah mencoba GL_TEXTURE_2D_ARRAY, glActiveTexture, dan beberapa opsi lain yang tampaknya tidak bermanfaat.

Setelah memilah-milah tas campuran referensi ke OpenGL dan GLSL baru dan lama, saya sampai pada kesimpulan bahwa saya mungkin perlu glGetUniformLocation. Bagaimana tepatnya saya menggunakan ini dalam file cpp OpenGL untuk melewati tuas tekstur yang sudah terisi ke shader fragmen?

(Ini adalah pekerjaan rumah jadi tolong jawab dengan fragmen kode minimal (jika ada). Terima kasih!)

Kegagalan itu, apakah ada yang memiliki mesh nyaman teh?


13
2017-08-11 21:12


asal


Jawaban:


Ini sangat sederhana, sungguh. Yang Anda butuhkan hanyalah mengikat sampler ke beberapa unit tekstur glUniform1i. Jadi untuk contoh kode Anda, dengan asumsi dua samplers seragam:

uniform sampler2D DecalTex;  // The texture  (we'll bind to texture unit 0)
uniform sampler2D BumpTex;   // The bump-map (we'll bind to texture unit 1)

Dalam kode inisialisasi Anda:

// Get the uniform variables location. You've probably already done that before...
decalTexLocation = glGetUniformLocation(shader_program, "DecalTex");
bumpTexLocation  = glGetUniformLocation(shader_program, "BumpTex");

// Then bind the uniform samplers to texture units:
glUseProgram(shader_program);
glUniform1i(decalTexLocation, 0);
glUniform1i(bumpTexLocation,  1);

Oke, seragam shader yang ditetapkan, sekarang kita render. Untuk melakukannya, Anda akan membutuhkan yang biasa glBindTexture plus glActiveTexture:

glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, decalTexHandle);

glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, bumpHandle);

// Done! Now you render normally.

Dan di shader, Anda akan menggunakan contoh tekstur seperti yang sudah Anda lakukan:

vec4 a = texture2D(DecalTex, tc);
vec4 b = texture2D(BumpTex,  tc);

Catatan: Untuk teknik seperti pemetaan-benjolan, Anda hanya perlu satu set koordinat tekstur, karena teksturnya sama, hanya berisi data yang berbeda. Jadi Anda mungkin harus lulus koordinat tekstur sebagai atribut verteks.


27
2017-08-11 21:49



alih-alih menggunakan:

glUniform1i(decalTexLocation, 0);
glUniform1i(bumpTexLocation,  1);

dalam kode Anda, kamu bisa memiliki:

layout(location=0) uniform sampler2D DecalTex;  
// The texture  (we'll bind to texture unit 0)
layout(location=1)uniform sampler2D BumpTex;   
// The bump-map (we'll bind to texture unit 1)

di shader Anda. Itu juga berarti Anda tidak perlu menanyakan lokasi.


0
2018-06-26 06:33