2012-01-28 3 views
4

쉐이더에 2 개의 텍스처를 바인딩하려고합니다. 그러나 무엇인가의 이유로 그것은 항상 내가 정의한 마지막 이미지를 취하는 것으로 보인다. 내가 뭐 잘못하고 있니? 난 내 쉐이더에서 반사와 굴절 모두 'reflect.tga'볼이 경우 텍스처 2 개를 바인딩하는 경우에만 1을 참조하십시오.

GLuint textures[2]; 

glEnable(GL_TEXTURE_2D); 

glGenTextures(2, textures); 
glBindTexture(GL_TEXTURE_2D, textures[0]); 
glfwLoadTexture2D("C:\\front.tga", GLFW_BUILD_MIPMAPS_BIT); 

glBindTexture(GL_TEXTURE_2D, textures[1]); 
glfwLoadTexture2D("C:\\reflect.tga", GLFW_BUILD_MIPMAPS_BIT); 

...

const vec3 Xunitvec = vec3 (1.0, 0.0, 0.0); 
const vec3 Yunitvec = vec3 (0.0, 1.0, 0.0); 

uniform vec3 BaseColor; 
uniform float Depth; 
uniform float MixRatio; 

// need to scale our framebuffer - it has a fixed width/height of 2048 
uniform float FrameWidth; 
uniform float FrameHeight; 

uniform sampler2D EnvMap; 
uniform sampler2D RefractionMap; 

varying vec3 Normal; 
varying vec3 EyeDir; 
varying vec4 EyePos; 
varying float LightIntensity; 

void main (void) 
{ 
    // Compute reflection vector 
    vec3 reflectDir = reflect(EyeDir, Normal); 

    // Compute altitude and azimuth angles 

    vec2 index; 

    index.y = dot(normalize(reflectDir), Yunitvec); 
    reflectDir.y = 0.0; 
    index.x = dot(normalize(reflectDir), Xunitvec) * 0.5; 

    // Translate index values into proper range 

    if (reflectDir.z >= 0.0) 
     index = (index + 1.0) * 0.5; 
    else 
    { 
     index.t = (index.t + 1.0) * 0.5; 
     index.s = (-index.s) * 0.5 + 1.0; 
    } 

    // if reflectDir.z >= 0.0, s will go from 0.25 to 0.75 
    // if reflectDir.z < 0.0, s will go from 0.75 to 1.25, and 
    // that's OK, because we've set the texture to wrap. 

    // Do a lookup into the environment map. 

    vec3 envColor = vec3 (texture2D(EnvMap, index)); 

    // calc fresnels term. This allows a view dependant blend of reflection/refraction 
    float fresnel = abs(dot(normalize(EyeDir), Normal)); 
    fresnel *= MixRatio; 
    fresnel = clamp(fresnel, 0.1, 0.9); 

    // calc refraction 
    vec3 refractionDir = normalize(EyeDir) - normalize(Normal); 

    // Scale the refraction so the z element is equal to depth 
    float depthVal = Depth/-refractionDir.z; 

    // perform the div by w 
    float recipW = 1.0/EyePos.w; 
    vec2 eye = EyePos.xy * vec2(recipW); 

    // calc the refraction lookup 
    index.s = (eye.x + refractionDir.x * depthVal); 
    index.t = (eye.y + refractionDir.y * depthVal); 

    // scale and shift so we're in the range 0-1 
    index.s = index.s/2.0 + 0.5; 
    index.t = index.t/2.0 + 0.5; 

    // as we're looking at the framebuffer, we want it clamping at the edge of the rendered scene, not the edge of the texture, 
    // so we clamp before scaling to fit 
    float recip1k = 1.0/2048.0; 
    index.s = clamp(index.s, 0.0, 1.0 - recip1k); 
    index.t = clamp(index.t, 0.0, 1.0 - recip1k); 

    // scale the texture so we just see the rendered framebuffer 
    index.s = index.s * FrameWidth * recip1k; 
    index.t = index.t * FrameHeight * recip1k; 

    vec3 RefractionColor = vec3 (texture2D(RefractionMap, index)); 

    // Add lighting to base color and mix 
    vec3 base = LightIntensity * BaseColor; 
    envColor = mix(envColor, RefractionColor, fresnel); 
    envColor = mix(envColor, base, 0.2); 

    gl_FragColor = vec4 (envColor, 1.0); 
} 
+0

쉐이더의 모양은 어떻습니까? – user1118321

+0

@ user1118321 내 조각 쉐이더의 코드가 추가되었습니다. – Vivendi

+0

나는 분명히 잘못된 점을 발견하지 못했습니다. 샘플러 변수의 균일 한 위치를 어떻게 설정하고 있습니까? (예를 들어,'glUniform1i (envMapLoc, 0);에 대한 호출은 어떻게 생겼습니까?) – user1118321

답변

6

샘플러 유니폼 텍스쳐 객체하지만 텍스처 유닛을 결합하지 않습니다. 텍스처 오브젝트는 텍스처 단위에 바인딩됩니다. 그래서 셰이더에 텍스처를 바인딩 시퀀스

glActiveTexture(GL_TEXTURE0 + texture_unit1); 
glBindTexture(GL_TEXTURE_..., texture_object1); 

glActiveTexture(GL_TEXTURE0 + texture_unit2); 
glBindTexture(GL_TEXTURE_..., texture_object2); 


glUniform1i(sampler1_location, texture_unit1); 
glUniform1i(sampler2_location, texture_unit2); 

질감 단위의 범위는 0 ... GL_MAX_TEXTURE_UNITS에있다.

+0

대단히 고마워요. 그 좋은 일은 지금 :) 내 담당자 때문에 투표 할 수 없다 :-( – Vivendi

+0

참고 :'glUniformive'는'glActiveTexture'와 같은 값으로'glUniform1i'를 전달할 수 없습니다 .'glActiveTexture'는 열거 형을 사용하고'glUniform1i '는 텍스처 유닛 인덱스를 취합니다. 그래서 일반적으로 이것은'glActiveTexture (GL_TEXTURE0 + texture_unit1); ... glUniform1i (sampler1_location, texture_unit1);' –

관련 문제