Unity Shader - shader forge - #pragma only_renderers 和 exclude_renderers - 导致像素全黑 - subprogram指令丢失

141 篇文章 34 订阅


环境

Unity : 2018.2.11f11
Pipeline : Built-In


目的

今天合作部门的某位程序同学可能对 shader 不熟悉
他是在省外的(异地)
但是公司没有了解 shader 的同学(-_- ~~!!)
所以有比较多的一些效果问题、兼容性问题,都只能找到我~ (-_- ~~!!)


问题


DX 没有问题

在这里插入图片描述


OpenGLES 就全黑色

在这里插入图片描述


分析

很有可能就是平台设置问题

然后我使用 frame debug 查看绘制区别


DX 的

在这里插入图片描述


OpenGLES 的

看着和 DX 的差别非常大,而且很多参数、状态值都没对上,如下:Queue 的设置都无效了

主要的是我们 shader 的 "Queue"="Transparent",按正常情况下,会再 Render.TransparentGeometry 列队中,但是 Frame Debug 面板中可以看到他是在 Render.OpaqueGeometry 队列里绘制的

所以非常有可能就是平台不兼容,直接跳过了 正常的变量、参数应用

在这里插入图片描述


问题所在

// Shader created with Shader Forge v1.38 
// Shader Forge (c) Neat Corporation / Joachim Holmer - http://www.acegikmo.com/shaderforge/
// Note: Manually altering this data may prevent you from opening it in Shader Forge
/*SF_DATA;ver:1.38;sub:START;pass:START;ps:flbk:,iptp:0,cusa:False,bamd:0,cgin:,lico:0,lgpr:1,limd:0,spmd:1,trmd:0,grmd:0,uamb:True,mssp:True,bkdf:False,hqlp:False,rprd:False,enco:False,rmgx:True,imps:True,rpth:0,vtps:0,hqsc:True,nrmq:1,nrsp:0,vomd:0,spxs:False,tesm:0,olmd:1,culm:2,bsrc:0,bdst:1,dpts:2,wrdp:True,dith:0,atcv:False,rfrpo:True,rfrpn:Refraction,coma:15,ufog:False,aust:False,igpj:True,qofs:0,qpre:3,rntp:2,fgom:False,fgoc:False,fgod:False,fgor:False,fgmd:0,fgcr:0.5,fgcg:0.5,fgcb:0.5,fgca:1,fgde:0.01,fgrn:0,fgrf:300,stcl:False,atwp:False,stva:128,stmr:255,stmw:255,stcp:6,stps:0,stfa:0,stfz:0,ofsf:0,ofsu:0,f2p0:False,fnsp:False,fnfb:False,fsmp:False;n:type:ShaderForge.SFN_Final,id:4013,x:33414,y:32662,varname:node_4013,prsc:2|emission-2850-OUT,alpha-8675-OUT,clip-8675-OUT;n:type:ShaderForge.SFN_Tex2d,id:8569,x:32586,y:32713,ptovrint:False,ptlb:mask,ptin:_mask,varname:node_8569,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,tex:e3ecf11490c25124ab2cd8b4631fc9c3,ntxv:0,isnm:False;n:type:ShaderForge.SFN_VertexColor,id:4253,x:32311,y:32623,varname:node_4253,prsc:2;n:type:ShaderForge.SFN_Multiply,id:6979,x:32893,y:32668,varname:node_6979,prsc:2|A-4253-RGB,B-8569-RGB;n:type:ShaderForge.SFN_Multiply,id:8675,x:32893,y:32790,varname:node_8675,prsc:2|A-8569-A,B-9765-OUT;n:type:ShaderForge.SFN_OneMinus,id:3587,x:32325,y:32777,varname:node_3587,prsc:2|IN-4253-A;n:type:ShaderForge.SFN_Tex2d,id:9067,x:31855,y:32896,ptovrint:False,ptlb:wenli,ptin:_wenli,varname:node_9067,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,tex:28c7aad1372ff114b90d330f8a2dd938,ntxv:0,isnm:False|UVIN-8700-UVOUT;n:type:ShaderForge.SFN_TexCoord,id:8700,x:31483,y:32896,varname:node_8700,prsc:2,uv:0,uaff:False;n:type:ShaderForge.SFN_Panner,id:626,x:31669,y:32896,varname:node_626,prsc:2,spu:0,spv:0|UVIN-8700-UVOUT;n:type:ShaderForge.SFN_If,id:9765,x:32586,y:32875,varname:node_9765,prsc:2|A-2909-OUT,B-3587-OUT,GT-1324-OUT,EQ-9084-OUT,LT-9084-OUT;n:type:ShaderForge.SFN_Vector1,id:1324,x:32325,y:33024,varname:node_1324,prsc:2,v1:1;n:type:ShaderForge.SFN_Vector1,id:9084,x:32325,y:33093,varname:node_9084,prsc:2,v1:0;n:type:ShaderForge.SFN_Add,id:9052,x:32048,y:32896,varname:node_9052,prsc:2|A-3427-OUT,B-9067-R;n:type:ShaderForge.SFN_OneMinus,id:3427,x:32048,y:32760,varname:node_3427,prsc:2|IN-4253-A;n:type:ShaderForge.SFN_OneMinus,id:2909,x:32325,y:32902,varname:node_2909,prsc:2|IN-9052-OUT;n:type:ShaderForge.SFN_Multiply,id:385,x:32893,y:32920,varname:node_385,prsc:2|A-9765-OUT,B-3931-OUT;n:type:ShaderForge.SFN_Vector1,id:3931,x:32586,y:33011,varname:node_3931,prsc:2,v1:0.1;n:type:ShaderForge.SFN_ValueProperty,id:7697,x:32881,y:33105,ptovrint:False,ptlb:glow,ptin:_glow,varname:node_7697,prsc:2,glob:False,taghide:False,taghdr:False,tagprd:False,tagnsco:False,tagnrm:False,v1:5;n:type:ShaderForge.SFN_Multiply,id:2850,x:33202,y:32952,varname:node_2850,prsc:2|A-6979-OUT,B-7697-OUT,C-385-OUT;proporder:8569-9067-7697;pass:END;sub:END;*/

Shader "LJShader_Dev/Effect/Dissove blend" {
    Properties {
        _mask ("mask", 2D) = "white" {}
        _wenli ("wenli", 2D) = "white" {}
        _glow ("glow", Float ) = 5
        [HideInInspector]_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    }
    SubShader {
        Tags {
            "IgnoreProjector"="True"
            "Queue"="Transparent"
            "RenderType"="Transparent"
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            Cull Off
            
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            //#define UNITY_PASS_FORWARDBASE
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase
			#pragma only_renderers d3d9 d3d11 glcore
            #pragma target 3.0
            uniform sampler2D _mask; uniform float4 _mask_ST;
            uniform sampler2D _wenli; uniform float4 _wenli_ST;
            uniform float _glow;
            struct VertexInput {
                float4 vertex : POSITION;
                float2 texcoord0 : TEXCOORD0;
                float4 vertexColor : COLOR;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;
                float4 vertexColor : COLOR;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                o.vertexColor = v.vertexColor;
                o.pos = UnityObjectToClipPos( v.vertex );
                return o;
            }
            float4 frag(VertexOutput i, float facing : VFACE) : COLOR {
                float4 _mask_var = tex2D(_mask,TRANSFORM_TEX(i.uv0, _mask));
                float4 _wenli_var = tex2D(_wenli,TRANSFORM_TEX(i.uv0, _wenli));
                float node_9765_if_leA = step((1.0 - ((1.0 - i.vertexColor.a)+_wenli_var.r)),(1.0 - i.vertexColor.a));
                float node_9765_if_leB = step((1.0 - i.vertexColor.a),(1.0 - ((1.0 - i.vertexColor.a)+_wenli_var.r)));
                float node_9084 = 0.0;
                float node_9765 = lerp((node_9765_if_leA*node_9084)+(node_9765_if_leB*1.0),node_9084,node_9765_if_leA*node_9765_if_leB);
                float node_8675 = (_mask_var.a*node_9765);
                clip(node_8675 - 0.5);
// Lighting:
// Emissive:
                float3 emissive = ((i.vertexColor.rgb*_mask_var.rgb)*_glow*(node_9765*0.1));
                float3 finalColor = emissive;
                return fixed4(finalColor,node_8675);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
}

留意其中的

#pragma only_renderers d3d9 d3d11 glcore

这是仅仅只对 dx9, dx11, opengl core版本的 渲染器才有效的
而我们要是设置在 OpenGLES2 下,那么效果肯定是有问题的

而这句话一般我们如果知道我们的程序运行平台只有那么几个平台,那么可以用这个指令指定平台
然后可以使用这些平台的一些高级特性

从上面的 shader 可以看出来,这 shader 是 shader forge 连连看生成的
除了 可读性、和性能问题不说,还有上面的 only_renderers 也是自动添加的

这在 shader forge 论坛上已经有人吐槽过:Can’t permanently turn off #pragma only_renderers
在这里插入图片描述

从上图可以了解到,如果将 only_renderers 删除了,这时再用 shader forge 打开此 shader,又会添加 only_renderers 的指令回去


关于 only_renderers 和 exclude_renderers 可以参考:Writing vertex and fragment shaders
或是可以参考我之前翻译的:Unity Shader - Writing vertex and fragment shader 编写顶点和片段着色器

#pragma only_renderers d3d9 d3d11 glcore // 这里仅仅只对 dx9,dx11, glcore 有效,那么其他的渲染系统将会 输出全是黑色的像素,如果这么用,手机上就没法兼容了

你可以使用 #pragma exclude_renderers gles // 这里可以测试 排除掉 gl es 的,同样可以参考我上面的链接了解 exclude_renderers
原来的 shaderlab 还设置了 #pragma target 3.0 // 使用不了高级特性,可以不设置 target,默认是 target 2.5

target 设置可以参考我之前翻译的:Unity Shader - Shader Compilation Target Levels 着色器编译目标级别


注意

除了渲染异常,我们还使用了 asset studio 工具反编译了 shader ab 包资源,发现对应的 shader 中的 subprogram 都是没有生成

因此我们在开发跨平台的 shader 尽量不使用 only_renderers 指令


修复

所以我们只需要将 #pragma only_renderers d3d9 d3d11 glcore 这句代码注释即可


修复归修复,但是啊,shader forge 生产的代码可读性太低了那么下面顺便优化


优化

优化前:可以发现可读性超级差,而且 uniform 的变量命名也是渣渣,应该是美术同学使用 shader forge 的连连看产物
优化后:

经过重命名变量名
了解用意
发现一段没用的写法
原因就是 上面很有可能是对 图形学基础没了解过的 美术同学编辑的 shader forge 连连看
或是对节点了解程度不够深,才会有一堆没有用的操作

Shader "xxx" {
	Properties{
		_MaskTex1("Mask1", 2D) = "white" {}
		_MaskTex2("Mask2", 2D) = "white" {}
		_Brightness("Brightness", Float) = 5
		[HideInInspector]_Cutoff("Alpha cutoff", Range(0,1)) = 0.5
	}
	SubShader{
		Tags {
			"IgnoreProjector" = "True"
			"Queue" = "Transparent"
			"RenderType" = "Transparent"
		}
		Pass {
			Name "FORWARD"
			Tags {
				"LightMode" = "ForwardBase"
			}
			Cull Off
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			//#define UNITY_PASS_FORWARDBASE
			#include "UnityCG.cginc"
			#pragma multi_compile_fwdbase
			// only_renderers 和 exclude_renderers 可以参考:https://docs.unity3d.com/2019.3/Documentation/Manual/SL-ShaderPrograms.html
			// 或是可以参考我之前翻译的:https://blog.csdn.net/linjf520/article/details/94378653
			//#pragma only_renderers d3d9 d3d11 glcore // 这里仅仅只对 dx9,dx11, glcore 有效,那么其他的渲染系统将会 输出全是黑色的像素,如果这么用,手机上就没法兼容了
			//#pragma exclude_renderers gles // 这里可以测试 排除掉 gl es 的
			// target 可以参考:https://docs.unity3d.com/2019.3/Documentation/Manual/SL-ShaderCompileTargets.html
			//#pragma target 3.0 // 使用不了高级特性,可以不设置 target
			uniform sampler2D _MaskTex1; uniform float4 _MaskTex1_ST;
			uniform sampler2D _MaskTex2; uniform float4 _MaskTex2_ST;
			uniform float _Brightness;
			struct VertexInput {
				float4 vertex : POSITION;
				float2 texcoord0 : TEXCOORD0;
				float4 vertexColor : COLOR;
			};
			struct VertexOutput {
				float4 pos : SV_POSITION;
				float2 uv0 : TEXCOORD0;
				float4 vertexColor : COLOR;
			};
			VertexOutput vert(VertexInput v) {
				VertexOutput o = (VertexOutput)0;
				o.uv0 = v.texcoord0;
				o.vertexColor = v.vertexColor;
				o.pos = UnityObjectToClipPos(v.vertex);
				return o;
			}
			float4 frag(VertexOutput i, float facing : VFACE) : COLOR {
				float4 _maskCol = tex2D(_MaskTex1,TRANSFORM_TEX(i.uv0, _MaskTex1));
				float4 _wenliCol = tex2D(_MaskTex2,TRANSFORM_TEX(i.uv0, _MaskTex2));
				float doubleVertexColMinusTex2AlphaMinusOne = step(0, 2 * i.vertexColor.a - _wenliCol.r - 1.0);
				float alpha = (_maskCol.a * doubleVertexColMinusTex2AlphaMinusOne);
				clip(alpha - 0.5);
				float3 finalColor = ((i.vertexColor.rgb * _maskCol.rgb) * (_Brightness* doubleVertexColMinusTex2AlphaMinusOne * 0.1));
				return fixed4(finalColor, alpha);
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
	CustomEditor "ShaderForgeMaterialInspector"
}

优化后,可读性会高很多,而且浪费性能的运算也会少很多


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值