2016-01-03 6 views
0

Я пытаюсь адаптировать код из пары шейдеров HLSL в библиотеке эффектов пиксельных шейдеров WPF на Codeplex, чтобы создать пиксельный шейдер, который создает диагональный переход от Texture1 to Texture2 путем сдвига Texture2 в Texture1, как если бы он накладывался (т.е. Texture1 остается «неподвижным», а Texture2 постепенно заменяет Texture1) в верхнем левом углу.Как создать диагональный шейдер перехода HLSL

Я борюсь за то, чтобы правильно понимать нотацию «uv» и как манипулировать ею для достижения моей цели.

До сих пор я пытался

float Progress : register(C0); 

sampler2D Texture1 : register(s0); 
sampler2D Texture2 : register(s1); 

struct VS_OUTPUT 
{ 
    float4 Position : POSITION; 
    float4 Color  : COlOR; 
    float2 UV  : TEXCOORD; 
}; 

float4 SampleWithBorder(float4 border, sampler2D tex, float2 uv) 
{ 
    if (any(saturate(uv) - uv)) 
{ 
    return border; 
} 
else 
{ 
    return tex2D(tex, uv); 
} 
} 

float4 SlideDiagonal(float2 uv,float progress) 
{ 
    uv += progress; 

    float4 c1 = SampleWithBorder(float4(0,0,0,0), Texture2, uv); 

    if(c1.a <=0) 
    { 
     return tex2D(Texture1, uv); 
    } 

    return c1; 
} 

//-------------------------------------------------------------------------------------- 
// Pixel Shader 
//-------------------------------------------------------------------------------------- 
float4 main(VS_OUTPUT input) : COlOR 
{ 
    return SlideDiagonal(input.UV, Progress/100); 
} 

, а также

float Progress : register(C0); 

sampler2D Texture1 : register(s1); 
sampler2D Texture2 : register(s0); 


float4 SampleWithBorder(float4 border, sampler2D tex, float2 uv) 
{ 
if (any(saturate(uv) - uv)) 
{ 
    return border; 
} 
else 
{ 
    return tex2D(tex, uv); 
} 
} 

float4 Shrink(float2 uv,float progress) 
{ 
float speed = 200; 
float2 center = float2(0.001, 0.001); 
float2 toUV = uv - center; 
float distanceFromCenter = length(toUV); 
float2 normToUV = toUV/distanceFromCenter; 

float2 newUV = center + normToUV * (distanceFromCenter *(progress*speed+1)); 

float4 c1 = SampleWithBorder(float4(0,0,0,0), Texture2, newUV); 

if(c1.a <= 0) 
{ 
    return tex2D(Texture1, uv); 
} 

return c1; 

} 

//-------------------------------------------------------------------------------------- 
// Pixel Shader 
//-------------------------------------------------------------------------------------- 
float4 main(float2 uv : TEXCOORD) : COlOR 
{ 
return Shrink(uv, Progress/100); 
} 

, но в обоих случаях «слайд» работает в обратном направлении, уменьшая количество видимых texture2 как прогресс увеличивается до 1 и, в случае первого Texture1 вообще не отображается.

Я вернулся к проблеме несколько раз по Рождеству безрезультатно, и теперь я думаю, что я страдаю от проблемы «дерева для деревьев».

Если кто-либо знает решение этой конкретной проблемы, будем признательны.

И в духе «научить человека ловить рыбу», если бы была какая-то информация, чтобы помочь мне понять, как манипулировать «УВ», что также было бы здорово.

Заранее большое спасибо за вашу помощь привет Ян Carson

ответ

1

координаты текстуры (uv) указать, где искать в текстуру. С линией

uv += progress; 

Вы меняете координату текстуры в зависимости от хода. Если он равен нулю, используются исходные координаты (и отображается весь Texture2). Увеличивая progress, вы все больше и больше выходите в правый нижний угол Texture2 и рисуете его в исходном положении. Это позволяет текстуре скользить в левый верхний угол. Поэтому, если вы хотите это наоборот, попробуйте:

uv += 1 - progress; 
0

Большое спасибо Нико за создание поляны на деревьях! Его ответ дал мне изменение перспективы, я должен решить эту проблему. @Nico - Upvote для вас, спасибо мат.

Для полноты я включил окончательный результат из моих вокалистов Shazzam, который позволяет использовать диагональный слайд из любого из четырех углов, используя поплавковый вход, называемый (образно) «Угол». В производстве поплавок заменяется на int, приводимым из перечисления возможных углов - TopLeft, TopRight, BottomRight, BottomLeft. Порядок в коде как показано, представлены 1, 2, 3 & 4.

Вот шейдер:

/// <summary>Modifies the Progress value.</summary> 
/// <minValue>0</minValue> 
/// <maxValue>100</maxValue> 
/// <defaultValue>0</defaultValue> 
float Progress : register(C0); 

/// <summary>Modifies the Corner value.</summary> 
/// <minValue>1</minValue> 
/// <maxValue>1</maxValue> 
/// <defaultValue>1</defaultValue> 
float Corner : register(C1); 

sampler2D Texture1 : register(s0); 
sampler2D Texture2 : register(s1); 

float4 SampleWithBorder(float4 border, sampler2D tex, float2 uv, float corner) 
{ 
    if (any(saturate(uv) - uv)) 
    { 
     return border; 
    } 
    else 
    { 
     float2 rev = uv; 

     //Swap y position again to counteract the inversion caused by 
     //needing to get to get to corners BottomLeft and TopRight 
     if(corner >=2 && corner < 3 || corner>=4 
     { 
      rev.y = 1 - rev.y; 
     } 

     return tex2D(tex, rev); 
    } 
} 

float4 SlideDiagonal(float2 uv, float progress, float corner) 
{ 
    float2 rev = uv; 

    //Swap y position to get to corners BottomLeft and TopRight 
    if(corner >=2 && corner < 3 || corner>=4) 
    { 
     rev.y = 1 - rev.y; 
    } 

    float2 newUV; 

    //TopLeft 
    if(corner >= 1 && corner < 2) 
    { 
     newUV = rev + (1- progress); 
    } 

    //TopRight 
    if(corner >= 2 && corner < 3) 
    { 
     newUV = rev - (1- progress); 
    } 

    //BottomRight 
    if(corner >= 3 && corner < 4) 
    { 
     newUV = rev - (1- progress); 
    } 

    //BottomLeft 
    if(corner >= 4) 
    { 
     newUV = rev + (1- progress); 
    } 


    float4 c1 = SampleWithBorder(float4(0,0,0,0), Texture2, newUV, corner); 

    if(c1.a <=0) 
    { 
     return tex2D(Texture1, uv); 
    } 

    return c1; 
} 

//-------------------------------------------------------------------------------------- 
// Pixel Shader 
//-------------------------------------------------------------------------------------- 
float4 main(float2 input : TEXCOORD) : COlOR 
{ 
    return SlideDiagonal(input, Progress/100, Corner); 
}