Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Шейдеры и все-все-все.

Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Сообщение marooned 31 окт 2009, 17:48

Собственно сабж..ИСПОЛЬЗОВАТЬ ТОЛЬКО В СЦЕНАХ С ОДНИМ ДИРЕКТНЫМ ИСТОЧНИКОМ СВЕТА
Код: Выделить всё
Shader "RefTest" {
Properties {
     _Bumpheight ("Bump Height", Range (0, 2)) = 0.01
     _Reflective ("Reflectivity", Range (0, 1)) = 0.4
     _Fresnel ("Fresnel_Coeff", Range (0, 10)) = 2
    _Color ("Main Color", Color) = (1,1,1,0.5)
     _MainTex ("Base (RGB)", 2D) = "white" {}
     _LightMap ("Lightmap (RGB)", 2D) = "light" {}
     _BumpMap ("Bumpmap (RGB)", 2D) = "white" {}
}

Category {
    Blend AppSrcAdd AppDstAdd
    Fog { Color [_AddFog] }

    // Fragment program cards
    SubShader {
       
        Pass {
            Tags { "LightMode" = "Pixel" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"

struct a2v {
         //float4 vertex : POSITION;
         float2  texcoord : TEXCOORD0;
         float2 texcoord1 : TEXCOORD1;
            float3 tangent      : TANGENT;
      };

struct v2f {
    V2F_POS_FOG;
    LIGHTING_COORDS // <= note no semicolon!
    //float4 color : COLOR0;
     float2     uv :TEXCOORD4;
     float2     uv2 :TEXCOORD3;
     float3 normal : TEXCOORD0;
     float3 ldir : TEXCOORD1;
     float3 tangent : TEXCOORD2;
     float3 binormal : COLOR0;
     float3 viewDir: TEXCOORD5;
     
     
     
};

// Vertex program
v2f vert (appdata_base v, a2v i)
{
    v2f o;
    PositionFog( v.vertex, o.pos, o.fog );
o.uv = i.texcoord;
     o.uv2 = i.texcoord1;
     
    float3 ldir = normalize( ObjSpaceLightDir( v.vertex ) );
    float diffuse = dot( v.normal, ldir );
   // o.color = diffuse * _ModelLightColor0;
     float3 binormal = cross(v.normal, i.tangent);
o.normal      = v.normal;// normalize(mul((v.normal) , (float3x3)_Object2World));
     o.tangent      = i.tangent;
     //o.binormal      = binormal;//normalize(mul((binormal) , (float3x3)_Object2World));
     o.viewDir = -(ObjSpaceViewDir( v.vertex ));
         
o.ldir=ldir;
   
    TRANSFER_VERTEX_TO_FRAGMENT(o);
    return o;
}
uniform  float _Bumpheight;
uniform  float _Reflective;
uniform  float _Fresnel;
uniform sampler2D _MainTex;
uniform sampler2D _LightMap;
uniform sampler2D _BumpMap;
uniform  samplerCUBE _Mycube;
// Fragment program
float4 frag (v2f i) : COLOR
{
//////         -=_LIGHTMAP_=-
half4 lightmap=tex2D(_LightMap, i.uv2);

//////        -=_MAIN TEXTURE_=-
float4 texcol = tex2D(_MainTex,i.uv);

//////          -=_BUMP_=-
float3 normaltex = tex2D(_BumpMap, i.uv.xy).xyz;
half3 smooth = half3(0.5,0.5,1.0);
half3 normalc= lerp( smooth, normaltex , _Bumpheight);
half3 normalb= normalize( ( normalc* 2.0f ) - 1.0f );
float3 N = normalize(normalb.x*i.tangent-normalb.y*i.binormal+normalb.z*i.normal);
half ndotl = saturate(dot(N, i.ldir));

//////      -=_REFLECTION_=-
float3 V = i.viewDir;
float3 R= (reflect(V, N));
R=mul( (float3x3)_Object2World, R );
float4 refcol = texCUBE(_Mycube,R);
half tipa_fresnel = 0.2+saturate(1-dot(N, normalize(-V)));
tipa_fresnel = saturate(pow(tipa_fresnel, _Fresnel));
         
     
    return lightmap*lerp(texcol*(ndotl * LIGHT_ATTENUATION(i) +_PPLAmbient)*4* _ModelLightColor0, refcol, _Reflective*tipa_fresnel);///texcol*(ndotl * LIGHT_ATTENUATION(i) +_PPLAmbient)* 4;
}
ENDCG
        }
    }
}

Fallback "VertexLit"
}


Пишите в случае каких-либо ошибок...
PS Юзайте CrazyBump
PPS Рефлектит кубмап заданный через сетглобал --- uniform samplerCUBE _Mycube; --- вот строчка
Последний раз редактировалось marooned 02 ноя 2009, 00:48, всего редактировалось 2 раз(а).
Аватара пользователя
marooned
UNец
 
Сообщения: 37
Зарегистрирован: 20 сен 2009, 19:26

Re: Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Сообщение Const_47 31 окт 2009, 23:00

В моем варианте этот этот шейдер выглядел бы немного иначе; Но я старался исправить, на мой взгляд самые критичные моменты, как можно меньше изменяя ваш код. Вы пишете шейдеры вообще не учитывая особенностей Юнити, и как мне кажется не разобравшись толком в синтаксисе "Юнити придатков" ;
Код: Выделить всё
Shader "Const_47/RefTestFIXED" {
Properties {
     _Bumpheight ("Bump Height", Range (0, 2)) = 0.01
     _Reflective ("Reflectivity", Range (0, 1)) = 0.4
     _Fresnel ("Fresnel_Coeff", Range (0, 10)) = 2
     _Color ("Main Color", Color) = (1,1,1,0.5)
     _MainTex ("Base (RGB)", 2D) = "white" {}
     _LightMap ("Lightmap (RGB)", 2D) = "light" {}
     _BumpMap ("Bumpmap (RGB)", 2D) = "white" {}
    _Mycube ("display name", Cube) = "white" {}
}

Category {
    Blend AppSrcAdd AppDstAdd
    Fog { Color [_AddFog] }

    // Fragment program cards
    SubShader {
       
        Pass {
///////////////////////////AmbientPass////////////////////////////////////////////
            Tags { "LightMode" = "Always" }
         
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"


struct appdata {
         float4 vertex        : POSITION;
         float2  texcoord    : TEXCOORD0;
         float2 texcoord1   : TEXCOORD1;
       float3 normal        : NORMAL;
       float3 tangent       : TANGENT;
      };

struct v2f {
     V2F_POS_FOG;
     float4 color : COLOR0;
     float2     uv :TEXCOORD0;
     float2     uv2 :TEXCOORD1;
     float3 normal : TEXCOORD2;
     float3 tangent : TEXCOORD3;
     float3 viewDir: TEXCOORD4;
     
     
     
};

// Vertex program
v2f vert (appdata v)
{
     v2f o;
     PositionFog( v.vertex, o.pos, o.fog );
     o.uv = v.texcoord;
     o.uv2 = v.texcoord1;
    o.normal       = v.normal;
     o.tangent      = v.tangent;
     o.viewDir = -(ObjSpaceViewDir( v.vertex ));
    o.color = _PPLAmbient*2;   
     return o;
}
uniform  float _Bumpheight;
uniform  float _Reflective;
uniform  float _Fresnel;
uniform sampler2D _MainTex;
uniform sampler2D _LightMap;
uniform sampler2D _BumpMap;
uniform  samplerCUBE _Mycube;

// Fragment program
float4 frag (v2f i) : COLOR
{
//////         -=_LIGHTMAP_=-
half4 lightmap=tex2D(_LightMap, i.uv2);

//////        -=_MAIN TEXTURE_=-
float4 texcol = tex2D(_MainTex,i.uv);

//////          -=_BUMP_=-
float3 normaltex = tex2D(_BumpMap, i.uv.xy).xyz;
half3 smooth = half3(0.5,0.5,1.0);
half3 normalc= lerp( smooth, normaltex , _Bumpheight);
half3 normalb= normalize( ( normalc* 2.0f ) - 1.0f );
float3 N = normalize(normalb.x*i.tangent-normalb.y*float3(0,0,0)+normalb.z*i.normal);


//////      -=_REFLECTION_=-
float3 V = i.viewDir;
float3 R= (reflect(V, N));
R=mul( (float3x3)_Object2World, R );
float4 refcol = texCUBE(_Mycube,R);
half tipa_fresnel = 0.2+saturate(1-dot(N, normalize(-V)));
tipa_fresnel = saturate(pow(tipa_fresnel, _Fresnel));
         
float4 final = lerp(texcol*i.color,refcol, _Reflective*tipa_fresnel)*lightmap;

return final;
}
ENDCG
        }
      
        Pass {
///////////////////////////PixelLightPass////////////////////////////////////////////
            Tags {"LightMode" = "Pixel" }
         
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"


struct appdata {
         float4 vertex        : POSITION;
         float2  texcoord    : TEXCOORD0;
         float2 texcoord1   : TEXCOORD1;
       float3 normal        : NORMAL;
       float3 tangent       : TANGENT;
      };

struct v2f {
     V2F_POS_FOG;
    LIGHTING_COORDS // <= note no semicolon!
     float2    uv :TEXCOORD0;
     float2    uv2 :TEXCOORD1;
     float3 normal : TEXCOORD2;
     float3 ldir : TEXCOORD3;
     float3 tangent : TEXCOORD4;
     float3 viewDir: TEXCOORD5;
     
     
     
};

// Vertex program
v2f vert (appdata v)
{

     v2f o;

     PositionFog( v.vertex, o.pos, o.fog );
   
     o.uv = v.texcoord;
     o.uv2 = v.texcoord1;
     
    o.normal       = v.normal;
     o.tangent      = v.tangent;
   
     o.viewDir = -(ObjSpaceViewDir( v.vertex ));
    o.ldir = normalize( ObjSpaceLightDir( v.vertex ));
   

     TRANSFER_VERTEX_TO_FRAGMENT(o);
     return o;
}
uniform  float _Bumpheight;
uniform  float _Reflective;
uniform  float _Fresnel;
uniform sampler2D _MainTex;
uniform sampler2D _LightMap;
uniform sampler2D _BumpMap;
uniform  samplerCUBE _Mycube;

// Fragment program
float4 frag (v2f i) : COLOR
{
//////         -=_LIGHTMAP_=-
half4 lightmap=tex2D(_LightMap, i.uv2);

//////        -=_MAIN TEXTURE_=-
float4 texcol = tex2D(_MainTex,i.uv);

//////          -=_BUMP_=-
float3 normaltex = tex2D(_BumpMap, i.uv.xy).xyz;
half3 smooth = half3(0.5,0.5,1.0);
half3 normalc= lerp( smooth, normaltex , _Bumpheight);
half3 normalb= normalize( ( normalc* 2.0f ) - 1.0f );
float3 N = normalize(normalb.x*i.tangent-normalb.y*float3(0,0,0)+normalb.z*i.normal);


//////      -=_REFLECTION_=-
float3 V = i.viewDir;
float3 R= (reflect(V, N));
R=mul( (float3x3)_Object2World, R );
float4 refcol = texCUBE(_Mycube,R);
half tipa_fresnel = 0.2+saturate(1-dot(N, normalize(-V)));
tipa_fresnel = saturate(pow(tipa_fresnel, _Fresnel));
half ndotl = saturate(dot(N, i.ldir)); 
 
float4 final = lerp(texcol*ndotl* LIGHT_ATTENUATION(i)*_ModelLightColor0,refcol, _Reflective*tipa_fresnel)*lightmap;

return final;
}
ENDCG
        }
      
    }
}

Fallback "VertexLit"
}
Const_47
Герой Форума
 
Сообщения: 271
Зарегистрирован: 23 мар 2009, 19:24
Откуда: Украина. Львов\Новояворовск

Re: Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Сообщение marooned 01 ноя 2009, 22:51

А тогда вопрос что именно фактически изменится если таким образом переделать код?
тиаретически при тяжелых шейдерах может быть плюс в скорости в 2х пассовом варианте, но этот не сильно тяжелый, ну и если юнити использует рендеринг з-дептх как з-early-pass то выгоды от амбиентпасса быть недолжно вообще нивкаких случаях
Аватара пользователя
marooned
UNец
 
Сообщения: 37
Зарегистрирован: 20 сен 2009, 19:26

Re: Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Сообщение marooned 01 ноя 2009, 23:17

в моей демке поменял шейдер на "фиксеный"...с моим показывает 140 фпс с новым "типа отредактированным" 120 ....
возможно он идеалогически не правельный, но с моим дроуколов меньше.
Аватара пользователя
marooned
UNец
 
Сообщения: 37
Зарегистрирован: 20 сен 2009, 19:26

Re: Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Сообщение Const_47 01 ноя 2009, 23:24

У вас мнение о шейдинге на Юнити, как о шейдинге на Q3D. Где вы можете четко указать на какой именно источник света реагировать. Проведите эксперимент, поставьте возле модели с вашим шейдером больше одного источника света, а потом по очереди ручками в редакторе плавно меняйте им позицию, поймете о чем это я.
В реальной сцене, кроме проблем плюсов никаких. Плюс убрал чуточку бреда.

Все же, если вам интересно контролировать конкретный тип - источник света(для описание всего того о чем вы писали выше), то делать нужно было совсем иначе.
Const_47
Герой Форума
 
Сообщения: 271
Зарегистрирован: 23 мар 2009, 19:24
Откуда: Украина. Львов\Новояворовск

Re: Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Сообщение Const_47 01 ноя 2009, 23:30

Код: Выделить всё
в моей демке поменял шейдер на "фиксеный"...с моим показывает 140 фпс с новым "типа отредактированным" 120 ....
возможно он идеалогически не правельный, но с моим дроуколов меньше


Ну если в вашей демке один источник света, то проблем не должно быть, но тогда хотя бы уберите из "типо правильного" весь бредокод, возможно еще поднимете производительность. Ну и стоило бы написать для людей, постив такой шейдер, что его нельзя использовать при количестве источников в сцене больше одного.
Const_47
Герой Форума
 
Сообщения: 271
Зарегистрирован: 23 мар 2009, 19:24
Откуда: Украина. Львов\Новояворовск

Re: Однопроходный Bump+Reflection(Псевдо Fresnel)+LM

Сообщение marooned 01 ноя 2009, 23:43

Согласен на все 1000%. Подправил пост...Спасибо за критику...Побольше бы таких обсуждений здесь...было бы меньше бредокода :D
Аватара пользователя
marooned
UNец
 
Сообщения: 37
Зарегистрирован: 20 сен 2009, 19:26


Вернуться в Shader Lab

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2