【Reading Notes】cp6-Fragment Shaders and Grab Pass
앞에 쓰다
지금까지 우리는 모두 Surface Shaders를 바탕으로 기능을 실현했다.Surface Shader의 디자인은 간단한 Shader 인코딩 실현 방법을 제공하여 예술가에게 매우 의미 있는 도구를 제공했다.Shader에 대해 더 알고 싶다면, 버텍스(정점)와 Fragment(편원) 착색기의 영역에 발을 들여놓을 때가 됐다.
본 장 내용: + 정점 착색과 편원 착색의 기본 이해 + Grab pass + Grab 착색 + 물 효과 실현, 2D 게임
소개하다.
Surface Shader에 비해 교점과 패브릭 착색기는 물리적 음영처리 기능이 적지만 더 강력한 에너지로 바뀌어 물리적 구속이 없어 비현실적인 렌더링 효과를 많이 실현할 수 있다.이 장에서는 쉐더가 물체의 변형을 시뮬레이션할 수 있도록 하는 Grab Pass를 중점적으로 다룹니다.
정점 착색기와 필름 착색기의 기본을 이해하다
vertex와 Fragment 착색기를 배우는 가장 좋은 방법은 직접 하나를 실현하는 것이다.이 소절은 간단한vertex,fragment 착색기를 실현하여 주 무늬와 색을 간단하게 읽을 수 있습니다.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "CookbookShaders/self/grab" {
Properties {
_MainTex("Base (RGB) Trans(A)", 2D) = "white"{}
_Color("Color", Color) = (1, 1, 1, 1)
}
SubShader{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float _Magnitude;
float4 _Color;
struct vertInput
{
float4 vertex: POSITION;
float2 texcoord: TEXCOORD0;
};
struct vertOutput
{
float4 vertex: POSITION;
float2 texcoord: TEXCOORD0;
};
vertOutput vert(vertInput v)
{
vertOutput o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
return o;
}
half4 frag(vertOutput i):COLOR
{
half4 mainColor = tex2D(_MainTex, i.texcoord);
return col * mainColor * _Color;
}
ENDCG
}
}
FallBack "Diffuse"
}
How is works 주요 사항
#pragma vertex vert
#pragma fragment frag
struct vertInput
{
float4 vertex: POSITION;
float2 texcoord: TEXCOORD0;
};
struct vertOutput
{
float4 vertex: POSITION;
float2 texcoord: TEXCOORD0;
};
어의 귀속
묘사
POSITION, SV_POSITION
정점의 좌표, 모형 공간에서float3/float4
NORMAL
정점의 법방향량,float3
TEXCOORD0 … TEXCOORDi
무늬 좌표,float2/float3/float4
TANGENT
수직 매핑용 탄젠트 벡터, float4
COLOR, COLOR0, DIFFUSE, SV_TARGET
정점 색상 정보, float4
COLOR1
정점에 저장된 두 번째 색은 보통 하이라이트 색이다.float4
+ 출력 구조 의미 귀속
의미
묘사
POSITION, SV_POSITION, HPOS
정점 좌표, 카메라 좌표계 내(clip space, 범위 0-1)
COLOR, COLOR0, COL0, COL, SV_TARGET
주색
COLOR1, COL1
두 번째 색상
TEXCOORD0…TEXCOORDi
텍스쳐 좌표
WPOS
The position, in pixels, in the window(origin in the lower left corner) (잘 모름)
비록 의미 귀속이라고 하지만 사실 구조 안에 어떤 데이터를 저장해야 하는지는 개발자가 제어할 수 있는 것이다.NORMAL의 데이터를 POSITION 의미로 충분히 저장할 수 있습니다.
Grab Pass 사용
4장에서는 PBR 재료에 투명 속성을 추가하여 한 재료가 어떻게 투명하게 이루어지는지 알 수 있습니다.투명도 재료는 장면에 그려질 수 있지만 장면에 그려진 것은 바꿀 수 없다.이것 또한 이런 재질이 유리나 물 아래의 무대 모양을 나타낼 수 없다는 것을 나타낸다.이러한 변형을 시뮬레이션하기 위해 Grab pass라는 새로운 기술을 소개합니다. 이것은 현재 그려진 장면에 그려진 데이터를 방문하여 사용할 수 있도록 합니다.
Grab pass
코드는 간단합니다. grab pass는 Unity가 정의한 특수한 pass입니다. 그는 자동으로 TextureName이라는 무늬를 만들 것입니다. 기본 이름은 입니다.GrabTexture, 다음 패스에 정의해야 접근할 수 있습니다.이 무늬에 대한 샘플링을 통해 현재 그리기 전의 내용을 얻을 수 있습니다.샘플링의 무늬 좌표를 계산하는 사고방식은 정점 좌표를 화면 좌표로 바꾸는 것이다. 여기에Unity는 우리에게 내부의 사랑 함수를 제공한다. ComputeGrabScreenPos(o.vertex).그리고 메타 셰이더의 실제 샘플링 시 매크로 UNITY 사용PROJ_COORD가 마지막 결과를 얻었는데 이 매크로는 그가 원래의 값을 되돌렸다고 볼 수 있다. 그의 정의를 보면 PSP에 따라 구분했을 뿐이라는 것을 알 수 있다.
#if defined(SHADER_API_PSP2)
#define UNITY_BUGGY_TEX2DPROJ4
#define UNITY_PROJ_COORD(a) (a).xyw
#else
#define UNITY_PROJ_COORD(a) a
#endif
GrabPass{"TextureName"}
유리 효과를 실현하다
유리는 비교적 복잡한 재질로 대부분의 유리 재질은 완벽하지 않다. 왜냐하면 더욱 완벽해지기 위해 유리를 통해 보이는 물체가 변형되기 때문이다.사상은 정점과 편원 착색기에서 Grab pass의texture를 이용하여 UV 무늬 좌표를 약간 바꾸어 형태를 구성하는 것이다.
구체를 통해 형변(투명하지 않아도 볼 수 있는)을 볼 수 있고 2기는 측면에서 보면 환경이 비치는 효과도 볼 수 있다.편원 착색기 코드를 통해 알 수 있듯이 우리는 법선 방향을 따라 Grab pass 무늬에 대한 샘플링을 바꾸어 보이는 변형 효과에 도달했다.
Shader "CookbookShaders/self/grab" {
Properties {
_MainTex("Base (RGB) Trans(A)", 2D) = "white"{}
_BumpMap("Noise text", 2D) = "bump" {}
_Magnitude("Magnitude", Range(0, 1)) = 0.05
_Color("Color", Color) = (1, 1, 1, 1)
}
SubShader{
Tags{ "Queue" = "Transparent" }
GrabPass
{
"_GrabTexture"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _GrabTexture;
sampler2D _MainTex;
sampler2D _BumpMap;
float _Magnitude;
float4 _Color;
struct vertInput
{
float4 vertex: POSITION;
float2 texcoord: TEXCOORD0;
};
struct vertOutput
{
float4 vertex: POSITION;
float2 texcoord: TEXCOORD0;
float4 uvgrab: TEXCOORD1;
};
vertOutput vert(vertInput v)
{
vertOutput o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
o.uvgrab = ComputeGrabScreenPos(o.vertex);
return o;
}
half4 frag(vertOutput i):COLOR
{
half4 mainColor = tex2D(_MainTex, i.texcoord);
half4 bump = tex2D(_BumpMap, i.texcoord);
half2 distortion = UnpackNormal(bump).rg;
i.uvgrab.xy += distortion * _Magnitude;
fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
return col * mainColor * _Color;
}
ENDCG
}
}
FallBack "Diffuse"
}
실현수, 2D 게임즈
원리와 위의 차이는 단지 소음 스티커와 인 함수를 추가하여 대형변화의 시간에 따라 변화를 실현할 뿐이다.여기는 서술이 많을 뿐이다.
Shader "CookbookShaders/self/water" {
Properties{
_NoiseTex("Base (RGB) Trans(A)", 2D) = "white"{}
_Period("Period", Range(0, 50)) = 1
_Magnitude("Magnitude", Range(0, 1)) = 0.05
_Color("Color", Color) = (1, 1, 1, 1)
_Scale("Scale", Range(0, 10)) = 1
}
SubShader{
Tags{ "Queue" = "Transparent" }
GrabPass
{
"_GrabTexture"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _GrabTexture;
sampler2D _NoiseTex;
float _Period;
float _Magnitude;
float4 _Color;
float _Scale;
struct vertInput
{
float4 vertex: POSITION;
float2 texcoord: TEXCOORD0;
float4 uvgrab: TEXCOORD2;
};
struct vertOutput
{
float4 vertex: POSITION;
fixed4 color : COLOR;
float2 texcoord: TEXCOORD0;
float4 worldPos: TEXCOORD1;
float4 uvgrab: TEXCOORD2;
};
vertOutput vert(vertInput v)
{
vertOutput o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.uvgrab = ComputeGrabScreenPos(o.vertex);
return o;
}
half4 frag(vertOutput i) :COLOR
{
float sinT = sin(_Time.w / _Period);
float2 distortion = float2(tex2D(_NoiseTex, i.worldPos.xy / _Scale + float2(sinT, 0)).r - 0.5,
tex2D(_NoiseTex, i.worldPos.xy / _Scale + float2(0, sinT)).r - 0.5
);
i.uvgrab.xy += distortion * _Magnitude;
fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
col *= _Color;
return col;
}
ENDCG
}
}
FallBack "Diffuse"
}
최후
효율성에서 볼 때Grab Pass는 비교적 나쁘기 때문에 매번 렌더링을 해서 추가texture를 생성해야 한다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Unity 최적화1. 프레임마다 처리하는 것을 최대한 피한다. 예를 들면: 5프레임당 한 번 처리로 변경할 수 있습니다. 2. 정시 반복 처리는 InvokeRepeating 함수로 이루어집니다. 예를 들어 0.5초 동안 시작한 후 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.