쉐이더는 일부 구성 세 SubShader 노트

면책 조항 :이 문서는 블로거 원본입니다, 추적 에 의해-SA의 CC 4.0 저작권 계약, 복제, 원본 소스 링크이 문을 첨부 해주세요.
이 링크 : https://blog.csdn.net/wangjiangrong/article/details/89335208

태그

컬러면이 태그에 의해 결정되는 셰이더를 호출하는 때를 결정하는 개질 하드웨어 라벨 (태그) 복수 일 수있다. 예를 들어 태그 { "RenderType"= "불투명"} , 시스템이 렌더링해야 말해 불투명 한 물체를 할 때 우리를 호출합니다. 화합은 렌더링 과정의 연속을 정의하고, 불투명 RenderType 명백하다 대응 "RenderType" = "Transparent"도시 렌더링 포함하는, 투명성을 때 개체를 호출. 다음은 출력이 불투명 년에 기록, 투명하지 않은 객체 인 경우, 사실에 쉐이더 출력 무엇인지 힌트를 태그, 당신은 투명 또는 반투명 픽셀을 렌더링 할 경우, 그것은 투명 작성해야합니다.

또한이 유용한 라벨 " IgnoreProjector" =" True" , ((프로젝터) 효과 돌출되지 않는다) " ForceNoShadowCasting" =" True" (그림자가 발생하지 않음) 및 " Queue" =" xxx" 와 같은 (순서 큐 렌더링을 지정),

Tags
{
    "Queue" = "Transparent"
    "IgnoreProjector" = "True"
    "RenderType" = "Transparent"
}

여기에 당신은 유니티가 투명하고 불투명 한 물체의 어떤 조합을 이루어 사용하는 경우에 대한 라벨 큐 인 이야기에 초점을 원하십니까, 불투명 한 물체가 투명 오브젝트 후 경우에 렌더링 할 수 없습니다 경험 한 것 같다. 이는 쉐이더 렌더링이 발생하는 잘못된 순서로 가능성이 높습니다. 큐는 큐 소정와 물체 (작은 값, 이전에 렌더링)의 렌더링 순서 지정

렌더링 대기열 대기열 설명 렌더링 큐 값을 렌더링
배경 이 큐는 먼저 렌더링된다. 이 같은 스카이 박스를 사용한다. 1,000
기하학 이는 기본 렌더링 대기열입니다. 그것은 개체의 대부분에 사용됩니다. 큐를 사용하여 불투명 기하. 2,000
AlphaTest 큐를 사용하여 채널 형상을 확인합니다. 기하학과 다른 큐, 모든 채널의 관점보다 효율적으로 렌더링 그리기 개체의 검사를위한 객체입니다. 2,450
투명한 큐 렌더링과 기하학 AlphaTest 큐 후 렌더링합니다. 믹싱 채널의 상관 (즉, 깊이 버퍼 쉐이더에 기록되지 않은) 유리 입자 효과와 큐 오브젝트를 사용. 3000
위에 까는 것 렌더 큐 효과 및 서비스를 커버한다. 상관 마지막 렌더링 큐 오브젝트, 예를 들면, 렌즈 플레어. 4000

우리가 실제로 큐 값을 설정하는 경우뿐만 아니라, 당신은 우리는 또한 다음과 같이 기록 된 자신의 가치 대기열을 지정할 수 있습니다, 위의 몇 가지 미리 정의 된 값을 사용할 수 있습니다 : "Queue"="Transparent+100"투명 (100) 이후 대기열에 전화를 나타냅니다. 값 대기열을 조정하여, 우리는이 기술은 때때로 매우 유용, 이전 또는 렌더링 후 특정 다른 오브젝트에서 그 특정 개체를 보장 할 수 있습니다.

 

LOD

LOD는 (세부 수준), 즉 LOD (200)로서, (사실 내장 유니티의 확산 쉐이더 설정 값이다) (200)로 지정. 이 값은 우리가 쉐이더 할 수있는 작업을 결정합니다. LOD를가 LOD를 사용할 수없는이 SubShader 지정 설정 SubShader보다 작은 경우 품질 설정 유니티 LOD에서 우리는, 최대 허용을 설정할 수 있습니다. 그들의 LOD가 그들의 셰이더를 실현할 때 유니티 내장 쉐이더 LOD 값들의 세트를 정의하고, 우리는 기준값으로 설정할 수 있도록하는 조정은 더 정확하게 화질을 조정하는 장치 성능 그래픽에 따라 제조 될 수 후 제어 할 수 있습니다.

LOD 설정 매개 변수는 유니티 셰이더에 내장
이름
그 시리즈 VertexLit (100)
칼, 반사 VertexLit (150)
퍼지다 (200)
확산 세부 사항, 반사 충돌 꺼짐, 반사 부딪혀 VertexLit (250)
부딪혀, 경면 (300)
부딪혀 경면 (400)
시차 (500)
시차 경면 600

 

도태 (제외)

이 설정으로, 우리는 성능을 최적화하기 위해, 다양한 상황에서 사용되는 사용자 평면에 보이지 제거 할 수 있습니다. 우리는 다음과 같은 세 가지 속성을 가지고

도태로 돌아 가기 (기본값) 다시 렌더링하지 않기
도태 전면 아니 긍정적 렌더링하기
오프 추려 양측을 폐쇄하는 효과를 렌더링 제외

예를 들어, 비행기 (기본 추려 돌아 가기)를 만들 수있는 장면에서, 당신은 일반적으로 장면 뷰에서 비행기를 볼 수 있지만 당신은 비행기의 관점에서 장면의 뒤쪽으로 이동할 때, 비행기 추려 인, 사라진를 찾을 수 돌아 효과가있다. 따라서 다음 양쪽 (우리는 인상을 시도 할 수 있습니다 더 손을) 볼 수있는 오프 추려, 추려 전면 반대, 도입 할 수

 

ZWrite (쓰기 깊이) / ZTEST (깊이 테스트)

ZWrite 단편 결정된 깊이 값이 깊이 버퍼에 기록되어 구성 될 수있다 (ZWrite에서 (기본) / 오프 ZWrite)

ZTEST 후 시험에서의 결과는 단편이 삭제되어 있는지 여부를 확인, 다음의 구성

ZTEST 이하 현재 버퍼보다 ​​깊이 스루
ZTEST 큰 버퍼 흐르는 전류보다 더 깊게
ZTEST LEqual (기본값) 버퍼를 통한 전류와 동일 깊이보다 적은
ZTEST GEqual 이것은 버퍼를 통한 전류와 동일 깊이보다 크다
ZTEST 평등 캐시를 통해 현재와 같은 깊이
ZTEST 같지 않음 현재의 버퍼의 깊이를 통한 동일하지 않은
ZTEST 항상 에 관계없이를 통해 (ZTEST 오프 ZTEST 항상 동일)

거기 시스템이다 컬러 버퍼깊이 버퍼 및 컬러 값을 화면에 표시되어야 하는지를 결정하는 색 깊이 값을 저장한다. 객체의 깊이 값은 월드 공간 거리에있는 카메라입니다. 큰 거리, 큰 심도 값, 깊이 값이 작을수록 짧은 거리.

다음 메인 흐름은 : 제 판단 깊이 테스트를 열 것인지, 열 경우 , 프래그먼트 깊이 값과 깊이 값이 이미 깊이 버퍼에 존재하는 구성에 따라 얻어진 결과와 비교된다. 이 깊이 테스트를 통과하면 , 다시, 기록 가능 깊이 깊이 값 (즉, 어떤 기록이 설정되지 아니된다), 깊이 버퍼에 기록하고, 처리를 종료 될 경우, 기록 오픈 깊이는, 상기 컬러 버퍼가 기록되어 있는지 여부를 판정한다 당신이 깊이 테스트를 통과하지 않을 경우 직접 조각, 프로세스의 끝을 폐기합니다. 열린 테스트 깊이가없는 경우 , 직접 깊은 쓰기를 열고 뒤에 관련 프로세스를 수행할지 여부를 판단합니다.

그것은과 같이 요약 될 수있다

1. 깊이 테스트가 통과되면, 기록 오픈 깊이 : 깊이 버퍼 물품은 컬러 버퍼가 작성된 

2. 깊이 테스트는, 쓰기의 깊이를 전달합니다, 깊이 버퍼 쓰기 컬러 버퍼를 쓰지 않는다 

색상 버퍼를 작성하지 않는, 깊이 버퍼를 쓰지 않는다 3. 깊이 테스트는, 또는 해제 깊이 쓰기 실패

 

혼합 (믹스)

주요 역할을 혼합하여 색상 혼합이 다음 픽셀이 잘 그려되었습니다 형성되는 모든 렌더링 된 이미지의 완료 후에 실시하고, 화면에 그래픽 이미지를 가지고있다, 혼합 색상을하지만, 객체이기 때문에 완전히 완료되지 않은 각 캐시에 저장 자신의 미완성 그림을 가지고 있지만 알파 효과가 밖으로 재생 아직, 당신은 이미지가 모든 엔티티가 아닌 반투명하고 투명한 부분이되기 전에 화면에, 믹스를 추가 할 필요가있다. 짧은 혼합에서 가장 중요한 역할은 알파는 물론, 변경, 색상을 강화 혼합, 등등 약화 및 위해 할 수있는 역할 반투명를 재생하는 것입니다.

참조 : "고급 프로그래밍 Unity3D 고급 메인 프로그램,"제 VII, 쉐이더 (육) - 패스 (3 개) 혼합을

우리는 "원색"기존 "목표 색"이라고 (배경색)의 색에 대응하는 프레임 버퍼의 픽셀 셰이더로서 산출 색 조각. 혼합 연산은 어떤 옵션과 결합 된 목표 색으로 원색으로한다. 다음과 같은 형식입니다 :

Blend SrcFactor DstFactor

우리는 RGBA 색상을 계산하기 위해 다음과 같은 식으로 처리를 혼합하는 옵션을 선택 :

float4 result = SrcFactor * fragment_output + DstFactor * pixel_color;

SrcFactor DstFactor하고 다음 값을 가질 수있는 상기 (원의 색 A, 원래 채널 A_alpha이 목표 색이 B 인 것을 가정, 대상 채널 B_alpha이다)

하나

1의 값은이 요소는 원색으로 또는 완전히 관통 목표 색의 프레임 버퍼를 확인한다. * 1
제로 원색 또는 목표 색의 프레임 버퍼를 제거하는이 인자의 값을 이용하여, 0. * 0
SrcColor 현재 프레임 버퍼 원색 값의 계수를 곱한 값을 사용   *는을
Shrcalf 이 요소를 사용하는 것은 알파 소스 컬러 프레임 버퍼의 현재 값에 의해 승산된다.  * A_alpha
DstColor 이 요소를 사용하는 것은 상기 타겟 컬러 프레임 버퍼의 현재 값에 의해 승산된다. * B
DstAlpha 이 요소를 사용하는 것은 현재 프레임 버퍼 알파 목표 색 성분 값으로 곱해진다.  * B_alpha
OneMinusSrcColor (프레임 - 버퍼 원색 값 1)이 계수의 현재 값을 곱하여  * (1 - A)
OneMinusSrcAlpha - 현재의 값이 계수 (프레임 버퍼의 알파 컴포넌트 원색 값 l)을 곱   * (1 - A_alpha)
OneMinusDstColor 이 인자의 현재 값이 곱해진다 (1 - 목표 색상 값)  * (1 - B) 
OneMinusDstAlpha 현재의 값이 계수 (L - 대상 성분의 알파 값)를 곱한 값이다  * (1 - B_alpha) 

예를 들면 :

SRCALPHA OneMinusSrcAlpha를 혼합 X + 원색 소스 채널 목표 색 × (1 - 소스 채널)  A * A_alpha + B * (1 - B_alpha)
하나 하나를 혼합 源颜色 + 目标颜色(叠加模式) A + B
Blend SrcAlpha One 源颜色 x 源通道 + 目标颜色(带通道的叠加模式) A * A_alpha + B
Blend DstColor SrcColor 源颜色 x 目标颜色 + 目标颜色 x 源颜色(正片叠底的效果) A * B + A * B
Blend DstColor Zero 源颜色 x 目标颜色 + 0(目标颜色 x 0) A * B + 0

 

颜色的相加与相乘:

1,颜色乘法,可以视为颜色(或者说图像)的叠加

为什么乘法颜色节点能够让颜色叠加。 我们把两个RGBA值转换成为0-1之间的范围就可以明白了。 比如白色(1,1,1,1),灰色(0.5,0.5,0.5,1),两个颜色相乘得到(0.5,0.5,0.5,1) 还是灰色,也就是说在白色的底板上,画上灰色的颜色,颜色就叠加了,这就是颜色的叠加方法。

颜色相乘的公式是 Color a, Color b, a*b = new Color(a.r * b.r, a.g * b.g, a.b * b.b, a.a * b.a); 从此公式可以看出,因为所有数字都小于等于1,所以相乘只会让颜色更加深,也就是更加接近黑色,不断的叠加各种各样的颜色,最后都会无限接近黑色(0,0,0,1)或者无限接近黑色透明(0,0,0,0)

2,颜色加法,可以视为颜色(或者说图像)加白(或者说亮)。

为什么说加法可以视为颜色的加白操作。因为颜色相加后,不能超过最大值1(或者另一种表达方式的数字255),超过部分都会被截断。加法的公式是:Color a, Color b, a+b = new Color(a.r + b.r, a.g + b.g, a.b + b.b, a.a + b.a); 从此公式可以看出,所有的数字都小于等于1,所以r,g,b,a,随着不断加各种颜色,最终会到达最大值1。也就是不透明白色(1,1,1,1)

 

实例演示

举几个简单的例子来对上面的一些知识点进行深入理解,小伙伴们自己也可以动手试试举一反三。

首先我们先创建两个最简单的shader,Custom/ShaderDemo1和Custom/ShaderDemo2,内容相同如下(名称不一样),并分别挂在两个新的material下。同时光源的颜色设置为白色,去除光源摄像机的阴影效果。

Shader "Custom/ShaderDemo1" {
	
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
	}
	
	SubShader {
		Tags { "RenderType"="Opaque"}
		
		CGPROGRAM
		#pragma surface surf Lambert//使用Lambert光照色差较小

		fixed4 _Color;

		struct Input {
			float3 viewDir;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			o.Albedo = _Color.rgb;
			o.Alpha = _Color.a;
		}
		ENDCG
	}
}

然后我们在场景中创建两个Cube,挂上新的material,color值自行设置(例子中为蓝色对应shader1和绿色对应shader2)。将摄像机的Clear Flags设置为Solid Color,Background自行设置即可(例子中为红色,方便看效果)。如下。

在这里我们做个假设,由于蓝色方块离摄像机较近,我们暂定为蓝色方块的深度值为0.3,绿色方块的深度值为0.6,摄像机的深度值为1。

打开Window->Frame Debugger可以查看渲染的顺序,我们可以看到系统先渲染了蓝色方块,然后渲染绿色方块(修改Queue值可以修改渲染顺序,例子中Queue值相同),由于默认的Zwrite On与ZTest LEqual(深度小于等于当前缓存则通过)。所以系统会先渲染蓝色方块,现在缓存中对比屏幕的深度值1。0.3<1即全部通过。显示蓝色方块并将0.3的深度值写入缓存中。接着渲染绿色方块的时候。被遮挡的部分深度值0.6与缓存中的0.3对比,0.6>0.3不通过则不渲染,未遮挡的部分与1比较,0.6<1,渲染。得到上面的画面。

这个时候如果我们将蓝色方块的shader1添加一句ZWrite Off,即渲染完蓝色方块后不会将蓝色方块的深度值写入深度缓存。所以再之后渲染绿色方块的时候,将和深度1相比较,全部通过。

假设我们shader1继续为ZWrite Off,但是将绿色的shader2修改为ZTest GEqual(深度大于等于当前缓存则通过)。即渲染绿色的时候被遮挡部分0.6>0.3,通过渲染,未被遮挡部分0.6<1,未通过不渲染,如下:

有关ZWrite 和 ZTest 的暂时就举例这么多,小伙伴们可以自己试试其他参数其他情况。

假如现在我们要让蓝色的小方块变为透明,但是只修改蓝色material的color的布尔值并不会起效果,根据第一篇的内容,我们需要将fullforwardshadows改为alpha。效果如下

可以发现,虽然蓝色方块确实变透明了,但是绿色方块的层级并不对。但是在shader中我们并没有关闭ZWrite和修改ZTest。通过Frame Debug我们可以发现,渲染顺序依旧是先蓝色后绿色,但是蓝色的ZWrite却被关闭了(透明物体不写入深度缓存)。根据上面的知识,我们应该将蓝色方块的material的Render Queue值设为Transparent(先渲染绿色方块再渲染蓝色方块),即可得到正确的效果

 

接下来我们试试Blend。新建一个Shader如下:

Shader "Custom/BlendDemo" {
	Properties {
		_Color("Color", Color) = (1,1,1,1)
	}

	SubShader {
		Tags{ "RenderType" = "Transparent"  "Quene" = "Transparent" }
		
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata {
				float4 vertex : POSITION;
			};

			struct v2f {
				float4 vertex : SV_POSITION;
			};

			v2f vert (appdata v) {
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				return o;
			}
			
			fixed4 _Color;

			fixed4 frag (v2f i) : SV_Target {
				return _Color;
			}
			ENDCG
		}
	}
}

同样新建一个material关联此shader并绑定到cube_blue上,cube_green不变,此时不管怎么改变新的shader上颜色的透明度,发现都不会有效果。

此时假设我们蓝色方块的RGB值为(0,255,255)即(0,1,1),透明度为0.7。绿色方块的RGB值为(0,255,0)即(0,1,0),透明度为1,背景红色RGB值为(255,0,0)即(1,0,0),透明度为1。

想要实现透明,我们可以加一句Blend SrcAlpha OneMinusSrcAlpha即可。效果如下:

通过上面的知识,我们知道SrcAlpha是自己的透明通道即值为0.7,OneMinusSrcAlpha即为1 - 0.7 = 0.3。

蓝色和红色的部分,原颜色即为蓝色(0,1,1),目标颜色即为红色(1,0,0)得

最终颜色 = (0,1,1) * 0.7 + (1,0,0) * 0.3 = (0,0.7,0.7) + (0.3,0,0) = (0.3,0.7,0.7) = (77,179,179)

蓝色和绿色的部分,原颜色即为蓝色(0,1,1),目标颜色即为绿色(0,1,0)得

最终颜色 = (0,1,1) * 0.7 + (0,1,0) * 0.3 = (0,0.7,0.7) + (0,0.3,0) = (0,1,0.7) = (0,255,179)

我们通过颜色选择工具获取透明蓝色方块的两种颜色可以发现正确无误。

 

 

 

 

 

 

추천

출처blog.csdn.net/wangjiangrong/article/details/89335208