20 Мая 2024, 06:58:09
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Навигация по форуму







guest3d
Quest3D - Русскоязычное сообщество > Quest3D > Визуализация, Шейдеры > Шейдеростроение с уклоном в Q3D (для начинающих)
Шейдеростроение с уклоном в Q3D (для начинающих)
(Прочитано 27148 раз)
  [1] 2
Печать
Const_47 | **** | Старожил | Сообщений: 299 | « 30 Ноября 2008, 00:01:27 »
Шейдеростроение с уклоном в Q3D (для начинающих) |
0
Привет всем. Я наконец то разгребся со своими проблемами, и снова тут Улыбающийся)) Как и обещал, напишу об адаптации шейдеров из
Композера,Обезьяны и Мельници. Попрошу модератора править мои грамматические ошибки, а программистов логические:))). Дело в том, что мой родной язык не русский, и если разговаривать и читать я как нибудь научился, то с писанием большие проблемы.

Материал для начинающих, люди с опытом могут даже не читать, сомневаюсь что найдут что то новое.

Для того, что бы приступить к материалу по адаптации, который будет по немного появляться, нужно усвоить некоторые азы. Вот тут архивчик
http://rapidshare.com/files/168654875/shader.zip.html
В архивчике несколько сgr, и fx файлов к ним.

Разгребать в такой последовательности
1White - Самые общие сведения о шейдере.
2Slider - Подключение слайдеров.
3Texture - Подключение текстур.
4Light  - Подключение источника света.

На всякий случай, я продублирую fx файлы на форуме, так как архивчик с файлообменника могут удалить, а вся инфа в комментах. Люди с опытом если вы все же читаете, пожалуйста комментируйте и правте мои утверждения, так как знаю я значительно меньше чем не знаю Улыбающийся))

Редактирование (KBECT0MAH):
прикрепил архив с примерами к теме.
Название темы изменено.
.
* Const47_shader.zip (279.43 Кб - загружено 788 раз.)
« Последнее редактирование: 02 Декабря 2008, 10:54:18 от KBECT0MAH »
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #1 30 Ноября 2008, 00:04:29 »
Re: Шейдероваяние для начинающих |
1
//White
/*
Матрица преобразования в пространство отсечения(экран монитора:))

где float4x4 - ТипРазмерность,
WorldVP - Идентификатор(Имя),
WorldViewProjection - семантика
*/

float4x4 WorldVP : WorldViewProjection; 


/*
Здесь мы определяем структуру appdata, из экземпляра которой мы будем
читать данные, что нужны нам для обработки в вершинном шейдере.
Такую структуру мы будем заполнять теми данными, которые нам нужны от
геометрии нашей модели. Q3D читает эти данные из channel 3D оbject data,
в котором по сути содержится геометрия, потом они попадают:) на обработку
видео, где на определенном этапе у нас есть возможность их перехватить из
потока вершин, для личного использования:) 
 О том каким значением инициализировать, как что и куда передавать заботится СЕМАНТИКА.   
*/

 
struct appdata
{
/*        
 Заполним структуру переменной Position
 где float3 ТипРазмерность(Трехкомпонентный вектор)
 Position - Идентификатор(Имя)
 POSITION - семантика, которая гарантирует что в такую переменную будет помещено
 значение позиции вершины нашей модели(х,y,z координаты), те данные которые мы
 перехватим из потока вершин для КОНКРЕТНОЙ вершины.   
*/ 
// Вот этой переменной будет присвоено значение не преобразованной вершины.
// Локальные координаты вершины нашей модели     

    float3 Position   : POSITION;
};

/*
Определяем промежуточную структуру vertexOutput.
Такую структуру мы будем заполнять теми данными, которые
будет обрабатывать сначала вершинный а потом возможно пиксельный шейдер
Выходные данные от вершинного и входные для пиксельного шейдера

*/


struct vertexOutput {
    //Вот этой переменной будет присвоено значение преобразованной вершины
   //Вершина нашей модели в пространстве отсечения

    float4 HPosition   : POSITION;
};

/*
А вот это Вершинный шейдер, это именно та функция, в которой мы будем обрабатывать
КАЖДУЮ ВЕРШИНУ нашей геометрии, и делать это по своему усмотрению.
 
vertexOutput это возвращаемый функцией тип(наша промежуточная структура),
VS - имя функции, appdata IN - передаваемый функции аргумент (экземпляр нашей входной структуры),
где appdata тип данных, IN - имя конкретной переменной(экземпляра)

*/ 

vertexOutput VS(appdata IN)
{
   //экземпляр нашей выходной структуры, которому мы обнуляем все данные.
   //vertexOutput - тип, OUT - имя.

    vertexOutput OUT = (vertexOutput)0; 

   //преобразование вершины модели в пространство отсечения                                   
    OUT.HPosition = mul(float4(IN.Position,1),WorldVP);
   
      
    return OUT;//Возвращаем значение
}

/*
А вот это Пиксельный шейдер, это именно та функция, в которой мы будем обрабатывать
КАЖДЫЙ ПИКСЕЛЬ нашей геометрии, ДА!Я не ошибся, именно Пиксель.К этому времени видеокарта
уже позаботилась:) о том, чтобы преобразовать наши вершины в итоговые пиксели.
Учтите! Чем больше пикселей итоговой геометрии(картинки) будет рисоваться  на мониторе,
"тяжелее" для просчета алгоритм получения финальной закраски,тем больше времени ей нужно
 для просчетов.

 float4 - возвращаемый функцией тип(пиксель),PS - имя функции, vertexOutput IN - экземпляр
 нашей промежуточной структуры, из которой в пиксельном шейдере мы можем читать необходимые
 для нас данные, уже обработанные в вершинном, СOLOR - cемантика.
*/

 
float4 PS(vertexOutput IN) : COLOR
{

   // Объявляем и инициализируем
   // переменную result = {r,g,b,a};
   // Поэкспериментируйтe c возвращаемым значением, 1 это тоже что и 255 для оттенка
   // токо в диапазоне от 0 к 1; 
 
   float4 result = {1,1,1,1};
   
    return result; //возвращаем цвет пикселя, в этом примере закрашиваем в белый цвет
}

//Указываем видео, что именно, и как ему нужно просчитать.
technique white
 {
    //рисуем в один проход
    pass p0

 {
        VertexShader = compile vs_2_0 VS();
        PixelShader = compile ps_2_0 PS();

 }
}
« Последнее редактирование: 26 Декабря 2010, 01:23:49 от Sqwer »
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #2 30 Ноября 2008, 00:06:09 »
Re: Шейдероваяние для начинающих |
2
//Slider

//Матрица преобразования в пространство отсечения(экран монитора:))
float4x4 WorldVP : WorldViewProjection; 

/*
Вот так подключаются слайдера(GUI), позволяющие визуальную настройку шейдера
в Q3D редакторе материалов(Object->material/shader propeties)
*/
//Cлайдер вектор , подключаем к Q3D c помощю семантики : CHANNELVECTOR
//Cмотрите в Q3Dредактор материалов
float3 SurfaceColor : CHANNELVECTOR0 <
    string UIName =  "Surface";  //имя в редакторе
    string UIWidget = "Color";   //указание Q3D нарисовать наш слайдер в редакторе
> = {1,1,1};

//Cлайдер cкаляр , подключаем к Q3D c помощю семантики : CHANNELVALUE
//Cмотрите в Q3Dредактор материалов
float multipler : CHANNELVALUE0 <
    string UIWidget = "slider"; //указание Q3D нарисовать наш слайдер в редакторе
    float UIMin = 0.0;          //Мин значение
    float UIMax = 2.0;          //Макс значение
    float UIStep = 0.01;        //Шаг
    string UIName =  "mulptipler";//имя в редакторе
> = 0.5;


//Для ваших шейдеров, скорее всего будут нужны ише слайдера-векторы или слайдера-скаляры
//поэтому при копипасте не забываем менять имя переменной и номер семантики
//например
/*
float3 SUPERSurfaceColor : CHANNELVECTOR1 <
    string UIName =  "SUPER"; 
    string UIWidget = "Color";
> = {1,1,1};

float multipler2 : CHANNELVALUE1 <
    string UIWidget = "slider";
    float UIMin = 0.0;
    float UIMax = 5.0;
    float UIStep = 0.02;
    string UIName =  "fignya kakayato";
> = 2.5;

*/

//А может вам нужно передавать в шейдер переменную из Q3D, но вы не хотите что бы
//такая переменная имела возвожность редагированния из редактора
//пример

/*
float3 windvector : CHANNELVECTOR1;
float  timer : CHANNELVALUE1;

//Такие переменне будут брать значение из канала Q3D vector, или value которые нужно
линковать к каналу hlsl. НОМЕР ЛИНКА И НОМЕР СЕМАНТИКИ ДОЛЖНЫ СОВПАДАТЬ!!!
первый линк в Q3D это номер семантки 0, второй это 1 и так далее.

*/
//Структуры
struct appdata {                     
    float3 Position   : POSITION;

};

struct vertexOutput {
    float4 HPosition   : POSITION;

};
//Вершинный шейдер
vertexOutput VS(appdata IN)
{
    vertexOutput OUT = (vertexOutput)0; 
                                      
    OUT.HPosition = mul(float4(IN.Position,1),WorldVP);
      
    return OUT;
}
//Пиксельный шейдер
float4 PS(vertexOutput IN) : COLOR
{
    /*
   Внимательно посмотрите на возвращаемый параметр, цвет пикселя.
   Почему так - float4(SurfaceColor*multipler,1); а не так SurfaceColor*multipler?
   Дело в том, что видеокарта ожидает получить от пиксельного шейдера четырех
   компонентный вектор float4(r,g,b,a);, а в нашем случае SurfaceColor это трехкомпонентный
   описывающий float3(r,g,b) и multipler скаляр, значение которого мы используем как
   множитель:) цвета. Я просто добавил к всему этому альфу = 1;

   C другой стороны, мне ничего не мешает написать вот так
   return multipler; Я думаю, что видео поймет это
    вот так float4(multipler,multipler,multipler,multipler);

    Но возвратить такой тип float2; или float3; не получится.

   */
    return float4(SurfaceColor*multipler,1);


   
}
//Техника

technique Slider
 {
    pass p0

 {
        VertexShader = compile vs_2_0 VS();
        PixelShader = compile ps_2_0 PS();

 }
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #3 30 Ноября 2008, 00:07:49 »
Re: Шейдероваяние для начинающих |
3
//Texture

//Матрица преобразования в пространство отсечения(экран монитора:))
float4x4 WorldVP : WorldViewProjection; 

/*
Давайте подключим текстуры из Q3D

texture - тип, TextureOne - имя,СOLORMAP - Q3D ceмантика, с помощю которой мы можем
линковать текстуру из Q3D, обратите внимание на номер семантики, а теперь на порядок
ликовки в Q3D Channel Graph, канала текстуры к каналу surfase.
*/

texture TextureOne : COLORMAP0 <
    string ResourceName = "default_reflection.dds";
    string UIName =  "Environment";
    string ResourceType = "Cube";
>;

/*
А вот это семплер, Каждому видео нужно знать Улыбающийся)), как текстуру рисовать Улыбающийся))
*/
sampler Texture1 = sampler_state {

  //передаем нашему семплеру первую текстуру из Q3D
    Texture = <TextureOne>;
 //антиализинг
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
 //режим адресации
    AddressU = Clamp;
    AddressV = Clamp;
    AddressW = Clamp;
};

//А вот это подключение второй текстуры из Q3D
texture TextureSecond : COLORMAP1 <
    string ResourceName = "default_reflection.dds";
    string UIName =  "Environment";
    string ResourceType = "Cube";
>;
/*
Хочу заметить, что весь тот текст, который нужен для набора описания текстуры и
семплера я самым наглым образом скопипастил из другого кода, во избежания лишней
роботы рук, подредактировав лиш то, что посчитал нужным. В данном примере, это
название переменной текстуры, номер семантики и названия семплера.

 
*/

//Cемплер для второй текстуры
sampler Texture2 = sampler_state {
    Texture = <TextureSecond>;
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;

    AddressU = Clamp;
    AddressV = Clamp;
    AddressW = Clamp;
};



/*
Посмотрите на наши структуры, как они поправились Улыбающийся)). Теперь, я хочу получить от
геометрии  ише и текстурные координаты. Это те самые, которые мы используем в 3D
пакетах для текстуризации.   
*/
struct appdata {                     
    float3 Position    : POSITION;
   //А вот и сами текстурные координаты, где float2 это x.y(u.v) позиуия нашей верщины
   //в пространстве текстуры, Texcoord0 - имя, а TEXCOORD - cемантика, где номер
   //текстурный сет из Q3D нащей модели.
   float2 Texcoord0 : TEXCOORD0;
   float2 Texcoord1 : TEXCOORD1;

};

//промежуточная структура
struct vertexOutput {
    float4 HPosition   : POSITION;
   float2 Texcoord0 : TEXCOORD0;
   float2 Texcoord1 : TEXCOORD1;
};

//Вершинный шейдер
vertexOutput VS(appdata IN)
{
    vertexOutput OUT = (vertexOutput)0;
                                      
    OUT.HPosition = mul(float4(IN.Position,1),WorldVP);
//Теперь в вершинном щейдере, передадим пиксельному нашы текстурные координаты
   OUT.Texcoord0 = IN.Texcoord0;
   OUT.Texcoord1 = IN.Texcoord1;
   
      
    return OUT;
}

//Пиксельный шейдер 
float4 PS(vertexOutput IN) : COLOR
{
   //А здеся мы будем читать наши текстуры, с помощю встроенной HLSL функции
   //для чтения двухмерных текстур tex2D(sampler,texcoord);
   //...
   float4 Text1 = tex2D(Texture1,IN.Texcoord0);
   float4 Text2 = tex2D(Texture2,IN.Texcoord1);
    //...
    //...и рисовать Улыбающийся))
    return Text1*Text2; //возвращаем цвет пикселя.
// Аналог эфекта тultiply из фотожоповскиx леерсов
}


technique Textures
 {
    pass p0

 {
        VertexShader = compile vs_2_0 VS();
        PixelShader = compile ps_2_0 PS();

 }
}
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #4 30 Ноября 2008, 00:10:44 »
Re: Шейдероваяние для начинающих |
4
//Light

//Матрица преобразования в пространство отсечения(экран монитора:))
float4x4 WorldVP : WorldViewProjection;
//В данном примере нам будут нужны ише две матрицы

float4x4 World   : World;  //Матрица мирового преобразования
float4x4 WorldIT : WorldInverseTranspose; //инвертированная - транспонировання мир матрица
     


/*
А теперь пдключим к шейдеру Q3DLight POINT, позицию источника и цвет освещения.
*/

//Это макрос, мы узазываем заменять всюду в коде MAX_LIGHTS на 8;
#define MAX_LIGHTS 8

//это подключение позиции Q3D источника света,
//где float3 - тип(x,y,z), lightpos[MAX_LIGHTS] - имя массива,где MAX_LIGHTS - коли-
//чество элементов(в нашем случае Крутой, LIGHTPOS - Q3Dсемантика.
float3 lightpos[MAX_LIGHTS] : LIGHTPOS;

//это подключение цвета освещения Q3D источника света,
//где float3 - тип(r,g,b), lightcol[MAX_LIGHTS] - имя массива,где MAX_LIGHTS - коли-
//чество элементов(в нашем случае Крутой, LIGHTCOLOR - Q3Dсемантика.
float3 lightcol[MAX_LIGHTS] : LIGHTCOLOR;




/*
Теперь от геометрии модели, я хошу получить направление нормаля вершины, который в
дальнейшем нам будет нужен для просчета освещения.
*/
struct appdata {                     
    float3 Position    : POSITION;
//Для этого добавим в входную структуру переменную normal, где float3 - тип направ-
//ление нормали(x,y,z), normal - имя, NORMAL - семантика.
    float3 normal    : NORMAL;


};

//промежуточная структура
struct vertexOutput {
    float4 HPosition   : POSITION;
/*
Добаим переменные wnormal и LightVector в первой будет содержатся направление нормаля
в мировом пространстве, во второй вектор света.Эти значения будут помещены в переменные
после пощета в вершинном шейдере.Обратите внимание на семантику
*/
   float3 wnormal      : TEXCOORD2;
   float3 LightVector  : TEXCOORD3;

};

//Вершинный шейдер
vertexOutput VS(appdata IN)
{
    vertexOutput OUT = (vertexOutput)0;

    //Получаем направление нормаля в мировой системе координат и отдаем на обработку в
   //пиксельный шейдер
   OUT.wnormal = mul(IN.normal,WorldIT);

   //Получаем позицию вершины в мировом пространстве
   float3 wpos = mul(IN.Position,World);

   /*
   Здеся мы просчитаем вектор света, для этого нам нужны вершины в мировом пространстве
   которые мы получили выше, и позиция источника света которые мы получаем от Квеста
   УЖЕ в мировой системе координат.

   Вот это -> lightpos[0] массив, где индекс номер элемента такого массива.
   Первый элемент позиция первого источника света который я прилинковал к каналу
   рендер в Квесте(номер чилда).
   
   */   
   OUT.LightVector = lightpos[0]-wpos;


   //:)))                           
    OUT.HPosition = mul(float4(IN.Position,1),WorldVP);

   
      
    return OUT;
}

//Пиксельный шейдер 
float4 PS(vertexOutput IN) : COLOR
{
   /*
   Здесь мы получаем из нашей промежуточной структуры вектор нормали и света
   IN.wnormal,IN.LightVector нормализируем их с помощю встроеной в HLSL функции
   normalize(), и помещаем значения в переменные N и L

   Что такое normalize(arg)? Нормализация вектора это преобразование
   вектора к единичной длине.
   */
    float3 N = normalize(IN.wnormal);
    float3 L = normalize(IN.LightVector);

   /*
   Прощитаем диффузную составляющую света с помощью встроенной функции dot(arg,arg)
   Такая функция возвращает скалярное произведение векторов, cos угла между вектором
   нормали и вектором света.
   */
   float diff = dot(N,L);

   
    //А здеся мы закрасим нашу дифузу в цвет источника света.
   //-> lightcol[0] цвет первого источника, теперь цвет освещения можно редагировать
   //из Квеста
   float3 result = lightcol[0]*diff;
   
    return float4(result,1); //возвращаем цвет пикселя.

}


technique Light
 {
    pass p0

 {
        VertexShader = compile vs_2_0 VS();
        PixelShader = compile ps_2_0 PS();

 }
}
→|๖ۣۜDen|← | ***** | Администратор | Ветеран | Сообщений: 570 | «Ответ #5 30 Ноября 2008, 13:02:11 »
Re: Шейдероваяние для начинающих |
5
Спасибо тебе Const_47, после такого долгого перерыва всё таки сделал топик!)) Будем разбираться! Целующий Смеющийся
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #6 01 Декабря 2008, 00:02:22 »
Re: Шейдероваяние для начинающих |
6
Привет, а теперь поговорим о адаптации шейдеров от NVIDIA
Почему от NVIDIA? Потому что с такими шейдерами меньше всего
проблем при адаптации к Квесту. Начинающим будет проще разобратся. Как образец я взял шейдер Metal.fx от сюда
http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html
А вот тут уже адаптированный шейдер для Квеста
http://rapidshare.com/files/168971910/adapt.zip.html
Ниже приведу пример исходника оригинала, конешно моих комментов в оригинале нету:)))
 
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #7 01 Декабря 2008, 00:06:57 »
Re: Шейдероваяние для начинающих |
7
/*
Шейдер от Nvidia четыре техники, point и direct light, поддержка DX10
Вот это все то что ниже,в нашем случае хлам, гарантирующий что этод код будет работать для "всех cлучаев жизни"Улыбающийся))
Нам это не нужно, моно спокойно это удалять. Макросы и коменты.
*/
/*********************************************************************NVMH3****
*******************************************************************************
$Revision: #4 $

Copyright NVIDIA Corporation 2008
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Это описание того, что умеет такой шейдер
% A phong-shaded metallic surface lit from either
% a point or directional source.
% Textured, untextured, quadratic falloff or not
keywords: material classic
date: 070411


keywords: DirectX10
// Note that this version has twin versions of all techniques,
//   so that this single effect file can be used in *either*
//   DirectX9 or DirectX10

To learn more about shading, shaders, and to bounce ideas off other shader
    authors and users, visit the NVIDIA Shader Library Forums at:

    http://developer.nvidia.com/forums/

*******************************************************************************
******************************************************************************/

/*****************************************************************/
/*** HOST APPLICATION IDENTIFIERS ********************************/
/*** Potentially predefined by varying host environments *********/
/*****************************************************************/

// #define _XSI_      /* predefined when running in XSI */
// #define TORQUE      /* predefined in TGEA 1.7 and up */
// #define _3DSMAX_      /* predefined in 3DS Max */
#ifdef _3DSMAX_
int ParamID = 0x0003;      /* Used by Max to select the correct parser */
#endif /* _3DSMAX_ */
#ifdef _XSI_
#define Main Static      /* Technique name used for export to XNA */
#endif /* _XSI_ */

#ifndef FXCOMPOSER_VERSION   /* for very old versions */
#define FXCOMPOSER_VERSION 180
#endif /* FXCOMPOSER_VERSION */

#ifndef DIRECT3D_VERSION
#define DIRECT3D_VERSION 0x900
#endif /* DIRECT3D_VERSION */

#define FLIP_TEXTURE_Y   /* Different in OpenGL & DirectX */

/*****************************************************************/
/*** EFFECT-SPECIFIC CODE BEGINS HERE ****************************/
/*****************************************************************/

/******* Lighting Macros *******/
/** To use "Object-Space" lighting definitions, change these two macros: **/
#define LIGHT_COORDS "World"
// #define OBJECT_SPACE_LIGHTS /* Define if LIGHT_COORDS is "Object" */


float Script : STANDARDSGLOBAL <
    string UIWidget = "none";
    string ScriptClass = "object";
    string ScriptOrder = "standard";
    string ScriptOutput = "color";
//  string Script = "Technique=Technique?Simple:Simple10:Textured:Textured10:SimpleFalloff:SimpleFalloff10:TexturedFalloff:TexturedFalloff10;";
> = 0.8;

//Хлам окончен.Ниже обявление матриц.

/**** UNTWEAKABLES: Hidden & Automatically-Tracked Parameters **********/

// transform object vertices to world-space:
float4x4 gWorldXf : World < string UIWidget="None"; >;
// transform object normals, tangents, & binormals to world-space:
float4x4 gWorldITXf : WorldInverseTranspose < string UIWidget="None"; >;
// transform object vertices to view space and project them in perspective:
float4x4 gWvpXf : WorldViewProjection < string UIWidget="None"; >;
// provide tranform from "view" or "eye" coords back to world-space:
float4x4 gViewIXf : ViewInverse < string UIWidget="None"; >;

/************* TWEAKABLES **************/
/*
То что ниже это переменные, описывающие виртуальный источник света
gLamp0DirPos -> позиция-направление, gLamp0Color -> цвет, gLamp0Intensity -> интенсивность.
В нашем случае они не нужны кроме gLamp0Intensity, мы будем использовать квестовский источник. 
*/
// "DirPos" Lamp 0 /////////
float4 gLamp0DirPos : POSITION < // or direction, if W==0
    string Object = "Light0";
    string UIName =  "Lamp 0 Position/Direction";
    string Space = (LIGHT_COORDS);
> = {-0.5f,2.0f,1.25f,1.0};
float3 gLamp0Color : SPECULAR <
    string UIName =  "Lamp 0";
    string Object = "Light0";
    string UIWidget = "Color";
> = {1.0f,1.0f,1.0f};
float gLamp0Intensity <
    string UIWidget = "slider";
    float UIMin = 1.0;
    float UIMax = 10000.0f;
    float UIStep = 0.1;
    string UIName =  "Lamp 0 Quadratic Intensity";
> = 1.0f;

/*
А вот собсно нужные нам слайдера, но вот с семантикой под Квест у них не сложилось:)))
Нужно подредактировать
*/
// Ambient Light
float3 gAmbiColor : AMBIENT <
    string UIName =  "Ambient Light";
    string UIWidget = "Color";
> = {0.07f,0.07f,0.07f};

// surface color
float3 gSurfaceColor : DIFFUSE <
    string UIName =  "Surface";
    string UIWidget = "Color";
> = {1,1,1};

float gSpecExpon <
    string UIWidget = "slider";
    float UIMin = 1.0;
    float UIMax = 128.0;
    float UIStep = 1.0;
    string UIName =  "Specular Exponent";
> = 12.0;

float gKd <
    string UIWidget = "slider";
    float UIMin = 0.0;
    float UIMax = 1.0;
    float UIStep = 0.01;
    string UIName =  "Diffuse";
> = 0.1;

float gKr <
    string UIWidget = "slider";
    float UIMin = 0.0;
    float UIMax = 1.0;
    float UIStep = 0.05;
    string UIName =  "Reflection";
> = 0.2;

//////////
//Текстуры и семплеры, тоже нуждаются в подредактировании под Квест
texture gColorTexture : DIFFUSE <
    string ResourceName = "default_color.dds";
    string UIName =  "Diffuse Texture";
    string ResourceType = "2D";
>;

sampler2D gColorSampler = sampler_state {
    Texture = <gColorTexture>;
#if DIRECT3D_VERSION >= 0xa00   //Макрос проверяющий случайно у нас не версия DX10 или выше?
    Filter = MIN_MAG_MIP_LINEAR; //В нашем случае хлам для DX10
#else /* DIRECT3D_VERSION < 0xa00 */
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
#endif /* DIRECT3D_VERSION */
    AddressU = Wrap;
    AddressV = Wrap;
}; 

texture gEnvTexture : ENVIRONMENT <
    string ResourceName = "default_reflection.dds";
    string UIName =  "Environment";
    string ResourceType = "Cube";
>;

samplerCUBE gEnvSampler = sampler_state {
    Texture = <gEnvTexture>;
#if DIRECT3D_VERSION >= 0xa00
    Filter = MIN_MAG_MIP_LINEAR;
#else /* DIRECT3D_VERSION < 0xa00 */
    MinFilter = Linear;
    MipFilter = Linear;
    MagFilter = Linear;
#endif /* DIRECT3D_VERSION */
    AddressU = Clamp;
    AddressV = Clamp;
    AddressW = Clamp;
};

// shared shadow mapping supported in Cg version

/************* DATA STRUCTS **************/
//Данные которые нам нужны от вершин нашей геометрии
/* data from application vertex buffer */
struct appdata {
    float3 Position   : POSITION;
    float4 UV      : TEXCOORD0;
    float4 Normal   : NORMAL;
    float4 Tangent   : TANGENT0;// В этом шейдере Тангент и Бинормаль не используется
    float4 Binormal   : BINORMAL0;//Удаляем,
};

//Данные которые нам нужны для пиксельного шейдера
/* data passed from vertex shader to pixel shader */
struct vertexOutput {
    float4 HPosition   : POSITION;
    float2 UV      : TEXCOORD0;
    // The following values are passed in "World" coordinates since
    //   it tends to be the most flexible and easy for handling
    //   reflections, sky lighting, and other "global" effects.
    float3 LightVec   : TEXCOORD1;
    float3 WorldNormal   : TEXCOORD2;
    float3 WorldTangent   : TEXCOORD3;//Удаляем
    float3 WorldBinormal : TEXCOORD4;//Удаляем
    float3 WorldView   : TEXCOORD5;
};

/*********** vertex shader for pixel-shaded versions ******/
//Вершинный шейдер
/*********** Generic Vertex Shader ******/

vertexOutput std_dp_VS(appdata IN,
   uniform float4x4 WorldITXf, // our four standard "untweakable" xforms
   uniform float4x4 WorldXf,
   uniform float4x4 ViewIXf,
   uniform float4x4 WvpXf,
   uniform float4 LampDirPos
) {
    vertexOutput OUT = (vertexOutput)0;
    OUT.WorldNormal = mul(IN.Normal,WorldITXf).xyz;
    OUT.WorldTangent = mul(IN.Tangent,WorldITXf).xyz;
    OUT.WorldBinormal = mul(IN.Binormal,WorldITXf).xyz;
    float4 Po = float4(IN.Position.xyz,1);
    float4 Pw = mul(Po,WorldXf);   // convert to "world" space
#ifdef OBJECT_SPACE_LIGHTS
    float4 Lw = mul(LampDirPos,WorldXf);   // convert to "world" space
#else /* !OBJECT_SPACE_LIGHTS -- standard world-space lights */
    float4 Lw = LampDirPos;
#endif /* !OBJECT_SPACE_LIGHTS */
    if (Lw.w == 0) {
   OUT.LightVec = -normalize(Lw.xyz);
    } else {
   // we are still passing a (non-normalized) vector
   OUT.LightVec = Lw.xyz - Pw.xyz;
    }
#ifdef FLIP_TEXTURE_Y
    OUT.UV = float2(IN.UV.x,(1.0-IN.UV.y));
#else /* !FLIP_TEXTURE_Y */
    OUT.UV = IN.UV.xy;
#endif /* !FLIP_TEXTURE_Y */
    OUT.WorldView = normalize(ViewIXf[3].xyz - Pw.xyz);
    OUT.HPosition = mul(Po,WvpXf);
    return OUT;
}

/********* pixel shaders ********/
//Окраска по Фонгу+Рефлект
void metal_shared(vertexOutput IN,
         uniform float Kd,
         uniform float SpecExpon,
         uniform float Kr,
         uniform samplerCUBE EnvSampler,
         float3 LightColor,
         uniform float3 AmbiColor,
         out float3 DiffuseContrib,
         out float3 SpecularContrib)
{
    float3 Ln = normalize(IN.LightVec.xyz);
    float3 Nn = normalize(IN.WorldNormal);
    float3 Vn = normalize(IN.WorldView);
    float3 Hn = normalize(Vn + Ln);
    float4 litV = lit(dot(Ln,Nn),dot(Hn,Nn),SpecExpon);
    DiffuseContrib = litV.y * Kd * LightColor + AmbiColor;
    SpecularContrib = litV.z * LightColor;
    float3 reflVect = -reflect(Vn,Nn);
    float3 ReflectionContrib = Kr * texCUBE(EnvSampler,reflVect).rgb;
    SpecularContrib += ReflectionContrib;
}
//Ниже четыре пиксельных шейдера, которые нужны для разных техник
float4 metalPS(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
   metal_shared(IN,Kd,SpecExpon,Kr,
         EnvSampler,LampColor,AmbiColor,
         diffContrib,specContrib);
    float3 result = SurfaceColor * (specContrib + diffContrib);
    return float4(result,1);
}

float4 metalPS_t(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform sampler2D ColorSampler,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
   metal_shared(IN,Kd,SpecExpon,Kr,
         EnvSampler,LampColor,AmbiColor,
         diffContrib,specContrib);
    float3 map = tex2D(ColorSampler,IN.UV).xyz;
    float3 result = SurfaceColor * map * (specContrib + diffContrib);
    return float4(result,1);
}

// same as above with the addition of quadratic falloff

float4 metalQPS(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float LampIntensity,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
    float3 Cl = (LampIntensity/dot(IN.LightVec.xyz,IN.LightVec.xyz)) * LampColor;
    metal_shared(IN,Kd,SpecExpon,Kr,
          EnvSampler,Cl,AmbiColor,
          diffContrib,specContrib);
    float3 result = SurfaceColor * (specContrib + diffContrib);
    return float4(result,1);
}

float4 metalQPS_t(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform sampler2D ColorSampler,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float LampIntensity,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
    float3 Cl = (LampIntensity/dot(IN.LightVec.xyz,IN.LightVec.xyz)) * LampColor;
    metal_shared(IN,Kd,SpecExpon,Kr,
          EnvSampler,Cl,AmbiColor,
          diffContrib,specContrib);
    float3 map = tex2D(ColorSampler,IN.UV).xyz;
    float3 result = SurfaceColor * map * (diffContrib+specContrib);
    return float4(result,1);
}

///////////////////////////////////////
/// TECHNIQUES ////////////////////////
///////////////////////////////////////


#if DIRECT3D_VERSION >= 0xa00
//
// Standard DirectX10 Material State Blocks
//
RasterizerState DisableCulling { CullMode = NONE; };
DepthStencilState DepthEnabling { DepthEnable = TRUE; };
DepthStencilState DepthDisabling {
   DepthEnable = FALSE;
   DepthWriteMask = ZERO;
};
BlendState DisableBlend { BlendEnable[0] = FALSE; };

technique10 Simple10 <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        SetVertexShader( CompileShader( vs_4_0, std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, metalPS(gSurfaceColor,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gAmbiColor) ) );
       SetRasterizerState(DisableCulling);
       SetDepthStencilState(DepthEnabling, 0);
       SetBlendState(DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    }
}

#endif /* DIRECT3D_VERSION >= 0xa00 */

technique Simple <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        VertexShader = compile vs_3_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_3_0 metalPS(gSurfaceColor,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gAmbiColor);
    }
}

//Ниже техники для DX9 и DX10
//Техники для DX10 удаляем, во всяком случае пока Квест не научили "понимать" DX10
#if DIRECT3D_VERSION >= 0xa00

technique10 Textured10 <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        SetVertexShader( CompileShader( vs_4_0, std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, metalPS_t(gSurfaceColor,gColorSampler,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gAmbiColor) ) );
       SetRasterizerState(DisableCulling);
       SetDepthStencilState(DepthEnabling, 0);
       SetBlendState(DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    }
}

#endif /* DIRECT3D_VERSION >= 0xa00 */

technique Textured <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        VertexShader = compile vs_3_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_3_0 metalPS_t(gSurfaceColor,gColorSampler,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gAmbiColor);
    }
}

// pixel shaded, quadratic falloff


#if DIRECT3D_VERSION >= 0xa00

technique10 SimpleFalloff10 <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        SetVertexShader( CompileShader( vs_4_0, std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, metalQPS(gSurfaceColor,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gLamp0Intensity,
                  gAmbiColor) ) );
       SetRasterizerState(DisableCulling);
       SetDepthStencilState(DepthEnabling, 0);
       SetBlendState(DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    }
}

#endif /* DIRECT3D_VERSION >= 0xa00 */

technique SimpleFalloff <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        VertexShader = compile vs_3_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_3_0 metalQPS(gSurfaceColor,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gLamp0Intensity,
                  gAmbiColor);
    }
}

#if DIRECT3D_VERSION >= 0xa00

technique10 TexturedFalloff10 <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        SetVertexShader( CompileShader( vs_4_0, std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, metalQPS_t(gSurfaceColor,gColorSampler,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gLamp0Intensity,
                  gAmbiColor) ) );
       SetRasterizerState(DisableCulling);
       SetDepthStencilState(DepthEnabling, 0);
       SetBlendState(DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    }
}

#endif /* DIRECT3D_VERSION >= 0xa00 */

technique TexturedFalloff <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        VertexShader = compile vs_3_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            gLamp0DirPos);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_3_0 metalQPS_t(gSurfaceColor,gColorSampler,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  gLamp0Color,gLamp0Intensity,
                  gAmbiColor);
    }
}

/***************************** eof ***/
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #8 01 Декабря 2008, 00:09:20 »
Re: Шейдероваяние для начинающих |
8
//Const_47
/*
А вот то, что у меня получилось после адаптации NVIDIA шейдера для Q3D
Четыре однопроходных техники ->Simple,Textured,SimpleFalloff,TexturedFalloff
Менять в канале HLSL в вкладке сверху Улыбающийся))
Реагирует на POINT и DIRECTIONAL лайт. Все "запчасти" от DX10 выброшены
*/


#define MAX_LIGHTS 8 //Макрос - Подставляет всюду в коде 8 вместо MAX_LIGHTS

#define LIGHT_TYPE_POINT            1//Aналогично
//#define LIGHT_TYPE_SPOT             2
#define LIGHT_TYPE_DIRECTIONAL      3

float  lighttype[MAX_LIGHTS]:LIGHTTYPE; //Массив содержит инфу о типе освещения
//0 - нет, 1 - point, 2 - spot, 3 - direct
float3 lightpos[MAX_LIGHTS] : LIGHTPOS; //Содержит  позиции источников света
float3 lightcol[MAX_LIGHTS] : LIGHTCOLOR;//Содержит  цвет источников
float4 lightDirection[MAX_LIGHTS]     : LIGHTDIR;//Cодержит z-вектора источников, нужен для direct light 

/**** UNTWEAKABLES: Hidden & Automatically-Tracked Parameters **********/
//Матрици
// transform object vertices to world-space:
float4x4 gWorldXf : World ;
// transform object normals, tangents, & binormals to world-space:
float4x4 gWorldITXf : WorldInverseTranspose;
// transform object vertices to view space and project them in perspective:
float4x4 gWvpXf : WorldViewProjection;
// provide tranform from "view" or "eye" coords back to world-space:
float4x4 gViewIXf : ViewInverse ;

/************* TWEAKABLES **************/
//Подключил Слайдера для редактора материалов
//Слайдер gLamp0Intensiti будет работать только с техниками Simple и Textured
float gLamp0Intensity : CHANNELVALUE0 <
    string UIWidget = "slider";
    float UIMin = 0.1;//Подкоректируем мин значение
    float UIMax = 10.0f;//Подкоректируем под себя макс значение
    float UIStep = 0.01;//Подкоректируем шаг
    string UIName =  "Lamp 0 Quadratic Intensity";
> = 1.0f;


// Ambient Light
float3 gAmbiColor : CHANNELVECTOR0
 <
    string UIName =  "Ambient Light";
    string UIWidget = "Color";
> = {0.07f,0.07f,0.07f};

// surface color
float3 gSurfaceColor : CHANNELVECTOR1
 <
    string UIName =  "Surface";
    string UIWidget = "Color";
> = {1,1,1};

float gSpecExpon : CHANNELVALUE1
<
    string UIWidget = "slider";
    float UIMin = 1.0;
    float UIMax = 128.0;
    float UIStep = 1.0;
    string UIName =  "Specular Exponent";
> = 12.0;

float gKd : CHANNELVALUE2
<
    string UIWidget = "slider";
    float UIMin = 0.0;
    float UIMax = 1.0;
    float UIStep = 0.01;
    string UIName =  "Diffuse";
> = 0.1;

float gKr : CHANNELVALUE3
<
    string UIWidget = "slider";
    float UIMin = 0.0;
    float UIMax = 1.0;
    float UIStep = 0.05;
    string UIName =  "Reflection";
> = 0.2;

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

sampler2D gColorSampler = sampler_state {
    Texture = <gColorTexture>;

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

    AddressU = Wrap;
    AddressV = Wrap;
}; 
//Кубическую текстуру
texture gEnvTexture : ENVIRONMENT1 <
    string ResourceName = "default_reflection.dds";
    string UIName =  "Environment";
    string ResourceType = "Cube";
>;

samplerCUBE gEnvSampler = sampler_state {
    Texture = <gEnvTexture>;

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

    AddressU = Clamp;
    AddressV = Clamp;
    AddressW = Clamp;
};



/************* DATA STRUCTS **************/
// Оставил те данные которые мне нужны от вершины
/* data from application vertex buffer */
struct appdata {
    float3 Position   : POSITION; //позиция вершины
    float4 UV      : TEXCOORD0;//текстурные координаты 
    float4 Normal   : NORMAL;//нормаль
 //   float4 Tangent   : TANGENT0;
 //   float4 Binormal   : BINORMAL0;
};

/* data passed from vertex shader to pixel shader */
//И те данные которые мне нужны для пиксельного шейдера
struct vertexOutput {
    float4 HPosition   : POSITION;//преобразованная вершина
    float2 UV      : TEXCOORD0;//текстурные координаты
    // The following values are passed in "World" coordinates since
    //   it tends to be the most flexible and easy for handling
    //   reflections, sky lighting, and other "global" effects.
    float3 LightVec   : TEXCOORD1; // Световой вектор в мировом
    float3 WorldNormal   : TEXCOORD2; //нормаль в мировом пространстве
 //   float3 WorldTangent   : TEXCOORD3;
 //   float3 WorldBinormal : TEXCOORD4;
    float3 WorldView   : TEXCOORD5;//видовой вектор в мировом
};

/*********** vertex shader for pixel-shaded versions ******/

/*********** Generic Vertex Shader ******/
//Вершинный шейдер
/*
В вершинный шейдер в качестве аргументов передают матрици, направление освещения для
DirectLight LampDirPos и я немного подкоректировал под себя, передаю переменную lightpos
которая мне нужна для просчета освещения от PointLight.

*/
vertexOutput std_dp_VS(appdata IN,
   uniform float4x4 WorldITXf, // our four standard "untweakable" xforms
   uniform float4x4 WorldXf,
   uniform float4x4 ViewIXf,
   uniform float4x4 WvpXf,
   uniform float4 LampDirPos,
   uniform float3 lightpos
) {
    vertexOutput OUT = (vertexOutput)0;
    OUT.WorldNormal = mul(IN.Normal,WorldITXf).xyz;//Нормаль в мировом
 //   OUT.WorldTangent = mul(IN.Tangent,WorldITXf).xyz;
 //   OUT.WorldBinormal = mul(IN.Binormal,WorldITXf).xyz;

 /*
 А вот это построение из трех компонентного вектора, четырех компонентного. В данном
 случае под вектором я подразумеваю тип данных а не направление. Последний элемент
 единица это маштаб вершины, в буквальном смысле этого слова.
 */
    float4 Po = float4(IN.Position.xyz,1); 


   
    float4 Pw = mul(Po,WorldXf);   // convert to "world" space:)))


/*
Вот здесь я существенно переделал оригинал. Почему я так зделал? Ведь двойная
проверка для каждой вершины модели на тип источника это лишние просчеты, и если
для этой цели использовать макросы их можно избежать.Такой подход позволяет менять
реакцию шейдера на смену в сцене типа источника динамически, в отличии от макросов.
В квесте Вкладка Anim -> Выберите источник света, и поменяйте его тип. И если вам
в сцене нет нужды менять динамически тип источника света НИКОГДА ТАК НЕ ДЕЛАЙТЕ!!!
В этом примере понимает только два типа.
*/   
   if (lighttype[0] == LIGHT_TYPE_POINT)
    {
     OUT.LightVec = lightpos - Pw;//Если поинт 
    }
 
    if (lighttype[0] == LIGHT_TYPE_DIRECTIONAL)
   {
     OUT.LightVec  = -LampDirPos;//Если директ
    }


   
   OUT.UV = IN.UV;//текстурные координаты
   
    OUT.WorldView = normalize(ViewIXf[3].xyz - Pw.xyz);//Видовой вектор
   
    OUT.HPosition = mul(Po,WvpXf);//вершина в пространстве отсечения
    return OUT;
}

/********* pixel shaders ********/
/*
А вот это та функция, которую мы будем вызыват в пиксельном шейдере
Это просчет закраски по Фонгу с помощю Lit функции + отражения
*/
void metal_shared(vertexOutput IN,
         uniform float Kd,
         uniform float SpecExpon,
         uniform float Kr,
         uniform samplerCUBE EnvSampler,
         float3 LightColor,
         uniform float3 AmbiColor,
         out float3 DiffuseContrib,
         out float3 SpecularContrib)
{
    float3 Ln = normalize(IN.LightVec.xyz);//Световой вектор
    float3 Nn = normalize(IN.WorldNormal);//Нормаль
    float3 Vn = normalize(IN.WorldView);//Видовой вектор
    float3 Hn = normalize(Vn + Ln);//Серединный вектор
    float4 litV = lit(dot(Ln,Nn),dot(Hn,Nn),SpecExpon);//Lit функция
    DiffuseContrib = litV.y * Kd * LightColor + AmbiColor;//Диффуз,цвет освещения+aмбиент
    SpecularContrib = litV.z * LightColor;//Спекуляр,цвет освещения
    float3 reflVect = -reflect(Vn,Nn);//Вектор отражения
    float3 ReflectionContrib = Kr * texCUBE(EnvSampler,reflVect).rgb;//Читаем куб текстуру
    SpecularContrib += ReflectionContrib;//Спекуляр+отражение
}
//Пиксельный шейдер для Техники Simple
float4 metalPS(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
   metal_shared(IN,Kd,SpecExpon,Kr,
         EnvSampler,LampColor,AmbiColor,
         diffContrib,specContrib);
    float3 result = SurfaceColor * (specContrib + diffContrib);//Финальная закраска
    return float4(result,1);
}
//Пиксельный шейдер для Техники Textured
float4 metalPS_t(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform sampler2D ColorSampler,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
   metal_shared(IN,Kd,SpecExpon,Kr,
         EnvSampler,LampColor,AmbiColor,
         diffContrib,specContrib);
    float3 map = tex2D(ColorSampler,IN.UV).xyz;//Читаем из 2D текстуры
    float3 result = SurfaceColor * map * (specContrib + diffContrib);
    return float4(result,1);
}

// same as above with the addition of quadratic falloff
//Пиксельный шейдер для Техники SimpleFalloff
float4 metalQPS(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float LampIntensity,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
//А вот это просчет того самого Falloff
    float3 Cl = (LampIntensity/dot(IN.LightVec.xyz,IN.LightVec.xyz)) * LampColor;
    metal_shared(IN,Kd,SpecExpon,Kr,
          EnvSampler,Cl,AmbiColor,
          diffContrib,specContrib);
    float3 result = SurfaceColor * (specContrib + diffContrib);
    return float4(result,1);
}
//Пиксельный шейдер для Техники ТеxturedFalloff
float4 metalQPS_t(vertexOutput IN,
          uniform float3 SurfaceColor,
          uniform sampler2D ColorSampler,
          uniform float Kd,
          uniform float SpecExpon,
          uniform float Kr,
          uniform samplerCUBE EnvSampler,
          uniform float3 LampColor,
          uniform float LampIntensity,
          uniform float3 AmbiColor
) : COLOR {
    float3 diffContrib;
    float3 specContrib;
    float3 Cl = (LampIntensity/dot(IN.LightVec.xyz,IN.LightVec.xyz)) * LampColor;
    metal_shared(IN,Kd,SpecExpon,Kr,
          EnvSampler,Cl,AmbiColor,
          diffContrib,specContrib);
    float3 map = tex2D(ColorSampler,IN.UV).xyz;
    float3 result = SurfaceColor * map * (diffContrib+specContrib);
    return float4(result,1);
}

///////////////////////////////////////
/// TECHNIQUES ////////////////////////
///////////////////////////////////////

/*
А вот это Техники, в которых я подредактировал собсно модель шейдера из _3_0
к _2_0, поскольку в шейдере нет ничего непонятного для вторых. Зато теперь обла-
датели видеокарт не поддерживающих 3 смогут увидеть шейдер. Ну и конешно аргументы
lightDirection[0],lightpos[0] для вершинного, и lightсol[0] для пиксельного.   

!!!Если вы обладатель современного видео и шейдер у вас подтормаживает, подредактируйте
модель шейдера из двойки на тройку, поскольку некоторые современные видеокарты не
совсем корректно работают с 2_0.
*/
technique Simple
 {
    pass p0

    {
        VertexShader = compile vs_2_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            lightDirection[0],lightpos[0]);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_2_0 metalPS(gSurfaceColor,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  lightcol[0],gAmbiColor);
    }
}

technique Textured

 {
    pass p0
   {
        VertexShader = compile vs_2_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            lightDirection[0],lightpos[0]);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_2_0 metalPS_t(gSurfaceColor,gColorSampler,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  lightcol[0],gAmbiColor);
    }
}


technique SimpleFalloff

 {
    pass p0

    {
        VertexShader = compile vs_2_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            lightDirection[0],lightpos[0]);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_2_0 metalQPS(gSurfaceColor,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  lightcol[0],gLamp0Intensity,
                  gAmbiColor);
    }
}



technique TexturedFalloff <
   string Script = "Pass=p0;";
> {
    pass p0 <
   string Script = "Draw=geometry;";
    > {
        VertexShader = compile vs_2_0 std_dp_VS(gWorldITXf,gWorldXf,
            gViewIXf,gWvpXf,
            lightDirection[0],lightpos[0]);
      ZEnable = true;
      ZWriteEnable = true;
      ZFunc = LessEqual;
      AlphaBlendEnable = false;
      CullMode = None;
        PixelShader = compile ps_2_0 metalQPS_t(gSurfaceColor,gColorSampler,
                  gKd,gSpecExpon,gKr,
                  gEnvSampler,
                  lightcol[0],gLamp0Intensity,
                  gAmbiColor);
    }
}

/***************************** eof ***/
 
Danro | * | Новичок | Сообщений: 26 | «Ответ #9 02 Декабря 2008, 10:04:35 »
Re: Шейдероваяние для начинающих |
9
Const_47 большое тебе, человеческое спасибо.
BROTHERMECHANIC | ** | Пользователь | Сообщений: 62 | «Ответ #10 03 Декабря 2008, 15:54:24 »
Re: Шейдеростроение с уклоном в Q3D (для начинающих) |
10
Привет.
Const_47, безмерно благодарен тебе!!!
У меня получилось!
Вот, если не верите.
(сценка для Quest3D 4.2.2 + FX)
http://rapidshare.com/files/169824904/YA_SDELAL_ETO.rar.html
Просто ламберт, который АВТОМАТИЧЕСКИ РЕАГИРУЕТ НА СВЕТ!

Я ВЕЛИКИЙ ШЕЙДЕРОПИСЕЦ!
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #11 03 Декабря 2008, 21:10:28 »
Re: Шейдеростроение с уклоном в Q3D (для начинающих) |
11
Я рад, что смог помочь.

&Brothermecanic
Начало должно быть великим:), иначе зачем начинать?

Сейчас готовлю новый материал, думаю в смысле творчества он
еще больше развяжет руки.
BROTHERMECHANIC | ** | Пользователь | Сообщений: 62 | «Ответ #12 04 Декабря 2008, 11:33:14 »
Re: Шейдеростроение с уклоном в Q3D (для начинающих) |
12
Спасибо еще раз.
Я продолжаю копать MM и возникла пара затруднений, мне не поддающихся.
Шейдеры в квесте прекрасно работают с Phong (лучше всех - illumination phong),
но никак не получается внедрить ward (illumination ward неработает даже в FX Composer-е),
работает но неправильно шейдер на Component_ashikhmin_shirley.
http://rapidshare.com/files/170092787/Component_ashikhmin_shirley.rar.html
(phong неподходит для стали поэтому нужен ward)

Почему после применения к обьекту шейдера из MM он становится меньше?

НО ГЛАВНЫЙ СТУПОР - немогу назначить текстурам НЕПЕРВЫЙ UV set (2-й, 3-й...)

http://rapidshare.com/files/170089737/3UV.rar.html

по примеру Const_47 "texture" нашел строку
struct App2vert
{
   float3 position : POSITION;
   float3 normal : NORMAL;

   float4 texcoord0 : TEXCOORD0;

   float4 texcoord1 : TEXCOORD1;
   float4 texcoord2 : TEXCOORD2;
   float4 texcoord3 : TEXCOORD3;

Меняя TEXCOORD0 на TEXCOORD1 - меняется и UV set - ТО ЧТО НУЖНО!,
НО!!!!!! он меняется на ВСЕХ текстурах!!!((((((((
Что делать, незнаю Грустный
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #13 04 Декабря 2008, 23:44:47 »
Re: Шейдеростроение с уклоном в Q3D (для начинающих) |
13
&Brothermechanic
Значит ты делаеш, что то не так Улыбающийся))
Набирись терпения и читай - разгребай дальше Улыбающийся))
Const_47 | **** | Старожил | Сообщений: 299 | «Ответ #14 04 Декабря 2008, 23:51:59 »
Re: Шейдеростроение с уклоном в Q3D (для начинающих) |
14
 Привет. Я тут ))). Теперь отойдем немного от копипаста шейдеров NVIDIA, и подумаем.
 Толку нам то от этого шейдера? Ведь задачи у каждого разные, и врятли без редагирования
 под себя, получится эго куда нибудь приклеить:)))

 И Что копипаст умер? НЕТ!!!Пусть живет КОПИПАСТ!!!
 
 Только теперь мы будем собирать шейдер под НАШУ конкретную задачу, используя(КОПИПАСТЯ)
 у NVIDIA графические алгоритмы.

 Итак наша задача ->
 
 1. Два поинт лайта. Фонг, Фаллоф.
 2. Два текстурных сета, первая и вторая развертка:) из 3D пакета.
 На первой  Грязь,Амбиент Оклюжн, На второй Текстура, и Спекуляр мап.
 3. Рефлект с цветом отражения.

 Для этой цели, я использую УЖАСНУЮ модель табурета, которую я собсноручно слепил
 за две минуты в максе, и несколько первых попавшихся под руку текстур:)))
 
 Все это дело я буду собирать поэтапно, что бы все было понятно что и одкуда появилось
В этом примере я использую только то, что скопипастил от Metal.Fx и ничего более, делая
это специально как наглядный пример.

Итак Разгребать это вот в таком порядке
http://rapidshare.com/files/170279648/adapt2.zip.html
1 Fong1Light
2 Fong1LightFallof
3 Fong2LightFallof
4 Fong2LightTexture
5 Fong2LightTextureCubeR

Последний пример(5) не будет работать на видео не поддерживающих шейдеры 3.0.

С точки зрения удобночитаемости топика, я не буду дублировать fx файлы на форуме, поэтому БОЛЬШАЯ ПРОСЬБА к
МОДЕРАТОРУ - залить архив туда, откуда не исчезнет никогда
Улыбающийся)) 
 
  [1] 2
Печать
 
Quest3D - Русскоязычное сообщество > Quest3D > Визуализация, Шейдеры > Шейдеростроение с уклоном в Q3D (для начинающих)
Перейти в: