ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RenderDoc[03] 还原粒子特效shader

2021-01-07 13:34:07  阅读:314  来源: 互联网

标签:03 RenderDoc MainTex uv xlat0 shader vertexcolor xy


对于未加密的ab,可以用对应版本的unity load出来。
模型可以正常显示,但是粒子特效使用的是自制shader,所以显示为红色。
在这里插入图片描述这次的目标是还原粒子特效shader。
最终还原效果如下图:本文转自https://huutu.blog.csdn.net/article/details/112307325
在这里插入图片描述

1.查找对应shader代码

在这里插入图片描述选中粒子特效后,在属性面板可以看到shader名字。
例如上图粒子特效,使用shader名为 Basic Additive。
在RenderDoc中找到shader资源。本文转自https://huutu.blog.csdn.net/article/details/112307325
在这里插入图片描述在这里插入图片描述
来看动图本文转自https://huutu.blog.csdn.net/article/details/112307325
在这里插入图片描述

2.创建shader

在unity中新建Unlit shader。

根据属性面板,添加对应Property。
在这里插入图片描述

Properties
{
    [HDR] _TintColor("Tint Color", Color) = (1,1,1,1)
    _MainTex ("Particle Texture", 2D) = "white" {}
    _UVScroll("UV Scroll", Vector) = (0,0,0,0)
}

并添加透明处理

SubShader
    {
        //透明处理
        Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" }
        Blend SrcAlpha One

        LOD 100

然后在Pass中引入新添加的Property。

Pass
{
    ......
    sampler2D _MainTex;
    float4 _MainTex_ST;

    //引入新添加的Property
    float4 _UVScroll;
    float4 _TintColor;

3.还原顶点shader

在这里插入图片描述乍一看,代码多又乱,但是之前已经解释过了,这里的代码都是经过展开的,还原回Unity就是几行代码。

整理一下

#version 300 es

uniform 	vec4 _Time;
uniform 	vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
uniform 	vec4 hlslcc_mtx4x4unity_MatrixVP[4];
uniform 	mediump vec4 _MainTex_ST;
uniform 	mediump vec2 _UVScroll;
in mediump vec4 in_POSITION0;
in mediump vec4 in_COLOR0;
in mediump vec2 in_TEXCOORD0;
out mediump vec4 vs_COLOR0;
out mediump vec2 vs_TEXCOORD0;
vec4 u_xlat0;
vec4 u_xlat1;
mediump vec2 u_xlat16_2;
void main()
{
    u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0] * in_POSITION0.xxxx + u_xlat0;
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2] * in_POSITION0.zzzz + u_xlat0;
    u_xlat0 = u_xlat0 + hlslcc_mtx4x4unity_ObjectToWorld[3];
    u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0] * u_xlat0.xxxx + u_xlat1;
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[2] * u_xlat0.zzzz + u_xlat1;
    u_xlat0 = hlslcc_mtx4x4unity_MatrixVP[3] * u_xlat0.wwww + u_xlat1;
	
	//上面这几行代码就是做了顶点变换,相当于
	//o.vertex = UnityObjectToClipPos(v.vertex);
	
    gl_Position = u_xlat0;
	
    vs_COLOR0 = in_COLOR0;//传递顶点色到片段shader
	
    u_xlat16_2.xy = in_TEXCOORD0.xy * _MainTex_ST.xy + _MainTex_ST.zw;//相当于 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
	
	
    u_xlat0.xy = _Time.xx * _UVScroll.xy + u_xlat16_2.xy;//uv滚动
    vs_TEXCOORD0.xy = u_xlat0.xy;
    return;
}

其实需要处理的的代码就两行。

vs_COLOR0 = in_COLOR0;//传递顶点色到片段shader
u_xlat0.xy = _Time.xx * _UVScroll.xy + u_xlat16_2.xy;//uv滚动

在新创建的shader中,加上这两行的逻辑。

v2f vert (appdata v)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);

    o.vertexcolor = v.vertexcolor;//传递顶点色到片段shader

    o.uv.xy = _Time.xx * _UVScroll.xy + o.uv.xy;//uv滚动
    return o;
}

4.还原片段shader

在这里插入图片描述
代码不多,但是变量名很乱,比较难看,进行梳理。

#version 300 es

precision highp float;
precision highp int;
uniform 	mediump vec4 _TintColor;
uniform mediump sampler2D _MainTex;
in mediump vec4 vs_COLOR0;
in mediump vec2 vs_TEXCOORD0;
layout(location = 0) out mediump vec4 SV_Target0;
mediump vec4 u_xlat16_0;
mediump vec4 u_xlat16_1;
void main()
{
    u_xlat16_0 = vs_COLOR0 + vs_COLOR0;//顶点色叠加
    u_xlat16_1 = texture(_MainTex, vs_TEXCOORD0.xy);//采样
    u_xlat16_0 = u_xlat16_0 * u_xlat16_1;//采样颜色 和 叠加的顶点色 混合
    u_xlat16_0 = u_xlat16_0 * _TintColor;//再和 _TintColor 混合
    SV_Target0 = u_xlat16_0;
    return;
}

在自己创建的shader里面实现

fixed4 frag(v2f i) : SV_Target
{
    //对顶点色叠加一次
    fixed4 vertexcolor = i.vertexcolor + i.vertexcolor;//顶点色叠加

    // sample the texture
    fixed4 col = tex2D(_MainTex, i.uv);//采样

    vertexcolor = vertexcolor * col;//采样颜色 和 叠加的顶点色 混合

    vertexcolor = vertexcolor * _TintColor;//再和 _TintColor 混合

    col = vertexcolor;
    // apply fog
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

这样就还原了shader。

完整的shader如下:

Shader "Effect/Basic Additive"
{
    Properties
    {
        [HDR] _TintColor("Tint Color", Color) = (1,1,1,1)
        _MainTex ("Particle Texture", 2D) = "white" {}
        _UVScroll("UV Scroll", Vector) = (0,0,0,0)
    }

    SubShader
    {
        //透明处理
        Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" }
        Blend SrcAlpha One

        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float4 vertexcolor : COLOR0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float4 vertexcolor : COLOR0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            //引入新添加的Property
            float4 _UVScroll;
            float4 _TintColor;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);

                o.vertexcolor = v.vertexcolor;//传递顶点色到片段shader

                o.uv.xy = _Time.xx * _UVScroll.xy + o.uv.xy;//uv滚动
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                //对顶点色叠加一次
                fixed4 vertexcolor = i.vertexcolor + i.vertexcolor;//顶点色叠加

                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);//采样

                vertexcolor = vertexcolor * col;//采样颜色 和 叠加的顶点色 混合

                vertexcolor = vertexcolor * _TintColor;//再和 _TintColor 混合

                col = vertexcolor;
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

5.更加复杂的shader

还原的过程中遇到更复杂的shader,逻辑代码量有个20多行,看起来有点头大。
如果只是为了还原个七七八八,可以尝试只还原而不是弄懂。
本文转自https://huutu.blog.csdn.net/article/details/112307325
直接拷贝逻辑代码,然后将glsl标记替换为cg标记。
这里先提供几个我遇到的。

#define vec4 fixed4
#define vec3 fixed3
#define vec2 fixed2
#define mix lerp
#define texture tex2D

放在 CGPROGRAM 后面就可以。

6.发现问题

1.RenderDoc资源列表有多份同名的shader,会对应不同的shader代码。暂不清楚原因,后续跟进。
在这里插入图片描述
2.粗糙还原出来shader的效果和原来游戏并不一致。

7.参考博文

修改 UV 坐标实现纹理贴图的滚动 模拟水流效果
https://huutu.blog.csdn.net/article/details/50953900

Unity Shader 结构函数内置变量
https://zhuanlan.zhihu.com/p/132607912

GLSL转换HLSL
https://blog.csdn.net/u010778229/article/details/107488048

opengl shader函数
https://www.shaderific.com/glsl-functions/

标签:03,RenderDoc,MainTex,uv,xlat0,shader,vertexcolor,xy
来源: https://blog.csdn.net/cp790621656/article/details/112307325

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有