Показать сообщение отдельно
Старый 19.01.2012, 00:28   #8
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Преобразование шейдера на HLSL в ShaderLab

Но тестировал без текстур, так что может работать не так как ожидалось

Shader "Custom/Glass" {

    
Properties {

        
_Environment ("Environment Cubemap", Cube) = "" { TexGen CubeReflect }

        
_Rainbow ("Rainbow", 2D) = "white" {}

        
_RefractionScale ("Refraction Scale", Range(0,1)) = 1.0

        _RainbowScale 
("Rainbow Scale", Range(0,1)) = 0.2

        _RainbowSpread 
("Rainbow Spread", Range(0,3)) = 0.18

        _Color
("Main Color", Color) = (0.72, 0.70, 0.76, 1.00)

        
_Ambient("Ambient", Range(0,1)) = 0.2

        _IndexOfRefractionRatio 
("Index Of Refraction Ratio", Range(0,2)) = 1.14

        _ReflectionScale 
("Reflection Scale", Range(0,1)) = 1.0



    
}

    
SubShader {

        
Tags { "RenderType"="Opaque" }

        
LOD 200

        

        CGPROGRAM

        
#pragma surface surf Lambert alpha



        
samplerCUBE _Environment;

        
sampler2D _Rainbow;

        
float _RefractionScale;

        
float _RainbowScale;

        
float _RainbowSpread;

        
float4 _Color;

        
float _Ambient;

        
float _IndexOfRefractionRatio;

        
float _ReflectionScale;



        
struct Input {

            
float2 uv_MainTex;

            
float3 viewDir;

        };



        
void surf (Input IN, inout SurfaceOutput o) {



           
// Look up the reflection

           
float3 reflVec = reflect(-IN.viewDir, o.Normal);

           
float4 reflection = texCUBE(_Environment, IN.viewDir);



           
// We'll use Snell's refraction law:

           // n  * sin(theta ) = n  * sin(theta )

           //  i            i     r            r



           // sin(theta )

           //          i

           
float cosine = dot(IN.viewDir, o.Normal);

           
float sine = sqrt(1 - cosine * cosine);



           
// sin(theta )

           //          r

           
float sine2 = saturate(_IndexOfRefractionRatio * sine);

           
float cosine2 = sqrt(1 - sine2 * sine2);



           
// Out of the sine and cosine of the angle between the

           // refraction vector and the normal we can construct the

           // refraction vector itself given two base vectors.

           // These two base vectors are the negative normal and

           // a tangent vector along the path of the incoming vector

           // relative to the surface.

           
float3 x = -o.Normal;

           
float3 y = normalize(cross(cross(IN.viewDir, o.Normal), o.Normal));



           
// Refraction

           
float3 refrVec = x * cosine2 + y * sine2;

           
float4 refraction = texCUBE(_Environment, reflVec);



           
// Colors refract differently and the difference is more

           // visible the stronger the refraction. We'll fake this

           // effect by adding some rainbowish colors accordingly.

           
float4 rainbow = tex2D(_Rainbow, float2(pow(cosine, _RainbowSpread),0));



           
float4 rain = _RainbowScale * rainbow * _Color;

           
float4 refl = _ReflectionScale * reflection;

           
float4 refr = _RefractionScale * refraction * _Color;



           
// There is more light reflected at sharp angles and less

           // light refracted. There is more color separation of refracted

           // light at sharper angles

           
half4 c = sine * refl + (1 - sine2) * refr + sine2 * rain + _Ambient;

            
o.Albedo = c.rgb;

            
o.Alpha = c.a;

        }

        
ENDCG

    
} 

    
FallBack "Diffuse"

} 
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием