forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Xors3D (http://forum.boolean.name/forumdisplay.php?f=126)
-   -   Xors3D. Шейдеры. Урок первый (http://forum.boolean.name/showthread.php?t=8564)

Arton 12.08.2014 15:55

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

Сообщение от Mr_F_ (Сообщение 285260)
да, потому что ты объявляешь пустую неопределённую переменную и сравниваешь ещё с чем-то.
VFACE над вставить в входящие данные PS.
там где у тебя всякие TexCoords : TEXCOORD0, туда же вставляешь что-нибудь типа whatFace : VFACE.

Уже делал, дебагер ругается на "lit", не объявленная переменная:



Код:

float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ;
float4x4 matrixWorld            : MATRIX_WORLD;         

float3        lightDirection            : LIGHT0_DIRECTION;   
float4        lightColor                      : LIGHT0_COLOR;       

float4        entityColor            : COLOR_DIFFUSE;       
float          whatFace              : VFACE;

texture  diffuseTexture      : TEXTURE_0;           


sampler        diffuseSampler = sampler_state

{
        Texture = <diffuseTexture>;

        AddressU        = WRAP;
        AddressV        = WRAP;
        AddressW        = WRAP;

        MinFilter        = ANISOTROPIC;
        MagFilter        = ANISOTROPIC;
        MipFilter        = ANISOTROPIC;


        MaxAnisotropy        = 16;
};



struct        VSInput {
        float4 position  : POSITION0;
        float3 normal          : NORMAL;
        float2 texCoords : TEXCOORD0;
};



struct VSOutput {
        float4 position  : POSITION0;
        float3 normal          : TEXCOORD1;
        float2 texCoords : TEXCOORD0;
};



VSOutput VSMain(VSInput input) {


        VSOutput output;



        output.position  = mul (input.position, matrixWorldViewProj);



        output.normal          = normalize(mul(input.normal, matrixWorld));

        output.texCoords = input.texCoords;



        return output;
}


float4 PSMain( VSOutput input) : COLOR {

        float4 diffuse  = tex2D(diffuseSampler, input.texCoords);

       
        float4 color;
    color = tex2D( diffuseSampler, input.texCoords.xy);
       
        if (diffuse.a < 0.5f) discard;


        if (whatFace < -1 )
        {

                        float lit        = dot(-input.normal , -lightDirection);
        }
        else
        {
                        float lit        = dot(input.normal , -lightDirection);
        }

        return diffuse * entityColor * lit * lightColor;
}

technique Diffuse {
        pass p0 {
                PixelShader  = compile ps_3_0 PSMain();
                VertexShader = compile vs_3_0 VSMain();
               
                CullMode = none;
        }
}



______________________________

Запихал ретурн после каждого условия и понял что мой код не работает вообще. То есть освещение не флипается там где надо, у меня флипается всё.

______________________________

Кажется понял что я не так сделал. Но как сделать правильно не понял.

Samodelkin 12.08.2014 16:46

Ответ: Xors3D. Шейдеры. Урок первый
 
У каждой переменной есть область видимости (scope), которая обычно задается фигурными скобками {}. Объявленная внутри них переменная не может использоваться вне своей зоны видимости. Поэтому можно вынести объявление lit за пределы конструкции if-else:
Код:

float lit;
if ( whatFace < -1 ) {
    lit = dot( -input.normal, -lightDirection );
} else {
    lit = dot( input.normal, -lightDirection );
}
return diffuse * entityColor * lit * lightColor;

Вообще синтаксис и семантика HLSL (да и GLSL) во многом схожи с языком С. Поэтому если у тебя есть время - почитай книжки всякие про него. В отличие от С++, С не так трудно начинать изучать.

Arton 13.08.2014 02:39

Ответ: Xors3D. Шейдеры. Урок первый
 
Не понимаю почему так не работает?
Проверки тупо нету.

Код:

float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ;
float4x4 matrixWorld            : MATRIX_WORLD;         

float3        lightDirection            : LIGHT0_DIRECTION;   
float4        lightColor                      : LIGHT0_COLOR;       

float4        entityColor            : COLOR_DIFFUSE;       
float          whatFace                          : VFACE;

texture  diffuseTexture      : TEXTURE_0;           


sampler        diffuseSampler = sampler_state

{
        Texture = <diffuseTexture>;

        AddressU        = WRAP;
        AddressV        = WRAP;
        AddressW        = WRAP;

        MinFilter        = ANISOTROPIC;
        MagFilter        = ANISOTROPIC;
        MipFilter        = ANISOTROPIC;


        MaxAnisotropy        = 16;
};



struct        VSInput {
        float4 position  : POSITION0;
        float3 normal          : NORMAL;
        float2 texCoords : TEXCOORD0;
};



struct VSOutput {
        float4 position  : POSITION0;
        float3 normal          : TEXCOORD1;
        float2 texCoords : TEXCOORD0;
};



VSOutput VSMain(VSInput input) {


        VSOutput output;



        output.position  = mul (input.position, matrixWorldViewProj);



        output.normal          = normalize(mul(input.normal, matrixWorld));

        output.texCoords = input.texCoords;



        return output;
}


float4 PSMain( VSOutput input) : COLOR {

        float4 diffuse  = tex2D(diffuseSampler, input.texCoords);

       
        float4 color;
    color = tex2D( diffuseSampler, input.texCoords.xy);
       
        if (diffuse.a < 0.5f) discard;

        float lit;
        if ( whatFace == -1 )
        {

                        lit        = dot(-input.normal , -lightDirection);
        }
        else
        {
                        lit        = dot(input.normal , -lightDirection);
                       
        }



        return diffuse * entityColor * lit * lightColor;
}

technique Diffuse {
        pass p0 {
                PixelShader  = compile ps_3_0 PSMain();
                VertexShader = compile vs_3_0 VSMain();
               
                CullMode = none;
        }
}



Слева Хорс, справа шейдер:


Mr_F_ 13.08.2014 02:59

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

if ( whatFace == -1 )
попробуй if ( whatFace < 0 ), не уверен что там точное значение стоит на каждый фейс.

Arton 13.08.2014 03:32

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

Сообщение от Mr_F_ (Сообщение 285273)
попробуй if ( whatFace < 0 ), не уверен что там точное значение стоит на каждый фейс.

Сделала в первую очередь :(

Как ещё можно сделать подобную штуку? Попробовать считать свет для обеих сторон?

Mr_F_ 13.08.2014 03:44

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

float whatFace : VFACE;
только сейчас заметил, что он у тебя как глобал объявлен.
нужно в VSOutput вставить.
в глобале только то, что одинаково на весь шейдер.
в VSOutput у тебя то, что приходит в пиксельный шейдер из VS интерполированное, и VFACE дополнительно из растеризатора - это инфа попиксельная.

Arton 13.08.2014 04:12

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

Сообщение от Mr_F_ (Сообщение 285275)
только сейчас заметил, что он у тебя как глобал объявлен.
нужно в VSOutput вставить.
в глобале только то, что одинаково на весь шейдер.
в VSOutput у тебя то, что приходит в пиксельный шейдер из VS интерполированное, и VFACE дополнительно из растеризатора - это инфа попиксельная.

Но, как это правильно сделать?
Если так то переменная "whatFace" не найдена:

Код:

float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ;
float4x4 matrixWorld            : MATRIX_WORLD;         

float3        lightDirection            : LIGHT0_DIRECTION;   
float4        lightColor                      : LIGHT0_COLOR;       

float4        entityColor            : COLOR_DIFFUSE;       

texture  diffuseTexture      : TEXTURE_0;           


sampler        diffuseSampler = sampler_state

{
        Texture = <diffuseTexture>;

        AddressU        = WRAP;
        AddressV        = WRAP;
        AddressW        = WRAP;

        MinFilter        = ANISOTROPIC;
        MagFilter        = ANISOTROPIC;
        MipFilter        = ANISOTROPIC;


        MaxAnisotropy        = 16;
};



struct        VSInput {
        float4 position  : POSITION0;
        float3 normal          : NORMAL;
        float2 texCoords : TEXCOORD0;
};



struct VSOutput {
        float4 position  : POSITION0;
        float3 normal          : TEXCOORD1;
        float2 texCoords : TEXCOORD0;
        float whatFace  : VFACE;
};



VSOutput VSMain(VSInput input) {


        VSOutput output;

        output.position  = mul (input.position, matrixWorldViewProj);


        output.normal          = normalize(mul(input.normal, matrixWorld));

        output.texCoords = input.texCoords;



        return output;
}


float4 PSMain( VSOutput input) : COLOR {

        float4 diffuse  = tex2D(diffuseSampler, input.texCoords);
       
       
        float4 color;
    color = tex2D( diffuseSampler, input.texCoords.xy);
       
        if (diffuse.a < 0.5f) discard;

        float lit;

        if ( whatFace == -1 )
        {

                        lit        = dot(-input.normal , -lightDirection);
        }
        else
        {
                        lit        = dot(input.normal , -lightDirection);
                       
        }



        return diffuse * entityColor * lit * lightColor;
}

technique Diffuse {
        pass p0 {
                PixelShader  = compile ps_3_0 PSMain();
                VertexShader = compile vs_3_0 VSMain();
               
                CullMode = none;
        }
}


Mr_F_ 13.08.2014 04:14

Ответ: Xors3D. Шейдеры. Урок первый
 
ну потому что теперь ты её должен читать как input.whatFace. так же как и всё, что ты читаешь из VSOutput.

Arton 13.08.2014 04:34

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

Сообщение от Mr_F_ (Сообщение 285279)
ну потому что теперь ты её должен читать как input.whatFace. так же как и всё, что ты читаешь из VSOutput.

То есть так?

Код:

float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ;
float4x4 matrixWorld            : MATRIX_WORLD;         

float3        lightDirection            : LIGHT0_DIRECTION;   
float4        lightColor                      : LIGHT0_COLOR;       

float4        entityColor            : COLOR_DIFFUSE;       

texture  diffuseTexture      : TEXTURE_0;           


sampler        diffuseSampler = sampler_state

{
        Texture = <diffuseTexture>;

        AddressU        = WRAP;
        AddressV        = WRAP;
        AddressW        = WRAP;

        MinFilter        = ANISOTROPIC;
        MagFilter        = ANISOTROPIC;
        MipFilter        = ANISOTROPIC;


        MaxAnisotropy        = 16;
};



struct        VSInput {
        float4 position  : POSITION0;
        float3 normal    : NORMAL;
        float2 texCoords : TEXCOORD0;
        float  whatFace : VFACE;
};



struct VSOutput {
        float4 position  : POSITION0;
        float3 normal          : TEXCOORD1;
        float2 texCoords : TEXCOORD0;
        float  whatFace        : VFACE;
       
};



VSOutput VSMain(VSInput input) {


        VSOutput output;
       
        output.position  = mul (input.position, matrixWorldViewProj);


        output.normal          = normalize(mul(input.normal, matrixWorld));

        output.texCoords = input.texCoords;
       
        output.whatFace        = input.whatFace;



        return output;
}


float4 PSMain( VSOutput input) : COLOR {

        float4 diffuse  = tex2D(diffuseSampler, input.texCoords);
       
        float4 color;
    color = tex2D( diffuseSampler, input.texCoords.xy);
       
        if (diffuse.a < 0.5f) discard;

        float lit;

        if ( input.whatFace == -1 )
        {

                        lit        = dot(-input.normal , -lightDirection);
        }
        else
        {
                        lit        = dot(input.normal , -lightDirection);
                       
        }


        return diffuse * entityColor * lit * lightColor;
}

technique Diffuse {
        pass p0 {
                PixelShader  = compile ps_3_0 PSMain();
                VertexShader = compile vs_3_0 VSMain();
               
                CullMode = none;
        }
}



Дебагер говорит инвалид:
Цитата:

(35): error X4502: invalid input semantic 'VFACE'
(99): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
ID3DXEffectCompiler: Compilation failed

Samodelkin 13.08.2014 05:33

Ответ: Xors3D. Шейдеры. Урок первый
 
VFACE нету на входе в вершинный шейдер - он вычисляется автоматически между вершинным и пиксельным шейдером. Поэтому он не может быть в структуре VSInput.
Попробуй сначала убрать whatFace из VSInput а в вершинном шейдере ничего не присваивай output.whatFace или присвой 0.
А уже из пиксельного ты можешь обратиться к ней как input.whatFace и в ней уже будет содержаться нужное значение.
Должно работать.
Однако если вдруг компилятор всё-равно скажет что нет такой семантики (хотя вроде не должен), тогда тебе придется разделить VSOutput на две разные структуры - VSOutput и PSInput, и во второй добавишь VFACE.

Arton 13.08.2014 06:35

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

Сообщение от Samodelkin (Сообщение 285282)
VFACE нету на входе в вершинный шейдер - он вычисляется автоматически между вершинным и пиксельным шейдером. Поэтому он не может быть в структуре VSInput.
Попробуй сначала убрать whatFace из VSInput а в вершинном шейдере ничего не присваивай output.whatFace или присвой 0.
А уже из пиксельного ты можешь обратиться к ней как input.whatFace и в ней уже будет содержаться нужное значение.
Должно работать.

Не сработало, куча ошибок.

Цитата:

Однако если вдруг компилятор всё-равно скажет что нет такой семантики (хотя вроде не должен), тогда тебе придется разделить VSOutput на две разные структуры - VSOutput и PSInput, и во второй добавишь VFACE.
:??

Код:

float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ;
float4x4 matrixWorld            : MATRIX_WORLD;         

float3        lightDirection            : LIGHT0_DIRECTION;   
float4        lightColor                      : LIGHT0_COLOR;       

float4        entityColor            : COLOR_DIFFUSE;       

texture  diffuseTexture      : TEXTURE_0;           


sampler        diffuseSampler = sampler_state

{
        Texture = <diffuseTexture>;

        AddressU        = WRAP;
        AddressV        = WRAP;
        AddressW        = WRAP;

        MinFilter        = ANISOTROPIC;
        MagFilter        = ANISOTROPIC;
        MipFilter        = ANISOTROPIC;


        MaxAnisotropy        = 16;
};



struct        VSInput {
        float4 position  : POSITION0;
        float3 normal          : NORMAL;
        float2 texCoords : TEXCOORD0;
};



struct VSOutput {

        float4 position  : POSITION0;
        float3 normal          : TEXCOORD1;
        float2 texCoords : TEXCOORD0;
       
}

        PSInput {
       
        float  whatFace        : VFACE;

       
};



VSOutput VSMain(VSInput input) {


        VSOutput output;
       
        output.position  = mul (input.position, matrixWorldViewProj);


        output.normal          = normalize(mul(input.normal, matrixWorld));

        output.texCoords = input.texCoords;
       
       
        output.whatFace = iput.whatFace;



        return output;
}


float4 PSMain( VSOutput input) : COLOR {

        float4 diffuse  = tex2D(diffuseSampler, input.texCoords);
       
        float4 color;
    color = tex2D( diffuseSampler, input.texCoords.xy);
       
        if (diffuse.a < 0.5f) discard;

        float lit;

        if ( input.whatFace == -1 )
        {

                        lit        = dot(-input.normal , -lightDirection);
        }
        else
        {
                        lit        = dot(input.normal , -lightDirection);
                       
        }


        return diffuse * entityColor * lit * lightColor;
}

technique Diffuse {
        pass p0 {
                PixelShader  = compile ps_3_0 PSMain();
                VertexShader = compile vs_3_0 VSMain();
               
                CullMode = none;
        }
}


Mr_F_ 13.08.2014 11:45

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

iput
iput, ок. и вообще убери эту строку полностью.

+ не надо ничего разделять, просто блин оставь так
struct VSOutput {

float4 position : POSITION0;
float3 normal : TEXCOORD1;
float2 texCoords : TEXCOORD0;
float whatFace : VFACE
}

Arton 13.08.2014 15:09

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

Сообщение от Mr_F_ (Сообщение 285284)
iput, ок. и вообще убери эту строку полностью.

+ не надо ничего разделять, просто блин оставь так
struct VSOutput {

float4 position : POSITION0;
float3 normal : TEXCOORD1;
float2 texCoords : TEXCOORD0;
float whatFace : VFACE
}

О, это уже не соображал.

Так тоже сделала в первую очередь:

Код:

float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ;
float4x4 matrixWorld            : MATRIX_WORLD;         

float3        lightDirection            : LIGHT0_DIRECTION;   
float4        lightColor                      : LIGHT0_COLOR;       

float4        entityColor            : COLOR_DIFFUSE;       

texture  diffuseTexture      : TEXTURE_0;           


sampler        diffuseSampler = sampler_state

{
        Texture = <diffuseTexture>;

        AddressU        = WRAP;
        AddressV        = WRAP;
        AddressW        = WRAP;

        MinFilter        = ANISOTROPIC;
        MagFilter        = ANISOTROPIC;
        MipFilter        = ANISOTROPIC;


        MaxAnisotropy        = 16;
};



struct        VSInput {
        float4 position  : POSITION0;
        float3 normal          : NORMAL;
        float2 texCoords : TEXCOORD0;
};



struct VSOutput {

        float4 position : POSITION0;
        float3 normal : TEXCOORD1;
        float2 texCoords : TEXCOORD0;
        float whatFace : VFACE;

};



VSOutput VSMain(VSInput input) {


        VSOutput output;
       
        output.position  = mul (input.position, matrixWorldViewProj);


        output.normal          = normalize(mul(input.normal, matrixWorld));

        output.texCoords = input.texCoords;




        return output;
}


float4 PSMain( VSOutput input) : COLOR {

        float4 diffuse  = tex2D(diffuseSampler, input.texCoords);
       
        float4 color;
    color = tex2D( diffuseSampler, input.texCoords.xy);
       
        if (diffuse.a < 0.5f) discard;

        float lit;

        if ( input.whatFace == -1 )
        {

                        lit        = dot(-input.normal , -lightDirection);
        }
        else
        {
                        lit        = dot(input.normal , -lightDirection);
                       
        }


        return diffuse * entityColor * lit * lightColor;
}

technique Diffuse {
        pass p0 {
                PixelShader  = compile ps_3_0 PSMain();
                VertexShader = compile vs_3_0 VSMain();
               
                CullMode = none;
        }
}



Дебагер говорит:
Цитата:

(65): error X4000: variable 'output' used without having been completely initialized
(98 ): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
ID3DXEffectCompiler: Compilation failed

Mr_F_ 13.08.2014 15:29

Ответ: Xors3D. Шейдеры. Урок первый
 
попробуй тогда убрать его из VSOutput, а вместо этого PSMain поменять типа
float4 PSMain(VSOutput input, float whatFace : VFACE) : COLOR {

Arton 13.08.2014 15:59

Ответ: Xors3D. Шейдеры. Урок первый
 
Цитата:

Сообщение от Mr_F_ (Сообщение 285289)
попробуй тогда убрать его из VSOutput, а вместо этого PSMain поменять типа
float4 PSMain(VSOutput input, float whatFace : VFACE) : COLOR {

error X3018: invalid subscript 'whatFace'

Нифига не понимаю, попробовал в шейдерах других игр покопаться, не нашёл.


Часовой пояс GMT +4, время: 04:43.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot