【Unity Shader】浅析Unity shader中RenderType的作用及_CameraDepthNormalsTexture

Unity shader之RenderType的应用 阅读详情
初学Unity ShaderLab的时候,一定有接触过Unity Shader中的Tags标签块,比如:
在CODE上查看代码片派生到我的代码片
        "LightMode"="Vertex"  
        "Queue"="Transparent"   
        "IgnoreProjector"="True"   
        "RenderType"="Transparent"   
        "PreviewType"="Plane" 

其中LightMode标签指定该pass的渲染路径,Queue指定渲染顺序,IgnoreProjector指定是否忽略Projector的影响,PreviewType一般用于UIshader,PreviewType=Plane的话在材质面板看到的就是一个平面而不是材质球。

但是很多人对RenderType的了解可能相比其他标签要稍微淡薄一些,只知道比如渲染不透明物体使用Opaque,渲染透明物体使用Transparent等,而官网上有提到RenderType会用于材质替代渲染(RenderWithShader   SetReplacementShader),但究竟是如何去使用的,今天我总结下自己的理解。


首先,关于材质替代渲染,其主要就是Camera类的两个函数SetReplacementShader和RenderWithShader,其形参完全一样,第一个参数是用于替代的shader,以下记为RPShader,后一个参数是个字符串,表示用于替代的标签,包括自定义标签,以下记为mType,也就是假如我们调用SetReplacementShader(RPShader,"mType"),这个摄像机会检查所有渲染到的物体的shader,检查其是否包含mType标签,如果不存在则这个物体将不渲染,如果存在,在看这个标签的值,假如"mType"="A",则在RPShader中找到"mType"="A"的subshader并用它来替代这个物体,假如RPShader中不包含"mType"="A"的标签,那么这个物体也不会渲染。


接下来,我们需要去unity的内置shader中找一个shader,(内置shader请去官网下载源码)。

我们找到内置shader源码路径下这个文件夹:\DefaultResources,在里面可以找到这个shader:Camera-DepthNormalTexture.shader,(PS:5.x之前的版本还能找到Camera-DepthTexture.shader,从内容上看,其似乎会在UNITY_MIGHT_NOT_HAVE_DEPTH_TEXTURE这个宏条件成立的情况下渲染深度,之前尝试使用这个shader做替代渲染但没有成功得到和_CameraDepthTexture一样的效果,后来官网上看到这句:

    UNITY_MIGHT_NOT_HAVE_DEPTH_TEXTURE - defined if a platform might emulate shadow maps or depth textures by manually rendering depth into a texture.

不过在5.x新特性中可以看到这个内容:

所以5.x中我们已经找不到Camera-DepthTexture.shader这个shader了)

(补充:后来在5.x中研究了_CameraDepthTexture的渲染,写到这篇文章里了:http://blog.youkuaiyun.com/mobilebbki399/article/details/50559732)


打开Camera-DepthNormalTexture.shader,其内容如下:
在CODE上查看代码片派生到我的代码片
    Shader "Hidden/Camera-DepthNormalTexture" {  
    Properties {  
        _MainTex ("", 2D) = "white" {}  
        _Cutoff ("", Float) = 0.5  
        _Color ("", Color) = (1,1,1,1)  
    }  
      
    SubShader {  
        Tags { "RenderType"="Opaque" }  
        Pass {  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    struct v2f {  
        float4 pos : SV_POSITION;  
        float4 nz : TEXCOORD0;  
    };  
    v2f vert( appdata_base v ) {  
        v2f o;  
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    fixed4 frag(v2f i) : SV_Target {  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }  
      
    SubShader {  
        Tags { "RenderType"="TransparentCutout" }  
        Pass {  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    struct v2f {  
        float4 pos : SV_POSITION;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
    uniform float4 _MainTex_ST;  
    v2f vert( appdata_base v ) {  
        v2f o;  
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    uniform sampler2D _MainTex;  
    uniform fixed _Cutoff;  
    uniform fixed4 _Color;  
    fixed4 frag(v2f i) : SV_Target {  
        fixed4 texcol = tex2D( _MainTex, i.uv );  
        clip( texcol.a*_Color.a - _Cutoff );  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }  
      
    SubShader {  
        Tags { "RenderType"="TreeBark" }  
        Pass {  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "Lighting.cginc"  
    #include "UnityBuiltin3xTreeLibrary.cginc"  
    struct v2f {  
        float4 pos : SV_POSITION;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
    v2f vert( appdata_full v ) {  
        v2f o;  
        TreeVertBark(v);  
          
        o.pos = mul( UNITY_MATRIX_MVP, v.vertex );  
        o.uv = v.texcoord.xy;  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    fixed4 frag( v2f i ) : SV_Target {  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }  
      
    SubShader {  
        Tags { "RenderType"="TreeLeaf" }  
        Pass {  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "Lighting.cginc"  
    #include "UnityBuiltin3xTreeLibrary.cginc"  
    struct v2f {  
        float4 pos : SV_POSITION;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
    v2f vert( appdata_full v ) {  
        v2f o;  
        TreeVertLeaf(v);  
          
        o.pos = mul( UNITY_MATRIX_MVP, v.vertex );  
        o.uv = v.texcoord.xy;  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    uniform sampler2D _MainTex;  
    uniform fixed _Cutoff;  
    fixed4 frag( v2f i ) : SV_Target {  
        half alpha = tex2D(_MainTex, i.uv).a;  
      
        clip (alpha - _Cutoff);  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }  
      
    SubShader {  
        Tags { "RenderType"="TreeOpaque" "DisableBatching"="True" }  
        Pass {  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "TerrainEngine.cginc"  
    struct v2f {  
        float4 pos : SV_POSITION;  
        float4 nz : TEXCOORD0;  
    };  
    struct appdata {  
        float4 vertex : POSITION;  
        float3 normal : NORMAL;  
        fixed4 color : COLOR;  
    };  
    v2f vert( appdata v ) {  
        v2f o;  
        TerrainAnimateTree(v.vertex, v.color.w);  
        o.pos = mul( UNITY_MATRIX_MVP, v.vertex );  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    fixed4 frag(v2f i) : SV_Target {  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }   
      
    SubShader {  
        Tags { "RenderType"="TreeTransparentCutout" "DisableBatching"="True" }  
        Pass {  
            Cull Back  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "TerrainEngine.cginc"  
      
    struct v2f {  
        float4 pos : SV_POSITION;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
    struct appdata {  
        float4 vertex : POSITION;  
        float3 normal : NORMAL;  
        fixed4 color : COLOR;  
        float4 texcoord : TEXCOORD0;  
    };  
    v2f vert( appdata v ) {  
        v2f o;  
        TerrainAnimateTree(v.vertex, v.color.w);  
        o.pos = mul( UNITY_MATRIX_MVP, v.vertex );  
        o.uv = v.texcoord.xy;  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    uniform sampler2D _MainTex;  
    uniform fixed _Cutoff;  
    fixed4 frag(v2f i) : SV_Target {  
        half alpha = tex2D(_MainTex, i.uv).a;  
      
        clip (alpha - _Cutoff);  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
        Pass {  
            Cull Front  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "TerrainEngine.cginc"  
      
    struct v2f {  
        float4 pos : SV_POSITION;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
    struct appdata {  
        float4 vertex : POSITION;  
        float3 normal : NORMAL;  
        fixed4 color : COLOR;  
        float4 texcoord : TEXCOORD0;  
    };  
    v2f vert( appdata v ) {  
        v2f o;  
        TerrainAnimateTree(v.vertex, v.color.w);  
        o.pos = mul( UNITY_MATRIX_MVP, v.vertex );  
        o.uv = v.texcoord.xy;  
        o.nz.xyz = -COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    uniform sampler2D _MainTex;  
    uniform fixed _Cutoff;  
    fixed4 frag(v2f i) : SV_Target {  
        fixed4 texcol = tex2D( _MainTex, i.uv );  
        clip( texcol.a - _Cutoff );  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
      
    }  
      
    SubShader {  
        Tags { "RenderType"="TreeBillboard" }  
        Pass {  
            Cull Off  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "TerrainEngine.cginc"  
    struct v2f {  
        float4 pos : SV_POSITION;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
    v2f vert (appdata_tree_billboard v) {  
        v2f o;  
        TerrainBillboardTree(v.vertex, v.texcoord1.xy, v.texcoord.y);  
        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);  
        o.uv.x = v.texcoord.x;  
        o.uv.y = v.texcoord.y > 0;  
        o.nz.xyz = float3(0,0,1);  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    uniform sampler2D _MainTex;  
    fixed4 frag(v2f i) : SV_Target {  
        fixed4 texcol = tex2D( _MainTex, i.uv );  
        clip( texcol.a - 0.001 );  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }  
      
    SubShader {  
        Tags { "RenderType"="GrassBillboard" }  
        Pass {  
            Cull Off          
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "TerrainEngine.cginc"  
      
    struct v2f {  
        float4 pos : SV_POSITION;  
        fixed4 color : COLOR;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
      
    v2f vert (appdata_full v) {  
        v2f o;  
        WavingGrassBillboardVert (v);  
        o.color = v.color;  
        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);  
        o.uv = v.texcoord.xy;  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    uniform sampler2D _MainTex;  
    uniform fixed _Cutoff;  
    fixed4 frag(v2f i) : SV_Target {  
        fixed4 texcol = tex2D( _MainTex, i.uv );  
        fixed alpha = texcol.a * i.color.a;  
        clip( alpha - _Cutoff );  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }  
      
    SubShader {  
        Tags { "RenderType"="Grass" }  
        Pass {  
            Cull Off  
    CGPROGRAM  
    #pragma vertex vert  
    #pragma fragment frag  
    #include "UnityCG.cginc"  
    #include "TerrainEngine.cginc"  
    struct v2f {  
        float4 pos : SV_POSITION;  
        fixed4 color : COLOR;  
        float2 uv : TEXCOORD0;  
        float4 nz : TEXCOORD1;  
    };  
      
    v2f vert (appdata_full v) {  
        v2f o;  
        WavingGrassVert (v);  
        o.color = v.color;  
        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);  
        o.uv = v.texcoord;  
        o.nz.xyz = COMPUTE_VIEW_NORMAL;  
        o.nz.w = COMPUTE_DEPTH_01;  
        return o;  
    }  
    uniform sampler2D _MainTex;  
    uniform fixed _Cutoff;  
    fixed4 frag(v2f i) : SV_Target {  
        fixed4 texcol = tex2D( _MainTex, i.uv );  
        fixed alpha = texcol.a * i.color.a;  
        clip( alpha - _Cutoff );  
        return EncodeDepthNormal (i.nz.w, i.nz.xyz);  
    }  
    ENDCG  
        }  
    }  
    Fallback Off  
    }  

(PS:顺便可以注意一下这个shader的完整路径名前面包括一个Hidden,当然你也可以这么给你的shader写上这个,这意味着你的shader在材质面板的shader选择界面中是隐藏的,unity很多内置的特殊功能的shader都使用了这个前缀路径,包括我们最熟悉的粉红色ErrorShader ^_^)

接下来讲解这个内置的Camera-DepthNormalTexture.shader,注意这个shader包含了很多SubShader,其中几乎包含了所有我们熟知的RenderType,不过没有Transparent,这个shader的主要作用就是当我们开启摄像机的DepthTextureMode为DepthNormals时该摄像机会使用这个shader以及"RenderType"这个标签做替代渲染,也就是SetReplacementShader(Camera-DepthNormalTexture,"RenderType"),刚刚有提过,只有被替代的shader中包含RenderType标签,且这个标签的值在替代的shader中存在,才会用这个SubShader去替代,显然RenderType=Transparent的标签在这个Camera-DepthNormalTexture.shader中并不存在。

当然_CameraDepthNormalsTexture我们知道其存储的内容是法线和深度,UnityCG.cginc文件中有定义两个函数,EncodeDepthNormal和DecodeDepthNormal用于对法线和深度进行编码和解码,我们已经看到在Camera-DepthNormalTexture.shader中的SubShader都是输出经过EncodeDepthNormal的深度和法线,其法线会被编码到xy分量,深度编码到zw分量。所以使用的时候需要通过DecodeDepthNormal将其解码。

以下是我尝试直接用这个shader做替代渲染的结果:

如下,一图是原始图像,二图是直接输出_CameraDepthNormalsTexture的结果,三图是我直接做替代渲染后得到的结果:

可以看到直接替代渲染和_CameraDepthNormalsTexture的内容是一样的,证明unity中_CameraDepthNormalsTexture是通过这个shader及RenderType标签做替代渲染得到的,其中RenderType=Transparent的物体并没有被写入_CameraDepthNormalsTexture,而RenderType=TransparentCutout的物体被裁切的地方也不会写入_CameraDepthNormalsTexture。

接下来尝试将两张图解码获取深度图:

以下一图是原始图像,二图是直接输出_CameraDepthTexture,三图是输出Linear01Depth(tex2D(_CameraDepthTexture,i.uv).r),四图是输出经过Decode解码的_CameraDepthNormalsTexture的深度,五图是输出我直接替代渲染后并经过Decode解码的深度:


可以注意到三、四、五这三张图的颜色范围相近,也就是说_CameraDepthNormalsTexture中存的深度值是在eye到farClipPlane之间范围为0-1的,通过Linear01Depth函数将_CameraDepthTexture转换后输出的也是这个结果(图三)。

不过注意图三会发现第五个shader,其RenderType=Opaque的物体并没有被写入_CameraDepthTexture,虽然上图是在测试的时候关闭了它的zwrite,但实际上开启zwrite得到的也是这个效果,这是因为这个shader其内容只包含一个RenderType=Opaque的pass,是从Unlit shader的基础上修改的,之前有提到过_CameraDepthTexture在5.x中似乎不再是通过替代渲染得到了,而_CameraDepthNormalsTexture貌似还是替代渲染获得的,所以图四和图五这个shader显示都是正常的,同样是在无论zwrite是否开启的情况下。

最后一个,就是注意到我的最后一个物体的shader其RenderType=Opaque,但是zwrite off,也就是说不会写入深度缓存,但因为其RenderType=Opaque的,所以对于_CameraDepthNormalsTexture其还是未关闭写入的。

以上就是经过试验得出的结论,希望对你理解RenderType的作用有所帮助。
原文地址:http://blog.youkuaiyun.com/mobilebbki399/article/details/50512059
Shader 学习笔记(11) RenderType为Transparent的混合透明 透明度混合可以实现真正的透明,本例中采用的混合方式为Blend SrcAlpha OneMinusSrcAlpha.Blend命令后接着写入不同的混合方式.混合方式有多种组合(后续单独写一篇).SrcAlpha OneMinusSrcAlpha的混合后效果的公式为Shader "wx/AlphaBlendMat"{ Properties{ _Color("Main Tint",Color)=... 阅读详情

相关推荐

Unity-URP 动态设置Camera.Rendering的参数

/URP中的摄像机参数基本会使用该API来修改。

枫叶的博客 2437

unity shader之基础 一二三:渲染简介

一:渲染流水线: 应用阶段:主要在CPU执行,准备好需要渲染的数据,输出渲染图元 几何阶段:在GPU执行,主要处理顶点的坐标空间转换,把这些处理过的数据传递给下一阶段 光栅化阶段:在GPU执行,对上一阶段产生的数据,进行着色,最终输出到屏幕上 由于顶点数量要远小于片元数量的,所以一个片元的颜色、深度等,是对顶点进行线性插值得到的 裁剪:把不在摄像机视野内的顶点裁剪掉 三角形设置:根据顶点数据,生成三角形数据 三角形遍历:根据像素和三角形的覆盖情况,获取片元 片元着色器:进行着色 逐片元

qq_37672438的博客 1214

Unity渲染管线与Shader面试核心:从原理到实战的深度解析

图形渲染管线是计算机图形学的核心概念,它定义了从三维场景数据到最终屏幕像素的完整处理流程。其基本原理包括应用阶段的数据准备、几何阶段的坐标变换、光栅化阶段的像素转换以及逐片段操作的颜色混合与测试。理解渲染管线的价值在于能够针对不同硬件平台和应用场景(如移动端、PC游戏、VR应用)进行性能优化与效果定制。在Unity引擎中,开发者需要在前向渲染与延迟渲染之间做出关键抉择,这直接关系到项目的性能表现与视觉效果实现。本文聚焦于Unity面试中的高频考点,深入探讨渲染管线实现、Shader优化策略以及卡通渲染等实战

weixin_30667649的博客 368

【Unity Shader】Shadow Caster、RenderType和_CameraDepthTexture

在做很多效果的时候我们需要使用_CameraDepthTexture和_CameraDepthNormalsTexture,其中_CameraDepthTexture存储的是屏幕深度信息,而_CameraDepthNormalsTexture存储的还包括法线信息,常会用到的情况,比如做景深效果,我们需要根据深度来对模糊的图像和正常的图像插值完成景深效果,或者软粒子效果,需要根据深度差判断粒子网格是

MrASL的博客 1万+

Unity渲染顺序深度解析:RenderQueue核心原理与五大实战应用

在计算机图形学中,渲染顺序是决定像素最终颜色的关键机制,它直接影响了视觉正确性与渲染性能。其核心原理在于GPU必须按序执行绘制命令,而深度测试与混合等管线状态决定了像素的写入与合成方式。掌握渲染顺序的技术价值在于,开发者可以精准控制物体间的遮挡与混合关系,从而解决透明物体错乱、UI融合等视觉顽疾,并有效优化性能减少过度绘制。这一技术广泛应用于游戏UI与3D场景的融合、多层透明特效的正确呈现、角色描边高亮、渲染性能优化以及自定义后处理效果等场景。本文聚焦Unity引擎中的RenderQueue,这一底层调度指

weixin_30698297的博客 467

深度剖析URP渲染管线:解决材质消失与深度测试失效的DepthOnlyPass缺失问题

在现代实时渲染管线中,深度缓冲(Z-Buffer)是决定像素可见性的核心技术,它通过深度测试机制高效解决物体间的遮挡关系。其原理是在渲染颜色前,先将场景中物体的深度信息写入专门的缓冲区,后续渲染时通过比较深度值来丢弃被遮挡的片元,从而大幅减少过度绘制(Overdraw),提升渲染性能。这一机制在Unity通用渲染管线(URP)中通过深度预渲染阶段实现,其技术价值在于为屏幕空间后处理效果(如SSAO、景深)提供准确的深度图,并确保复杂场景中渲染顺序的正确性。当自定义Shader缺失关键的DepthOnlyPa

weixin_34208283的博客 436

Unity描边Shader实战:从背面膨胀到屏幕后处理,彻底掌握轮廓渲染

在计算机图形学中,轮廓渲染(Outline Rendering)是一种用于突出物体边缘、增强视觉层次的核心技术。其基本原理是通过检测物体表面在深度、法线或颜色上的不连续性,来识别并高亮显示边界区域。这项技术的核心价值在于能显著提升场景的可读性和视觉表现力,广泛应用于游戏角色高亮、交互反馈、卡通渲染(Cel-Shading)以及各类风格化视觉特效中。从实现层面看,主要分为物体空间法(如背面膨胀)和屏幕空间后处理法两大流派。前者通过沿法线挤出模型背面实现,适合快速原型和单个物体突出;后者基于深度/法线纹理进行边

weixin_30321449的博客 350

MATLAB自动驾驶(1)——预构建场景库

MATLAB自动驾驶(1)——预构建场景库

Ucicorn Gundam的博客 3265

Unity深度特效开发全流程:从深度纹理获取到Shader优化实战

深度缓冲是计算机图形学中记录像素到相机距离的核心数据结构,它通过存储每个像素的深度值来实现遮挡检测和三维空间感知。其工作原理是在渲染管线中,将物体顶点变换到裁剪空间后,通过深度测试决定像素的可见性。深度信息的技术价值在于为屏幕空间特效提供了关键的几何数据,是实现景深、体积雾、边缘光等高级视觉效果的基础。在游戏开发与实时渲染的应用场景中,深度纹理的获取、解码与空间重建是高频技术难点。本文聚焦Unity引擎,针对深度纹理的精度处理、世界空间位置重建以及特效Shader编写中的常见问题,提供系统性的解决方案与性能

weixin_34341117的博客 358

最短线性递推式求解与有理函数重建

这一算法来自于我们对“线性递推式拟合”的视角转换,其后得到的算法是自然的。 引理 1. 如果两个有理分式 p1/q1,p2/q2p_1/q_1, p_2/q_2p1​/q1​,p2​/q2​ 均有 deg⁡p<n,deg⁡q≤n\deg p<n, \deg q\leq ndegp<n,degq≤n 且展开式 p1/q1≡p2/q2(modx2n)p_1/q_1 \equiv p_2/q_2 \pmod {x^{2n}}p1​/q1​≡p2​/q2​(modx2n),那么 p1/q1=p2/

Entropy Increaser 的博客 2589

深入解析Lora SX1268:从基础配置到高级应用

本文深入解析了LoRa SX1268芯片从基础配置到高级应用的全过程。详细介绍了LoRa与FSK模式选择、核心参数(BW、SF、CR、LDRO)的配置策略、数据帧结构、缓冲区管理以及CAD模式等关键概念,旨在帮助开发者充分发挥SX1268在远距离、低功耗物联网通信中的潜力,并提供实用的调试技巧。

weixin_29168393的博客 116

Unity Sprite Shaders 全功能解析:Spine 精灵 Uber Shader 的照明、混合与渲染原理

本文是 spine-runtimes 仓库中 [Sprite 目录 README](https://link.gitcode.com/i/090ecaf7be2734978228b468e848a7bd) 的技术解读与源码级展开。Spine Unity 运行时内置了一套专门为 Sprite 渲染优化的 Uber Shader(一套 shader 通过开关组合覆盖多种渲染需求),支持 Forward

gitblog_00193的博客 172

从解压到编译:手把手带你用TeXstudio搞定第一篇ACM LaTeX论文

本文详细指导如何使用TeXstudio从解压ACM LaTeX模板到成功编译第一篇学术论文的全过程。涵盖环境准备、模板配置、TeXstudio设置及常见问题排查,特别针对ACM会议论文格式要求,帮助学术新人快速掌握LaTeX写作技巧。

weixin_30655569的博客 254

Unity屏幕空间物体描边与幽灵遮挡后处理实现

屏幕空间描边是游戏开发中常见的目标高亮技术,但物体被障碍物遮挡时如何提示玩家位置则更具挑战。借助Unity后处理管线中的深度法线纹理,可以检测场景几何边缘,再结合目标物体的独立深度渲染,能够同时实现可见物体的轮廓描边与遮挡物体的幽灵透视效果。该方案不依赖模型额外顶点数据,只需在主相机挂载脚本并配合两个Shader,即可通过Layer统一控制多个目标,适用于任务指引、战术指示器、解谜高亮等批量标记场景。相比逐物体编写材质,统一的后处理流程在性能和维护成本上更优,尤其适合需要灵活切换目标或大面积部署的队伍协作玩

weixin_33924312的博客 413

从一个过气考渣的角度看LLM智能化测试用例生成

根据业务需求生成测试用例,会涉及到相关上下文的召回、用例生成等场景。除了用例生成之外,也可以考虑应用LLM进行用例评审。因此,本文将涉及以下内容。

software_test010的博客 827

别再手动算电阻了!手把手教你从ITF/IRCX文件自动生成EMX工艺文件(附脚本思路)

本文详细介绍了如何从ITF/IRCX文件自动生成EMX工艺文件,提升芯片设计效率。通过解析厚度变化多项式和电阻率查表,实现工艺文件的高效转换,避免手动处理带来的错误。文章还提供了脚本思路和验证方法,确保数据精确度,特别适用于电感仿真等关键环节。

didui8202的博客 454

Unity模型描边方案全解析:Shader、后处理与代码生成对比

在实时渲染中,轮廓描边是卡通风格和物体高亮的常见需求,其本质是提取屏幕空间或几何空间的视觉边界。Unity提供了多种描边实现路径:基于顶点法线外扩的Shader方案通过背面渲染生成轮廓,性能出色但受法线质量影响;屏幕空间后处理利用深度法线检测边缘,风格统一但开销较高;GL绘制及CPU网格生成则适合调试和精确控制。理解不同方案的原理、性能代价与平台适配,能帮助开发者根据模型复杂度、目标平台及美术风格做出合理选型。本文结合实际案例,对比分析各类Unity描边方法的优劣与工程坑点,为渲染技术选型提供参考。

weixin_34242509的博客 338

第八章 GPU Scheduler 分析:8.3 drm_sched_entity — 调度实体

本文介绍了DRM GPU调度器中的drm_sched_entity结构,它作为用户提交命令进入调度器的提交通道,解决了归属、排序和公平性问题。文章首先分析了命令提交的归属需求,然后详细阐述了entity的核心模型,包括其职责、进程映射关系和核心字段。接着说明了用户态提交进入内核后的关键节点路径,以及entity内部的FIFO语义和激活机制。entity通过组织同一context的命令提交包为FIFO队列,使调度器能够在多个entity之间进行优先级和公平性调度,同时保证同一提交通道的顺序执行。

图形/计算GPU的驱动与虚拟化技术分享园地 643

Unity模型描边方案全解析:Shader、后处理与轮廓网格对比

在Unity游戏开发中,描边技术常用于角色轮廓、选中反馈和风格化渲染。其实现原理涉及顶点法线外扩、深度法线边缘检测、模板缓冲以及网格生成等多种技术路径。不同方案的性能开销、效果稳定性和适用场景差异显著,直接影响移动端表现与美术效果。理解各方案的底层机制,有助于开发者根据目标设备与需求做出合理选型,并规避描边断裂、穿模、闪烁等常见问题。从通用技术概念出发,全面对比常用描边实现方式,并给出工程实践建议。

weixin_34301132的博客 331

【AI应用实战-claude】在飞书上接入claudecode进行远程使用(十三)

本文介绍了三种将ClaudeCode接入飞书的方案,包括官方飞书CLI工具(推荐)、cc-connect中转工具和MCP协议集成。官方飞书CLI适合自动化办公场景,通过简单配置即可实现消息发送和文档管理;cc-connect适用于远程调用Claude功能,通过飞书群聊触发响应;MCP协议则适合开发者构建复杂工作流。文章提供了详细的操作步骤,并针对不同使用场景给出了选择建议。

1008

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【Shader进阶】SubShader块标签Tags——RenderType

目录 目的:理解RenderType的作用 ,当初学习《Shader入门精要》时写有如下总结 使用替换的着色器渲染(官方解释) 一、 Camera.SetReplacementShader实战 二、Camera.SetReplacementShader总结 三、Camera.RenderWithShader实战 四、Camera.RenderWithShader总结 目的:理解Ren...

两水先木示的博客 2417

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Unity Shader学习六:渲染顺序与渲染控制指令

观前提示:本文章是个人笔记,只是给自己看的,我自己看得懂就行。

miwuwu的博客 1851

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

unity shader之 RenderType的作用

Tags{ “RenderType” = “Opaque” } 替换shader时候用的。 比如,你希望全场景的带某个标签的shader统一换了 Camera.SetPlacementShader(Shader1, “”); 这样就全部替换了 Camera.SetPlacementShader(Shader1, “RenderType”); 这样只替换RenderType的value一样的 Tags{ “RenderType”=“Opaque” "CheckRenderTypeTag=“On” } Came

游戏人生 2016
上一篇: 【Unity Shader】Shadow Caster、RenderType和_CameraDepthTexture
下一篇: Unity Shader-边缘光(RimLight)效果
cbbbc
博客等级 码龄15年 609粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值