Страница 1 из 1

Получение данных освещения (Relief_Correct_Silhouettes)

СообщениеДобавлено: 29 мар 2010, 19:05
Skval
Народ помогите пожайлуста, я уже обыскался просто, может кто знает как можно получить в шейдер color освещения и позицию и при возможности направление света от Directional light? Дело в том что у меня имеется шейдер рельеф мапки(с http://www.unity3d.com), но он не принимает внешнее освещение, я собирался его подкрутить, но не нашёл информации о том как получить нужные данные. Если что вот шейдер:
Синтаксис:
Используется glsl
Shader "Relief_Correct_Silhouettes" {
        Properties {
                _MainTex ("Color Map",          2D) = "white" {}
                _ReliefMap ("ReliefMap Map",    2D) = "white" {}
                _Depth ("Depth", Float) = 0.1
                _Tile ("Tile", Float) = 4
                _Curvature("Curvature", Float) = 1
                _Ambient ("Ambient Color", Color) = (0.1, 0.1, 0.1, 1.0)
                _Diffuse ("Diffuse Color", Color) = (0.8, 0.8, 0.8, 1.0)
                _Specular ("Specular Color", Color) = (1, 1, 1, 1.0)
                _LightPosition ("Light Position", Vector) = (-10,10,-10,1)
                _LightColor ("Light Color", Color) = (1,1,1,1)
        }
        SubShader
        {
        Pass    
        {
               
CGPROGRAM //-----------
#pragma target 3.0
#pragma vertex          vertex_shader
#pragma fragment        main_relief
#pragma profileoption MaxTexIndirections=64
#include "UnityCG.cginc"

uniform sampler2D       _MainTex;
uniform sampler2D       _ReliefMap;
uniform float           _Depth;
uniform float           _Tile;
uniform float           _Curvature;
uniform float4          _Ambient;
uniform float4          _Diffuse;
uniform float4          _Specular;
uniform float3          _LightPosition;
uniform float4          _LightColor;

struct a2v
{
        float4 vertex           : POSITION;
        float4 tangent          : TANGENT;
        float3 normal           : NORMAL;
        float2 texCoord         : TEXCOORD0;
};

struct v2f
{
        float4 hpos             : POSITION;
        float3 vpos             : TEXCOORD0;
        float2 texcoord         : TEXCOORD1;
        float3 view             : TEXCOORD2;
        float3 light            : TEXCOORD3;
        float3 scale            : TEXCOORD4;
        float2 curvature        : TEXCOORD5;
};

struct f2s
{      
        float4 color : COLOR;
};

v2f vertex_shader(a2v In)
{
        v2f Out;
       
        float4 pos = float4(In.vertex.xyz, 1.0);
       
        Out.hpos                = mul(glstate.matrix.mvp, pos);
        Out.texcoord    = In.texCoord.xy*_Tile;;       

        float3 In_binormal = cross( In.normal, In.tangent.xyz )*In.tangent.w;
       
        float3x3 tangentspace;
        tangentspace[0] = In.tangent.xyz;
        tangentspace[1] = -In_binormal;
        tangentspace[2] = In.normal;
               
        float3 osEyeVec = _ObjectSpaceCameraPos - In.vertex.xyz;
        Out.view                = mul(tangentspace, osEyeVec);
       
        float3 wsLPos   = mul(In.vertex.xyz, (float3x3)_Object2World);
        float3 wsLVec   = _LightPosition - wsLPos;     
        float3 osLVec   = mul(wsLVec, (float3x3)_World2Object).xyz;
        Out.light               = mul(tangentspace, osLVec);
       
        // scale and curvature
        float c = _Curvature;
        Out.curvature = float2(c,c);
        Out.scale=float3(In.tangent.w,1,_Depth)/_Tile;
                                                               
        return Out;
}

float3 ray_position(
                                                in float t,                     // search parameters
                                                in float2 tx,           // original pixel texcoord
                                                in float3 v,            // view vector in texture space
                                                in float dataz)         // data constants
{
        float3 r=v*t;
        r.z-=t*t*dataz;
        r.xy+=tx;
        return r;
}

float ray_intersect_rm_curved(
                                                                in sampler2D reliefmap,
                                                                in float2 tx,
                                                                in float3 v,
                                                                in float tmax,
                                                                in float dataz)
{

   const int linear_search_steps=40;

   float t=0.0;
   float size=(tmax+0.001)/linear_search_steps;

   // search front to back for first point inside object
   for( int i=0;i<linear_search_steps;i++ )
   {
                float3 p=ray_position(t,tx,v,dataz);
                float4 tex=tex2D(reliefmap,p.xy);
                if (p.z<tex.w)
                        t+=size;
   }

   const int binary_search_steps=8;

   // recurse around first point for closest match
   for( int i=0;i<binary_search_steps;i++ )
   {
          size*=0.5;
          float3 p=ray_position(t,tx,v,dataz);
          float4 tex=tex2D(reliefmap,p.xy);
          if (p.z<tex.w)
                 t+=2*size;
          t-=size;
   }

   return t;
}

f2s main_relief(v2f IN)

{
        f2s OUT;

        // view vector in eye space
        float3 v=normalize(IN.view);

        // vector perpendicular to view closest to (0,0,1)
        float3 u=normalize(2*v*v.z-float3(0,0,2));

        // mapping scale from object to texture space
        float3 mapping=1.0/IN.scale;
       
        // quadric constants
        float dataz=IN.curvature.x*v.x*v.x+IN.curvature.y*v.z*v.z;
        dataz=sign(dataz)*max(abs(dataz),0.001);

        // compute max distance for search min(t(z=0),t(z=1))
        float d=v.z*v.z-4*dataz*IN.scale.z;
        float tmax=50;
        if (d>0)                // t when z=1
                tmax=min(tmax,(-v.z+sqrt(d))/(-2*dataz));
        d=v.z/dataz;    // t when z=0
        if (d>0)
                tmax=min(tmax,d);
       
        // transform view and quadric data to texture space
        v*=mapping;
        dataz*=mapping.z;

        // ray intersect depth map
        float t=ray_intersect_rm_curved(_ReliefMap,IN.texcoord,v,tmax,dataz);
        float alpha=1;
        if (t>tmax)
                discard; // discard fragment
       
        // compute intersected position
        float3 p=ray_position(t,IN.texcoord,v,dataz);

        // get normal and color
        float4 n=tex2D(_ReliefMap,p.xy);       
        float4 c=tex2D(_MainTex,p.xy);

        // expand normal from normal map
        n.xyz=normalize(n.xyz-0.5);

        // restore view vector
        v=normalize(IN.view);

        float3 light=normalize(IN.light);

        // compute diffuse and specular terms
        float diff=saturate(dot(light,n.xyz));
        float spec=saturate(dot(normalize(light-v),n.xyz));

        // attenuation factor
        float att=1.0-max(0,light.z); att=1.0-att*att;

        // ambient term
        float4 finalcolor=_Ambient*c;

        // compute final color
        finalcolor.xyz += att*(c.xyz*_Diffuse.xyz*diff+_Specular.xyz*pow(spec,_Specular.w));
        finalcolor.w=alpha;
        OUT.color=finalcolor;
       
        return OUT;
}

ENDCG //----------        
        } // Pass  
        } // SubShader  
} // Shader
 

Re: Получение данных освещения

СообщениеДобавлено: 29 мар 2010, 20:03
Neodrop
Учимся использовать тег Syntax :-w

Re: Получение данных освещения

СообщениеДобавлено: 29 мар 2010, 20:37
Kann
а где вы искали эти данные ? в соседней теме есть ссылка на книжку по шейдерам для OpenGL советую почитать, а направление света получаем через transform.TransformDirection

Re: Получение данных освещения

СообщениеДобавлено: 30 мар 2010, 09:13
Skval
Neodrop писал(а):Учимся использовать тег Syntax :-w


Глубоко извиняюсь))

Kann писал(а):а где вы искали эти данные ? в соседней теме есть ссылка на книжку по шейдерам для OpenGL советую
почитать, а направление света получаем через transform.TransformDirection


Ну так как освещение родное Юнити я рассматривал документацию, на одной из страниц в примерах создания простенького шейдера было упоминание о Lighting On
и Light Color, но толком как получить этот Light Color я не понял, не говоря уже о том, что ещё нужна и позиция...

Re: Получение данных освещения

СообщениеДобавлено: 30 мар 2010, 09:18
Neodrop
Глубоко извиняюсь))

Вы всё равно его использовали неправильно. В теге нужно писать не имя, а синтаксис языка. В вашем случае syntax=glsl
Я подправил :-B

Re: Получение данных освещения (Relief_Correct_Silhouettes)

СообщениеДобавлено: 07 ноя 2010, 03:02
gnoblin
Вопрос наверное уже не актуален.
Relief шейдер надо будет оформить в виде сурфейс шейдера - хороший эффект!