• Добро пожаловать на Quest3D - Русскоязычное сообщество.
 

"Крутизна и реализьм" - тема про шейдеры

Автор KBECT0MAH, 25 декабря 2007, 04:18:22

« назад - далее »

Sqwer

VIVID
можно, для этого достаточно иметь 2 текстуры:
текстура фон - для циферблата
текстура стрелка - для стрелки, должна быть с прозрачностью

дальше в шейдере идёт игра с текстурными координатами.


RazorSoul

Здравствуйте товарищи квестовцы! :) Я работаю в квесте недавно и в шейдерах неразобрался. Потому вопрос как в шейдер эф икс сделать шейдер который заливает тайловую текстуру с бампом на сурфэйс в зависимости от цвета вершин?? Подобное есть в примере нэйчурал рендер в квесте 4.2.3 тока без бампа. Но понять этот хслс без знаний шэйдеростроения невозможно. Плиз помогите разобраться :'(

Sqwer

#122

RazorSoul

Спасиб, попробую вызубрить :), только если не затруднит, можно ли в принципе прикрутить бамп или рельеф к вертекс колор. В примере шейдер эф икс я нашёл этот шейдер текстурирования, но там только 3 текстуры (каждой из них соответствует канал рэд, блю или грин), так вот можно ли как нибудь (или вообще в принципе )увеличить кол-во текстур. ???
если такое возможно(и с бампом, и с кол-вом текстур)то я фанат шэйдер текстур, и квеста ;D
ps. делаю диплом в квесте ;)

Sqwer

Можно до 8 текстур вроде в Квесте.

форматы текстур  тоже в квесте ограничены.


ЦитироватьСпасиб, попробую вызубрить , только если не затруднит, можно ли в принципе прикрутить бамп или рельеф к вертекс колор.
Курить вредно, потому что я руки  с мылом мою.

RazorSoul

 ;D Ага с мылом и курю. Дым с пузырями получается. ;D А если серьезно то я имел ввиду следующее: если вершина Red => заливается текстура кирпичики, если Green => камушки, Blue => травка. Так вот (просветите меня ламера) можно ли в квесте зделать так: если вершина Red => заливается текстура кирпичики с бампмэп (или рельефмэп) шейдером, если Green => камушки с бампмэп (или рельефмэп) шейдером, Blue => травка с бампмэп (или рельефмэп) шейдером?.

Sqwer

#126
Цитироватьесли вершина Red => заливается текстура кирпичики, если Green => камушки, Blue => травка.

обычный фильтр:


с вертексного в пиксельный  гоним   цвет вершины
IN.vertexColor

далее в пиксельном строим условия (если надо жёсткий переход)


float4 albedo;

if (IN.vertexColor.r>0.02f)
{
albedo=tex2D(семплер кирпичной текстуры, IN.texCoord);
}
else
{
albedo=tex2D(семплер камушки текстуры, IN.texCoord);
}

if (IN.vertexColor.b>0.02f)
{
albedo=tex2D(семплер травка текстуры, IN.texCoord);
}




если нужны плавные границы, то луч юзать текстуры в этих целях
и  в пиксельном просто миксовать
Цитировать
float3 targetVar;


float mixMask=tex2D(семплер маски текстуры, IN.texCoord);
float3 var1=tex2D(семплер кирпичной текстуры, IN.texCoord);
float3 var2=tex2D(семплер кирпичной текстуры, IN.texCoord);

targetVar=lerp(var1,var2, mixMask);

Cludz

#127
Люди помогите 2й ИС не светит, или очень слабо светит
Ткните пальцем что не так в коде

// DIFFUSE LIGHT+ATTENUATION+TEXTURE
/////////////////////////////////////////////////////////////////////////
///// Объявление Переменных /////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Матрицы
float4x4 WorldVP : WorldViewProjection; // Произведение мировой, видовой и проекционной матриц
float4x4 World   : World; // Матрица мирового преобразования
float4x4 WorldIT : WorldInverseTranspose; // Инвертированная - транспонированная мир матрица

// Макрос для замены в коде MAX_LIGHTS на 8
#define MAX_LIGHTS 8

// Источник света
float3 lightpos[MAX_LIGHTS] : LIGHTPOS; // Подключение позиции источника света
float3 lightcol[MAX_LIGHTS] : LIGHTCOLOR; // Подключение цвета источника
float light_atten[MAX_LIGHTS]: LIGHTATT1; // Затухание источника

// Одиночный слайдер для значения типа Value
float valueName :CHANNELVALUE0 < // CHANNELVALUE0 - номер канала
    string UIName = "Slider Value"; // Имя в редакторе
    string UIWidget = "slider"; // Тип
    float UIMin = 0.0;     // Минимальное значение
    float UIMax = 10.0;             // Максимальное значение
float UIStep = 0.01;
> = 2.2;

float3 DiffuseColor : CHANNELVECTOR0 <
    string UIName =  "Diffuse Color";  // Имя в редакторе
    string UIWidget = "Color";    // Тип виждета
> = {1,1,1}; // Дефолтовое значение

//////////
//Подключил текстуры из Квеста
//2D текстуру
texture gColorTexture : COLORMAP0 <
    string ResourceName = "default_color.dds";
    string UIName =  "Diffuse Texture";
    string ResourceType = "2D";
>;

sampler2D Texture1 = sampler_state {
    Texture = <gColorTexture>;

    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;

    AddressU = Wrap;
    AddressV = Wrap;
}; 

/////////////////////////////////////////////////////////////////////////
///// Структуры /////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Входящие данные

struct a2v
{
    float4 position : POSITION; // Позиция объекта
float3 normal    : NORMAL; // Нормаль к поверхности
float2 texCoor      : TEXCOORD0; // Текстурные координаты

};

// Исходящие данные
struct v2f
{
    float4 HPosition    : POSITION; // Позиция объекта
float3 wnormal    : TEXCOORD2; // Направление нормали в мировом пространстве
float3 LightVector0 : TEXCOORD1; // Вектор света
    float3 LightVector1 : TEXCOORD3;
float2 texCoor      : TEXCOORD0; // Текстурные координаты
};

/////////////////////////////////////////////////////////////////////////
///// Шейдеры ///////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

// Вершинный шейдер
v2f VS(a2v IN)
{
    v2f OUT = (v2f)0; // Обнуление выходной структуры
OUT.wnormal = mul(IN.normal,WorldIT); // Получение нормали в мировой системе координат
float3 worldSpacePos = mul(IN.position,World); // Получаем позицию вершины в мировом пространстве
OUT.LightVector0 = (lightpos[0]-worldSpacePos) * light_atten[0]*0.03; // Вносим радиус затухания в вектор света
    OUT.LightVector1 = (lightpos[1]-worldSpacePos) * light_atten[1]*0.03;
OUT.HPosition = mul(IN.position,WorldVP);
    OUT.texCoor = IN.texCoor;  // Передаем в пиксельный шейдер
    return OUT;
}

// Пиксельный шейдер
float4 PS(v2f IN) : COLOR
{
float3 N = normalize(IN.wnormal);
    float3 L = normalize(IN.LightVector0);
    float3 L1 = normalize(IN.LightVector1);
float diffuse = dot(N,L);
float diffuse1 = dot(N,L1);
float atten = saturate(1.0 - dot(IN.LightVector0, IN.LightVector0)); // Затухание
    float4 tex = tex2D(Texture1, IN.texCoor.xy);
float3 resultA = lightcol[0]*diffuse*DiffuseColor*atten*tex;
float3 resultB = lightcol[1]*diffuse1*DiffuseColor*atten*tex;
float3 result = resultA + resultB;
return float4(result,1);
}

/////////////////////////////////////////////////////////////////////////
///// Техника ///////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

technique Main
{
    pass p0
{
        VertexShader = compile vs_2_0 VS();
        PixelShader = compile ps_2_0 PS();
ZWriteEnable = true;
}
}


быдлокод дэтэктэд ;)



Цитироватьfloat atten = saturate(1.0 - dot(IN.LightVector0, IN.LightVector0)); // Затухание
в любых случаях выражение  имеет результат 0
Skype "Cludz159"

Alteste

Ха! Привет! Приятно видеть свой код.
Этот код написан для одного источника. Чтобы подключить несколько источников нужно делать отдельный проход (pass) для каждого. Чуть позже выложу полный код

Sqwer

#129
ЦитироватьХа! Привет! Приятно видеть свой код.
:P


ЦитироватьЭтот код написан для одного источника. Чтобы подключить несколько источников нужно делать отдельный проход (pass) для каждого. Чуть позже выложу полный код
ага и просадить FPS

pass = DIP

по возможности  надо стараться впихнуть в 1 проход   максимальное число ИС сколько он позволяет.

Cludz
Ниже рабочий пример    "как это делается" +  вывел расчёт  параметров ИС  в  методы, что  сократит инструкции  8)

Cludz

спасибо за помощь, у меня шок, код Sqwer в моем примере не работает... пробовал изменить пример Sqwer*а тож не пашет банально заменить 3dObjectData таже фигня
может дело в квесте (у меня версия 4.3.2) или в видяхе (NVIDIA GeForce 6800 GS) или еще какой черт, будем разбираться
Skype "Cludz159"

Sqwer

#131
Цитироватьспасибо за помощь, у меня шок, код Sqwer в моем примере не работает...

как тебе удалось обмануть ДХ?   ;D

100%   кривой пример у тебя

ещё раз сверься с моим примером  , с параметрами источников света.

3dObjectData - не влияет
версия 4.3.2 - не влияет
NVIDIA GeForce 6800 GS - не влияет

еще какой черт - скорее всего



а луч выложи свои наработки -  пофиксим


Цитироватьбанально заменить 3dObjectData таже фигня
если ты в моём примере менял, то  что-то не то  именно с Вертекс датой.

dfx

 :) Там нечему неработать. Единственное, что направление вектора света считается как для поинт-лайта и не важно, какой тип ставиться в самом квесте.

У меня вопрос к sqwer'у - динамическое ветвление в коде шейдера не позволяет ускорить вычисления путем введения условий для того, что бы отсеч ненужные на данный момент вычисления.
Фактически операции считаются параллельно в любом случае для обоих вариантов ветвления, но переменной присваивается  итоговое значение верное на данный момент. Я натыкался на информацию, что это особенность свойственна для многоядерной архитектуры, но к сожалению не могу найти эту информацию снова.
Существует ли возможность как-то обойти эту проблему? Или может быть тоже натыкался на эту инфу и поделишся ссылкой? ;)

Спасибо.

Sqwer

ЦитироватьУ меня вопрос к sqwer'у - динамическое ветвление в коде шейдера не позволяет ускорить вычисления путем введения условий для того, что бы отсеч ненужные на данный момент вычисления.
Фактически операции считаются параллельно в любом случае для обоих вариантов ветвления, но переменной присваивается  итоговое значение верное на данный момент.

нет,  в HLSL  есть   возможность переключения:

расскрывать ветвь и считать параллельно
и действовать как при настоящем условии (сперва выполнять условие и по результату считать)


кури HLSL на MSDN

тут референсы по всем условиям
http://msdn.microsoft.com/en-us/library/bb509600(v=VS.85).aspx

каждый тип условного оператора  имеет  предикат (атрибут), который и устанавливает спопоб работы оператора

например  IF
http://msdn.microsoft.com/en-us/library/bb509610(v=VS.85).aspx

Цитироватьbranch   Evaluate only one side of the if statement depending on the given condition.
- тип:  исполняется 1 вариант  поусловию

flatten   Evaluate both sides of the if statement and choose between the two resulting values.
- тип: исполняется 2 варианта  по результату

по умолчанию "branch"



ЗЫ  многие  высказывают  свой негатив по поводу использования  условных операторов, основываясь на больших штрафах  исполнения IF , чем на исполнение внутреннего кода.

ДА  это было так, старые карты   Gфорсы (до 8ххх серии) и АТИхи (до 3ххх)   не могли эффективно справляться с условными операторами, но сейчас уже на дворе 2011  и раритетных карт  уже почти не осталось, так что не стоит бояться этих  операторов и наоборот  почаще использовать, где они заметно дадут прирост. например циклы с участием выборки из текстуры (POM например).

dfx

#134
Спасибо, Sqwer! Похоже, это то, что надо. :)

ЗЫ.Сталкнулся с проблемой - в коде эффекта много таких переходов. Но использование входных параметров, которые по условиям должны исключать куски кода со сложными вычислениями, скорости не прибавляет. Т.е. она остается такой же как и при использовании этих блоков кода.