Здавалка
Главная | Обратная связь

Шейдер для эффекта металлической поверхности



Следующий шейдер имеет более интересный код а также более эффектный вид, хотя первое и второе напрямую не связано. Во первых, нужно сказать пару слов о том, чем металлическая поверхность отличается от обычной. Для металлических предметов характерен блеск. Это происходит потому, что кристаллическая решетка металлов плотная и таким образом, отражает свет и не пропускает его через себя. Таким образом, металлическая поверхность является зеркалом. Единственное отличие – это то, что металл может быть шероховатым, и чем больше шероховатость, тем меньше металл блестит. Однако зеркальные свойства сохраняются, только в очень рассеянном виде.

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

Зная координаты источника освещения, координаты текущей точки модели, нормаль к этой точке, и позицию наблюдателя, можно вычислить коэффициент блеска металла в текущей точке.

//------------------------------------------------------------------------------------// Vertex Shader//------------------------------------------------------------------------------------VS_OUTPUT VS( float4 Pos : POSITION, float4 Normal : NORMAL, float2 Tex: TEXCOORD){ VS_OUTPUT output = (VS_OUTPUT)0; output.Pos = mul( Pos, World ); output.Pos = mul( output.Pos, View ); output.Pos = mul( output.Pos, Projection ); output.Color=float4(0.0f,0.0f,0.0f,0); float4 lviewvec=normalize(vView-Pos); float4 lviewvec=mul(View,float4(0,0,1,0)); for (int i=0; i<2; i++) { float3 lpos=(float3)vLightPosition[i]; float a=dot(normalize(Normal),normalize(lpos-(float3)Pos)); float b=dot(normalize(Normal),(float3)lviewvec); float c=1.0f/(1.0f+(a-b)*(a-b)*5); c=pow(c,5); output.Color+=vLightColor[i]*c; } output.N=Normal; output.L=lviewvec;}

Разберем код вершинного шейдера для эффекта металла. Переменная, хранящая интенсивность цвета здесь – output.Color. Эта переменная наполняется в два прохода: каждый проход для одного из источников освещения. Каждый источник освещения может иметь свой цвет. Основная операция для освещения здесь – вычисление коэффициентов a и b. Коэффициент a обозначает угол между нормалью и источником освещения. Коэффициент b обозначает угол между нормалью и точкой наблюдателя. Если углы совпадают, и эти два числа равны значит угол падения равен углу отражения, и в такой точке металл должен обладать ярким свечением. Если коэффициенты различаются, значит углы разные и источник света в данной точке и под данными углами либо не отражается совсем, либо отражается лишь слегка. Теперь разберем пиксельныйшейдер для нашего эффекта:

//------------------------------------------------------------------------------------// Pixel Shader 0//------------------------------------------------------------------------------------float4 PS0( VS_OUTPUT input ) : SV_Target{ float3 refl=reflect((float3)input.L,(float3)input.N); return input.Color+txCube.Sample(samLinear,refl)*0.8f+float4(0.1f,0,0.1f,0);}

Так как эффект блеска источников освещения уже рассчитан, то, вообщем, мы могли бы просто сделать returninput.Color; Однако металл может отражать и что-то еще кроме источников света, поэтому в этом примере добавлена карта отражения, представленная в виде кубической текстуры. Для того, чтобы осуществить выборку из кубической текстуры, — в отличие от двухмерной текстуры, в которой нужно для выборки двухкомпонентный вектор, — в кубической текстуре нужно для выборки обычный трехкомпонентный вектор. Причем этот вектор должен быть рассчитан встроенной функцией reflect. В общем, наш пиксельный шейдер для металлической поверхности получился компактным и прозрачным. Это произошло благодаря тому, что большая часть эффекта металлической поверхности была рассчитана в вершинномшейдере.







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.