Wrap-around lighting

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

Wrap-around lighting

Сообщение Battle Angel Alita 05 фев 2010, 14:55

У стандартного lambert-diffuse есть одна очень неприятная особенность, полигоны которые обращены обратной стороной к источнику света совсем не освещаются и закрашиваются в ambient color. Чтобы этого избежать, есть такой интересный фэйк - Wrap-around lighting(ну или half-lambert).

добавляем в щейдер параметр wrap
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
_wrap ("wrap", Range (0.0, 1.0)) = 0.75
}

передаём его в шейдер
uniform sampler2D _BumpMap;
uniform sampler2D _MainTex;
uniform float _wrap;

передаём его в функцию расчёта освещения
return DiffuseLight( i.lightDirT, normal, texcol, LIGHT_ATTENUATION(i), _wrap );


копируем из UnityCG.cginc стандартную функцию света и немного её модифицируем
inline half4 DiffuseLight( half3 lightDir, half3 normal, half4 color, half atten, float wrap)
{
#ifndef USING_DIRECTIONAL_LIGHT
lightDir = normalize(lightDir);
#endif

half diffuse = dot( normal, lightDir );
diffuse = (diffuse + wrap) / (1.0 + wrap);

half4 c;
c.rgb = color.rgb * _ModelLightColor0.rgb * (diffuse * atten * 2);
c.a = 0; // diffuse passes by default don't contribute to overbright
return c;
}

wrap_light2.png
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось Battle Angel Alita 05 фев 2010, 16:11, всего редактировалось 1 раз.
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Wrap-around lighting

Сообщение Neodrop 05 фев 2010, 16:03

Я так понимаю, что "дедушка Ленин" который справа - это с half-lambert ?

(3A4OT)
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Wrap-around lighting

Сообщение Battle Angel Alita 05 фев 2010, 16:11

fixed
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Wrap-around lighting

Сообщение Neodrop 05 фев 2010, 16:13

Ух, как похож на вождя мирового пролетариата... :D
Классно. Спасибо большое!
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Wrap-around lighting

Сообщение gnoblin 05 фев 2010, 19:32

8-x
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Wrap-around lighting

Сообщение andru 26 фев 2010, 11:37

Вот вариант для диффуза
Синтаксис:
Используется glsl
Shader "Diffuse_wrap" {
Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _wrap ("wrap", Range (0.0, 1.0)) = 0.75
}

Category {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Blend AppSrcAdd AppDstAdd
        Fog { Color [_AddFog] }
       
        // ------------------------------------------------------------------
        // ARB fragment program
       
        SubShader {
                // Ambient pass
                Pass {
                        Name "BASE"
                        Tags {"LightMode" = "PixelOrNone"}
                        Color [_PPLAmbient]
                        SetTexture [_MainTex] {constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
                }
                // Vertex lights
                Pass {
                        Name "BASE"
                        Tags {"LightMode" = "Vertex"}
                        Lighting On
                        Material {
                                Diffuse [_Color]
                                Emission [_PPLAmbient]
                        }
                        SetTexture [_MainTex] { constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
                }
                // Pixel lights
                Pass {
                        Name "PPL"
                        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 v2f {
        V2F_POS_FOG;
        LIGHTING_COORDS
        float2  uv;
        float3  normal;
        float3  lightDir;
};

uniform float4 _MainTex_ST;

v2f vert (appdata_base v)
{
        v2f o;
        PositionFog( v.vertex, o.pos, o.fog );
        o.normal = v.normal;
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        o.lightDir = ObjSpaceLightDir( v.vertex );
        TRANSFER_VERTEX_TO_FRAGMENT(o);
        return o;
}

uniform sampler2D _MainTex;
uniform float _wrap;

inline half4 DiffuseLight( half3 lightDir, half3 normal, half4 color, half atten, float wrap)
{
        #ifndef USING_DIRECTIONAL_LIGHT
        lightDir = normalize(lightDir);
        #endif
       
        half diffuse = dot( normal, lightDir );
        diffuse = (diffuse + wrap) / (1 + wrap);
       
        half4 c;
        //c.rgb = color.rgb * _ModelLightColor0.rgb * (((diffuse + wrap) / (1 + wrap)) * atten * 2);
        c.rgb = color.rgb * _ModelLightColor0.rgb * (diffuse * atten * 2);
        c.a = 0; // diffuse passes by default don't contribute to overbright
        return c;
}


float4 frag (v2f i) : COLOR
{
        // The eternal tradeoff: do we normalize the normal?
        //float3 normal = normalize(i.normal);
        float3 normal = i.normal;
               
        half4 texcol = tex2D( _MainTex, i.uv );
       
        return DiffuseLight( i.lightDir, normal, texcol, LIGHT_ATTENUATION(i),_wrap);
}
ENDCG
                }
        }
       
        // ------------------------------------------------------------------
        // Radeon 9000

        SubShader {
                // Ambient pass
                Pass {
                        Name "BASE"
                        Tags {"LightMode" = "PixelOrNone"}
                        Color [_PPLAmbient]
                        SetTexture [_MainTex] {constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
                }
                // Vertex lights
                Pass {
                        Name "BASE"
                        Tags {"LightMode" = "Vertex"}
                        Lighting On
                        Material {
                                Diffuse [_Color]
                                Emission [_PPLAmbient]
                        }
                        SetTexture [_MainTex] { constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
                }
               
                // Pixel lights with 0 light textures
                Pass {
                        Name "PPL"
                        Tags {
                                "LightMode" = "Pixel"
                                "LightTexCount" = "0"
                        }

CGPROGRAM
#pragma vertex vert
#include "UnityCG.cginc"

struct v2f {
        V2F_POS_FOG;
        float2 uv               : TEXCOORD0;
        float3 normal   : TEXCOORD1;
        float3 lightDir : TEXCOORD2;
};

uniform float4 _MainTex_ST;

v2f vert(appdata_base v)
{
        v2f o;
        PositionFog( v.vertex, o.pos, o.fog );
        o.normal = v.normal;
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        o.lightDir = ObjSpaceLightDir( v.vertex );
        return o;
}
ENDCG
                        Program "" {
                                SubProgram {
                                        Local 0, [_ModelLightColor0]
                                        Local 1, (0,0,0,0)

"!!ATIfs1.0
StartConstants;
        CONSTANT c0 = program.local[0];
        CONSTANT c1 = program.local[1];
EndConstants;

StartOutputPass;
        SampleMap r0, t0.str;                   # main texture
        SampleMap r1, t2.str;                   # normalized light dir
        PassTexCoord r2, t1.str;                # normal
       
        DOT3 r5.sat, r2, r1.2x.bias;    # R5 = diffuse (N.L)
       
        MUL r0, r0, r5;
        MUL r0.rgb.2x, r0, c0;
        MOV r0.a, c1;
EndPass;
"

                                }
                        }
                        SetTexture[_MainTex] {combine texture}
                        SetTexture[_CubeNormalize] {combine texture}
                }
               
                // Pixel lights with 1 light texture
                Pass {
                        Name "PPL"
                        Tags {
                                "LightMode" = "Pixel"
                                "LightTexCount" = "1"
                        }

CGPROGRAM
#pragma vertex vert
#include "UnityCG.cginc"

uniform float4 _MainTex_ST;
uniform float4x4 _SpotlightProjectionMatrix0;

struct v2f {
        V2F_POS_FOG;
        float2 uv               : TEXCOORD0;
        float3 normal   : TEXCOORD1;
        float3 lightDir : TEXCOORD2;
        float4 LightCoord0 : TEXCOORD3;
};

v2f vert(appdata_tan v)
{
        v2f o;
        PositionFog( v.vertex, o.pos, o.fog );
        o.normal = v.normal;
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        o.lightDir = ObjSpaceLightDir( v.vertex );
       
        o.LightCoord0 = mul(_SpotlightProjectionMatrix0, v.vertex);
       
        return o;
}
ENDCG
                        Program "" {
                                SubProgram {
                                        Local 0, [_ModelLightColor0]
                                        Local 1, (0,0,0,0)

"!!ATIfs1.0
StartConstants;
        CONSTANT c0 = program.local[0];
        CONSTANT c1 = program.local[1];
EndConstants;

StartOutputPass;
        SampleMap r0, t0.str;                   # main texture
        SampleMap r1, t2.str;                   # normalized light dir
        PassTexCoord r4, t1.str;                # normal
        SampleMap r2, t3.str;                   # a = attenuation
       
        DOT3 r5.sat, r4, r1.2x.bias;    # R5 = diffuse (N.L)
       
        MUL r0, r0, r5;
        MUL r0.rgb.2x, r0, c0;
        MUL r0.rgb, r0, r2.a;                   # attenuate
        MOV r0.a, c1;
EndPass;
"

                                }
                        }
                        SetTexture[_MainTex] {combine texture}
                        SetTexture[_CubeNormalize] {combine texture}
                        SetTexture[_LightTexture0] {combine texture}
                }
               
                // Pixel lights with 2 light textures
                Pass {
                        Name "PPL"
                        Tags {
                                "LightMode" = "Pixel"
                                "LightTexCount" = "2"
                        }
CGPROGRAM
#pragma vertex vert
#include "UnityCG.cginc"

uniform float4 _MainTex_ST;
uniform float4x4 _SpotlightProjectionMatrix0;
uniform float4x4 _SpotlightProjectionMatrixB0;

struct v2f {
        V2F_POS_FOG;
        float2 uv               : TEXCOORD0;
        float3 normal   : TEXCOORD1;
        float3 lightDir : TEXCOORD2;
        float4 LightCoord0 : TEXCOORD3;
        float4 LightCoordB0 : TEXCOORD4;
};

v2f vert(appdata_tan v)
{
        v2f o;
        PositionFog( v.vertex, o.pos, o.fog );
        o.normal = v.normal;
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        o.lightDir = ObjSpaceLightDir( v.vertex );
       
        o.LightCoord0 = mul(_SpotlightProjectionMatrix0, v.vertex);
        o.LightCoordB0 = mul(_SpotlightProjectionMatrixB0, v.vertex);
       
        return o;
}
ENDCG
                        Program "" {
                                SubProgram {
                                        Local 0, [_ModelLightColor0]
                                        Local 1, (0,0,0,0)

"!!ATIfs1.0
StartConstants;
        CONSTANT c0 = program.local[0];
        CONSTANT c1 = program.local[1];
EndConstants;

StartOutputPass;
        SampleMap r0, t0.str;                   # main texture
        SampleMap r1, t2.str;                   # normalized light dir
        PassTexCoord r4, t1.str;                # normal
        SampleMap r2, t3.stq_dq;                # a = attenuation 1
        SampleMap r3, t4.stq_dq;                # a = attenuation 2
       
        DOT3 r5.sat, r4, r1.2x.bias;    # R5 = diffuse (N.L)
       
        MUL r0, r0, r5;
        MUL r0.rgb.2x, r0, c0;
        MUL r0.rgb, r0, r2.a;                   # attenuate
        MUL r0.rgb, r0, r3.a;
        MOV r0.a, c1;
EndPass;
"

                                }
                        }
                        SetTexture[_MainTex] {combine texture}
                        SetTexture[_CubeNormalize] {combine texture}
                        SetTexture[_LightTexture0] {combine texture}
                        SetTexture[_LightTextureB0] {combine texture}
                }
        }
       
        // ------------------------------------------------------------------
        // Radeon 7000
       
        Category {
                Material {
                        Diffuse [_Color]
                        Emission [_PPLAmbient]
                }
                Lighting On
                SubShader {
                        // Ambient pass
                        Pass {
                                Name "BASE"
                                Tags {"LightMode" = "PixelOrNone"}
                                Color [_PPLAmbient]
                                Lighting Off
                                SetTexture [_MainTex] {Combine texture * primary DOUBLE, primary * texture}
                        }
                        // Vertex lights
                        Pass {
                                Name "BASE"
                                Tags {"LightMode" = "Vertex"}
                                Lighting On
                                Material {
                                        Diffuse [_Color]
                                        Emission [_PPLAmbient]
                                }
                                SetTexture [_MainTex] {Combine texture * primary DOUBLE, primary * texture}
                        }
                        // Pixel lights with 2 light textures
                        Pass {
                                Name "PPL"
                                Tags {
                                        "LightMode" = "Pixel"
                                        "LightTexCount"  = "2"
                                }
                                ColorMask RGB
                                SetTexture [_LightTexture0]  { combine previous * texture alpha, previous }
                                SetTexture [_LightTextureB0] { combine previous * texture alpha, previous }
                                SetTexture [_MainTex] { combine previous * texture DOUBLE }
                        }
                        // Pixel lights with 1 light texture
                        Pass {
                                Name "PPL"
                                Tags {
                                        "LightMode" = "Pixel"
                                        "LightTexCount"  = "1"
                                }
                                ColorMask RGB
                                SetTexture [_LightTexture0] { combine previous * texture alpha, previous }
                                SetTexture [_MainTex] { combine previous * texture DOUBLE }
                        }
                        // Pixel lights with 0 light textures
                        Pass {
                                Name "PPL"
                                Tags {
                                        "LightMode" = "Pixel"
                                        "LightTexCount" = "0"
                                }
                                ColorMask RGB
                                SetTexture[_MainTex] { combine previous * texture DOUBLE }
                        }
                }
        }
}

Fallback "VertexLit", 2

}
 
_ttp://www.bigfishgames.com/download-ga ... index.html
_ttp://www.gamehouse.com/download-games/dreamwoods
Аватара пользователя
andru
UNец
 
Сообщения: 30
Зарегистрирован: 21 янв 2010, 23:30

Re: Wrap-around lighting

Сообщение gnoblin 26 фев 2010, 14:05

andru, без скриншота халтура :o)
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Wrap-around lighting

Сообщение gnoblin 05 ноя 2010, 01:23

Надеюсь никто не будет обижаться, если я запосчу пример из справки про custom lighting model для surface шейдера в Unity 3.0 (popcorn1)
TODO: сделать чтобы это работало с deferred lighting.

Бюста "дедушки Ленина" у меня нету, поэтому вот шарики...
diffuse:
diffuse.jpg

diffuse wrap:
diffuse wrapped.jpg


Синтаксис:
Используется glsl
Shader "Example/Diffuse Wrapped" {
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf WrapLambert

      half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten) {
          half NdotL = dot (s.Normal, lightDir);
          half diff = NdotL * 0.5 + 0.5;
          half4 c;
          c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
          c.a = s.Alpha;
          return c;
      }

      struct Input {
          float2 uv_MainTex;
      };
      sampler2D _MainTex;
      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }
У вас нет доступа для просмотра вложений в этом сообщении.
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Wrap-around lighting

Сообщение gnoblin 06 ноя 2010, 19:09

Что-то я не совсем понял, для deferred нельзя повторить wrap around? :-\
Надо погуглить (popcorn1).
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Wrap-around lighting

Сообщение Battle Angel Alita 06 ноя 2010, 20:17

ага, одна light-model на всё
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Wrap-around lighting

Сообщение gnoblin 06 ноя 2010, 21:04

Это как... То есть никакие другие модели освещения использовать низя?
Как в современных играх с этим живут? :D
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Wrap-around lighting

Сообщение Battle Angel Alita 06 ноя 2010, 21:55

так и живут
каждый в меру своих сил конечно извращается как может и придумывает свои трюки, но суть остаётся одна: разнообразные модели освещения в дифферед-лайтинге - pain in the ass

Кстати вот идея для тех кто её сможет донести до разрабов юнити(Арас-а там...)
На стадии PrePass считать всё освещение не с помощью BlinnPhong, а с помошью Wrap-around BlinnPhong. Затем на стадии основного рендера, в зависимости от материала, брать значение из буффера освещения и скэйлить его как нам надо.
wrap idea.png
У вас нет доступа для просмотра вложений в этом сообщении.
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Wrap-around lighting

Сообщение gnoblin 06 ноя 2010, 22:14

Ок, мысль попробуем донести.

Вопрос: а можно как-то в текущей версии юнити эмулировать wrap без своей модели освещения? (т.е. чтобы по-прежнему был blinn phong)
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Wrap-around lighting

Сообщение gnoblin 06 ноя 2010, 22:20

в папке CGIncludes есть разные интересные файлики.

Получится туда добавить wrap around или другую модель освещения самостоятельно? (понятно что будет использоваться, но просто другая)?
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Wrap-around lighting

Сообщение Battle Angel Alita 06 ноя 2010, 22:41

а можно как-то в текущей...

Сделать шейдер в которы прям через параметры передаётся положение источника света, посчитать освещение ручками и закинуть в Emission

в папке CGIncludes есть разные интересные файлики

Помоему они там просто для изучения валяются. По крайней мере в двойке я редактировала эти файлы, но ничего не происходило. Всё-равно попробуй, мало ли
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

След.

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

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

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