Specular

高光或者说镜面反射,是光线经过物体表面,反射到视野中,当反射光线与人的眼睛看得方向平行时,强度最大,夹角为90度时,强度最小。

人眼睛的位置: float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz); 都在世界坐标,_WorldSpaceCameraPos.xyz是摄像机位置,i.posWorld.xyz是顶点在世界坐标的位置;

float3 specularReflection = atten *_LightColor0.xyz * _SpecColor.rgb*max(0.0, dot(normalDirection,lightDirection))*pow(max(0,dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);

  atten:光强系数

  _LightColor0:光源颜色

  _SpecColor:高光颜色

  max(0.0, dot(normalDirection,lightDirection)):光源强度

  pow(max(0,dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess):高光强度

高光是建立在Lambert光照模型上的,加入Lambert光照结果为diffuseRefliction:

float3 lightFinal = diffuseReflection +specularReflection+ UNITY_LIGHTMODEL_AMBIENT.xyz;

return float4(lightFinal*_Color.rgb,1.0);

源代码:

Shader "JQM/Specular"
{
    Properties
    {
        _Color("Color", color) = (1.0,1.0,1.0,1.0)
        _SpecColor("Specular Color", color) = (1.0,1.0,1.0,1.0)
        _Shininess("Shininess",float) = 10
    }
    SubShader{
        Pass{

            Tags { "LightMode" = "ForwardBase"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //使用自定义变量
            uniform float4 _Color;
            uniform float4 _SpecColor;
            uniform float _Shininess;

            //使用Unity定义的变量
            uniform float4 _LightColor0;

            struct vertexInput{
                float4 vertex:POSITION;
                float3 normal:NORMAL;
            };

            struct vertexOutput{
                float4 pos:SV_POSITION;
                float4 posWorld:TEXCOORD0;
                float3 normalDir:TEXCOORD1;
            };

            //顶点程序
            vertexOutput vert(vertexInput v)
            {
                vertexOutput o;

                o.posWorld = mul(_Object2World, v.vertex);
                o.normalDir =  normalize( mul(float4(v.normal,0.0),_World2Object).xyz);

                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                return o;
            }

            //片段程序
            float4 frag(vertexOutput i):COLOR
            {

                float3 normalDirection = i.normalDir;
                float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz);
                float3 lightDirection;
                float atten = 1.0;

                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
                float3 diffuseReflection = atten * _LightColor0.xyz *  max(0.0, dot(normalDirection,lightDirection));
                float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb*max(0.0, dot(normalDirection,lightDirection))*pow(max(0,dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);
                float3 lightFinal = diffuseReflection +specularReflection+ UNITY_LIGHTMODEL_AMBIENT.xyz;
                return float4(lightFinal*_Color.rgb,1.0);
            }

            ENDCG
        }
    }

}
时间: 2024-12-19 15:31:52

Specular的相关文章

Anisotropic Specular Shader

[Anisotropic Specular] Anisotropic Specular(各向异性反射)模拟表面凹槽的方向性.就像CD表面一样.CD的表面凹槽是有方向的. BlinnPhong中Specular强度的由N*H得计算得到,如下: 在Anisotropic的简单实现中,需要Anisotropic Normal Map扰动后,由sin(radians(offset))转化一下,如下: 首先,经Anisotropic Normal Map扰动后,表面法线已经具备凹槽特性. 其次,Sin函数

Phong & Blinn Specular Shader

[Phong Specular Shader] 如果物体离摄像机很远,或者不需要高精度镜面反射,则Phong模型适用. Phong模型如下: 使用前必须指定使用自定义Phong. [Blinn Specular Shader] 前一篇博文中记录了Unity自带的BlinnPhong算法,下面是自定义BlinnPhong模型的算法实现.

Specular Mask Texture

[Specular Mask Texture] Specular Texture是一个Mask纹理,通过Mask纹理的texel可以控制每个像素的纹理. 在属性中添加Specular Mask Texture纹理. 在Surf函数中修改Mask: 下图是最后的结果:

Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF

在实时渲染中Physically-Based Rendering(PBR)中文为基于物理的渲染 它能为渲染的物体带来更真实的效果,而且能量守恒 稍微解释一下字母的意思,为对后文的理解有帮助, 从右到左 L为光线方向,H为半角向量,L是和V的中间,N为法线方向,V为我们眼睛的观察方向(相机看的方向),R为反射方向 Torrance-Sparrow光照模型的镜面反射公式 D为法线分布函数(NDF) F为反射函数(Fresnel 函数) G为阴影遮罩函数(几何函数),未被shadow或mask的比例

Specular Aliasing与Specular Leaking

上面两个问题是最近做高质量实时HDR PBR渲染中面临的最主要问题.若干思考如下: 问题1: 极高的动态范围HDR+高级BRDF+相对较低的采样率(比方说不考虑子像素的原始分辨率),在这3项因素的综合作用下,Specular Aliasing基本上的不可避免的.这已经不是存不存在Specular Aliasing的问题,而是如何去面对.何时面对的问题.模型精度越高.工作流越倾向于全PBR方式,则反射高光走样越明显. 问题2: 另外还有个麻烦,就是在不引入前期baking机制的前提下使用IBL,会

Soft & Hard Specular

[Soft & Hard Specular] 写一个Shader,通过控制参数来指明软.硬Shader. 通过给定的Specular Texture来实现.例如提供以下SpecularTexture中的任意一张. 算法未搞明白,后续更新...

unity shader笔记

clip函数可以用来切割mesh clip(var); var 的值小于0时就会被切割 表面着色器 其实就是生成了定点片元着色器,相当于一种包装和简化吧 标准的填充结构 struct SurfaceOutput { fixed3 Albedo; // diffuse color fixed3 Normal; // tangent space normal, if written fixed3 Emission; half Specular; // specular power in 0..1 r

outdated: 27.Shadows

这次的代码没有按照辅导代码中的来. VK_LEFT/VK_RIGHT/VK_UP/VK_DOWN控制长方体旋转,W/S/A/D/Q/E控制球移动,小键盘的8/5/4/6/7/9控制长方体移动,I/K/J/L/U/O控制光源移动. 在InitGLObject()函数中使用到的readObject()函数.setConnectivity()函数和calculatePlane()函数在3object.h中所写. readObject()函数在.txt文件中读取物体顶点数.顶点坐标.平面数.vertex

three.js笔记

/*** 场景(scene) ***/ var scene = new THREE.Scene(); // 创建场景 scene.add(x); // 插入场景 /*** 相机(camera) ***/ // 正交投影相机 var camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far); // 透视头像相机 var camera = new THREE.PerspectiveCamera(fov, as