zoukankan      html  css  js  c++  java
  • Unity 光照着色器

    光照着色器需要考虑光照的分类,一般分为漫反射和镜面反射。

    漫反射计算基本光照:

    float brightness=dot(normal,lightDir)    将法线和光的入射方向进行点积运算,求出光的亮度。

    float3 pixelColor=brightness*lightColor*surfaceColor  将光的亮度*光的颜色*物体表面颜色得到我们最终看到的颜色。

    Shader "Unlit/DiffuseShader"
    {
        Properties
        {
           _Color("Color",Color)=(1,0,0,1)
        }
        SubShader
        {
            #新加了光照模式标签
            Tags { "RenderType"="Opaque"  "LightMode"="ForwardBase"}
            LOD 100
    
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
    
                #include "UnityCG.cginc"
                #include "UnityLightingCommon.cginc"
    
                fixed4 _Color;
    
                struct appdata
                {
                    float4 vertex : POSITION;
                    float3 normal:NORMAL;                        #法线方向
                };
    
                struct v2f
                {
                    float4 vertex : SV_POSITION;
                    float3 worldNormal:TXCOORD0;                #
    
                };
    
                v2f vert (appdata v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    float3 worldNormal=UnityObjectToWorldNormal(v.normal);
                    o.worldNormal=worldNormal;
                    return o;
                }
    
                fixed4 frag (v2f i) : SV_Target
                {
                    float3 normalDirection=normalize(i.worldNormal);
                    float nl=max(0.0,dot(normalDirection,_WorldSpaceLightPos0.xyz));
                    float4 diffusTerm=nl*_Color*_LightColor0;
                    return diffusTerm;
                }
                ENDCG
            }
        }
    }

    镜面反射具体实现:

    R=2*(N*L)*N-L;

    float3 reflectionVector=reflect(-lightDir,normal);                 //用入射光线方向和法线求出反射光线方向

    float specDot=max(dot(reflectionVector,eyeDir),0.0);        //反射光线和眼睛入射方法求点积

    float spec=pow(specDot,spectExponent);

                fixed4 frag (v2f i) : SV_Target
                {
                    //标准化法向量
                    float3 normalDirection=normalize(i.worldNormal);
                    float3 viewDirection=normalize(UnityWorldSpaceViewDir(i.vertexWorld));
                    float3 lightDirection=normalize(UnityWorldSpaceViewDir(i.vertexWorld));
                    
                    //采样纹理
                    float4 tex=tex2D(_DiffuseTex,i.uv);
    
                    //漫反射计算,使用兰帕特近似方法lambert
                    float nl=max(0.0,dot(normalDirection,_WorldSpaceLightPos0.xyz));
                    float4 diffusTerm=nl*_Color*_LightColor0;
    
                    //镜面反射计算,使用芳式近似方法Phong
                    float3 reflectionDirection=reflect(-lightDirection,normalDirection);
                    float3 specularDot=max(0.0,dat(viewDirection,reflectionDirection));
                    float3 specular=pow(specularDot,_shininess);
    
                    //计算最终的颜色
                    float4 specularTerm=float4(specular,1)*_SpacColor*_LightColor;
                    float4 finalColor=diffusTerm*specularTerm;
    
                    return finalColor;
  • 相关阅读:
    Linux主机肉鸡木马minerd导致CPU跑满
    阿里云Redis加速Typecho博客访问
    啪啪啪!敲代码时你喜欢听什么音乐?
    排列组合的去重问题
    01背包变形
    判断两个线段是否相交
    Centos搭建SVN服务器三步曲
    nodejs for centos配置
    AngularJS 授权 + Node.js REST api
    1082 射击比赛 (20 分)C语言
  • 原文地址:https://www.cnblogs.com/Optimism/p/10569309.html
Copyright © 2011-2022 走看看