庄懂着色器_L17_屏幕UV/屏幕扰动

庄懂-BoyanTata的个人空间_哔哩哔哩_Bilibili


屏幕UV案例
代码部分
观察空间ViewSpace
UnityObjectToViewPos(v.vertex).xyz
以你的摄像机为基准的空间,它的X和Y轴就相当于你显示器上的横轴和竖轴,Z轴就是你摄像机的深度
将摄像机的横轴和竖轴将其理解为一个UV坐标,并去采样贴图,那样就可以将纹理采样到屏幕空间上了
但是如果直接用转换到观察空间的X,Y轴作为UV去采样,会发现贴图在模型的表面上会有一个"畸变",可以用X,Y轴去除以Z的深度即可(o.screenUV = posVS.xy/posVS.z),校正校正"畸变",校正过后还会有另一个问题,你的纹理它是相对于你的屏幕它是不变的(纹理tiling大小相对于显示器是不变的),但是你的模型在视窗显示大小,它相对于你的视口,它是跟它的距离成反比的,它离你越远显示越小,它离你越近显示越大,相对它的tiling的纹理映射在模型身上的时候也是它离你越远tiling越小,它离你越近tiling越大,所以不想出现这样的效果,要将其按距离做一个锁定,那就首先要讲距离求出来
核心代码分析
Shader "AP01/L17/ScreenUV"
{
    Properties
    {
        _MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}
        _Opacity ("透明度", range(0, 1)) = 0.5
        _ScreenTex ("屏幕纹理", 2d) = "black" {}
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"               // 调整渲染顺序
            "RenderType"="Transparent"          // 对应改为Cutout
            "ForceNoShadowCasting"="True"       // 关闭阴影投射
            "IgnoreProjector"="True"            // 不响应投射器
        }

        Pass
        {
            Name "FORWARD"
            Tags { "LightMode"="ForwardBase" }
            Blend One OneMinusSrcAlpha          // 混合方式
           
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            // 输入参数
            uniform sampler2D _MainTex;
            uniform half _Opacity;
            uniform sampler2D _ScreenTex;   uniform float4 _ScreenTex_ST

            // 输入结构
            struct VertexInput
            {
                float4 vertex : POSITION;       // 顶点位置 OS
                float2 uv : TEXCOORD0;          // UV信息
            };

            // 输出结构
            struct VertexOutput
            {
                float4 pos : SV_POSITION;       // 顶点位置 CS
                float2 uv : TEXCOORD0;          // UV信息
                float2 screenUV : TEXCOORD1;    // 屏幕UV
            };

            // 输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v)
            {
                VertexOutput o = (VertexOutput)0;
                o.pos = UnityObjectToClipPos(v.vertex);     // 顶点位置 OS>CS
                o.uv = v.uv;                                // UV信息
                float3 posVS = UnityObjectToViewPos(v.vertex).xyz;                  // 顶点位置 OS>VS
                float originDist = UnityObjectToViewPos(float3(0.0, 0.0, 0.0)).z;   // 原点位置 OS>VS
                o.screenUV = posVS.xy / posVS.z;            // VS空间畸变校正
                o.screenUV *= originDist;                   // 纹理大小按距离锁定
                o.screenUV = o.screenUV * _ScreenTex_ST.xy - frac(_Time.x * _ScreenTex_ST.zw);  // 启用屏幕纹理ST
                return o;
            }

            // 输出结构>>>像素
            half4 frag(VertexOutput i) : COLOR
            {
                half4 var_MainTex = tex2D(_MainTex, i.uv);              // 采样 基本纹理 RGB颜色 A透贴
                half var_ScreenTex = tex2D(_ScreenTex, i.screenUV).r;   // 采样 屏幕纹理
                // FinalRGB 不透明度
                half3 finalRGB = var_MainTex.rgb;
                half opacity = var_MainTex.a * _Opacity * var_ScreenTex;
                // 返回值
                return half4(finalRGB * opacity, opacity);
            }
            ENDCG
        }
    }
}
屏幕扰动案例
代码部分
GrabPass
就相当于在渲染模型之前,当你把背景的东西存成一张图,这张图的名字就是GrabPass后边大括号内的"_BGTex"
我将它扰动前的背景存下来,然后我在用屏幕的坐标UV把那张图给模型贴上去
核心代码分析
Shader "AP01/L17/ScreenWarp"
{
    Properties
    {
        _MainTex    ("RGB:颜色 A:透贴", 2d) = "gray"{}
        _Opacity    ("不透明度", range(0, 1)) = 0.5
        _WarpMidVal ("扰动中间值", range(0, 1)) = 0.5
        _WarpInt    ("扰动强度", range(0, 5)) = 1
    }


    SubShader
    {
        Tags
        {
            "Queue"="Transparent"               // 调整渲染顺序
            "RenderType"="Transparent"          // 对应改为Cutout
            "ForceNoShadowCasting"="True"       // 关闭阴影投射
            "IgnoreProjector"="True"            // 不响应投射器
        }

        // 获取背景纹理
        GrabPass { "_BGTex" }

        // Forward Pass
        Pass
        {
            Name "FORWARD"
            Tags { "LightMode"="ForwardBase" }
            Blend One OneMinusSrcAlpha          // 混合方式

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            // 输入参数
            uniform sampler2D _MainTex;
            uniform half _Opacity;
            uniform half _WarpMidVal;
            uniform half _WarpInt;
            uniform sampler2D _BGTex;   // 拿到背景纹理

            // 输入结构
            struct VertexInput
            {
                float4 vertex : POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
            };

            // 输出结构
            struct VertexOutput
            {
                float4 pos : SV_POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
                float4 grabPos : TEXCOORD1;     // 背景纹理采样坐标
            };

            // 输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v)
            {
                VertexOutput o = (VertexOutput)0;
                o.pos = UnityObjectToClipPos( v.vertex);    // 顶点位置 OS>CS
                o.uv = v.uv;                                // UV信息
                o.grabPos = ComputeGrabScreenPos(o.pos);    // 背景纹理采样坐标
                return o;
            }

            // 输出结构>>>像素
            half4 frag(VertexOutput i) : COLOR
            {
                // 采样 基本纹理 RGB颜色 A透贴
                half4 var_MainTex = tex2D(_MainTex, i.uv);
                // 扰动背景纹理采样UV
                i.grabPos.xy += (var_MainTex.b - _WarpMidVal) * _WarpInt * _Opacity;
                // 采样背景
                half3 var_BGTex = tex2Dproj(_BGTex, i.grabPos).rgb;
                // FinalRGB 不透明度
                half3 finalRGB = lerp(1.0, var_MainTex.rgb, _Opacity) * var_BGTex;
                half opacity = var_MainTex.a;
                // 返回值
                return half4(finalRGB * opacity, opacity);
            }
            ENDCG
        }
    }
}
<think>好的,我现在需要帮用户解决一个C/C++编译错误,具体是关于#include的错误,提示需要更新includePath。用户提供的错误信息显示在MY_GPIO.H的第3行,属于IntelliSense的问题。首先,我应该分析可能的原因,然后逐步给出解决方案。 首先,错误信息指出检测到#include错误,并建议更新includePath。这说明编译器或IntelliSense无法找到用户包含的头文件。常见的原因可能有以下几点: 1. **头文件路径不正确**:MY_GPIO.H可能不在项目的include路径中,或者路径被错误地指定。 2. **项目配置问题**:特别是在使用像HC32L17X这样的特定微控制器库时,可能需要正确配置IDE(如Keil、IAR或VS Code)中的包含路径。 3. **文件路径中的空格或特殊字符**:用户的路径中有“HC32L17X -6”文件夹,中间有一个空格,可能导致解析错误。 4. **未正确安装或链接SDK**:HC32L17X的SDK可能没有正确安装,或者项目没有正确引用SDK中的头文件。 接下来,我需要思考如何一步步引导用户检查这些问题。首先,检查头文件的实际位置是否正确。用户提供的路径是“c:/Users/admin/Desktop/hc32l17x/HC32L17X -6/source/MY_GPIO.H”,这里可能存在路径中的空格问题。在C/C++中,包含路径如果包含空格,可能需要使用引号或者转义字符,但通常在IDE中需要正确设置。 然后,考虑项目配置。如果用户使用的是VS Code,可能需要检查c_cpp_properties.json文件中的includePath设置是否正确添加了HC32L17X库的路径。此外,检查编译器路径是否正确,是否有必要的宏定义,比如芯片型号相关的宏。 另外,用户可能没有正确安装HC32L17X的SDK,或者项目文件中的相对路径引用有误。需要确认HC32L17X的库文件是否存在于指定位置,以及项目是否正确地引用了这些文件。 还需要注意MY_GPIO.H和MY_GPIO.c是否在同一个目录下,如果是的话,使用双引号包含头文件可能更合适,比如#include "MY_GPIO.H",而不是尖括号。但根据错误信息,用户可能已经使用了双引号,但路径仍然有问题。 此外,路径中的“-6”可能是一个版本号或目录名,中间的空格可能导致IDE解析路径时出错。建议用户将文件夹重命名,去掉空格,比如改为“HC32L17X-6”,然后更新项目中的路径引用。 总结下来,解决步骤可能包括: 1. 检查文件路径是否正确,特别是空格问题。 2. 确认IDE中的包含路径设置。 3. 检查头文件引用方式(双引号 vs 尖括号)。 4. 确保SDK正确安装并配置。 5. 重新生成或更新IntelliSense的配置。 在回答时,需要分步骤说明,确保用户能逐步排查问题。同时,提醒用户注意路径中的空格问题,并给出具体的配置示例,比如如何在VS Code中修改c_cpp_properties.json文件。此外,可能还需要指导用户如何验证路径是否存在,或者如何重新加载项目以使配置生效。</think>针对你遇到的C/C++ IntelliSense错误(错误代码1696),以下是分步解决方案: --- ### **错误原因分析** 错误提示表明:在编译`MY_GPIO.c`时,VS Code的IntelliSense无法找到`MY_GPIO.H`的头文件路径。常见原因: 1. **头文件路径未正确配置**:项目未包含头文件所在目录。 2. **路径中存在空格或特殊字符**:如`HC32L17X -6`中的空格可能导致解析错误。 3. **SDK未正确安装**:HC32L17X芯片的固件库未正确链接。 --- ### **解决方法** #### **1. 检查头文件物理路径** - 确认`MY_GPIO.H`实际存在于路径: `C:\Users\admin\Desktop\hc32l17x\HC32L17X -6\source\` - **注意**:路径中的`HC32L17X -6`包含空格,可能引发问题。建议重命名文件夹为`HC32L17X-6`(去掉空格)。 --- #### **2. 配置VS Code的includePath** 1. 打开VS Code,按`Ctrl+Shift+P` → 输入`C/C++: Edit Configurations (UI)` → 回车。 2. 在**Include Path**中添加以下路径: ```json "C:/Users/admin/Desktop/hc32l17x/HC32L17X -6/source/**", "C:/Users/admin/Desktop/hc32l17x/HC32L17X -6/device/include/**" // 假设SDK路径 ``` ![](https://example.com/path-to-screenshot) // 此处可添加实际配置截图提示 --- #### **3. 修改头文件引用方式** 在`MY_GPIO.c`中,将: ```c #include <MY_GPIO.H> ``` 改为**双引号**(适用于相对路径或当前目录): ```c #include "MY_GPIO.H" ``` --- #### **4. 处理路径空格问题** - **方法1**:在`includePath`中用反斜杠转义空格: ```json "C:/Users/admin/Desktop/hc32l17x/HC32L17X\\ -6/source/**" ``` - **方法2**(推荐):直接重命名文件夹为`HC32L17X-6`,避免空格。 --- #### **5. 验证SDK安装** - 确认HC32L17X的官方SDK已下载并解压到正确位置(如`hc32l17x`目录下)。 - 典型SDK结构应包含: ``` HC32L17X -6/ ├─ device/ │ ├─ include/ // 标准外设头文件 │ └─ driver/ // 驱动程序 └─ source/ // 用户代码 ``` --- #### **6. 重新加载VS Code** - 保存所有更改 → 重启VS Code → 按`Ctrl+Shift+P` → 输入`Reload Window`。 --- ### **附加建议** - 若使用Makefile/CMake,需同步更新编译脚本中的`-I`包含路径。 - 安装C/C++扩展更新(如微软官方扩展版本需≥1.8.4)。 --- ### **总结** 通过上述步骤,IntelliSense应能正确解析头文件路径。若问题仍存,请检查: 1. 实际路径与配置是否完全一致。 2. 防病毒软件是否拦截了文件访问。 3. 项目是否被正确加载到Workspace中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值