Unity URP PBR_Cook-Torrance模型
Cook-Torrance模型是一个微表面光照模型,认为物体的表面可以看作是由许多个理想的镜面反射体微小平面组成的。
单点反射=镜面反射+漫反射占比*漫反射
漫反射 = 基础色/Π
镜面反射=DFG/4(N·V)(N·L)
D代表微平面分布函数,描述的是法线与半角向量normalize(L+V)对齐的概率,对齐程度越高,反射程度越大。
F代表菲涅尔反射函数,描述的是视线与法线的夹角越小时,向镜面反射集中,反之向漫反射集中。
G代表几何衰减系数,源自微表面的自我遮蔽现象,入射光线或反射光线会被凹凸表面遮挡,越粗糙的材质表面越可能发生自我遮蔽
但是想要计算出微表面的光照,单点反射当然是不够的,对于一个点,有多个角度会产生光照结果,所以对于光照输入角度的积分是必须的。
输出光={单点反射*输入光*(N·V) }对于输入角度的积分
对于直接光的计算,通常可以直接遍历所有光源计算即可,但对于漫反射的计算,通常会采用近似的方式,因为运行时的积分计算是十分昂贵的。所以通常会使用近似函数或预计算采样的方式实现。
想要了解更多关于Cook-Torrance模型可以去知乎检索。
下面是具体实现代码:
Shader "Kerzh/PBRhlsl"
{Properties{_TessellationUniform ("Tessellation Uniform", Vector) = (1,1,1,1) // 曲面细分系数,默认1代表不做操作[Space(10)]_BaseColorTex ("_BaseColorTex", 2D) = "white" {}_MetallicTex ("_MetallicTex", 2D) = "white" {}_RoughnessTex ("_RoughnessTex", 2D) = "white" {}_EmissionTex ("_EmissionTex", 2D) = "black" {}//默认传入黑色,即不存在自发光[Space(10)]_NormalTex ("_NormalTex", 2D) = "bump" {}//默认传入是(0.5,0.5,1),这是法线的标准颜色,相当于一张没有影响的法线图_AOTex ("_AOTex", 2D) = "white" {} // 默认传入白色,即不存在光线遮蔽[Space(10)][Toggle(ENABLE_BRDF_LUT)]_EnableBrdfLut("Enable BrdfLut",Float) = 0_BRDFLut("BRDFLut",2D) = "black"{}}SubShader{Tags { "RenderPipeline" = "UniversalRenderPipeline" "LightMode" = "UniversalForward" }Pass{HLSLPROGRAM#pragma vertex vert#pragma hull hull#pragma domain domain#pragma geometry geom#pragma fragment frag#pragma target 4.6#pragma shader_feature _ ENABLE_BRDF_LUT // _ 默认关闭,是否使用预计算漫反射第二部分#pragma multi_compile _ADDITIONAL_LIGHTS_VERTEX // 用于激活VertexLighting方法中对次要光源的计算#include "CommonHlslInc.hlsl"#include "CustomTessellation.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SphericalHarmonics.hlsl"sampler2D _MainTex;float4 _MainTex_ST;float _Value, _RangeValue;float4 _Color, _BaseColor;float _Metallic, _Roughness;sampler2D _BaseColorTex, _MetallicTex, _RoughnessTex;sampler2D _EmissionTex, _AOTex, _NormalTex;sampler2D _BRDFLut;float4 _Emission;#define Eplison 0.001 // 防曝光点//D 微平面分布函数 Trowbridge-Reitz模型float D_DistributionGGX(float3 N, float3 H, float Roughness){float a = Roughness * Roughness;float a2 = a * a;float NH = max(dot(N, H), 0);float NH2 = NH * NH;float nominator = a2;float denominator = (NH2 * (a2 - 1.0) + 1.0);denominator = PI * denominator * denominator;return nominator / max(denominator, Eplison); //防止分母为0}//G 几何衰减系数 Schlick-GGX模型float GeometrySchlickGGX(float NV, float Roughness){float r = Roughness + 1.0;float k = r * r / 8.0;float nominator = NV;float denominator = k + (1.0 - k) * NV;return nominator / max(denominator, Eplison); //防止分母为0}// 获取几何衰减系数float G_GeometrySmith(float3 N, float3 V, float Roughness){float NV = max(dot(N, V), 0);float ggx = GeometrySchlickGGX(NV, Roughness);return ggx;}//F ->直接光float3 F_FrenelSchlick(float NV, float3 F0){return F0 + (1.0 - F0) * pow(1.0 - NV, 5);}//F ->间接光float3 FresnelSchlickRoughness(float NV, float3 F0, float Roughness){float s = 1.0 - Roughness;return F0 + (max(s.xxx, F0) - F0) * pow(1.0 - NV, 5.0);}//UE4中的近似计算函数 用于近似计算间接光漫反射第二部分float2 EnvBRDFApprox(float Roughness, float NoV){const half4 c0 = { -1, -0.0275, -0.572, 0.022 };const half4 c1 = { 1, 0.0425, 1.04, -0.04 };half4 r = Roughness * c0 + c1;half a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;half2 AB = half2(-1.04, 1.04) * a004 + r.zw;return AB;}MeshData vert(MeshData input){return input;}//如果不正确配置会报错[domain("tri")] // 正在处理三角形 "tri", "quad", or "isoline"[outputcontrolpoints(3)] // 每个面片输出的顶点为3个[outputtopology("triangle_cw")] // 当创建三角形时应是顺时针还是逆时针,这里应是顺时针 "point", "line", "triangle_cw", or "triangle_ccw"[partitioning("integer")] // 如何细分切割面片 "integer", "pow2", "fractional_even", or "fractional_odd"[patchconstantfunc("patchConstantFunction")] // 细分切割部分还必须提供函数处理,每个面片调用一次MeshData hull (InputPatch<MeshData, 3> patch, uint id : SV_OutputControlPointID) // 每个顶点调用一次,如果是处理三角形就是调用三次{// 如果_TessellationUniform输入值为1,不产生任何变化,但当输入值为2时,具体发生了什么// 对于一个三角形(因为我们配置的是处理三角形),根据三条边的二等分位置添加额外的一个顶点,如果是3就是三等分位置添加两个顶点// 对于一个三角形(因为我们配置的是处理三角形),根据三条个顶点添加一个中心顶点// 根据patchConstantFunction赋值分配生成顶点的插值权重return patch[id];}// barycentricCoordinates分别代表各个点的插值权重,每个面片调用一次,对细分后的三角顶点形进行处理(也就是说原顶点不经过此处理?)[domain("tri")] // 正在处理三角形MeshData domain(TessellationFactors factors, OutputPatch<MeshData, 3> patch, float3 barycentricCoordinates : SV_DomainLocation) {MeshData data; // 新的插值权重顶点#define MY_DOMAIN_PROGRAM_INTERPOLATE(fieldName) data.fieldName = \patch[0].fieldName * barycentricCoordinates.x + \patch[1].fieldName * barycentricCoordinates.y + \patch[2].fieldName * barycentricCoordinates.z;//对所有信息利用插值权重进行插值计算MY_DOMAIN_PROGRAM_INTERPOLATE(vertex)MY_DOMAIN_PROGRAM_INTERPOLATE(normalTS)MY_DOMAIN_PROGRAM_INTERPOLATE(tangentTS)MY_DOMAIN_PROGRAM_INTERPOLATE(uv1)MY_DOMAIN_PROGRAM_INTERPOLATE(uv2)MY_DOMAIN_PROGRAM_INTERPOLATE(vertexColor)return data;}//最大的顶点数,这里比如你要生成三个三角形面片,那么一个面片需要三个顶点,就是9个顶点,一般来讲这里直接填多一点即可,不过可能填太多了会导致内存占用?[maxvertexcount(9)]void geom (triangle MeshData input[3],inout TriangleStream<VOutData> triStream){//原样转换过去VOutData output[3];for(int i=0;i<3;i++){VOutData p0;p0 = FillBaseV2FData(input[i]);output[i] = p0;}triStream.RestartStrip(); // 重新开始一个新的三角形triStream.Append(output[0]);triStream.Append(output[1]);triStream.Append(output[2]);}float4 frag(VOutData i) : SV_Target{float3 lightDirWS = normalize(GetMainLight().direction);float3 viewDirWS = normalize(GetWorldSpaceViewDir(i.posWS));float3 halfVectorWS = normalize(viewDirWS + lightDirWS);float2 uv = i.uv1;//================== Normal Map ============================================== ////这里我们采样到一个法线贴图,向量是在切线空间下的,我希望把他变换到世界空间,所以我需要创建一个切线到世界的变换矩阵float3 NormalMap = UnpackNormal(tex2D(_NormalTex, uv));//在创造一个转换矩阵时,使用新坐标基在原空间中的向量构建,这样的矩阵可以从原坐标系变换到新坐标系//所以这里想要构建一个从切线空间转换到到世界空间的矩阵,虽然我们没有切线空间下的世界空间坐标,但至少拥有世界空间下的切线坐标基//且世界空间下这三个坐标基,正好是两两垂直的,满足正交矩阵,可以使用一个重要的性质:矩阵的逆=矩阵的转置//而这个矩阵的逆就是反向变换,即我们最开始想要的切线空间到世界空间的变换。float3x3 TangentToWorldMatrix = transpose(float3x3(i.tangentWS, normalize(i.bitangentWS), i.normalWS));float3 normalWS = normalize(mul(TangentToWorldMatrix, NormalMap));//================== PBR 贴图采样 ============================================== //float3 BaseColor = tex2D(_BaseColorTex, uv);float Roughness = tex2D(_RoughnessTex, uv).r;float Metallic = tex2D(_MetallicTex, uv).r;float3 Emission = tex2D(_EmissionTex, uv);float3 AO = tex2D(_AOTex, uv);//================== Direct Light 直接光部分 ============================================== ////Cook-Torrance BRDF模型float HV_WS = saturate(dot(halfVectorWS, viewDirWS));float NV_WS = saturate(dot(normalWS, viewDirWS));float NL_WS = saturate(dot(normalWS, lightDirWS));float NH_WS = saturate(dot(normalWS, halfVectorWS));//首先计算PBR三件套的DFG 要特别注意在这个PBR模型中直接光和间接光的F不同//微表面分布函数,描述的法线与半角向量对齐的概率,概率越大则反射越强float D = D_DistributionGGX(normalWS, halfVectorWS, Roughness);//菲尼尔,多影响高光和漫反射混合比例float3 F0 = lerp(0.04, BaseColor, Metallic);//经验近似值float3 F = F_FrenelSchlick(NV_WS, F0);//几何衰减系数,源自微表面的自我遮蔽现象,入射光线或反射光线会被凹凸表面遮挡,越粗糙的材质表面越可能发生自我遮蔽float G = G_GeometrySmith(normalWS, viewDirWS, Roughness);//还记得公式怎么写的吗//单点反射=镜面反射占比*镜面反射+漫反射占比*漫反射//漫反射 = 基础色/Π//镜面反射=DFG/4(N·V)(N·L)//输出光={单点反射*输入光*(N·V)}对于输入角度的积分//------------------------------直接光-----漫反射------------------------------float3 Diffuse_Direct;//直接光漫反射--光源float3 Diffuse_Direct_lightSource = BaseColor / PI;//直接光漫反射--比例:用(1-F)(1-metallc)公式float3 KD_DirectLight;KD_DirectLight = float3(1, 1, 1) - F;KD_DirectLight *= 1 - Metallic;Diffuse_Direct = Diffuse_Direct_lightSource * KD_DirectLight;//------------------------------直接光-----漫反射------------------------------//------------------------------直接光-----高光------------------------------float3 Specular_Direct;Specular_Direct = (D * F * G)/max(4*NV_WS*NL_WS, Eplison);//------------------------------直接光-----高光------------------------------//获得输入光float3 lightInput = VertexLighting(i.posWS, i.normalWS) + GetMainLight().color; // 包含Mainlight和AdditionalLights的输入光//而对于直接光,不用计算积分,因为只有一个直接光。使用这个公式:输出光={单点反射*输入光*(N·V)}对于输入角度的积分float3 DirectLightFinal = (Diffuse_Direct + Specular_Direct)* NL_WS * lightInput;//================== Indirect Light 间接光部分 ============================================== ////------------------------------间接光-----漫反射------------------------------float3 Diffuse_Indirect;//间接光漫反射--比例:用(1-F)(1-metallc)公式float3 KD_IndirectLight;//间接光 菲尼尔float3 F_IndirectLight = FresnelSchlickRoughness(NV_WS, F0, Roughness);KD_IndirectLight= float3(1, 1, 1) - F_IndirectLight;KD_IndirectLight *= 1 - Metallic;//间接光漫反射--辐照度:用球谐函数计算辐照度,在urp下不需要额外设置光照探针烘焙float3 irradianceSH;//球谐基数real4 SHCoefficients[7]; // https://blog.csdn.net/qq_41835314/article/details/129991046SHCoefficients[0] = unity_SHAr;SHCoefficients[1] = unity_SHAg;SHCoefficients[2] = unity_SHAb;SHCoefficients[3] = unity_SHBr;SHCoefficients[4] = unity_SHBg;SHCoefficients[5] = unity_SHBb;SHCoefficients[6] = unity_SHC;irradianceSH = SampleSH9(SHCoefficients, normalWS); // 计算球谐辐照度//间接光漫反射--光源:使用公式,辐照度*BaseColor/PI 这里乘上辐照度相当于单点漫反射光源做了积分float3 Diffuse_Indirect_lightSource;Diffuse_Indirect_lightSource = irradianceSH * BaseColor / PI;Diffuse_Indirect = Diffuse_Indirect_lightSource * KD_IndirectLight; //通过辐照度求出间接光的漫反射//------------------------------间接光-----漫反射------------------------------//------------------------------间接光-----高光------------------------------float3 Specular_Indirect;//间接光高光分为两部分计算,两部分为相乘关系,第一部分是输入光的积分,第二部分是数值模拟或预计算采样//间接光第一部分--输入光的积分:mipmap采样反射探针获得近似结果+AdditionalLightsfloat3 Specular_Indirect_lightSource_integral;// 间接光高光对于输入光积分的近似,以cubemap的mipmap采样方式近似float3 R = reflect(-viewDirWS, normalWS);//反射方向和计算mipmap进行采样float mip = Roughness * (1.7 - 0.7 * Roughness) * UNITY_SPECCUBE_LOD_STEPS;//这里的unity_SpecCube0是反射探针,最多访问两个最近的反射探针。float4 rgb_mip = SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, R, mip);//解码mipmap采样后的探针数据,也就是间接光高光的积分近似,unity_SpecCube0_HDR:HDR environment map decode instructionsSpecular_Indirect_lightSource_integral = DecodeHDREnvironment(rgb_mip, unity_SpecCube0_HDR) + VertexLighting(i.posWS, i.normalWS);//间接光第二部分--数值模拟或预计算采样float3 Specular_Indirect_PartTwo;#ifdef ENABLE_BRDF_LUT//预计算采样float2 env_brdf = tex2D(_BRDFLut, float2(lerp(0, 0.99, NV), lerp(0, 0.99, Roughness))).rg;#else//数值近似float2 env_brdf = EnvBRDFApprox(Roughness, NV_WS);#endifSpecular_Indirect_PartTwo = F_IndirectLight * env_brdf.r + env_brdf.g;Specular_Indirect = Specular_Indirect_lightSource_integral * Specular_Indirect_PartTwo;//------------------------------间接光-----高光------------------------------//------------------------------间接光-----最后计算------------------------------float3 IndirectLightFinal = (Diffuse_Indirect + Specular_Indirect) * AO; //计算ao影响//------------------------------间接光-----最后计算------------------------------//------------------------------最终输出------------------------------float4 FinalColor = 0;FinalColor.rgb = DirectLightFinal + IndirectLightFinal;FinalColor.rgb += Emission;//添加自发光return FinalColor;}ENDHLSL}// 阴影投射Pass{Name "ShadowCaster"Tags{"LightMode" = "ShadowCaster"}// -------------------------------------// Render State CommandsZWrite OnZTest LEqualColorMask 0Cull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex ShadowPassVertex#pragma fragment ShadowPassFragment// -------------------------------------// Material Keywords#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Universal Pipeline keywords// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE// This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"ENDHLSL}// 绘制到_CameraNormalsTexture纹理Pass{Name "DepthNormals"Tags{"LightMode" = "DepthNormals"}// -------------------------------------// Render State CommandsZWrite OnCull[_Cull]HLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex DepthNormalsVertex#pragma fragment DepthNormalsFragment// -------------------------------------// Material Keywords#pragma shader_feature_local _NORMALMAP#pragma shader_feature_local _PARALLAXMAP#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A// -------------------------------------// Unity defined keywords#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE// -------------------------------------// Universal Pipeline keywords#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"//--------------------------------------// GPU Instancing#pragma multi_compile_instancing#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"ENDHLSL}// 常规渲染过程中不使用,仅用于光照贴图烘焙。Pass{Name "Meta"Tags{"LightMode" = "Meta"}// -------------------------------------// Render State CommandsCull OffHLSLPROGRAM#pragma target 2.0// -------------------------------------// Shader Stages#pragma vertex UniversalVertexMeta#pragma fragment UniversalFragmentMetaLit// -------------------------------------// Material Keywords#pragma shader_feature_local_fragment _SPECULAR_SETUP#pragma shader_feature_local_fragment _EMISSION#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP#pragma shader_feature_local_fragment _ALPHATEST_ON#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED#pragma shader_feature_local_fragment _SPECGLOSSMAP#pragma shader_feature EDITOR_VISUALIZATION// -------------------------------------// Includes#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"ENDHLSL}}Fallback off
}
依赖库:CustomTessellation.hlsl、CommonHlslInc.hlsl
#ifndef CommonHlslInc
#define CommonHlslInc#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"//输入结构
struct MeshData
{float4 vertex : POSITION;float2 uv1 : TEXCOORD0;float2 uv2 : TEXCOORD1;float4 tangentTS :TANGENT;float3 normalTS : NORMAL;float4 vertexColor : COLOR;
};//传递结构
struct VOutData
{float4 pos : SV_POSITION; // 必须命名为pos ,因为 TRANSFER_VERTEX_TO_FRAGMENT 是这么命名的,为了正确地获取到Shadowfloat2 uv1 : TEXCOORD0;float2 uv2 : TEXCOORD1;float4 vertexColor : TEXCOORD2;float3 posOS : TEXCOORD3;float3 normalTS : TEXCOORD4;float3 tangentTS : TEXCOORD5;float3 posWS : TEXCOORD6;float3 normalWS : TEXCOORD7;float3 tangentWS : TEXCOORD8;float3 bitangentWS : TEXCOORD9;float3 posVS : TEXCOORD10;
};//传递结构赋值
VOutData FillBaseV2FData(MeshData input)
{VOutData output;output.pos = TransformObjectToHClip(input.vertex);output.uv1 = input.uv1;output.uv2 = input.uv2;output.vertexColor = input.vertexColor;output.posOS = input.vertex.xyz;output.normalTS = input.normalTS;output.tangentTS = input.tangentTS;output.posWS = mul(unity_ObjectToWorld, input.vertex);output.normalWS = normalize(TransformObjectToWorldNormal(input.normalTS));output.tangentWS = normalize(TransformObjectToWorldNormal(input.tangentTS));output.bitangentWS = cross(output.normalWS, output.tangentWS) * input.tangentTS.w; //乘上input.tangentTS.w 是unity引擎的bug,有的模型是 1 有的模型是 -1,必须这么写output.posVS = TransformWorldToView(output.posWS);return output;
}
#endif
#ifndef _CUSTOM_TESSELLATION_INCLUDED
#define _CUSTOM_TESSELLATION_INCLUDED// Tessellation programs based on this article by Catlike Coding:
// https://catlikecoding.com/unity/tutorials/advanced-rendering/tessellation/
// 关于参数的详细说明
// https://zhuanlan.zhihu.com/p/479792793#include "Assets/TA/ShaderLib/HlslInclude/CommonHlslInc.hlsl"//细分切割函数对于每个面片调用一次,对于每一个面片,比如三角形:每条边需要一个切割因子,内部需要一个切割因子
struct TessellationFactors {float edge[3] : SV_TessFactor; // 对应三条边的切割因子float inside : SV_InsideTessFactor; // 对应内部的切割因子
};float4 _TessellationUniform; // 细分因子,当值为1时不发生细分切割。因子可以分别设置,比如边因子是1内部因子是5,那就不会在边上生成顶点,会在中心生成五个顶点
//自定义的细分切割方法,每个面片调用一次
TessellationFactors patchConstantFunction (InputPatch<MeshData, 3> patch)
{TessellationFactors f;f.edge[0] = _TessellationUniform.x;f.edge[1] = _TessellationUniform.y;f.edge[2] = _TessellationUniform.z;f.inside = _TessellationUniform.w;return f;
}#endif
在unity中配置天空盒,适当设置后处理后,效果大致如下:
天空盒资源可以去这个网站下载:HDRIs • Poly Haven
相关文章:

Unity URP PBR_Cook-Torrance模型
Cook-Torrance模型是一个微表面光照模型,认为物体的表面可以看作是由许多个理想的镜面反射体微小平面组成的。 单点反射镜面反射漫反射占比*漫反射 漫反射 基础色/Π 镜面反射DFG/4(NV)(NL) D代表微平面分布函数,描述的是法线与半角向量normalize(L…...

Unity之XR Interaction Toolkit如何在VR中实现渐变黑屏效果
前言 做VR的时候,有时会有跳转场景,切换位置,切换环境,切换进度等等需求,此时相机的画面如果不切换个黑屏,总会感觉很突兀。刚好Unity的XR Interaction Toolkit插件在2.5.x版本,出了一个TunnelingVignette的效果,我们今天就来分析一下他是如何使用的,然后我们自己再来…...

html+vue编写分页功能
效果: html关键代码: <div class"ui-jqgrid-resize-mark" id"rs_mlist_table_C87E35BE"> </div><div class"list_component_pager ui-jqgrid-pager undefined" dir"ltr"><div id"pg…...

计算机网络 实验指导 实验17
实验17 配置无线网络实验 1.实验拓扑图 Table PC0 和 Table PC1 最开始可能还会连Access Point0,无影响后面会改 名称接口IP地址网关地址Router0fa0/0210.10.10.1fa0/1220.10.10.2Tablet PC0210.10.10.11Tablet PC1210.10.10.12Wireless互联网220.10.10.2LAN192.16…...

在 Vue中,v-for 指令的使用
在 Vue中,v-for 指令用于渲染一个列表,基于源数据多次渲染元素或模板块。它对于展示数组或对象中的数据特别有用。 数组渲染 假设你有一个数组,并且你想为每个数组元素渲染一个 <li> 标签: <template> <ul>…...

达梦数据库执行sql报错:数据溢出
数据库执行sql报错数据溢出 单独查询对应的数字进行计算是不是超过了某个字段类型的上限或下限 如果已经超过了,进行对字段进行cast类型转换处理,转换为dec num都可以尝试 这里就是从 max(T.BLOCK_ID as dec*8192t.bytes)/1024/1024 max_MB,换成了这个…...

从「宏大叙事」到「生活叙事」,小红书品牌种草的的“正确姿势”
不同于抖音和微博,在小红书上,品牌营销的基调应该是怎样的?品牌怎样与小红书用户对话?什么样的内容,才能走进小红书用户的心中?本期,小编将带大家洞察品牌在小红书营销的“正确姿势”。从「小美…...

Python Selenium 的基本使用方法
文章目录 1. 概述2. 安装Chrome及ChromeDriver2.1 安装Chrome2.2 安装ChromeDriver 3. 安装Selenium4. 常见用法4.1 启动4.2 查找元素4.3 等待页面加载元素 1. 概述 Selenium 是一个用于自动化 web 浏览器的工具,它提供了一套用于测试 web 应用程序的工具和库。Sel…...

上位机图像处理和嵌入式模块部署(树莓派4b固件功能设计)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们说过,上位机的功能都是基于插件进行开发的。但是上位机的成本比较贵,一般的企业不一定愿意接接受。这个时候另外一…...

新手入门人工智能:从零开始学习AI的正确途径
你是否对人工智能(AI)充满了好奇心和探索欲?你是否想了解如何从零开始学习AI,成为一名人工智能领域的专家?那么,这篇文章就是为你准备的!我们将带你了解人工智能的基本概念,学习如何…...

ubuntu git相关操作
1 安装git sudo apt install git git --version git version 2.25.1 2 解决git超时 2.1 扩大post的buffer git config --global http.postBuffer 524288000 git config --global http.postBuffer 157286400 2.2 换回HTTP1上传。上传之后再切换回HTTP2 …...

IDEA工具|添加 GitLab 账户之两三事
📫 作者简介:「六月暴雪飞梨花」,专注于研究Java,就职于科技型公司后端工程师 🏆 近期荣誉:华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 🔥 三连支持:欢迎 ❤️关注…...

蓝桥杯:棋盘(Java)
目录 问题描述输入格式输出格式代码实现 问题描述 小蓝拥有n n大小的棋盘,一开始棋盘上全都是白子。小蓝进行了m.次操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反(也就是白色棋子变为黑色,黑色棋子变为白色)。请输出所…...

跨界融合:ERP与TMS的区分、相通之处、融合方式,全告诉你。
Hi,如今系统的边界越来越模糊,A系统和B系统会有一些功能的交叉,贝格前端工场今天开始介绍第二篇ERP和TMS的融合。 一、什么是ERP和TMS ERP是企业资源规划(Enterprise Resource Planning)的缩写,是一种集成…...

SAP Smartform转存PDF方法汇总
用户会有保存SF至本地PDF文件的需求,下面详细说明一下Smartform转成PDF的四种方法,其中,方法二和三相比于其他方法更便捷实用,如果还有其他方法,欢迎留言补充。 一、代码开发 1)先调用smartform函数获取OTF格式数据 2)后调用函数CONVERT_OTF转换成PDF格式数据 3)再…...

Linux【实战篇】—— NFS服务搭建与配置
目录 一、介绍 1.1什么是NFS? 1.2客户端与服务端之间的NFS如何进行数据传输? 1.3RPC和NFS的启动顺序 1.4NFS服务 系统守护进程 二、安装NFS服务端 2.1安装NFS服务 2.2 创建共享目录 2.3创建共享目录首页文件 2.4关闭防火墙 2.5启动NFS服务 2.…...

Edge的使用心得与深度探索
Microsoft Edge 是微软推出的一款网页浏览器,基于 Chromium 开源项目开发。从 2020 年开始,Edge 浏览器经历了一次重大更新,采用了与 Google Chrome 相同的浏览器引擎,这使得它在性能、兼容性和扩展支持方面都得到了显著改善。以下…...

逆向案例二十八——红某点集登录接口逆向序
网址:aHR0cHM6Ly93d3cuaHJkanl1bi5jb20vIy9sb2dpbj9yZWRpcmVjdD0lMkZyZWFsVGltZUxpdmluZw 登录接口,发现两个参数加密,分别是pwd和sig,t很明显是时间戳。 观察pwd,发现很像md5加密,我输入的密码是123456,在在线加密网…...

我的创作纪念日20240418
机缘 我的技术博客起源于对编程的深深热爱和对知识的渴望。从一开始,我就被编程世界的无限可能所吸引,而这种热情也推动我开始了技术创作之旅。我创建博客的初衷有以下几点: 分享实战经验:在工作中,我遇到了许多技术…...

计算机视觉入门
计算机视觉是人工智能的一个分支,它涉及研究如何使计算机能够理解和解释图像和视频中的视觉信息。这个领域结合了计算机科学、工程学、神经科学和认知科学等多个学科的知识。以下是计算机视觉入门的一些关键点: 1. 基础概念 - **图像处理**:对…...

CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀)
CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀) 文章目录 CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀)前端验证—MIME绕过有关MIMEMIME的作用 解题时有…...

Java面试题笔记(持续更新)
Java基础 java中的Math.round(-1.5)等于多少? Math的round方法是四舍五入,如果参数是负数,则往大的数如,Math.round(-1.5)-1,如果是Math.round(1.5)则结果为2 JDK和JRE的区别? JDK 是 Java Development ToolKit 的简称,也就是…...

格式化字符串漏洞学习笔记
简单介绍 格式化字符串漏洞和栈溢出有相似之处,但又有所不同,都是利用了程序员的疏忽大意来改变程序运行的正常流程。 1、格式化字符串的介绍 printf()、fprint()等print()系列的函数可以按照一定的格式将数据进行输出。 实例…...

用友NC avatar接口文件上传漏洞
产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。 漏洞介绍 用友 NC avatar接口处…...

【Go语言快速上手(二)】 分支与循环函数讲解
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:Go语言专栏⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学习更多Go语言知识 🔝🔝 Go快速上手 1. 前言2. 分支与循环2.1…...

动手写sql 《牛客网80道sql》
第1章:SQL编写基础逻辑和常见问题 基础逻辑 SELECT语句: 选择数据表中的列。FROM语句: 指定查询将要从哪个表中检索数据。WHERE语句: 过滤条件,用于提取满足特定条件的记录。GROUP BY语句: 对结果进行分组。HAVING语句: 对分组后的结果进行条件过滤。O…...

Node.js、Java、Python、PHP在构建BS系统时的特点比较
在现代软件开发领域,构建一个稳定、高效的B/S(浏览器/服务器)系统对于企业的信息化发展至关重要。Node.js、Java、Python和PHP是当下流行的几种后端开发技术,它们各自具有独特的特点和优势。本文将对这几种技术在构建B/S系统时的特…...

快速入门深度学习9.1(用时20min)——GRU
速通《动手学深度学习》9.1 写在最前面九、现代循环神经网络9.1 门控循环单元(GRU)9.1.1. 门控隐状态9.1.1.1. 重置门和更新门9.1.1.2. 候选隐状态9.1.1.3. 隐状态 9.1.3 API简洁实现小结 🌈你好呀!我是 是Yu欸 🌌 20…...

基于51单片机的步进电机调速系统设计
基于51单片机的步进电机调速系统 (仿真+程序+原理图+设计报告) 功能介绍 具体功能: 1.按键可以控制电机正、反转,加、减速,停止; 2.一位7段数码管实时显示档位…...

postcss概述
PostCSS是一个用于转换CSS的工具,它使用插件来处理CSS,并提供了一种方式来编写可扩展的CSS代码。其主要特点如下: 插件驱动:PostCSS的核心非常轻量级,大部分功能都是通过插件来实现的。这意味着用户可以根据项目的需求…...