光照模型:用数学的方法模拟现实世界中的光照效果。
 
场景中模型身上的光反射到相机中的光线:
1.漫反射:产生明暗效果
2.高光反射:产生镜面反射,物体中有最亮且比较耀眼的一部分
3.自发光:
4.环境光:
 
漫反射
光线被粗糙的表面无规则的向各个方向反射的现象。
漫反射的计算公式(兰伯特光照模型)模拟漫反射
漫反射光 = 光照颜色和强度 * 漫反射颜色 * max(0, dot(法线方向,  光照方向))
光照颜色和强度:Unity引擎提供的,CGIncludes/UnityLightingCommon.cginc,需要引用
漫反射颜色:从属性面板获取的
法线方向:世界空间下的:需要把模型空间下的法线转换到世界空间下 
光照方向:从顶点指向光源的CGIncludes/UnityCG.cginc

逐顶点漫反射光照:是把光照计算放在顶点函数里,效果差(过渡区域),效率高

Shader "Lesson/VFVertDiffuse" {
Properties{
_DiffuseColor("漫反射颜色", Color) = (,,,)
}
SubShader{
Pass
{
//设置正确的光照渲染模式,前项渲染里的基础
Tags { "LightMode" = "ForwardBase" }
//定义Cg的开始和结束
CGPROGRAM
#pragma vertex vert//定义顶点函数名字
#pragma fragment frag//定义片元函数名字
#include "Lighting.cginc"//如果想要使用提供一些灯光变量和方法,需要引入文件 //漫反射光 = 光照颜色和强度 * 漫反射颜色 * max(0, dot(法线方向, 光照方向))
//漫反射颜色:从属性面板获取 _DiffuseColor
//光照颜色:系统提供的,_LightColor0
//法线方向:世界空间下的:需要把模型空间下的法线转换到世界空间下 worldNormal
fixed4 _DiffuseColor;//重定义属性变量 struct m2v
{
//需要获取顶点坐标和法线向量
float4 vex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
//把光照计算放在顶点函数中
//所以需要把计算之后的漫反射光Color传递到片元函数中
float4 position : SV_POSITION;
fixed4 color : COLOR0;
};
//实现定点和片元函数
v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex);//转换顶点坐标
float3 worldNormal = normalize(mul(UNITY_MATRIX_M, v.normal));//normalize归一化向量
float3 worldPosition = mul(UNITY_MATRIX_M, v.vex);//先获取世界空间下的顶点坐标
float3 lightDir = normalize(UnityWorldSpaceLightDir(worldPosition));//UnityWorldSpaceLightDir,获取光照方向
fixed3 color = _LightColor0.xyz * _DiffuseColor.xyz * max(, dot(worldNormal, lightDir));//漫反射颜色,光照不影响透明度,所以是.xyz没有w
f.color = fixed4(color, );
return f;
}
fixed4 frag(v2f f) : SV_Target
{
return f.color;
}
ENDCG
}
}
FallBack "Diffuse"
}

逐像素漫反射光照:是把光照计算放在片元函数里,效果好,效率低

Shader "Lesson/VFFragDiffuse" {
Properties{
_DiffuseColor("漫反射颜色", Color) = (,,,)
}
SubShader{
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
fixed4 _DiffuseColor; struct m2v
{
float4 vex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 position : SV_POSITION;
float3 worldNormal : COLOR0;//把世界空间下的法线传递过去
float3 worldPosition : COLOR1;//世界空间下的顶点坐标
};
v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex);
f.worldNormal = normalize(mul(UNITY_MATRIX_M, v.normal));//转换法线向量,变成世界空间下的
f.worldPosition = mul(UNITY_MATRIX_M, v.vex);
return f;
}
fixed4 frag(v2f f) : SV_Target
{
float3 lightDir = normalize(UnityWorldSpaceLightDir(f.worldPosition));
fixed3 color = _LightColor0.xyz * _DiffuseColor.xyz * max(, dot(f.worldNormal, lightDir));
return fixed4(color, );
}
ENDCG
}
}
FallBack "Diffuse"
}
Pass
{
//设置正确的光照渲染模式,前项渲染里的基础
Tags { "LightMode" = "ForwardBase" }
}

半兰伯特光照模型,解决兰伯特背光面毫无细节的问题。
漫反射光 = 光照颜色和强度 * 漫反射颜色 * (dot(法线方向,  光照方向) * 0.5 + 0.5)
 
实现半兰伯特光照的逐像素渲染和逐顶点渲染
fixed3 color = _LightColor0.xyz * _DiffuseColor.xyz * (dot(f.worldNormal, lightDir) * 0.5 + 0.5);
 
高光反射
高光:物体上最亮的部分。
镜面反射:当平行的入射光线射到物体光滑的表面,仍会平行的向一个方向反射出来。
高光(Specular) = 光照颜色和强度 * 高光颜色 * pow(max(0, dot(v, r)), 高光系数)
V:顶点到相机的方向
R:反射光的方向
Shader "Lesson/VFVertSpecular" {
Properties{
_DiffuseColor("漫反射颜色", Color) = (,,,)
_SpecularColor("高光颜色", Color) = (,,,)
_Gloss("高光系数", Range(, )) = 0.2
}
SubShader{
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc" fixed4 _DiffuseColor;
fixed4 _SpecularColor;
float _Gloss; struct m2v
{
float4 vex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 position : SV_POSITION;
fixed4 color : COLOR0;
};
v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex);
//高光(Specular) = 光照颜色和强度 * 高光颜色 * pow(max(0, dot(v, r)), 高光系数)
//V:顶点到相机的方向 UnityWorldSpaceViewDir(worldPosition)
//R:反射光的方向 reflect(-lightDir, worldNormal)
//光照颜色和强度 _LightColor0
//高光颜色 _SpecularColor
//高光系数 _Gloss
//世界空间下的法线
float3 worldNormal = normalize(mul(UNITY_MATRIX_M, v.normal));
//世界空间下的顶点坐标
float3 worldPosition = mul(UNITY_MATRIX_M, v.vex);
//顶点到光源的方向
float3 lightDir = normalize(UnityWorldSpaceLightDir(worldPosition));
//顶点到相机的方向
float3 cameraDir = normalize(UnityWorldSpaceViewDir(worldPosition));
//反射光的方向
float3 refDir = reflect(-lightDir, worldNormal);
//漫反射 半兰伯特
fixed3 diffuse = _LightColor0.xyz * _DiffuseColor.xyz * (dot(worldNormal, lightDir) * 0.5 + 0.5);
//高光
fixed3 specular = _LightColor0.xyz * _SpecularColor.xyz * pow(max(, dot(cameraDir, refDir)), _Gloss);
f.color = fixed4(diffuse + specular, );
return f;
}
fixed4 frag(v2f f) : SV_Target
{
return f.color;
}
ENDCG
}
}
FallBack "Diffuse"
}

实现漫反射,高光,自发光、贴图纹理混合影响的Shader

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Lesson/VFFragSpecular" {
Properties{
_MainTex("纹理", 2D) = "white"{}
_DiffuseColor("漫反射颜色", Color) = (,,,)
_SpecularColor("高光颜色", Color) = (,,,)
_Emission("自发光颜色", Color) = (0.05,0.05,0.05,)
_Gloss("高光系数", Range(, )) = 1.05
}
SubShader{
Pass
{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM #pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc" //重定义
fixed4 _DiffuseColor;
fixed4 _SpecularColor;
fixed4 _Emission;
float _Gloss;
sampler2D _MainTex; struct m2v
{
float4 vex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
}; struct v2f
{
//转换之后的坐标
float4 position : SV_POSITION;
//世界空间下法线向量
float3 worldNormal : COLOR0;
//世界空间下的顶点坐标
float3 worldPosition : COLOR1;
//uv
float2 uv : TEXCOORD0;
};
v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex);
f.worldNormal = normalize(mul(UNITY_MATRIX_M, v.normal));
f.worldPosition = mul(UNITY_MATRIX_M, v.vex);
f.uv = v.uv;
return f;
} fixed4 frag(v2f f) : SV_Target
{
/*高光(Specular) = 光照颜色和强度 * 高光颜色 * pow(max(0, dot(v, r)), 高光系数)
V: 顶点到相机的方向 UnityWorldSpaceViewDir(世界空间下的顶点坐标)
R:反射光的方向 reflect(从光源指向顶点的方向, 世界空间下的法线方向)
*/ //顶点到相机的方法
float3 cameraDir = normalize(UnityWorldSpaceViewDir(f.worldPosition));
//光照方向 从顶点指向光源方法
float3 lightDir = normalize(UnityWorldSpaceLightDir(f.worldPosition));
//反射光方向 -lightDir 从光源指向顶点方法
float3 refDir = reflect(-lightDir, f.worldNormal);
//漫反射 半兰伯特
fixed3 diffuse = _LightColor0.xyz * _DiffuseColor.xyz * (dot(f.worldNormal,lightDir) * 0.5 + 0.5);
//高光
fixed3 specular = _LightColor0.xyz * _SpecularColor.xyz * pow(max(, dot(cameraDir, refDir)), _Gloss);
//自发光 _Emission
//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
//光的颜色
fixed3 lightColor = diffuse + specular + _Emission + ambient;
//根据UV获取纹理的颜色
fixed4 texColor = tex2D(_MainTex, f.uv);
texColor.xyz = texColor.xyz * lightColor;
return texColor;
}
ENDCG
}
}
FallBack "Diffuse"
}

多光情况

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Lesson/VFMoreLightDiffuse" {
Properties{
_DiffuseColor("漫反射颜色", Color) = (,,,)
}
SubShader{
Pass
{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM #pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc" //重定义
fixed4 _DiffuseColor; struct m2v
{
float4 vex : POSITION;
float3 normal: NORMAL;
}; struct v2f
{
float4 position : SV_POSITION;
fixed4 color : COLOR0;
}; v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex); //世界空间下的法线
float3 worldNormal = normalize(mul(UNITY_MATRIX_M, v.normal));
//光照方向
float3 lightDir = normalize(UnityWorldSpaceLightDir(mul(UNITY_MATRIX_M, v.vex))); fixed3 diffuse = _LightColor0.xyz * _DiffuseColor.xyz * max(, dot(worldNormal, lightDir)); f.color = fixed4(diffuse, );
return f;
} fixed4 frag(v2f f) : SV_Target
{
return f.color;
}
ENDCG
}
Pass
{
Blend One One//把点光源(新)和太阳光(旧)混合
Tags{ "LightMode" = "ForwardAdd" }//最多添加4盏光源
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc" //重定义
fixed4 _DiffuseColor;
struct m2v
{
float4 vex : POSITION;
float3 normal: NORMAL;
};
struct v2f
{
float4 position : SV_POSITION;
fixed4 color : COLOR0;
};
v2f vert(m2v v)
{
v2f f;
f.position = UnityObjectToClipPos(v.vex);
//世界空间下的法线
float3 worldNormal = normalize(mul(UNITY_MATRIX_M, v.normal));
//光照方向
float3 lightDir = normalize(UnityWorldSpaceLightDir(mul(UNITY_MATRIX_M, v.vex)));
fixed3 diffuse = _LightColor0.xyz * _DiffuseColor.xyz * max(, dot(worldNormal, lightDir));
f.color = fixed4(diffuse, );
return f;
}
fixed4 frag(v2f f) : SV_Target
{
return f.color;
}
ENDCG
}
}
FallBack "Diffuse"
}

补充内容

补充:在障碍物后面显示轮廓阴影

Shader "Lesson/PlayerBody" {
Properties {
_Color ("Color", Color) = (,,,)
_OcculusionColor ("被挡住以后的颜色", Color) = (,,,)
}
SubShader {
Tags { "Queue"="Geometry+200" }
Pass
{
ZTest Greater
Color[_OcculusionColor]
}
Pass
{
ZTest Less
Color[_Color]
}
}
FallBack "Diffuse"
}

补充:物体多个材质球渲染,unity mobile shader:解决眼镜和身体的遮挡关系

Shader "Lesson/Glass" {
Properties {
_Color ("Color", Color) = (,,,)
_OcculusionColor ("被挡住以后的颜色", Color) = (,,,)
}
SubShader {
Tags { "Queue"="Geometry+100" }
Pass
{
ZTest Greater
ZWrite off
Color[_OcculusionColor]
}
Pass
{
ZTest Less
Color[_Color]
}
}
FallBack "Diffuse"
}

边缘发光

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader"Lesson/OutLine1"
{
Properties
{
_MainTex("main tex",2D) = "black"{}
_RimColor("rim color",Color) = (,,,)//边缘颜色
_RimPower("rim power",range(,)) = //边缘强度
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include"UnityCG.cginc"
struct v2f
{
float4 vertex:POSITION;
float4 uv:TEXCOORD0;
float4 NdotV:COLOR;
};
sampler2D _MainTex;
float4 _RimColor;
float _RimPower;
v2f vert(appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
float3 V = WorldSpaceViewDir(v.vertex);
V = mul(unity_WorldToObject,V);//视方向从世界到模型坐标系的转换
o.NdotV.x = saturate(dot(v.normal,normalize(V)));//必须在同一坐标系才能正确做点乘运算
return o;
}
half4 frag(v2f IN) :COLOR
{
half4 c = tex2D(_MainTex,IN.uv);
//用视方向和法线方向做点乘,越边缘的地方,法线和视方向越接近90度,点乘越接近0.
//用(1- 上面点乘的结果)*颜色,来反映边缘颜色情况
c.rgb += pow(( - IN.NdotV.x) ,_RimPower)* _RimColor.rgb;
return c;
}
ENDCG
}
}
FallBack"Diffuse"
}
 
轮廓
思路:两次渲染,第一次渲染背面,剔除正面,把模型顶点沿法线方向扩伸一定距离(用来表现描边的粗细)
第二次渲染,渲染正面,剔除背面
Shader "Lesson/OutLine2"
{
Properties
{
_MainTex("main tex",2D) = ""{}
_Factor("factor",Range(,0.1)) = 0.01//描边粗细因子
_OutLineColor("outline color",Color) = (,,,)//描边颜色
}
SubShader
{
Pass
{
Cull Front //剔除前面
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" struct v2f
{
float4 vertex :POSITION;
}; float _Factor;
half4 _OutLineColor; v2f vert(appdata_full v)
{
v2f o;
//v.vertex.xyz += v.normal * _Factor;
//o.vertex = mul(UNITY_MATRIX_MVP,v.vertex); //变换到视坐标空间下,再对顶点沿法线方向进行扩展
float4 view_vertex = mul(UNITY_MATRIX_MV,v.vertex);
float3 view_normal = mul(UNITY_MATRIX_IT_MV,v.normal);
view_vertex.xyz += normalize(view_normal) * _Factor; //记得normalize
o.vertex = mul(UNITY_MATRIX_P,view_vertex);
return o;
} half4 frag(v2f IN) :COLOR
{
//return half4(0,0,0,1);
return _OutLineColor;
}
ENDCG
}
Pass
{
Cull Back //剔除后面
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" struct v2f
{
float4 vertex :POSITION;
float4 uv:TEXCOORD0;
}; sampler2D _MainTex; v2f vert(appdata_full v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv = v.texcoord;
return o;
} half4 frag(v2f IN) :COLOR
{
//return half4(1,1,1,1);
half4 c = tex2D(_MainTex,IN.uv);
return c;
}
ENDCG
}
}
FallBack "Diffuse"
}
 
描边
思路:两次渲染。第一次渲染背面,剔除正面。利用Offset指令,向离摄像机更近的方式偏移
第二次正常渲染物体(不剔除),(或者可以渲染正面,剔除背面)。
Offset:深度偏移
Offset Factor,Units
Factor参数表示 Z缩放的最大斜率的值。
Units参数表示可分辨的最小深度缓冲区的值。
我的理解:深度偏移,Unity是左手坐标系,Z的正方向是朝屏幕里面。
沿Z的负方向偏移就是离摄像机更近,
沿Z的正方向偏移就是离摄像机更远。
作用:可以强制使位于同一位置上的两个几合体中的一个几何体绘制在另一个的上层
比如:几何体A的Z值比几何体B更远,此时B是在A的上层。
但是,给A设置了Offset 往Z的负方向偏移,此时A比B更近了,A就在B上层了。
在深度测试(Z test)的时候,会去比较Z值,近的会绘制在远的上面。
所以上面的思路,要么第一次渲染背面,往Z的负方向偏移
要么第二次渲染的,往Z的正方向偏移,都是可以的。
Shader "Lesson/OutLine3"
{
Properties
{
_MainTex("main tex", 2D) = ""{ }
_OutLineColor("outline color",Color) = (,,,)//描边颜色
}
SubShader
{
//描边
pass
{
Cull Front
Offset -,- //深度偏移
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" sampler2D _MainTex;
half4 _OutLineColor; struct v2f
{
float4 pos : SV_POSITION;
}; v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
return o;
} float4 frag(v2f i) : COLOR
{
return _OutLineColor;
}
ENDCG
}
//正常渲染物体
pass
{
//Cull Back
//Offset 5,-1
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc" sampler2D _MainTex;
float4 _MainTex_ST; struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
}; v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
} float4 frag(v2f i) : COLOR
{
float4 c = tex2D(_MainTex,i.uv);
return c;
}
ENDCG
}
}
}

Unity3D学习笔记(三十六):Shader着色器(3)- 光照的更多相关文章

  1. Unity3D学习笔记(十六):Animator新动画

    新动画系统: 给模型选择动画类型 普通动画:Generic 人形动画:Humanoid 建立动画控制器 - 在Project右击 - 选择Create-AnimatorContorller 将对应动画 ...

  2. 【Unity 3D】学习笔记三十六:物理引擎——刚体

    物理引擎就是游戏中模拟真是的物理效果.如两个物体发生碰撞,物体自由落体等.在unity中使用的是NVIDIA的physX,它渲染的游戏画面很逼真. 刚体 刚体是一个很很中要的组件. 默认情况下,新创的 ...

  3. PHP学习笔记三十六【try 二】

    <?php //定义一个顶级异常处理器 要定义在最上面 function my_exception($e) { echo "我是顶级异常处理:".$e->getMess ...

  4. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

  5. Nodejs学习笔记(十六)—Pomelo介绍&入门

    前言&介绍 Pomelo:一个快速.可扩展.Node.js分布式游戏服务器框架 从三四年前接触Node.js开始就接触到了Pomelo,从Pomelo最初的版本到现在,总的来说网易出品还算不错 ...

  6. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

  7. angular学习笔记(三十)-指令(7)-compile和link(2)

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

  8. angular学习笔记(三十)-指令(7)-compile和link(1)

    这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...

  9. angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

    在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...

  10. angular学习笔记(三十)-指令(5)-link

    这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...

随机推荐

  1. 【Hadoop学习之五】win7+Eclipse+hadoop3搭建本机开发环境

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 拓扑: 知识准备: 1.eclip ...

  2. JVM调优总结 -Xms

    转载自:http://unixboy.iteye.com/blog/174173/ 设置eclipse : -Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPer ...

  3. 英文名为什么最好不用joe?JOE英文名的寓意是什么?

    英文名为什么最好不用joe?JOE英文名的寓意是什么? Joe 的意思是乔,人名.意为,上帝还会赐予 Joe 乔(男子名, 对不相识者非正式的称呼; Joseph的昵称)(=GIJoe)[美俚]美国兵 ...

  4. vue去掉严格开发,即去掉vue-cli安装时的eslint

    vue去掉严格开发,即去掉vue-cli安装时的eslint : 1.vue-cli书写规范(主要是js规范) a.逗号.冒号后面要加空格 b.不能使用双引号,一律使用单引号 webpack的语法检查 ...

  5. Step6:SQL Server 数据变更时间戳(timestamp)在复制中的运用

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 方案(Solution) 方案一(Solution One) 方案二(Solution Two ...

  6. if语法

    语法一: if 条件:   条件成立时执行的子代码块 age_of_girl=31 if age_of_girl > 30: print('阿姨好') 语法二:if + else   if 条件 ...

  7. python-selenium,关于页面滑动的操作

    //移动到元素element对象的“顶端”与当前窗口的“顶部”对齐 ((JavascriptExecutor) driver).executeScript("arguments[0].scr ...

  8. Docker学习笔记之运行和管理容器

    0x00 概述 容器是基于容器技术所建立和运行的轻量级应用运行环境,它是 Docker 封装和管理应用程序或微服务的“集装箱”.在 Docker 中,容器算是最核心的部分了,掌握容器的操作也是 Doc ...

  9. Golang切片的三种简单使用方式及区别

    概念 切片(slice)是建立在数组之上的更方便,更灵活,更强大的数据结构.切片并不存储任何元素而只是对现有数组的引用. 三种方式及细节案例 ①定义一个切片,然后让切片去引用一个已经创建好的数组 pa ...

  10. python2.7安装mysql-python

    环境:python2.7.14+mysql-python-1.2.3.win-amd64-py2.7.exe 安装版本许参照解释器版本,有64和32位之分,如果安装错误版本,则运行时会报错:Impor ...