【UnityShader】模板Stencil测试

2023-11-04

效果


原理
使用后处理,

在后处理阶段先渲染产生一张RenderTexture,包含要被描边的物体,使用描边色渲染。
高斯模糊RenderTexture,会产生边缘
用高斯模糊的图片反向剔除未模糊的图,这样只保留模糊多出的部分。
此时RenderTexture上为只有边缘的图,将此边缘图与渲染结果图进行混合并输出屏幕,即得到结果。
实现
OutLineCameraComponent.cs 挂载在摄像机下,赋值两个shader。

using UnityEngine;  
using System.Collections.Generic;
using UnityEngine.Rendering;  


[ExecuteInEditMode]
public class OutLineCameraComponent
{  
    private RenderTexture renderTexture = null;  
    private CommandBuffer commandBuffer = null;  

    [Header("Outline/OutLineEffect.shader")]
    public Shader preoutlineShader = null;  
   [Header("Outline/OutlinePrePass.shader")]
     public Shader shader = null;

    private Material _material = null;

    public Material mMaterial
    {
        get
        {
            if (_material == null)
                _material = GenerateMaterial(shader);
            return _material;
        }
    }

    [Header("采样范围")]
    public float samplerArea = 1;  


    [Header("降分辨率")]
    public int downSample = 1;  


    [Header("迭代次数")]
    public int iteration = 2;

    [Header("描边强度")]
    [Range(0.0f, 10.0f)]  
    public float outLineStrength = 3.0f;  

    //根据shader创建用于屏幕特效的材质
        protected Material GenerateMaterial(Shader shader)
        {
            if (shader == null)
                return null;

            if (shader.isSupported == false)
                return null;
            Material material = new Material(shader);
            material.hideFlags = HideFlags.DontSave;

            if (material)
                return material;

            return null;
        }


    //目标对象  
    private List<OutLineTargetComponent> targetObjects = new List<OutLineTargetComponent>();

    public void AddTarget(OutLineTargetComponent target)
    {
        if(target.material==null)
            target.material = new Material(preoutlineShader);
        targetObjects.Add(target);

        RefreshCommandBuff();

    }
    public void RemoveTarget(OutLineTargetComponent target)
    {
        bool found = false;

        for (int i = 0; i < targetObjects.Count; i++)
        {
            if (targetObjects[i] == target)
            {
                targetObjects.Remove(target);
                DestroyImmediate(target.material);
                target.material = null;
                found = true;
                break;
            }
        }

        if(found)
            RefreshCommandBuff();
    }

    public void RefreshCommandBuff()
    {
        if (renderTexture)  
            RenderTexture.ReleaseTemporary(renderTexture);  
        renderTexture = RenderTexture.GetTemporary(Screen.width >> downSample, Screen.height >> downSample, 0);  

        commandBuffer = new CommandBuffer();  
        commandBuffer.SetRenderTarget(renderTexture);  
        commandBuffer.ClearRenderTarget(true, true, Color.black);
        for (int i = 0; i < targetObjects.Count; i++)
        {
            Renderer[] renderers = targetObjects[i].GetComponentsInChildren<Renderer>();  
            foreach (Renderer r in renderers)
                commandBuffer.DrawRenderer(r, targetObjects[i].material);
        }
    }


   void OnEnable()  
    {  
        if (preoutlineShader == null)  
            return;  
        RefreshCommandBuff();
    }  

    void OnDisable()  
    {  
        if (renderTexture)  
        {  
            RenderTexture.ReleaseTemporary(renderTexture);  
            renderTexture = null;  
        }  

        if (commandBuffer != null)  
        {  
            commandBuffer.Release();  
            commandBuffer = null;  
        }  

    }  

    void OnRenderImage(RenderTexture source, RenderTexture destination)  
    {  
        if (mMaterial && renderTexture && commandBuffer != null)  
        {  
            Graphics.ExecuteCommandBuffer(commandBuffer);  

            //对RT进行Blur处理  
            RenderTexture temp1 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0);  
            RenderTexture temp2 = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0);  

            //高斯模糊,两次模糊,横向纵向,使用pass0进行高斯模糊  
            mMaterial.SetVector("_offsets", new Vector4(0, samplerArea, 0, 0));  
            Graphics.Blit(renderTexture, temp1, mMaterial, 0);  
            mMaterial.SetVector("_offsets", new Vector4(samplerArea, 0, 0, 0));  
            Graphics.Blit(temp1, temp2, mMaterial, 0);  

            //如果有叠加再进行迭代模糊处理  
            for(int i = 0; i < iteration; i++)  
            {  
                mMaterial.SetVector("_offsets", new Vector4(0, samplerArea, 0, 0));  
                Graphics.Blit(temp2, temp1, mMaterial, 0);  
                mMaterial.SetVector("_offsets", new Vector4(samplerArea, 0, 0, 0));  
                Graphics.Blit(temp1, temp2, mMaterial, 0);  
            }  

            //用模糊图和原始图计算出轮廓图
            mMaterial.SetTexture("_BlurTex", temp2);  
            Graphics.Blit(renderTexture, temp1, mMaterial, 1);  

            //轮廓图和场景图叠加  
            mMaterial.SetTexture("_BlurTex", temp1);  
            mMaterial.SetFloat("_OutlineStrength", outLineStrength);  
            Graphics.Blit(source, destination, mMaterial, 2);  

            RenderTexture.ReleaseTemporary(temp1);  
            RenderTexture.ReleaseTemporary(temp2);  
        }  
        else  
        {  
            Graphics.Blit(source, destination);  
        }  
    }  
}  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
OutLineTargetComponent.cs 挂载在要使用描边的物体上

using UnityEngine;

[ExecuteInEditMode]
public class OutLineTargetComponent : MonoBehaviour
{
    public Color color = Color.green;

    public Material material { set; get; }

    void OnEnable()
    {
        Camera[] allCameras = Camera.allCameras;
        for (int i = 0; i < allCameras.Length; i++)
        {
            if (allCameras[i].GetComponent<OutLineCameraComponent>()!=null)
            {
                allCameras[i].GetComponent<OutLineCameraComponent>().AddTarget(this);
            }
        }
    }

    private void Update()
    {
        if(material!=null)
            material.SetColor("_OutLineColor", color);  
    }

    void OnDisable()
    {
        Camera[] allCameras = Camera.allCameras;
        for (int i = 0; i < allCameras.Length; i++)
        {
            if (allCameras[i].GetComponent<OutLineCameraComponent>()!=null)
            {
                allCameras[i].GetComponent<OutLineCameraComponent>().RemoveTarget(this);
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
OutlinePrePass.shader

Shader "OutLine/OutlinePrePass"  
{
    SubShader  
    {
        Pass  
        {
            CGPROGRAM
            #include "UnityCG.cginc"  
            fixed4 _OutLineColor;

            struct v2f  
            {  
                float4 pos : SV_POSITION;  
            };  

            v2f vert(appdata_full v)  
            {  
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
                return o;  
            }

            fixed4 frag(v2f i) : SV_Target  
            {  
                return _OutLineColor;
            }  


            #pragma vertex vert  
            #pragma fragment frag  
            ENDCG  
        }  
    }  
}  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
OutLineEffect.shader

Shader "OutLine/OutLineEffect" {  

    Properties{  
        _MainTex("Base (RGB)", 2D) = "white" {}  
        _BlurTex("Blur", 2D) = "white"{}  
    }  

    CGINCLUDE  
    #include "UnityCG.cginc"  

    //用于剔除中心留下轮廓  
    struct v2f_cull  
    {  
        float4 pos : SV_POSITION;  
        float2 uv : TEXCOORD0;  
    };  

    //用于模糊  
    struct v2f_blur  
    {  
        float4 pos : SV_POSITION;  
        float2 uv  : TEXCOORD0;  
        float4 uv01 : TEXCOORD1;  
        float4 uv23 : TEXCOORD2;  
        float4 uv45 : TEXCOORD3;  
    };  

    //用于最后叠加  
    struct v2f_add  
    {  
        float4 pos : SV_POSITION;  
        float2 uv  : TEXCOORD0;  
        float2 uv1 : TEXCOORD1;  
    };  

    sampler2D _MainTex;  
    float4 _MainTex_TexelSize;  
    sampler2D _BlurTex;  
    float4 _BlurTex_TexelSize;  
    float4 _offsets;  
    float _OutlineStrength;  

    //获得轮廓 pass 1
    v2f_cull vert_cull(appdata_img v)  
    {  
        v2f_cull o;  
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
        o.uv = v.texcoord.xy;  
        //dx中纹理从左上角为初始坐标,需要反向  
#if UNITY_UV_STARTS_AT_TOP  
        if (_MainTex_TexelSize.y < 0)  
            o.uv.y = 1 - o.uv.y;  
#endif    
        return o;  
    }  

    fixed4 frag_cull(v2f_cull i) : SV_Target  
    {  
        fixed4 colorMain = tex2D(_MainTex, i.uv);  
        fixed4 colorBlur = tex2D(_BlurTex, i.uv);  
        return colorBlur - colorMain;  
    }  

    //高斯模糊 pass 0
    v2f_blur vert_blur(appdata_img v)  
    {  
        v2f_blur o;  
        _offsets *= _MainTex_TexelSize.xyxy;  
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
        o.uv = v.texcoord.xy;  

        o.uv01 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1);  
        o.uv23 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 2.0;  
        o.uv45 = v.texcoord.xyxy + _offsets.xyxy * float4(1, 1, -1, -1) * 3.0;  

        return o;  
    }  
    fixed4 frag_blur(v2f_blur i) : SV_Target  
    {  
        fixed4 color = fixed4(0,0,0,0);  
        color += 0.40 * tex2D(_MainTex, i.uv);  
        color += 0.15 * tex2D(_MainTex, i.uv01.xy);  
        color += 0.15 * tex2D(_MainTex, i.uv01.zw);  
        color += 0.10 * tex2D(_MainTex, i.uv23.xy);  
        color += 0.10 * tex2D(_MainTex, i.uv23.zw);  
        color += 0.05 * tex2D(_MainTex, i.uv45.xy);  
        color += 0.05 * tex2D(_MainTex, i.uv45.zw);  
        return color;  
    }  

    //最终叠加 pass 2
    v2f_add vert_final(appdata_img v)  
    {  
        v2f_add o;  
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
        o.uv.xy = v.texcoord.xy;  
        o.uv1.xy = o.uv.xy;  
#if UNITY_UV_STARTS_AT_TOP  
        if (_MainTex_TexelSize.y < 0)  
            o.uv.y = 1 - o.uv.y;  
#endif    
        return o;  
    }  

    fixed4 frag_final(v2f_add i) : SV_Target  
    {  
        fixed4 ori = tex2D(_MainTex, i.uv1);  
        fixed4 blur = tex2D(_BlurTex, i.uv);  
        fixed4 final = ori + blur * _OutlineStrength;  
        return final;  
    }  

        ENDCG  

    SubShader  
    {  
        //pass 0: 高斯模糊  
        Pass  
        {  
            ZTest Off  
            Cull Off  
            ZWrite Off  
            Fog{ Mode Off }  

            CGPROGRAM  
            #pragma vertex vert_blur  
            #pragma fragment frag_blur  
            ENDCG  
        }  

        //pass 1: 剔除中心部分   
        Pass  
        {  
            ZTest Off  
            Cull Off  
            ZWrite Off  
            Fog{ Mode Off }  

            CGPROGRAM  
            #pragma vertex vert_cull
            #pragma fragment frag_cull
            ENDCG  
        }  


        //pass 2: 最终叠加  
        Pass  
        {  

            ZTest Off  
            Cull Off  
            ZWrite Off  
            Fog{ Mode Off }  

            CGPROGRAM  
            #pragma vertex vert_final
            #pragma fragment frag_final  
            ENDCG  
        }  

    }  
}
--------------------- 
作者:叫我上上 
来源:CSDN 
原文:https://blog.csdn.net/vikingsc2007_1/article/details/76570931 
版权声明:本文为博主原创文章,转载请附上博文链接!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【UnityShader】模板Stencil测试 的相关文章

  • unity:游戏对象不可见?

    我组合了两个可以显示透明度和截止 Alpha 的着色器 它工作得很好 只有两个小问题 1 在某些特定的摄像机角度下 对象的截止区域是可见的 仅当具有相同着色器的另一个对象位于该对象后面时 2 如果我淡出一个对象 它会变得黑色而不透明 我是着
  • 如何在 Unity Shader 中实现简单的高度图

    首先我要说的是我对着色器编程知之甚少 我这里的很多内容都是由在线资源和现有资产拼接而成的 我只需要知道如何将高度图正确集成到统一着色器中 它不必比标准 Unity 着色器更复杂 我无法使用标准着色器 因为我需要一个将多个纹理平铺在一起的着色
  • OpenGL 着色器。传递浮点数数组

    在我的场景中 我有许多物体想要同时旋转但角度不同 我有一个着色器 可以计算每个对象的位置并绘制整个场景 将顶点数组传递到带有顶点数组的着色器中 uniform float uRotation mat4 mz mat4 1 0 mz 0 0
  • 透明着色器允许下面的对象显示在上面

    在我的场景中 笑脸 带有 png 图像的四边形 放置在 Y 0 处 点 带有平铺 3X3 的四边形 放置在 Y 0 25 处 我需要用于笑脸的着色器是透明漫反射 因为我使用的是圆形 png 图像 但我在下面使用的点显示在笑脸上方 使用任何其
  • GLSL:如何执行类似 switch 的语句

    我想根据传递到着色器的数据动态调用缓动 所以用伪代码来说 var easing easings easingId var value easing point 我想知道在 GLSL 中完成此任务的最佳方法 我可以以某种方式使用 switch
  • 带有 OpenGL 的 Qt MDI 应用程序:如何获取有效的屏幕截图?

    我有一个MDI http en wikipedia org wiki Multiple document interface用 Qt 编写的应用程序 一些子窗口包括QGLWidgets 即 OpenGL 上下文 其中最突出的是使用 Open
  • openGL:带有着色器的线条

    如何使用着色器创建一条线 可能是彩色的 我正在使用可编程管道 并且我是 openGL 的初学者 我找不到有关如何使用着色器绘制线条的示例 我想我必须将 VAO 顶点数组对象 加载到着色器中 但是然后呢 我应该使用哪些功能以及如何使用 首先
  • Qt3D默认制服和属性

    我开始学习通过 QML 使用着色器 但找不到任何讨论传递给着色器的默认统一和属性值的参考资料 在某些示例中 我们可以看到其中的几个 例如顶点位置 or 模型视图投影 这也被传递为mvp 但是没有包含我们可以使用的所有变量的清晰列表 在调查
  • 将模板缓冲区可视化为纹理

    我正在尝试将模板缓冲区放入纹理中 以便在延迟渲染器中使用 I m getting other Color and Depth Attachments with glFramebufferTexture2D GL FRAMEBUFFER GL
  • 我们可以在透明窗口上应用着色器吗

    I am looking to apply a particular shader to a transparent window for example on a live desktop I want to create a trans
  • OpenGL Phong 光照:镜面高光错误

    我的 OpenGL 中的 Phong 光照着色器似乎有一个奇怪的问题 镜面高光出现在对象的错误一侧 手头的问题 正如您所看到的 镜面高光出现在立方体的另一侧 从灯光的角度来看 也出现在立方体垂直边缘的角上 它应该只出现在最靠近灯光的一侧 立
  • 线性光模式的 Alpha 混合层

    我正在重新创建一些 Photoshop 混合 并尝试使用线性光模式 在 Photoshop 中 您将有一个不透明度为 100 的背景图层 然后是一个不透明度为 50 的顶层 其混合模式设置为 线性光 我确实找到了有关如何进行线性光混合的信息
  • 如何绘制存储在 SSBO 中的顶点?

    这是下面的一个问题OpenGL 和加载 读取 AoSoA 混合 SoA 格式的数据 https stackoverflow com questions 59616117 opengl and loading reading data in
  • 如何将shadershop公式转换成glsl

    我最近一直在学习着色器的一些基础知识 并且想出了一个很棒的视觉工具 着色器商店 http www cdglabs org Shadershop 但我无法将我在此站点中创建的公式转换为 glsl 一个简单的例子 我在此网站中创建了一个公式 我
  • 在Unity中如何使两个精灵的重叠区域透明?

    在Unity中如何使两个精灵的重叠区域透明 你能写一个关于它的着色器吗 经过一些研究 我了解到我应该使用模板缓冲区 但我不知道如何使用 这对我来说至关重要 我必须在 6 天内完成这个学校项目 请帮忙 示例图片 就这样 请记住这是我第一次使用
  • 使用着色器创建模糊过滤器 - 从片段着色器访问相邻像素?

    我想使用 OpenGL ES 2 0 中的片段着色器创建模糊效果 我感兴趣的算法只是一个平均模糊 将所有相邻像素添加到我自己中并除以 9 进行标准化 但是我有两个问题 1 这是否需要我首先渲染到帧缓冲区 然后切换渲染目标 或者有更简单的方法
  • Unity 后处理 PostProcessEffectRenderer 在编辑器中显示,但在构建中不显示

    将 PostProcessEffectRenderer 的实现添加到 Unity 后处理堆栈后 效果在 Unity 编辑器中完美运行 但不会在构建的游戏中显示 对构建质量的更改没有效果 使用针对 Windows x86 64 构建的最高质量
  • 对 VBO 中的特定三角形使用不同的纹理

    我有 9 个由三角形组成的四边形 如下所示 我在用着VBO存储有关它们的数据 它们的位置和纹理坐标 我的问题是 是否可以仅使用一个来使四边形 5 具有与其余四边形不同的纹理VBO and shader 绿色代表纹理 1 黄色代表纹理 2 到
  • DirectX 世界视图矩阵乘法 - GPU 或 CPU 的地方

    我是 directx 的新手 但令我惊讶的是 我看到的大多数示例中 世界矩阵和视图矩阵都是作为顶点着色器的一部分相乘 而不是与 CPU 相乘并将结果传递给着色器 对于刚性对象 这意味着您为对象的每个顶点将相同的两个矩阵相乘一次 我知道 GP
  • Unity3D:在 AA 解析后绘制粒子以提高性能

    我正在尝试评估 MSAA 对 Unity 中含有大量粒子的场景的影响 为此 我需要 使用 8x MSAA 绘制场景中的所有非粒子对象 使用上一个通道中解析的深度缓冲区来渲染所有 将非遮挡粒子系统转移到较小的渲染目标上 将 2 的颜色缓冲区与

随机推荐

  • Server-Sent Events 一种轻量级的Push方式

    文章目录 SSE工作原理 SSE的特点 SSE的推送数据格式 SSE的使用 客户端 服务端 效果展示 简单来说 Server Sent Events 简称SSE 是服务端发送事件 即服务端Push的一种机制 SSE工作原理 一般来说HTTP
  • 封装NavLink组件

    之后可以通过
  • 后继者:找出二叉搜索树中指定节点的“下一个”节点

    后继者 设计一个算法 找出二叉搜索树中指定节点的 下一个 节点 也即中序后继 如果指定节点没有对应的 下一个 节点 则返回null 来源 力扣 LeetCode 链接 https leetcode cn problems successor
  • nextTick 原理及作用

    Vue 的 nextTick 其本质是对 JavaScript 执行原理 EventLoop 的一种应用 nextTick 的核心是利用了如 Promise MutationObserver setImmediate setTimeout的
  • Leetcode刷题-最长公共前缀

    Leetcode刷题 最长公共前缀 简介 题目 个人答案及结果 学习一下官方的 简介 最近尝试下大家口口相传的神器 leetcode cn com 大家自己注册就可以选择题库进行使用了 我都会先自己出一个答案 然后再学习别人的标准答案 进行
  • element修改el-table 表头的背景颜色横向渐变色 + 修改表头背景颜色

    vue element ui 修改el table 表头的背景颜色横向渐变色 修改表头背景颜色 表头背景颜色横向渐变效果图 修改表头背景颜色和字体颜色效果图 直接上代码 修改表头的背景颜色横向渐变色的代码 html
  • SSH一段时间未使用自动断开的解决办法

    有两种解决方案 可以修改服务器端的参数 也可以修改本地链接的参数 为了安全起见 我这里选择了修改我本地的配置 在路径 etc ssh ssh config下添加如下配置 ServerAliveInterval 60 ServerAliveC
  • HTML的Input(type)的属性都有哪些

    作者介绍 一个有梦想 有理想 有目标的 且渴望能够学有所成的追梦人 学习格言 不读书的人 思想就会停止 狄德罗 个人主页 进入博主主页 欢迎小伙伴们访问到博主的文章内容 在浏览阅读过程发现需要纠正的地方 烦请指出 愿能与诸君一同成长 目录
  • [ZZ]计算机视觉、机器学习相关领域论文和源代码大集合

    注 下面有project网站的大部分都有paper和相应的code Code一般是C C 或者Matlab代码 最近一次更新 2013 1 29 一 特征提取Feature Extraction SIFT 1 Demo program SI
  • [python logging]日志记录模块

    logging 介绍 Logger从来不直接实例化 经常通过logging模块级方法 Module Level Function logging getLogger name 来获得 其中如果name不给定就用root 名字是以点号分割的命
  • 解决iframe的frameborder在chrome/ff/ie下的差异

    最近的项目中使用了动态创建iframe的js方法 发现iframe frameborder 0 在IE7下不管用 而chrome ff都正常的 很是郁闷 var iframe document createElement iframe if
  • Docker Compose安装教程

    Docker Compose安装 准备二进制文件 并移动到指定目录 在线安装 直接执行下面命令下载 sudo curl L https github com docker compose releases download v2 6 1 d
  • windows安装mpi4py

    为了能够在windows 本次测试为win7 上使用MPI 试了很多种办法 现在将本人可行的办法在这里发出来 供大家参考 下载安装MS MPI 下载链接 MS MPI Release Notes 选择自己心仪的版本下载 包含两个文件 msm
  • 期货的本质(期货的本质是什么)

    期货的本质是什么 本质是一个风险转移工具 通过把风险转移给愿意投机获利 亏损的人 产业方得以获得确定的盈利预期 这是期货的核心价值 狭义理论认为期货市场是 零和 负和 游戏 但如果把眼光放宽 把实体产业加进来 可以发现期货是市场环境里一项必
  • Flink高手之路4-Flink流批一体

    文章目录 Flink高手之路4 Flink流批一体API开发 一 流批一体相关的概念 1 数据的时效性 2 流处理和批处理 1 批处理 2 流处理 3 两者对比 3 流批一体API 4 流批一体的编程模型 二 Data Source 1 预
  • enum(枚举)

    C enum 枚举 枚举是 C 语言中的一种基本数据类型 它可以让数据更简洁 更易读 枚举语法定义格式为 enum 枚举名 枚举元素1 枚举元素2 接下来我们举个例子 比如 一星期有 7 天 如果不用枚举 我们需要使用 define 来为每
  • IOS安全测试(资源学习笔记)

    客户端程序安全 位置无关代码 检测客户端是有启用Position Independent Executable PIE 编译选项 采用PIE选项编译的引用程序允许使用地址空间随机分布功能 ASLR Address Space Layout
  • PHPExcel导入导出操作总结

    PHPExcel 是用来操作Office Excel 文档的一个PHP类库 它基于微软的OpenXML标准和PHP语言 可以使用它来读取 写入不同格式的电子表格 如 Excel BIFF xls Excel 2007 OfficeOpenX
  • CocosCreator中TiledMap简单使用

    在开发游戏过程中 有时候会用到TiledMap 瓦片地图 我这边使用的是1 4 3版本的tiledmap 2 3 4版本的CocosCreator 其他版本的tiledmap会有做不了动画的问题 后面会说到 视频参考 B站UP主 阿信OL
  • 【UnityShader】模板Stencil测试

    效果 原理 使用后处理 在后处理阶段先渲染产生一张RenderTexture 包含要被描边的物体 使用描边色渲染 高斯模糊RenderTexture 会产生边缘 用高斯模糊的图片反向剔除未模糊的图 这样只保留模糊多出的部分 此时Render