Shader笔记(一)
Shader
Fixed shader: shader1.0 固定管线
Vertex/Fragment shader : shader 2.0 顶点/片段
Surface shader :Unity3d 特有的 表面
Shader1.0
开关式编程
最终呈现效果计算公式
环境光 * Unity环境光设置 +
漫反射 * 灯光的颜色 +
镜面反射 * 灯光的颜色 +
自发光
流水线
过程:
- 顶点着色器
- 光栅化
- 片段着色器
- alpha测试
- 模板测试
- 深度测试
- blend
- gbuffer
- framebuffer
- frontbuffer
- 显示器
shader1.0
开关式编程
shader2.0
能够编程的
- 顶点着色器
- 计算顶点的位置 MVP:以相机为坐标系,超框不显示;
- 计算顶点的大小
- 计算顶点的颜色
- 光栅化:
- 将顶点变成像素 (计算插值)
- 片段(像素)着色器
- 计算像素颜色
- 结合灯光计算像素的颜色
- 结合贴图计算像素的颜色
- alpha测试
- 淘汰像素 RGBA:根据a值淘汰i像素
- 深度测试
- 根据深度值淘汰像素(离相机远近)
- 模板测试
- 程序自定义的值淘汰像素
- 分辨率:1280720 float[1280720] RGBA:32bit,
- 颜色缓存区(RGBA float[1280720]),深度缓存区(深度值8bit Byte[1280720] 或 short[1280720]) 模板缓存区(模板值8bit Byte[1280720]):
- blend (每个相机都会有 模板深度颜色的buffer):
- 将已经渲染到屏幕上的像素和即将渲染到屏幕上的像素做混合,存到gbuffer里
- framebuffer、frontbuffer:
- 将颜色缓存区里面的东西写入framebuffer里
- 交换到显示器上去
Unity3D编程
- Fixed shader:固定管线编程 shader1.0
- Vertex/fragement shader:顶点 片段着色器编程shader2.0
- Surface shader :表面着色器编程 U3D特有
四种光
光照公式:
光照I = 自发光+环境光+漫反射+镜面反射
环境光=环境光颜色 * 环境光向量
漫反射=漫反射光颜色 * 漫反射强度 * (光源向量·法线向量)
镜面反射=镜面光颜色 * 镜面反射强度 * (反射光向量·视角方向)^n
漫反射 (Diffuse)
- 跟观察角无关
- 跟入射角有关
- Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) )
Tip:cosθ = 光方向· 法线方向
镜面反射 (Specular)
- 跟观察角有关
- 跟入射角有关
- Specular=直射光 * pow( max(cosθ,0),10)
θ:是反射光方向和视野方向的夹角
环境光 (Ambient)
周围环境光线
自发光 (Emission)
自己发光
Ambient + Lighting Window’s Ambient Intensity Setting + (Light Color * Diffuse + Light Color * Specular) + Emission
顶点着色器
//路径名
Shader "Custom/TestProperty"
{//属性:定义属性Properties{//1.数值,滑动条//2.颜色,向量//3.贴图//变量名,显示名,类型, 默认值_MainTex ("Texture", 2D) = "white" {}_TestFloat("Test float", float) = 2.5//GPU 只有浮点数_TestInt("Test int", int) = 2//滑动条_TestRange("TestRange", Range(1,10)) = 5//颜色_TestColor("TestColor", Color) = (1,1,1,1)//向量//四维向量xyzw,三维矩阵变换,w表示平移_TestVector("TestVector", Vector) = (1,1,1,1)//贴图_TestTexture("TestTexture", 2D) = "white" {}_TestCube("TestCube", Cube) = "white" {}_Test3D("Test3D", 3D) = "white" {}}//渲染流程:选择对应显卡,只用一个SubShader{//渲染通道:每出现一次就渲染一次//写代码Pass{//sahder1.0顶点着色器编程(开关式编程)://Color:表示顶点颜色的定义
// Color (1,0,0,1)//使用变量Color[_TestColor]//Material:定义物体自身材质属性://设置物体自身四种光,漫反射,镜面反射,环境光,自发光material{}//sahder1.0开关式编程SeparateSpecular On//灯光总开关lighting On}}//可以适配多个显卡SubShader{Pass{}}//没找到适配显卡,选择默认shaderFallback "Diffuse"
}
片段着色器
SetTexture指令
- Previous是上一次SetTexture的结果
- previous指的是先前的数据,将代码改成“combine texture * previous”,这里的意思就是用当前纹理的值去乘上当前settexture操作之前所有计算和采样过后的结果。
- Primary是来自光照计算的颜色或是当它绑定时的顶点颜色
- primary代表了前面所有计算材质和光照后的颜色值,将贴图和这个值相乘,就会得到一个混合的新的颜色值。
- Texture是在SetTexture中被定义的纹理的颜色
- Constant是被ConstantColor定义的颜色
SubShader{Pass{//设置图片指令SetTexture[_BlendTex]{//代码逻辑//combine texture //加减乘 当前贴图颜色combine texture * Primary}SetTexture[_MainTex]{//加减乘 之前贴图颜色combine texture * Previous}}}
lerp插值
lerp(a,b,t) = a* t + b*(1-t)
lerp(RGBA1, RGBA3, RGBA2.A)
Constant 常量指令
SetTexture[_BlendTex]{ConstantColor(0,1,0,1)combine texture * constant}
alpha测试 深度测试
/* **********************************************************************Copyright © 2019 Unity1903*File Name: TestTexture.shader*Author: lvzhijie*CreateTime: 2019年10月29日 9:33:44*Describe: Add a description here*********************************************************************
*/
Shader "Shader02/TestTexture"
{Properties{_MainTex ("Texture", 2D) = "white" {}_BlendTex("Blend", 2D) = "white"{}_BlendTex2 ("Blend2", 2D) = "white" {}_ConstantColor ("ConstantColor", Color) = (1,0,0,1)}SubShader{//消融效果//Blend srcalpha oneminussrcalphaPass{//01 练习 Primary Previous Constant//设置图片指令
/* SetTexture[_MainTex]{//加减乘 上当前贴图颜色combine texture * Primary}SetTexture[_BlendTex]{//代码逻辑combine texture + Previous}SetTexture[_BlendTex]{ConstantColor [_ConstantColor]combine texture * constant}*//*02片段着色器//顶点着色器写在最前面Color[_ConstantColor]//片段着色器SetTexture[_BlendTex]{combine texture}SetTexture[_MainTex]{
// combine texture * Primary + Primarycombine texture * Primary + Previous}SetTexture[_BlendTex2]{combine texture + Previous}*///03 lerp 插值 视频52分钟/*Color(1,0,0,1)SetTexture[_MainTex]{//调用Constant值设置变量ConstantColor[_ConstantColor]//根据变量设置lerp的alpha值combine Primary lerp(constant) texture}*//*三大测试shader1.0 shader2.0通用alpha测试, 模板测试, 深度测试*//* alpha测试:AlphaTest comparison AlphaValue对比方法:Greater:大于GEqual:大于等于Less:小于LEqual:钓鱼灯也Equal:等于NotEqual:不等于Always:一直等于Never:从不等于*///三大测试写在pass里只应用与pass,pass外应用于所有pass//取所有alpha大于0.9的值//AlphaTest Greater 0.9//Always 和 Never 后必须跟值,值无意义//AlphaTest Always 0/*深度测试:根据深度值判断淘汰像素深度值:物体到相机的距离深度缓冲区:跟颜色缓冲区匹配 Float[1024*768]指令:Cull Back|Front|Off:剔除,不渲染前或后,或都渲染ZWrite Off : 是否替换ZTest : 判断替换Offset : 微调*///前后都渲染,或两次渲染,从后往前,cull front 然后cull back//cull Off//一直显示ZTest Always//微调 (防止同一位置的两个物体重叠闪烁)Offset -1,-1SetTexture[_MainTex]{combine texture}}//Cube渲染前后两个面//从后往前渲染/*Pass{cull frontSetTexture[_MainTex]{combine texture}}pass{cull backSetTexture[_MainTex]{combine texture}}Pass{Offset -1,-1cull backAlphaTest Greater [_TexTure01Float]SetTexture [_TexTure02]{ConstantColor [_ConstantColor]combine Texture}}*/}
}
模板测试
所使用的代码
- referenceValue:即将渲染的像素模板值:0-255默认0
- ReadMask:加密值,默认255
- WriteMask:加密值,默认255
- comparisonFunction:大于小于等于。。。
- stencilBufferValue:模板缓存区里的值
if(referenceValue & readMask comparisonFunctionstencilBufferValue & readMask)通过i像素else丢弃像素
关键字
- Ref :设定讲讲渲染的像素模板值 referenceValue值
- ReadMask:设置读遮罩,做加密
- WriteMask:设置写遮罩,做加密
- Comp:设置对比表达式(大于小于等于) 取值范围
- Pass:深度测试通过,模板测试也通过的操作,后处理,对模板缓存区里面的值取一个操作
- Fail:两个测试都失败,取一个操作
- ZFail:表示当深度测试失败,模板测试通过,取一个操作
- Keep:模板缓存区里的值保持不变
- Zero:模板缓存区里的值变成0
- Replace:模板缓存区里的值替换当前渲染的像素的模板值
- IncrSat:Increment,自增,到255,大于255为255
- DecrSat:自减,到0
- Invert:所有的位取反
- IncrWrap:循环自增,0-255-0-255
- DecrWrap:循环自减,255-0-255-0
使用方法
Pass
{Stencil{Ref 2 Comp always 2Pass replace }
}
- 设定当前渲染的像素模板
- 设定跟gbuffer里的值进行对比
- 设定后处理
Blend
指令
Blend SrcFactor DstFactor:
SrcFactor:即将渲染的像素RGBA
DstFactor:已经渲染的RGBA
SrcColor:即将渲染的像素RGB
SrcAlpha:即将渲染的A值
DstColor:已经渲染的RGB
DstAlpha:已经渲染的A值
OneMinusSrcColor:1-即将渲染的RGB
OneMinusDstColor:1-已经渲染的RGB
OneMinusSrcAlpha:1-即将渲染的A
OneMinusDstAlpha:1-已经渲染的A
想改变+号
BlendOP Sub
Add:加法
Sub:减法
Blend SrcAlpha OneMinusSrcAlpha
即将渲染的A值 * 即将渲染的像素RGBA + (1-即将渲染的像素A值) * 已经渲染的RGBA
Blend One OneMinusSrcAlpha
1 * 即将渲染的像素RGBA + (1-即将渲染的像素A值) * 已经渲染的RGBA
Blend One One
1 * 即将渲染的像素RGBA + 1 * 已经渲染的RGBA
Blend OneMinusDstColor One
(1-已经渲染的像素RGB) * 即将渲染的像素RGBA + 1 * 已经渲染的RGBA
Blend DstColor One
已经渲染的像素RGB * 即将渲染的像素RGBA + 1 * 已经渲染的RGBA
Blend DstColor SrcColor
已经渲染的像素RGB * 即将渲染的像素RGBA + 即将渲染的像素RGB * 已经渲染的RGBA
Shader2.0
*** 1.0和2.0代码不能混用 ***
可以更改过程
不能直接跟灯光计算(可以间接计算),一般用来做屏幕后期特效
CG语言
CG宏指令
引申:
Jit (just in time) :即时编译语言
例如Lua, python
Aot (a head of time) : 预编译语言
例如C#,java
制作效果
制作UV贴图旋转
SubShader{/*旋转贴图UV动画,旋转需要用到矩阵转换,1. 移动原点到中心2. 旋转3. 移动原点到原来位置*///混合透明Blend SrcAlpha OneMinusSrcAlphaPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}sampler2D _MainTex;fixed4 frag (v2f i) : SV_Target{fixed2 tmpUV = i.uv;//移动中心到圆点tmpUV -=fixed2(0.5,0.5);//设置长度范围,防止出现多余的图片if(length(tmpUV) > 0.5)return fixed4(0,0,0,0);float angle = _Time.y;float xx = tmpUV.x * cos(angle) + tmpUV.y * sin(angle);float yy = -tmpUV.x * sin(angle) + tmpUV.y * cos(angle);tmpUV = fixed2(xx,yy);//还原中心tmpUV += fixed2(0.5,0.5);fixed4 col = tex2D(_MainTex, tmpUV);return col;}ENDCG}}
制作流水效果
SubShader{// No culling or depth//Cull Off ZWrite Off ZTest AlwaysPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};float _WaveW;float _WaveA;v2f vert (appdata v){v2f o;v.vertex.y += _WaveA * sin(_WaveW * v.vertex.x + _Time.y);o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}sampler2D _MainTex;float _Speed;fixed4 frag (v2f i) : SV_Target{fixed2 tmpUV = i.uv;tmpUV.x += _Time.y * _Speed;fixed4 col = tex2D(_MainTex, tmpUV);//fixed4 col = tex2D(_MainTex, i.uv);// just invert the colors//col = 1 - col;return col;}ENDCG}}
OutLine
需要两次渲染,关闭需要显示物体的ZWrite,关闭ZTest则会一直显示,影响视觉,
SubShader{//渲染边框Pass{ZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};float _OutLineWidth;v2f vert (appdata v){v2f o;//加边框v.vertex.xyz *= _OutLineWidth;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}sampler2D _MainTex;fixed4 _OutLineColor;fixed4 frag (v2f i) : SV_Target{//fixed4 col = tex2D(_MainTex, i.uv);// just invert the colors//col = 1 - col;return _OutLineColor;//return fixed4(1,0,0,1);}ENDCG}//渲染贴图Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};v2f vert (appdata v){v2f o;//加边框v.vertex.xyz *=1.2;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}sampler2D _MainTex;fixed4 frag (v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv);// just invert the colors//col = 1 - col;return col;}ENDCG}}
高斯模糊
通过设置多次贴图偏移,达到模糊效果
Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}sampler2D _MainTex;float _OffSet;fixed4 frag (v2f i) : SV_Target{//自己fixed4 col = tex2D(_MainTex, i.uv);//上fixed4 col2 = tex2D(_MainTex, i.uv + float2(0, _OffSet));//下fixed4 col3 = tex2D(_MainTex, i.uv - float2(0, _OffSet));//左fixed4 col4 = tex2D(_MainTex, i.uv + float2(-_OffSet,0));//右fixed4 col5 = tex2D(_MainTex, i.uv + float2(_OffSet, 0));//上col = (col + col2+ col3+ col4+ col5) / 5;// just invert the colors//col = 1 - col;return col;}ENDCG}
抗锯齿(多重采样)
时域进行卷积 = 频域乘积(叉乘低频滤波器),得到一张模糊处理的图片,对图片进行采样;
卷积操作类似这里的高斯模糊,这里写的高斯模糊是上下左右进行平均,卷积操作可以简化为n*n(n为大于2的奇数)的矩阵与原始图片叉乘取平均;
摄像机后处理
Unity生命周期里的后处理过程
/// <summary>/// /// </summary>/// <param name="src">OnRender以前的画面</param>/// <param name="dest">更改以后传递回去的画面</param>private void OnRenderImage(RenderTexture src, RenderTexture dest){//用myMat对src图片渲染,之后存入dest//src, texture, dest renderTextureGraphics.Blit(src, dest, myMat);}
Surface Shader
Tag 标签
Queue 渲染队列
当场景中跟game窗口中不一样的时候要加Queue
Unity渲染整个场景 将场景中的所有物体分类
从小到大渲染(可以设置"Queue" = “Background+1”)
Background:最先渲染(1000)
Geometry :渲染不透明的物体,实体物体(2000)
AlphaTest:要经过alpha测试的队列(2450)
Transparent:透明的,半透明的物体(3000)
Overlay:最后渲染(如UI)(4000)
RenderPath 渲染通道
相机上的属性
Rendering Path:
- Use Graphics Settings
- Forward:质量要求低的 (渲染2次,效率高)
- Deferred:延迟渲染,次时代游戏 (渲染2次,效率高。)
- Legacy Vertex Lit:渲染顶点 (渲染1次,最快,支持硬件最多,效率最高,效果最差)
- Legacy Deferred:Unity 5.0之前的算法 (渲染3次,效率低)
Project Setting-> Graphics:
可以设置渲染通道
Seuface Shader使用
SurfcaceOutputStandard
struct SurfcaceOutputStandard
{
fixed3 Albedo;像素颜色,RGB
fixed3 Normal;法线
half Emission;自发光
half Metallic;金属光泽,0没有金属,1最强烈
half Smoothness;粗糙度,0粗糙,1光滑
half Occlusion;默认1 高光遮罩
fixed Alpha;透明度
}
高光颜色
struct SurfcaceOutputStandardSpecular
{
…
fixed3 Specular;高光
…
}
自定义surface shader
自定义灯光入口函数:
//unity5之前的
#pragma light surf Custom
void vert(inout appdata_full v, out Input o)
{
o.uv_MainTex = v.texcoord.xy;
}
//自定义表面着色器入口
#pragma surface surf Custom vertex:vert finalcolor:myColor
void surf(inout appdata_full v, out Input o)
{
}
//自定义灯光入口函数
half4 LightingCustom (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
return half4 (1,0,0,1);
}
//自定义雾效果
void myColor(Input IN, SurfaceOutput o, inout fixed4 color)
{
}
计算公式:
冯氏着色:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IHpotTtY-1599059227728)(en-resource://database/402:1)]
Blinn phone着色:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vrDymkNp-1599059227731)(en-resource://database/403:1)]
雾:
float pos = length(UnityObjectToViewPos(v.vertex.xyz).xyz);//距离计算//float dencity = (pos - _fogStart) / (pos - _fogEnd)//指数计算雾的浓度float dencity = exp(- _fogDensity * abs(pos));o.FogDensity = 1-dencity;
//菲尼尔公式
float fresnel = _fresnelBase + _fresnelScale*pow(1 - dot(N, V), _fresnelIndensity);
法线
设置法线贴图
void surf (Input IN, inout SurfaceOutputStandard o) {// Albedo comes from a texture tinted by colorfixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;//设置法线贴图fixed4 normalColor = tex2D (_NormalTex, IN.uv_NormalTex);//从法线贴图到fixed3类型的法线o.Normal = UnpackNormal(normalColor);o.Albedo = c.rgb;// Metallic and smoothness come from slider variableso.Metallic = _Metallic;o.Smoothness = _Glossiness;o.Alpha = c.a;}
边缘检测
o.Emission = _EmissionColor.rgb
* (1-clamp(
dot(o.Normal, IN.viewDir)
, 0, 1))
* _Power;
立方体贴图
真假反射
真反射:RenderTexture
需要IO写操作,影响性能
假反射:采集环境做成立方体贴图
使用:
立方体贴图采样
反射
//设置反射天空盒颜色o.Emission = texCUBE(_CubeMap, IN.worldRefl);o.Emission = texCUBE(_CubeMap, IN.worldRefl);
C#编写代码
使用GL
https://docs.unity3d.com/ScriptReference/index.html
复制GL代码
透视投影变正交投影GL.LoadOrtho();
Shader笔记(一)相关推荐
- Unity学习shader笔记[一百]简单焦散Caustic效果
焦散是模仿光透过水底的一个投影景象 有两个版本,改版最后效果如下 这里是简单的基于物体的焦散,基于水体的焦散思路是水面物体的shader中拿到ColorBuffer,然后用水体的屏幕空间坐标取采集Co ...
- OpenGL shader笔记
OpenGL shader笔记 目录 OpenGL shader笔记 uniform varying 访问顶点 访问顶点--颜色 访问顶点属性--法线 gl_Normal 访问顶点--纹理坐标 at ...
- 毛玻璃,磨砂玻璃材质,shader笔记
最近需要用到这个shader,就稍微研究了一下,这里做一下笔记,免得回来自己忘了- 思路: 看了不少文章,其实都大同小异,分为3步完成. 1,先建一个平面出来(也可以是个精灵),来显示效果.当然你要是 ...
- Unity海洋shader笔记①
不久前玩了神秘海域4和盗贼之海,对游戏中形状生动颜色通透的大海产生了兴趣,于是开始查着资料学习自己动手写一个海洋的水效渲染.这个shader基本是边学边写的,编写过程中我学到了很多新的知识. 目前的效 ...
- Unity学习shader笔记[一百零八]简单萤火效果
之前用粒子系统基于原有萤火虫的粒子改了一波慢萤火效果就被惊艳到了,开始大家讨论,就都觉得这样大数量的粒子消耗挺大的,后面测试过才发现单纯的粒子系统在总粒子数量3000,每秒300的生成数量,屏幕呈现有 ...
- Unity Shader笔记之 Unity的光源类型
Unity一共支持4种光源类型:平行光.点光源.聚光灯和面光源 (area light) . 面光源仅在烘焙时才可发挥作用. 光源类型有什么影响 最常使用的光源属性有光源的位置 .方向 (更具体说就是 ...
- 【Shader笔记10】更复杂的光照-Unity的光源类型
目录 光源类型 在前向渲染中处理不同的光源类型 Unity的光照衰减 光源类型 分类:平行光.点光源.聚光灯.面光源 属性:位置.方向.颜色.强度.衰减 面光源仅在烘培时才可发挥作用 PS:需要在Sc ...
- Shader笔记十七 卡通渲染
卡通风格渲染的游戏画面通常物体颜色分界明显,具有黑色的线条描边.卡通渲染的实现有多种方法,基于色调的着色技术是其中之一,实现过程中通过使用漫反射系数对一维纹理进行采样,控制漫反射色调.之前通过一张渐变 ...
- Shader笔记——使用粒子序列图实现体积云
最近看到一个效果还不错的体积云,了解了下其实现原理,将其实现思路做一个简单的整理和记录,并重写该Shader 其效果图: 该效果来自名为CloudPuff的Unity资源包中示例场景截图 实 ...
最新文章
- Linux环境下查PG库的慢sql,postgresql慢SQL
- 去重之后统计条数_BOPET:12的普通包装膜到底去哪了?
- 高速缓存系统之memcache c++使用实例
- 只显示小方格_木托盘拼成院子围栏,镂空方格里都种上菜,一物两用,收获满满...
- 【CodeForces - 1199C】MP3(思维,离散化)
- php 执行mysql查询_php中执行mysql的常用操作
- python爬取b站评论_python高效之爬了B站再爬微博
- 重学 VBA - 基础与实战篇(含正则表达式)
- emui内核支持kvm吗_KVM虚拟化详解
- 复旦邱锡鹏组最新综述:A Survey of Transformers!
- 远程桌面配置php,Win2008 R2实现多用户远程连接设置方法(图)
- mysql 5.6 datetime 保存精确到秒
- 凯撒密码加密,解密的实现,可以在项目上使用
- Jackson解析XML
- Sublime Text3 插件集合
- Notepad2 巧妙替换回车换行符
- Java编译器使用入门
- SharePoint Designer 2013 连接 Office 365 必需安装2个SP
- 第15届“开源中国开源世界”高峰论坛成功举办,腾讯获得重要奖项
- [分享]RFID之我的M1离线卡爆破过程
热门文章
- 软件下载站点提交的一点经验.
- HER2靶向药物研发进展-销售数据-上市药品前景分析
- DEV C++光标不在有汉字一行时汉字不显示以及中文乱码问题解决方法
- 使用 CentOS7 搭建服务器
- linux redhat 版本查看,查看RedHat linux版本的三种方法
- AI ISP发展应用与落地的机遇与挑战
- 华为云WeLink:用科技帮助乡村教师,推动乡村教育发展
- python新手入门英文词汇_Python新手入门基础英文笔记
- 二叉搜索树及其操作详解
- EntLib.com 电子商务系统 v2.5 – 前台购物网站/网店发布-- 源码包