Surface shader: Fresnel Reflective bumped specular

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

Surface shader: Fresnel Reflective bumped specular

Сообщение gnoblin 10 окт 2010, 01:16

Хочется добавить к стандартному reflective bumped specular (в Unity 3.0, surface shader) коэффициент френеля для более прикольного отражения.
Нагуглил формулу, но что-то результаты меня не радуют. Может кто-нибудь подсказать где я ошибся? :D

Синтаксис:
Используется glsl
Shader "Reflective/Bumped Specular Fresnel" {
Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.078125
        _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
        _MainTex ("Base (RGB) RefStrGloss (A)", 2D) = "white" {}
        _Cube ("Reflection Cubemap", Cube) = "" { TexGen CubeReflect }
        _BumpMap ("Normalmap", 2D) = "bump" {}
        _Fresnel("Fresnel Coef.", Range (0.01, 0.7)) = 0.35
}

SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 400
CGPROGRAM
#pragma surface surf BlinnPhong
#pragma target 3.0

sampler2D _MainTex;
sampler2D _BumpMap;
samplerCUBE _Cube;

float4 _Color;
float4 _ReflectColor;
float _Shininess;
float _Fresnel;

struct Input {
        float2 uv_MainTex;
        float2 uv_BumpMap;
        //float3 normal;
        float3 viewDir;
        float3 worldRefl;
        INTERNAL_DATA
};

//подперто с gamedev.ru
float fresnel(float VdotN, float eta)
{
 float sqr_eta = eta * eta; // квадрат показателя преломления
 float etaCos = eta * VdotN; // η·cos(Θ)
 float sqr_etaCos = etaCos*etaCos; // в квадрате
 float one_minSqrEta = 1.0 - sqr_eta; // 1 – η2
 float value = etaCos - sqrt(one_minSqrEta + sqr_etaCos);
 value *= value / one_minSqrEta; // возводим в квадрат и делим на 1 – η2
 return min(1.0, value * value); // финальное возведение в квадрат
}
 
  //float fFresnel = fresnel(dot(vViewNormal, vNormalWS), indexOfRefraction);
 
void surf (Input IN, inout SurfaceOutput o) {
        half4 tex = tex2D(_MainTex, IN.uv_MainTex);
        half4 c = tex * _Color;
        o.Albedo = c.rgb;
       
        o.Gloss = tex.a;
        o.Specular = _Shininess;
       
        o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
       
        float3 worldRefl = WorldReflectionVector (IN, o.Normal);

        half4 reflcol = texCUBE (_Cube, worldRefl);
        reflcol *= tex.a;
       
        //reflcol = lerp(c, reflcol, fresnel(worldRefl, _Fresnel));
        reflcol = lerp(c, reflcol, fresnel(dot(IN.viewDir,o.Normal), _Fresnel));

        o.Emission = reflcol.rgb * _ReflectColor.rgb;
        o.Alpha = reflcol.a * _ReflectColor.a;
}
ENDCG
}

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение Battle Angel Alita 11 окт 2010, 15:16

Юнити почему-то передает ненормализированый вьюДир. надо просто написать normalize(IN.viewDir)
+ вот мой код для фреснеля
_FPOW = 5.0, _R0 = 0.05
Код: Выделить всё
half fresnel = saturate(1.0 - dot(o.Normal, normalize(IN.viewDir)));
fresnel = pow(fresnel, _FPOW);
fresnel = _R0 + (1.0 - _R0) * fresnel;
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение gnoblin 11 окт 2010, 17:46

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение gnoblin 18 окт 2010, 01:29

Так получше? :)

Синтаксис:
Используется glsl
Shader "Reflective/Bumped Specular Fresnel 2" {
Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.078125
        _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
        _MainTex ("Base (RGB) RefStrGloss (A)", 2D) = "white" {}
        _Cube ("Reflection Cubemap", Cube) = "" { TexGen CubeReflect }
        _BumpMap ("Normalmap", 2D) = "bump" {}
        _FPOW("FPOW", Float) = 5.0
        _R0("R0", Float) = 0.05
}

SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 400
CGPROGRAM
#pragma surface surf BlinnPhong
#pragma target 3.0

sampler2D _MainTex;
sampler2D _BumpMap;
samplerCUBE _Cube;

float4 _Color;
float4 _ReflectColor;
float _Shininess;
float _FPOW;
float _R0;

struct Input {
        float2 uv_MainTex;
        float2 uv_BumpMap;
        //float3 normal;
        float3 viewDir;
        float3 worldRefl;
        INTERNAL_DATA
};
 
void surf (Input IN, inout SurfaceOutput o) {
        half4 tex = tex2D(_MainTex, IN.uv_MainTex);
        half4 c = tex * _Color;
        o.Albedo = c.rgb;
       
        o.Gloss = tex.a;
        o.Specular = _Shininess;
       
        o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
       
        float3 worldRefl = WorldReflectionVector (IN, o.Normal);

        half4 reflcol = texCUBE (_Cube, worldRefl);
        reflcol *= tex.a;    

        half fresnel = saturate(1.0 - dot(o.Normal, normalize(IN.viewDir)));
        fresnel = pow(fresnel, _FPOW);
        fresnel = _R0 + (1.0 - _R0) * fresnel;
        reflcol = lerp(c, reflcol, fresnel);

        o.Emission = reflcol.rgb * _ReflectColor.rgb;
        o.Alpha = reflcol.a * _ReflectColor.a;
}
ENDCG
}

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение gnoblin 24 окт 2010, 09:55

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение Battle Angel Alita 24 окт 2010, 12:11

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение gnoblin 26 окт 2010, 03:15

А какие еще могут быть техники для улучшения рефлектив шейдера?

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение GrueGames 26 окт 2010, 06:06

Вообще-то спекуляр - ни что иное, как имитация отражения источника света. В физически корректных рендерах, например в maxwell render, он полностью заменен отражением, а источники света имеют для этого размер в пространстве.
Так что на спекуляр по идее тоже должен распространяться эффект френеля.
Аватара пользователя
GrueGames
UNITрон
 
Сообщения: 200
Зарегистрирован: 11 апр 2009, 16:42
Откуда: Samara, Russia
  • Сайт
  • ICQ

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение gnoblin 30 окт 2010, 01:03

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение Левша 03 ноя 2010, 11:52

Хороший шейдер, как раз такой нужен был.
А можно глупый вопрос, как реализавать изменение параметров Main Color? Т.е. привязать к интерфейсу (ползункам).
В квест 3d сделал, а в Unity даже не знаю с какой стороны подойти :(
Аватара пользователя
Левша
UNец
 
Сообщения: 15
Зарегистрирован: 30 сен 2009, 09:00
Откуда: КЧР
  • ICQ

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение 666marat666 03 ноя 2010, 19:20

Както так:

Синтаксис:
Используется glsl
Shader "Freshnel"
{
        Properties
        {
_Color0("_Color0", Color) = (1,1,1,1)
_Diffuse("_Diffuse", 2D) = "white" {}
_NormalMap("_NormalMap", 2D) = "white" {}

        }
       
        SubShader
        {
                Tags
                {
"Queue"="Geometry+0"
"IgnoreProjector"="False"
"RenderType"="Opaque"

                }

               
Cull Back
ZWrite On
ZTest LEqual


                CGPROGRAM
#pragma surface surf BlinnPhongEditor  vertex:vert
#pragma target 2.0

                        struct EditorSurfaceOutput {
                                half3 Albedo;
                                half3 Normal;
                                half3 Emission;
                                half3 Gloss;
                                half Specular;
                                half Alpha;
                        };
                       
                        inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
                        {
                                #ifndef USING_DIRECTIONAL_LIGHT
                                lightDir = normalize(lightDir);
                                #endif
                                viewDir = normalize(viewDir);
                                half3 h = normalize (lightDir + viewDir);
                               
                                half diff = max (0, dot (s.Normal, lightDir));
                               
                                float nh = max (0, dot (s.Normal, h));
                                float3 spec = pow (nh, s.Specular*128.0) * s.Gloss;
                               
                                half4 c;
                                c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);
                                c.a = s.Alpha + _LightColor0.a * Luminance(spec) * atten;
                                return c;
                        }
                       
                        inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
                        {
                                half3 spec = light.a * s.Gloss;
                               
                                half4 c;
                                c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
                                c.a = s.Alpha + Luminance(spec);
                                return c;
                        }
                       
                        struct Input {
                                float2 uv_Diffuse;
float3 viewDir;
float2 uv_NormalMap;

                        };
                       
                        void vert (inout appdata_full v, out Input o) {

                        }
                       
float4 _Color0;
sampler2D _Diffuse;
sampler2D _NormalMap;



                        void surf (Input IN, inout EditorSurfaceOutput o) {
                                o.Albedo = 0.0;
                                o.Normal = float3(0.0,0.0,1.0);
                                o.Emission = 0.0;
                                o.Gloss = 0.0;
                                o.Specular = 0.0;
                                o.Alpha = 1.0;
float4 Tex2D1=tex2D(_Diffuse,(IN.uv_Diffuse.xyxy).xy);
float4 Multiply0=_Color0 * Tex2D1;
float4 Tex2DNormal0=UnpackNormal( tex2D(_NormalMap,(IN.uv_NormalMap.xyxy).xy) );
float4 Fresnel0=float4( 1.0 - dot( normalize( float4(IN.viewDir, 1.0).xyz), normalize( Tex2DNormal0.xyz ) ) );
float4 Master0_2_NoInput = float4(0,0,0,0);
float4 Master0_3_NoInput = float4(0,0,0,0);
float4 Master0_4_NoInput = float4(0,0,0,0);
float4 Master0_5_NoInput = float4(1,1,1,1);
float4 Master0_6_NoInput = float4(1,1,1,1);
o.Albedo = Multiply0;
o.Normal = Fresnel0;
o.Alpha = 1.0;

                        }
                ENDCG
        }
        Fallback "Diffuse"
}
У вас нет доступа для просмотра вложений в этом сообщении.
Изображение

->Невозможно решить проблему на том же уровне, на котором она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.<-
Альберт Эйнштейн
Аватара пользователя
666marat666
UNIт
 
Сообщения: 139
Зарегистрирован: 04 авг 2010, 22:40
Откуда: Украина

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение gnoblin 03 ноя 2010, 20:12

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

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение 666marat666 03 ноя 2010, 20:45

Сори не заметил что ползунками , ну так это дело скрипта если не ошибаюсь O:-)
Изображение

->Невозможно решить проблему на том же уровне, на котором она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.<-
Альберт Эйнштейн
Аватара пользователя
666marat666
UNIт
 
Сообщения: 139
Зарегистрирован: 04 авг 2010, 22:40
Откуда: Украина

Re: Surface shader: Fresnel Reflective bumped specular

Сообщение Левша 08 ноя 2010, 09:29

gnoblin писал(а):Ползунками в гуи?

Ну да.
Аватара пользователя
Левша
UNец
 
Сообщения: 15
Зарегистрирован: 30 сен 2009, 09:00
Откуда: КЧР
  • ICQ


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

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

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