精华内容
下载资源
问答
  • shader半透明 unity3d
    千次阅读
    2022-02-18 00:48:00
    Shader "Unlit/半透明"
    {
        Properties
        {
            _Diffuse("Diffuse",Color) = (1,1,1,1)  //  漫反射
            _MainTex("MainTex",2D) = "white"{}  //  2D纹理贴图
            _AlphaScale("Alpha Scale",Range(0,1)) = 1  //  控制Alpha参数
        }
            SubShader
            {
                Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }   //  渲染顺序设置Transparent
                LOD 100
    
                Pass  //  用两个pass通道来处理,防止出现渲染错误,第一个pass通道  每个pass通道都会渲染一次
                {
    
                    ZWrite On  //  写入深度  为了确认渲染顺序
                    ColorMask 0  //  掩码遮罩  代表这个pass通道不写入任何颜色值
    
                }
    
    
    
                Pass  //  第二个pass通道
                {
                    Tags{"LightMode" = "ForwardBase"}
    
                    ZWrite Off  //  关闭ZWrite(深度写入)
                    Blend SrcAlpha OneMinusSrcAlpha  //  源颜色因子  正常透明混合
    
                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #include "UnityCG.cginc"
                    #include "Lighting.cginc"
    
                    struct v2f {
    
                        float4 vertex :SV_POSITION;  //  输出顶点信息
                        fixed3 worldNormal : TEXCOORD0;
                        float3 worldPos:TEXCOORD1;
                        float2 uv:TEXCOORD2;
    
                    };
    
                    fixed4 _Diffuse;
                    float _AlphaScale;
                    sampler2D _MainTex;
                    float4 _MainTex_ST;  //  是MainTex的Tiling和Offset两个属性  不需要在外面定义
    
                    v2f vert(appdata_base v)  //  顶点着色器
                    {
    
                        v2f o;  //  用这个结构体
                        o.vertex = UnityObjectToClipPos(v.vertex);  //  顶点信息从模型转到裁剪空间再放到输出结构体
                        fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);  //  法线从模型变换到世界坐标
                        o.worldNormal = worldNormal;
                        o.worldPos = mul(unity_ObjectToWorld, v.vertex);  //  顶点信息从模型转到世界坐标系
                        //o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;  //  为了让MainTex的Tiling和Offset两个属性能影响到uv
                        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);  //  unity纹理函数,和上面效果一样
                        return o;
                    }
    
                    fixed4 frag(v2f i) : SV_Target  //  片元着色器  片元高光反射
                    {
    
                        fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;  //  环境光
    
                        fixed4 texColor = tex2D(_MainTex, i.uv);  //  采样这个图
    
                        
    
                        //  漫反射
                        //fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                        fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
    
                        fixed3 diffuse = texColor.rgb * _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldLightDir,i.worldNormal) * 0.5 + 0.5);  //  漫反射公式  图的纹理采样乘进来,纹理属于漫反射
    
                        fixed3 color = ambient + diffuse;
                        return fixed4(color, texColor.a * _AlphaScale);  //  texColor的a值就是颜色通道的值  乘上_AlphaScale来控制
    
                    }
                    ENDCG
                }
            }
                        FallBack "Transparent/VertexLit"    
    }

    更多相关内容
  • Shader "Unlit/fresnel" { Properties { _FresnelColor("Fresnel Color",Color)=(1,1,1,1) _Fresnel("Fade(X) Intensity(Y)",vector)=(3,1,0,0) } SubShader { Tags { "RenderPipeline"="UniversalPipeline...

    Shader "Unlit/fresnel"
    {
        Properties
        {
            _FresnelColor("Fresnel Color",Color)=(1,1,1,1)
            _Fresnel("Fade(X) Intensity(Y)",vector)=(3,1,0,0)
        }
        SubShader
        {
            Tags { "RenderPipeline"="UniversalPipeline" "RenderType"="Transparent"
                    "Queue"="Transparent"
             }
            Blend One One
            ZWrite Off
            Pass
            {
                HLSLPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
    
                struct Attributes
                {
                    float4 vertexOS : POSITION;  
                    half3 normalOS:NORMAL;
                };
    
                struct Varyings
                {  
                    float4 vertexCS : SV_POSITION;
                    half3 normalWS:TEXCOORD;
                    float3 vertexWS:TEXCOORD1;
                };
    
                CBUFFER_START(UnityPerMaterial)
                half4 _Fresnel;
                half4 _FresnelColor;
                CBUFFER_END
    
                Varyings vert (Attributes v)
                {
                    Varyings o;
                    o.vertexCS = TransformObjectToHClip(v.vertexOS);
                    o.normalWS = TransformObjectToWorldNormal(v.normalOS);
                    o.vertexWS=TransformObjectToWorld(v.vertexOS);
                    return o;
                }
    
                half4 frag (Varyings i) : SV_Target
                {
                    half3 N=normalize(i.normalWS);
                    half3 V=normalize(_WorldSpaceCameraPos-i.vertexWS);
                    half dotNV=1-saturate(dot(N,V));
                    half4 fresnel=pow(dotNV,_Fresnel.x)*_Fresnel.y*_FresnelColor;
                    return fresnel;
                }
                ENDHLSL
            }
        }
    }
    

     

    展开全文
  • 令人敬畏的统一着色器这主要是自己博客专栏《【浅墨Unity3D Shader编程】》中推出的一些Shader代码的收集。 着色器专栏地址: : 推荐新的高品质Unity Shader项目| 推荐新的很棒的Unity Shader库X-PostProcessing ...
  • 文章目录透明度测试透明度混合开启深度写入的半透明常见的混合类型双面渲染透明度测试的双面渲染透明度混合的双面渲染 实现透明效果的方法有两种:透明度测试和透明度混合 透明度测试 透明度测试实现的效果只有...


    在这里插入图片描述
    实现透明效果的方法有两种:透明度测试和透明度混合

    透明度测试

    透明度测试实现的效果只有不透明和完全透明两种效果,不需要关闭深度写入。只要小于阈值就舍弃、
    在这里插入图片描述

    Shader "Unity Shaders Book/Chapter 8/Alpha Test" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
    	}
    	SubShader {
    	//IgnoreProjector:使这个shader不受投影器的影响
    	//RenderType:将这个shader归入提前定义的组
    		Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _Cutoff;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    				
    				// Alpha test
    				clip (texColor.a - _Cutoff);
    				// Equal to 
    //				if ((texColor.a - _Cutoff) < 0.0) {
    //					discard;
    //				}
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, 1.0);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/Cutout/VertexLit"
    }
    
    

    透明度混合

    使用当前片元的透明度作为和混合因子和颜色缓冲中的颜色值混合,需要关闭深度写入。
    在这里插入图片描述

    Shader "Unity Shaders Book/Chapter 8/Alpha Blend" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_AlphaScale ("Alpha Scale", Range(0, 1)) = 1
    	}
    	SubShader {
    		Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    
    			ZWrite Off
    			Blend SrcAlpha OneMinusSrcAlpha
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _AlphaScale;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, texColor.a * _AlphaScale);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/VertexLit"
    }
    
    

    开启深度写入的半透明

    增加一个pass,只开启深度写入,不输出颜色值

    Shader "Unity Shaders Book/Chapter 8/Alpha Blending With ZWrite" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_AlphaScale ("Alpha Scale", Range(0, 1)) = 1
    	}
    	SubShader {
    		Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    		
    		// Extra pass that renders to depth buffer only
    		Pass {
    			ZWrite On
    			//ColorMask RGBA0,0代表不输出颜色值
    			ColorMask 0
    		}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    			
    			ZWrite Off
    			Blend SrcAlpha OneMinusSrcAlpha
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _AlphaScale;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, texColor.a * _AlphaScale);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/VertexLit"
    }
    
    

    常见的混合类型

    在这里插入图片描述

    双面渲染

    透明度测试的双面渲染

    Cull Back(剔除背面) | Front(正面) | Off(关闭,即双面渲染)

    透明度混合的双面渲染

    分成三个Pass:背面——正面——混合(因为Pass顺序执行,所以先渲染背面)
    只需要在前两个Pass中cull front 和cull back即可

    Shader "Unity Shaders Book/Chapter 8/Alpha Test With Both Side" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
    	}
    	SubShader {
    		Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    			
    			// Turn off culling
    			Cull Off
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _Cutoff;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    
    				clip (texColor.a - _Cutoff);
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, 1.0);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/Cutout/VertexLit"
    }
    
    
    展开全文
  • unity3D自发光透明SHADER

    热门讨论 2014-06-25 01:45:58
    unity3D的自发光透明SHADER,用于UNITY里面的一种材质的代码
  • 一个项目,做世界地图时,希望未开启的地块是线稿,新地块开启时,做一个上色处理。 想到的方案就是:上了色的彩图盖在线稿上,然后用mask 控制彩图的局部显隐。 然后用mask不同的颜色来区分不同的色块,控制是否...
  • Unity Shader透明效果

    千次阅读 2022-02-16 16:53:04
    unity中,我们通常使用两种方法来实现透明效果:第一种是使用透明度测试,这种方法其实无法得到真正的半透明效果;另一种就是透明度混合。 对于不透明物体,不考虑他们的渲染顺序也能得到正确的排序效果,这是...

    在实时渲染中要实现透明效果,通常会在渲染模型时控制他的透明通道。当开启透明混合后,当一个物体被渲染到屏幕上时,每个片元除了颜色值和深度值之外,它还有另一个属性——透明度。当透明度为1时表示该像素是完全不透明的,当为0时,则表示像素完全不会显示。

    在unity中,我们通常使用两种方法来实现透明效果:第一种是使用透明度测试,这种方法其实无法得到真正的半透明效果;另一种就是透明度混合。

    对于不透明物体,不考虑他们的渲染顺序也能得到正确的排序效果,这是由于强大的深度缓冲的存在。在实时渲染中,深度缓冲是用于解决可见性问题的,它可以决定那个物体的那些部分会被渲染在前面,那些部分会被其他物体遮挡。他的基本思想是:根据深度缓存中的值来判断该片元距离摄像机的距离,当渲染一个片元时,需要把它的深度值和已经存在于深度缓冲中的值进行比较,如果他的之距离摄像机更远,那么说明这个片元不应该被渲染到屏幕上;否则,这个片元应该覆盖掉此时颜色缓冲中的像素值,并把它的深度值更新到深度缓冲中。

    使用深度缓冲,可以让我们不用关心不透明物体的渲染顺序,即使我们先渲染A再渲染B也不用担心B会遮盖掉A,因为再进行深度测试时会判断出B距离摄像机更远,也就不会写入到颜色缓冲中。但如果想要实现透明效果,我们就会关闭深度写入。

    透明度测试:它采用一种“霸道极端”的机制,只要一个片元的透明度不满足条件,那么他对应的片元就会被舍弃。被舍弃的片元将不会再进行任何处理,也不会对颜色缓冲产生任何影响;否则就会按照普通的不透明物体的处理方式来处理它,即进行深度测试,深度写入等。也就是说,透明度测试是不需要关闭深度写入的,它和其他不透明物体最大的不同就是他会根据透明度来舍弃一些片元,虽然简单,但是它产生的效果也很极端,要么完全透明,要么完全不透明。

    透明度混合:这种方法可以得到真正的半透明效果。他会使用当前片元的透明度作为混合因子,与已经存储再颜色缓冲中的颜色进行混合,得到新的颜色。但是,透明度混合需要关闭深度写入,这使得我们要非常小心物体的渲染顺序。需要注意的是,透明度混合之关闭了深度写入,但没有关闭深度测试,意味着,当使用透明度混合渲染一个片元时,还是会比较它的深度值与当前深度缓冲中的深度值,如果他的深度值距离摄像机更远,那么就不会再次进行深度混合操作。这一点决定了,当一个不透明物体出现在一个透明物体前,我们先渲染了不透明物体,它依然可以正常地遮挡住透明物体。也就是说,对于透明度混合来说,深度缓冲是只读的。

    为什么渲染顺序很重要

    对于透明混合技术,需要关闭深度写入,此时我们就要小心处理透明物体的渲染。

    为什么要关闭深度写入呢?如果不关闭深度写入,一个半透明表明背后的表面本来是可以透过它被我们看到的,但是由于深度测试时判断结果是该半透明表面距离摄像机更近,导致后面的表面将会被剔除,我们也就无法透过半透明表面看到后面的物体了。但是,我们由此破环了深度缓冲的工作机制。

    不同的渲染顺序会有什么结果呢。

    我们先渲染B再渲染A,那么由于不透明物体开启了深度测试和深度检验,此时深度缓冲中没有任何有效数据,因此B会首先写入颜色缓冲和深度缓冲。随后我们渲染A,透明物体仍然会进行深度测试,因此我们会发现和B相比A距离摄像机更近,我们会使用A的透明度来和颜色缓冲中的B的颜色进行混合,得到正确的半透明效果。

    如果我们先渲染A再渲染B。渲染A时,深度缓冲中没有任何有效数据,因此A直接写入颜色缓冲中,但由于对半透明物体关闭了深度写入,此时A不会修改深度缓冲。等到渲染B时,B会进行深度测试,发现,深度测试中还没有数据那B就写入到颜色缓冲中了,结果B就会覆盖A的颜色。从视觉上B就出现在了A的前面就错误了。

     

    我们还是考虑不同的渲染顺序有什么不同的结果。

    第一种,先渲染B再渲染A。那么B会正常写入颜色缓冲,然后会和颜色缓冲中的B颜色进行混合,得到半透明的效果。

    第二种情况,我们先渲染A再渲染B。那么A会先写入颜色缓冲,随后B会和颜色缓冲中的A进行混合,这样混合后的结果会反过来,看起来B就在A的前面,得到错误的半透明结果。

    基于这两点,渲染引擎一般都会先对物体进行排序,再渲染。常用的方法是。

    1. 先渲染所有不透明的物体,并开启他们的深度测试和深度写入。
    2. 把半透明物体按照他们距离摄像机的远近进行排序,然后按照从后往前的顺序渲染这些半透明物体,并开启他们的深度测试,但关闭深度写入。

    Unity自定义的五个渲染队列

    透明度测试

    从图中可以看到,透明测试得到的透明效果很极端,要么完全透明,要么完全不透明,他的效果往往像是在不透明物体上挖一个空洞。而且得到的透明效果在边缘处往往参差不起有锯齿,因为在边界纹理的透明度的变化精度问题。为了得到更加柔滑的透明效果,就可以使用透明度混合。

    代码

    Shader "Unity Shaders Book/Chapter 8/Alpha Test" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
    	}
    	SubShader {
    		Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _Cutoff;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    				
    				// Alpha test
    				clip (texColor.a - _Cutoff);
    				// Equal to 
    //				if ((texColor.a - _Cutoff) < 0.0) {
    //					discard;
    //				}
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, 1.0);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/Cutout/VertexLit"
    }
    

    透明度混合

    透明度混合的实现要比透明度测试复杂一些,这是因为我们在处理透明度测试时,实际上跟对待普通不透明的物体几乎是一样的,只是在片元着色器中增加了对透明度判断并裁剪片元的代码。

    透明度混合:这种方法可以真正的得到半透明的效果。它会使用当前片元的透明度作为混合因子,与已经存储颜色缓冲的颜色进行混合,得到新的颜色,但是透明度很合需要关闭深度写入这使得我们要非常小心物体的渲染顺序。

    为了进行很合,我们需要使用Unity提供混合命令——Blend。Blend是unity提供的设置混合模式的命令。想要实现半透明的效果就需要把当前自身色颜色和已经存在于颜色缓冲中的颜色进行混合,混合时使用的函数就是由该命令决定的。

     

    代码 

    Shader "Unity Shaders Book/Chapter 8/Alpha Blend" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_AlphaScale ("Alpha Scale", Range(0, 1)) = 1
    	}
    	SubShader {
    		Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    
    			ZWrite Off
    			Blend SrcAlpha OneMinusSrcAlpha
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _AlphaScale;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, texColor.a * _AlphaScale);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/VertexLit"
    }
    

    开启深度写入的半透明效果

    使用两个Pass来渲染模型:第一个pass开启深度写入,但不输出颜色,他的目的仅仅是为了把模型深度值写入深度缓冲中;第二个pass进行正常的透明度混合,由于上一个pass已经按照像素级别的深度排序结果进行透明渲染。但这种方法的缺点在于,多使用一个pass会对性能造成一定的影响。

    这个新添加的Pass的目的仅仅是为了把模型的深度信息写入深度缓冲中,从而剔除模型中被自身遮挡的片元。因此,在pass的第一行开启了深度写入。在第二行,我们使用一个新的渲染命令——ColorMask。在ShaderLab中,ColorMask用于设置颜色通道的写掩码。

    当ColorMask为0时,意味着该Pass不写入任何颜色通道,即不会输出任何颜色。这正是我们需要的——该pass只需要写入深度缓存即可。

    代码 

    Shader "Unity Shaders Book/Chapter 8/Alpha Blending With ZWrite" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_AlphaScale ("Alpha Scale", Range(0, 1)) = 1
    	}
    	SubShader {
    		Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    		
    		// Extra pass that renders to depth buffer only
    		Pass {
    			ZWrite On
    			ColorMask 0
    		}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    			
    			ZWrite Off
    			Blend SrcAlpha OneMinusSrcAlpha
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _AlphaScale;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, texColor.a * _AlphaScale);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/VertexLit"
    }
    

    ShaderLab的混合命令

    混合还有很多其他的用处,不仅仅是用于透明度的混合。当片元着色器产生一个颜色的时候,可以选择与颜色缓存中的颜色进行混合。这样一来混合就和两个操作数有关:源颜色和目标颜色。源颜色我们可用S表示,指的是由片元着色器产生的颜色值:目标颜色我们用D表示,指的是从颜色缓存中读取到的颜色值。对对他们进行混合后得到的输出颜色,我们用O来表示,他会重新写入到颜色缓存中,需要注意的是,当我们谈及混合中的源颜色目标颜色和输出颜色时,他们都包含了RGBA四个通道的值,而并非仅仅是RGB通道。

    想要使用混合,我们必须开启它。在Unity中,当我们使用Blend命令时,除了设置混合状态以外也开启了混合。但是,在其他图形api中我们是需要手动开启的。

     

     混合操作

     

    常见的混合类型

    通过混合操作和混合因子命令的组合,我们可以得到一些类似Photoshop混合模式中的混合效果:

    //正常,即透明度混合

    Blend SrcAlpha OneMinusSrcAlpha

    //柔和相加

    Blend OneMinnusDstColor One

    //正片叠低,即相乘

    Blend DstColor Zero

    //两倍相乘

    Blend DstColor SrcColor

    //变暗

    BlendOp Min

    Blend One One

    //变亮

    BlendOp Max

    Blend One One

    //滤色

    Blend OneMinusDstColor One

    //等同于

    Blend One OneMinusSrcColor

    //线性减淡

    Blend One One

    双面渲染的透明效果

    虽然上面使用Min和Max混合操作时仍然设置了混合因子,但实际上他们并不会对结果有任何影响,因为Min和Max混合操作回忽略混合因子。另一点是,虽然上面有混合模式并没有设置混合操作的种类,但是他们默认就是使用加法操作,相当于设置了BlendOpAdd。

    在显示生活中,如果一个物体是透明的,意味着我们不但能透过她看到其他物体还能看到她的内部结构。在前面无论是透明度测试还是透明度混合,我们都没有办法观察到正方形内部以及背面的形状,导致物体看起来就像是只有半个一样。这是因为默认情况下渲染引擎剔除了物体背面的渲染图元,只渲染物体的正面。如果我们想要得到双面的渲染效果,我们可以使用Cull命令来控制需要剔除那个面的渲染图元。

    Cull Back Front Off

    如果设置为Back,那么那些背对摄像机的渲染图元就不会被渲染,这也是默认情况下的剔除状态:如果设置为Front,那么那些朝向摄像机的渲染图元就不会被渲染:如果设置为Off,就会关闭剔除功能,那么所有的渲染图元都会被渲染,但由于这时需要渲染的图元数目会成倍增加,因此除非是特殊效果,例如这里的双面渲染的透明效果,通常情况是不会关闭剔除功能的。

    代码 

    Shader "Unity Shaders Book/Chapter 8/Alpha Test With Both Side" {
    	Properties {
    		_Color ("Color Tint", Color) = (1, 1, 1, 1)
    		_MainTex ("Main Tex", 2D) = "white" {}
    		_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
    	}
    	SubShader {
    		Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    		
    		Pass {
    			Tags { "LightMode"="ForwardBase" }
    			
    			// Turn off culling
    			Cull Off
    			
    			CGPROGRAM
    			
    			#pragma vertex vert
    			#pragma fragment frag
    			
    			#include "Lighting.cginc"
    			
    			fixed4 _Color;
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    			fixed _Cutoff;
    			
    			struct a2v {
    				float4 vertex : POSITION;
    				float3 normal : NORMAL;
    				float4 texcoord : TEXCOORD0;
    			};
    			
    			struct v2f {
    				float4 pos : SV_POSITION;
    				float3 worldNormal : TEXCOORD0;
    				float3 worldPos : TEXCOORD1;
    				float2 uv : TEXCOORD2;
    			};
    			
    			v2f vert(a2v v) {
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				
    				o.worldNormal = UnityObjectToWorldNormal(v.normal);
    				
    				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    				
    				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    				
    				return o;
    			}
    			
    			fixed4 frag(v2f i) : SV_Target {
    				fixed3 worldNormal = normalize(i.worldNormal);
    				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    				
    				fixed4 texColor = tex2D(_MainTex, i.uv);
    
    				clip (texColor.a - _Cutoff);
    				
    				fixed3 albedo = texColor.rgb * _Color.rgb;
    				
    				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
    				
    				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
    				
    				return fixed4(ambient + diffuse, 1.0);
    			}
    			
    			ENDCG
    		}
    	} 
    	FallBack "Transparent/Cutout/VertexLit"
    }
    

    展开全文
  • Unity3D Shader系列之描边

    千次阅读 2022-04-08 23:23:03
    Unity Shader-描边效果 Outline Shader offset的作用 Unity Shader 中 Offset 设置的作用 Shader Depth Offset [Polygon Offset] [OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题
  • Unity3D----Unity Shader

    2021-12-03 11:21:46
    借鉴于《Unity Shader 入门精要》
  • Unity3dshader透明模式双pass解决方案

    千次阅读 2021-12-01 00:14:36
    Shader "Unlit/AlphaBlend_2pass" { Properties { _Color("Main Tint",Color)=(1,1,1,1) _MainTex ("Texture", 2D) = "white" {} _AlphaScale("Alpha Scale",Range(0,1))=1 } SubShader { Tags { "Queue"=...
  • Unity Shader 之遮挡透明

    2022-04-05 19:29:19
     当被遮挡时,遮挡部分透明处理,那么需要涉及渲染深度的知识。引擎是如何判断哪个物体在前面哪个物体在后面呢?  深度:每个像素有自己的深度值,离摄像机近的深度小,远的深度大  深度缓冲区:存储每个像素的...
  • Shader "Transparent/VertexLit with Z" {Properties {_Color ("Main Color", Color) = (1,1,1,1)_SpecColor ("Spec Color", Color) = (1,1,1,0)_Emission ("Emissive Color", Color) = (0,0,0,0)_Shininess ("Shini...
  • Unity 3D模型做半透明剪影效果

    千次阅读 2020-08-04 19:37:11
    项目组需要一个类似如下的半透明剪影效果,不过我们是3D模型,那么就需要一些特殊的做法。 最终通过使用Stencil Buffer解决了。 详解 一、刚开始的的自以为是 刚做这个需求之前,以为很容易做,不就是在frag ...
  • Unity3D内部Shader详解

    2017-10-07 15:16:32
    (因此Unity文档里面的Shader,都是指用ShaderLab编写的代码) 然后我们来看下Unity3D自带的60多个Shader。 这些Shader被分为五个大类:Normal,Transparent,Transparent Cutout,Self-llluminated,Reflective。
  • Unity3D Shader系列之透视效果XRay

    千次阅读 2022-03-26 11:27:10
    Shader实现透视效果,X光效果。
  • Shader "Custom/StencilStandardTransparentCull" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _NormalMap("NormalMap", 2D) = "bump" {} _BumpScale(...
  • Unity Shader透明遮罩效果

    千次阅读 2019-12-17 10:40:06
    透明遮罩位于被遮住物体(图中红色)和显示物体(绿色和白色)前面,优先渲染遮罩,第一个Pass记录透明遮罩的深度之后在绘制透明颜色,这样到绘制被遮住物体时,只要开启ZTest就可以使其深度测试失败,透明遮罩罩住...
  • Mesh这个类该怎么使用,可以参考我之前写的《Unity3D C#数学系列之创建圆柱体》。 但是在UGUI上使用时,上面LineRenderer出现的层级问题,这种方式依然会出现,所以也不是一种好的方法。 using System.Collections....
  • Unity3D 双面渲染Shader实现

    千次阅读 2021-10-04 11:46:21
    概述 ...Unity 的standard shader就是这样,我们只要创建一个平面就能看出这种效果。 创建一个平面,默认此平面正面朝上。 我们调整角度从下往上看,平面完全不渲染了。除了一个选中的什么都看不见
  • unity3D简单的水面shader实现
  • unityshader 透明效果:透明度测试、透明度混合、开启深度缓存的透明度混合,双面渲染
  • 猫都能学会的Unity3D Shader入门指南
  • Unity3D Shader 入门第一天

    千次阅读 多人点赞 2018-07-18 15:13:59
    刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D Shader编程望而却步。该系列教程的第一篇文章(译者注:即本文,后续还有5篇文章)详细介绍了Unity3D中的表面着色器...
  • 可以用双面shader解决。发现一个比较好用的,转载码一下。原地址:https://blog.csdn.net/liang_704959721/article/details/88681768 shader代码如下: Shader "yh/DoubleSide" { Properties { _...
  • Awesome-Unity-Shader, 分享炫酷的Unity3D着色器| 关于超酷的Unity3D着色程序 Awesome-Unity-ShaderShader专栏地址:http://blog.csdn.net/column/details/unity3d-shader.html卷 1凹凸纹理显示 自选边缘颜色和强度...
  • // 用于指明该Shader是一个使用了透明度混合的Shader // IgnoreProjector=True这意味着该Shader // 不会受到投影器(Projectors)的影响 // 为了使用透明度混合的Shader一般都应该在SubShader // 中设置...
  • unity找到的最好的描边着色器shader,平常的描边shader加上去后物体没了高光效果,里面的Standard那一款完美解决此问题.
  • 基于物理渲染-unity实现PBR shader + 多光源 + 半透明物体和阴影一,PBR光照1.1直接光照1.1.1直接光照漫反射1.1.2直接光照镜面反射1.2间接光照1.2.1间接光照漫反射1.2.2间接光照镜面反射二,多光源处理+阴影三,...
  • UnityShader入门精要——透明物体阴影

    千次阅读 2022-03-15 12:22:32
    Shader "Unity Shaders Book/Chapter 9/Alpha Test With Shadow" { Properties { _Color ("Color Tint", Color) = (1, 1, 1, 1) _MainTex ("Main Tex", 2D) = "white" {} _Cutoff ("Alpha Cutoff", Range(0, ...
  • 1.记录找到的一个模型描边中间透明shader,大概就是下图Cube这样. 2.脚本 Shader "Unlit/Shaer" { Properties{ _Color("Main Tint", Color) = (1, 1, 1, 1) _MainTex("Texture", 2D) = "white" {} _...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,954
精华内容 781
关键字:

shader半透明 unity3d