Рефракция OpenGL, текстура повторяется на эллипсоиде - PullRequest
2 голосов
/ 26 января 2011

У меня есть вопрос относительно преломления.

Я использую изображение текстуры для преломления (refertest_car.png).

Но каким-то образом текстура увеличивается и дает искаженное изображение (см. Снимок экрана).png)

Я использую следующий шейдер.

attribute highp vec4 vertex;
attribute mediump vec3 normal;

uniformhighp mat4 matrix;
uniformhighp vec3 diffuse_color;
uniformhighp mat3 matrixIT;

uniformmediump mat4 matrixMV;
uniformmediump vec3  EyePosModel;
uniformmediump vec3  LightDirModel;
varyingmediump vec4 color;

constmediump float  cShininess = 3.0;
constmediump float  cRIR = 1.015;

varyingmediump vec2   RefractCoord;

vec3 SpecularColor= vec3(1.0,1.0,1.0);

voidmain(void)
{
     vec3 toLight = normalize(vec3(1.0,1.0,1.0));

     mediump vec3 eyeDirModel = normalize(vertex.xyz -EyePosModel);
     mediump vec3 refractDir =refract(eyeDirModel,normal, cRIR);

     refractDir = (matrix * vec4(refractDir, 0.0)).xyw;

     RefractCoord = 0.5 * (refractDir.xy / refractDir.z) + 0.5;

     vec3 normal_cal = normalize(matrixIT *normal );
     float NDotL = max(dot(normal_cal, toLight), 0.0);

     vec4 ecPosition = normalize(matrixMV * vertex);
     vec3 eyeDir = vec3(1.0,1.0,1.0);
     float NDotH = 0.0;
     vec3 SpecularLight = vec3(0.0,0.0,0.0);

     if(NDotL > 0.0)
     {
         vec3 halfVector = normalize( eyeDirModel + LightDirModel);
         float NDotH = max(dot(normal_cal, halfVector), 0.0);
         float specular =pow(NDotH,3.0);

         SpecularLight = specular * SpecularColor;
     }

    color = vec4((NDotL * diffuse_color.xyz) + (SpecularLight.xyz)  ,1.0);

    gl_Position = matrix * vertex;
}

И

varyingmediump vec2 RefractCoord;
uniformsampler2D  sTexture;
varyingmediump vec4 color;

voidmain(void)
{
      lowp vec3 refractColor = texture2D(sTexture,RefractCoord).rgb;
      gl_FragColor = vec4(color.xyz + refractColor,1.0);
}

Может кто-нибудь дать мне знать решение этой проблемы?

Спасибо за любую помощь.

Извините, ребята, я не могу прикрепить изображение.

1 Ответ

0 голосов
/ 19 января 2012

Кажется, вы неправильно рассчитываете вектор преломления. Hovewer, ответ на ваш вопрос уже в заголовке. Если вы смотрите на эллипсоид, лучи от вида охватывают конус, оборачивая эллипсоид. Но после преломления конус может быть намного шире, простираясь за края ваших изображений, поэтому давая координаты текстуры больше 0 - 1 и приводя к наложению текстуры. Поэтому нам нужно позаботиться и об этом.

Во-первых, координата преломления должна быть вычислена в вершинном шейдере следующим образом:

vec3 eyeDirModel = normalize(-vertex * matrix);
vec3 refractDir = refract(eyeDirModel, normal, cRIR);

RefractCoord = normalize((matrix * vec4(refractDir, 0.0)).xyz); // no dehomog!

RefractCoord теперь содержит преломленные векторы пространства глаза. Это рассчитывает на то, что «матрица» будет матрицей вида модели (это не ясно из вашего кода, но я подозреваю, что это так). Вы можете пропустить нормализацию, если хотите, чтобы шейдер работал быстрее, это не должно вызывать заметных ошибок. Теперь немного изменений в вашем фрагментном шейдере.

vec3 refractColor = texture2D(sTexture, normalize(RefractCoord).xy * .5 + .5).rgb;

Здесь использование normalize () гарантирует, что координаты текстуры не приводят к повторению текстуры.

Обратите внимание, что использование 2D-текстуры для преломлений должно быть оправдано только генерацией ее на лету (как, например, Half-Life 2), в противном случае, вероятно, следует использовать текстуру кубической карты, которая выполняет нормализацию и дает вам цвет на основе трехмерного направления - это то, что вам нужно.

Надеюсь, это поможет ... (и, о да, я написал это по памяти, в случае каких-либо ошибок, пожалуйста, комментируйте).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...