美文网首页
UnityTips 之着色器编译器傻吗3 重复的计算需要提取吗

UnityTips 之着色器编译器傻吗3 重复的计算需要提取吗

作者: 暴走TA | 来源:发表于2023-05-17 10:53 被阅读0次

简介: 前段时间用ASE做效果的时候,为了优化把一些常用的ndotv ndotl这种的提前计算出来,然后进行传值,本意是为了减少重复计算,提升效率,但是导致一个问题,不同function为了公用这些值,不得不暴露很多的input。突发奇想,想看看着色器的编译器对于这种重复书写的计算有优化没
unity版本:20222.1.7fc1

准备测试用的着色器

为了减少额外的干扰,先做一个最简单的,逻辑最少的shader,我们暂且将它叫做 CompileTester 吧,提供了两个方法 ndotl1 和 ndotl2 ,他们中都包含了 一个一样的点积运算

Shader "CompileTester"
{
    Properties
    {
        _Color0("Color 0", Color) = (0,0,0,0)
    }

    SubShader
    {
        HLSLINCLUDE
        #pragma target 3.0
        #pragma prefer_hlslcc gles
        ENDHLSL
                //float4 uv1:TEXCOORD0;
                //half4 uv2:TEXCOORD1;
                //half2 uv3:TEXCOORD2;
        Pass
        {   
            Name "Forward"
            Tags { "LightMode"="UniversalForward" }
        
            HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            float4 _Color0;

            half ndotl1(half3 normal,half3 lightdir)
            {
                half d=dot(normal,lightdir);
                return d;
            }
            half ndot2(half3 normal,half3 lightdir)
            {
                half3 newNor=normal;
                return normalize(dot(newNor,lightdir));
            }

            struct VertexInput
            {
                float4 vertex : POSITION;
                float4 uv1:TEXCOORD0;
                half4 uv2:TEXCOORD1;
                half4 uv3:TEXCOORD2;
    
            };
            struct VertexOutput
            {
                float4 clipPos : SV_POSITION;
                float4 uv1:TEXCOORD0;
                half4 uv2:TEXCOORD1;
                half2 uv3:TEXCOORD2;
            };

            VertexOutput vert ( VertexInput v )
            {
                VertexOutput o ;
                o.clipPos= TransformWorldToHClip( TransformObjectToWorld( v.vertex.xyz ) );
                o.uv1=v.uv1;
                half2 uv=v.uv2.xy;
                o.uv3=v.uv3.xy;
                return o;
            }
            half3 _wnormal;
            half3 _lightdir;
            half4 frag ( VertexOutput IN  ) : SV_Target
            {   
                half3 normal=half3(1,1,1);
                half3 lightdir=half3(2,1,2);
                return ndotl1(_wnormal,_lightdir)+ndot2(_wnormal,_lightdir);
                return _Color0;
            }
            ENDHLSL
        }
    }
}

ndotl1 和 ndotl2 的差异

             half ndotl1(half3 normal,half3 lightdir)
            {
                half d=dot(normal,lightdir); // 将点击结果赋予一个临时变量,然后将其返回
                return d;
            }
            half ndot2(half3 normal,half3 lightdir)
            {
                half3 newNor=normal;  //将法线变量传递给一个临时变脸,然后用临时变量参与运算
                return normalize(dot(newNor,lightdir)); // 直接对点积结果进行归一化,然后直接返回
            }

实际产生的编译结果

    void main()
    {
        u_xlat16_0 = dot(_wnormal.xyz, _lightdir.xyz); //将点积操作提取了出来,赋值给一个临时变量
        u_xlat16_1 = u_xlat16_0 * u_xlat16_0; //接着的三步进行归一化
        u_xlat16_1 = inversesqrt(u_xlat16_1);
        SV_Target0 = vec4(u_xlat16_0) * vec4(u_xlat16_1) + vec4(u_xlat16_0);//归一化并凑了一个 mad 操作,
        return;
    }

实验结果

编译器还是比较 niubility 的,我可以回去大胆的取消掉统一预计算了,当然如果有的地方需要保持计算结果一致,并且为了便于计算方式一次修改便可到处生效还是需要提前计算并统一保存的

相关文章

  • OpenGLES着色器和程序

    需要创建两个基本对象才能用着色器进行渲染:着色器对象和程序对象,类似编译器和链接程序。 编译之后,着色器对象可以链...

  • 你说她傻吗?

    想要问问 端木钰晴傻吗? 一手好牌打得稀巴烂 傻吗 陈昌文先生,你说她傻吗? 为了爱情失去生命 傻吗? 你说她傻吗...

  • Maple符号 实数虚数

    方法1 提取实部和虚部 计算 方法2 提取实部和虚部 计算 方法3 提取实部和虚部 计算

  • 着色器渲染原理;着色器和程序的关系

    着色器进行渲染 着色器对象和程序对象。 着色器对象和程序对象就好比编译器和链接对象,着色器对象是包含单个着色器的对...

  • 数组中重复元素的处理

    1、取出数组中重复的元素(不重复的不提取,合并重复的元素) 2、合并重复的元素 (不重复的也提取) 3、剔除数组中...

  • 2019-10-13

    困,我能重复一百次吗?困,我能重复一百次吗困,我能重复一百次吗??困,我能重复一百次吗?困,我能重复一百次吗?困,...

  • 改变数学的命运——《计算进化史》读后感 @阿狸不歌

    2+2=4 需要证明吗?可以用计算的方式证明素数有无穷多个吗?计算机可以代替人进行所有的数学证明吗?如果你思...

  • unity手游开发上的着色器优化策略

    1. 将部分计算从片元着色器移到顶点着色器来计算 如果你的游戏需要在配置非常低的平台上进行流畅运行,你可以考虑牺牲...

  • Pacifist for Mac(软件提取工具) v3.6.1免

    需要一款软件提取工具吗?今天小编给大家带来一款简单易用的软件提取工具——Pacifist for Mac,感兴趣的...

  • 第一节(后半堂):我们不画三角形(2)

    上面说到需要编译两个着色器。 我们将编译着色器的方法提取出来: 第一步: 前面几行代码我就不解释了。 第四行:我们...

网友评论

      本文标题:UnityTips 之着色器编译器傻吗3 重复的计算需要提取吗

      本文链接:https://www.haomeiwen.com/subject/ialisdtx.html