美文网首页
GLSL in Unity 系列文章(五):Phong与Blin

GLSL in Unity 系列文章(五):Phong与Blin

作者: 雄关漫道从头越 | 来源:发表于2020-11-19 12:06 被阅读0次

    今天用GLSL在unity中实现一下Phong光照模型和Blinn-Phong光照模型,效果如下:

    Phong光照模型 Blinn-Phong光照模型

    关于Phong光照模型和Blinn-Phong光照模型这里就不再详细说明了,今天的知识点主要是法线与顶点坐标如何转换到世界空间,以及GLSL的normalize、reflect、saturate等函数的使用。

    Shader "GLSL/BlinnPhone"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _SpecularTex("_SpecularTex", 2D) = "white" {}//控制哪一部分会有高光:脸蛋,布料上千万别有高光,金属,陶瓷,皮具,甲克可以有高光。
            _SpecularGloss("_SpecularGloss", range(0.001, 100)) = 30//光斑大小,和本值成反比
            [Toggle] _IsBlinn("_IsBlinn", int) = 1
        }
        SubShader
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
    
            Pass
            {
                GLSLPROGRAM
                //gl_Vertex 顶点
                //gl_MultiTexCoord0 uv
                //gl_Normal 顶点法线
                //gl_Position 裁剪空间坐标输出到片元着色器
                //gl_FragColor 输出颜色
                #include "UnityCG.glslinc"
                //获取灯光颜色需要申明,unity会自动赋值
                uniform vec4 _LightColor0;// color of light source (from "Lighting.cginc")
    
                uniform vec4 _MainTex_ST;
                #ifdef VERTEX
                out vec2 textureCoord;//uv输入到fs阶段
                out vec3 worldNormal;//世界空间下的法线
                out vec3 vertexWorldPos;//世界空间下的顶点坐标
                void main()
                {
                    worldNormal = gl_NormalMatrix * vec3(gl_Normal);
                    vertexWorldPos = vec3(unity_ObjectToWorld * gl_Vertex);
                    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
                    textureCoord = TRANSFORM_TEX_ST(gl_MultiTexCoord0, _MainTex_ST);//处理tiling和offset
                }
                #endif
                #ifdef FRAGMENT
                // uniforms corresponding to properties
                uniform sampler2D _MainTex;
                uniform sampler2D _SpecularTex;
                uniform float _SpecularGloss;
                uniform int _IsBlinn;
                in vec2 textureCoord;//接收fs阶段传入的uv
                in vec3 worldNormal;
                in vec3 vertexWorldPos;
                void main()
                {
                    // sample the texture
                    vec4 color = texture2D(_MainTex, textureCoord);
    
                    vec3 normal = normalize(worldNormal);
                    vec3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
    
                    vec3 viewDir = normalize(vertexWorldPos.xyz -_WorldSpaceCameraPos.xyz);
    
                    vec3 useDir = vec3(0, 0, 0);
                    if (_IsBlinn > 0)//实际代码中不要这么写
                    {
                        //Blinn-Phong光照模型
                        vec3 halfDir = normalize(worldLight + viewDir);//半角向量
                        useDir = halfDir;
                    }
                    else
                    {
                        //Phong光照模型
                        vec3 reflectDir = normalize(reflect(-worldLight, normal));//reflect函数求反射角方向
                        useDir = reflectDir;
                    }
                    //漫反射
                    vec3 diffuse = color.rgb * _LightColor0.rgb * max(0.0, dot(normal, worldLight));
    
                    //高光
                    vec3 specular = _LightColor0.rgb * pow(saturate(dot(normal, useDir)), _SpecularGloss) * texture2D(_SpecularTex, textureCoord).r;
    
                    gl_FragColor = vec4(diffuse + specular,color.a);
                }
                #endif
                ENDGLSL  
            }
        }
    }
    
    

    github:https://github.com/eangulee/GLSLInUnity.git

    相关文章

      网友评论

          本文标题:GLSL in Unity 系列文章(五):Phong与Blin

          本文链接:https://www.haomeiwen.com/subject/yoikiktx.html