Shader 및 ShaderToy 시작

앞에 쓰기

        유니티가 공부하고 일한 지 3 년이 지났습니다. 개발에서 가장 먼저 만나는 것은 바이두 검색입니다. 내 자신의 아이디어가 없었고 부끄럽습니다. 더 이상 혼란스럽지 않다는 생각에 블로그를 열어서 개발에 도움이 된 것을 기록하기로 결정했습니다. 언젠가 내 인생이 헛된 것 같지 않았 으면 좋겠습니다. 도움이 필요한 일부 학생들을 도울 수 있다면 더 좋을 수 없습니다.

셰이더 정보

        말하자면 이전에 C #을 배웠기 때문에 셰이더와도 밀접한 관련이 있고, 첫 번째 일은 웹 사이트 백엔드 개발입니다. 유니티를 배우고 나서 도로에 익숙해 져 어렵지 않습니다. 기사를 훑어 보면서 조금만 안다는 걸 깨달았지만 인터뷰는 큰 문제가되지 않을 것 같아 인터뷰 전날 밤 인터뷰 질문을보고 셰이더의 존재를 깨달았습니다. 다음날 인터뷰는 Shader와 관련이있었습니다. 블로그의 첫 번째 기사는 Shader와 관련이 있습니다. 아마도 원래 의도로 돌아 가기 위해 아마도 그해에 처음으로 심어진 것입니다.

        이 쉐이더와 관련하여 블로거 candycat 에 대해 이야기해야합니다 . 작업을하고 난 후 기본적으로 개인적으로 해결할 수없는 셰이더 문제가 발생했습니다. 저를 데려 간 사람이이 블로거를 추천했습니다. 당시에는 CSDN 계정으로 로그인도하지 않았기 때문에 그녀의 기사를 하나씩 보면서 셰이더에 대해 배웠습니다. 그 기간 동안 그녀가 출판 한 셰이더 책도 구입했지만 아직 다 읽었 기 때문에 부끄럽습니다. 지금까지 배운 후에 셰이더를 이해할 수는 없지만 적어도 셰이더 코드를 읽고 간단한 셰이더 효과를 작성하는 것은 큰 문제가 아닙니다. Candycat 이 나보다 어린 소녀 라고 말하면 무의식적 인 감탄은 또 다른 요점을 추가합니다.

        최근 블로거의 shadetoy 관련 기사를 읽을 시간이 생겼기 때문에 shadertoy를 작성하고 싶습니다. 하지만 솔직히 말씀 드리면 이미 셰이더에 대해 어느 정도 이해하고있는 것 같지만 여전히 배우기가 매우 어렵습니다 .2 주간의 모색 끝에 조금 이해했을 것이므로이 셰이더 토이를 개입 포인트로 사용하고 싶습니다 내 자신의 학습 노트를 시작합니다. 무의식적으로 말도 안되는 글을 많이 썼으니 그냥 글쓰기를 시작하자.

본문

        shadertoy의 효과와 원리는 말할 것도없이 여기를 클릭 하여 관심이 있는지 확인할 수 있습니다 . 저는 Unity를 배우고 있기 때문에 Unity의 Shaderlab으로 전환 한 후에도 Shadertoy를 사용하는 것을 선호합니다. 가장 먼저 이야기 하고 싶은 것은 candycat 의 shadertoy to shaderlab 템플릿 입니다 . 아래는 블로거의 원본 코드입니다.

//Design By candycat(https://blog.csdn.net/candycat1992)
Shader "Shadertoy/Template" { 
    Properties{
        iMouse ("Mouse Pos", Vector) = (100, 100, 0, 0)
        iChannel0("iChannel0", 2D) = "white" {}  
        iChannelResolution0 ("iChannelResolution0", Vector) = (100, 100, 0, 0)
    }

    CGINCLUDE    
    #include "UnityCG.cginc"   
    #pragma target 3.0      

    #define vec2 float2
    #define vec3 float3
    #define vec4 float4
    #define mat2 float2x2
    #define mat3 float3x3
    #define mat4 float4x4
    #define iGlobalTime _Time.y
    #define mod fmod
    #define mix lerp
    #define fract frac
    #define texture2D tex2D
    #define iResolution _ScreenParams
    #define gl_FragCoord ((_iParam.scrPos.xy/_iParam.scrPos.w) * _ScreenParams.xy)

    #define PI2 6.28318530718
    #define pi 3.14159265358979
    #define halfpi (pi * 0.5)
    #define oneoverpi (1.0 / pi)

    fixed4 iMouse;
    sampler2D iChannel0;
    fixed4 iChannelResolution0;

    struct v2f {    
        float4 pos : SV_POSITION;    
        float4 scrPos : TEXCOORD0;   
    };              

    v2f vert(appdata_base v) {  
        v2f o;
        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
        o.scrPos = ComputeScreenPos(o.pos);
        return o;
    }  

    vec4 main(vec2 fragCoord);

    fixed4 frag(v2f _iParam) : COLOR0 { 
        vec2 fragCoord = gl_FragCoord;
        return main(gl_FragCoord);
    }  

    vec4 main(vec2 fragCoord) {
        return vec4(1, 1, 1, 1);
    }

    ENDCG    

    SubShader {    
        Pass {    
            CGPROGRAM    

            #pragma vertex vert    
            #pragma fragment frag    
            #pragma fragmentoption ARB_precision_hint_fastest     

            ENDCG    
        }    
    }     
    FallBack Off    
}

        솔직히 말해서 코드는 몇 줄을보기 전에 깜짝 놀랐습니다. 왜 하위 셰이더 외부에 셰이더 랩 코드의 큰 부분이 있습니까? 세 줄의 pragma 명령이 하위 셰이더 채널에 추가되는 이유는 무엇입니까? 버텍스 쉐이더와 프래그먼트 쉐이더는 어떻습니까? 질문이 하나씩 나왔지만 여전히 총알을 깨고 코드를 다시 작성했습니다 (코드 작성은 정말 중요합니다!). 정보를 확인하라고 강요했고, 마침내 단서를 찾았고, 다시 한 번 내가 배우지 못한다고 한탄했습니다.

         사실 코드를 볼 때 키워드를 놓쳤습니다.

CGINCLUDE

        처음봤을 때 CGINCLUDE를 shaderlab의 CGPROGRAM으로 직접 이해했습니다. 코드를 입력 할 때 자신있게 # 기호를 그 앞에 추가했습니다. 끔찍한 내기였습니다. 위의 코드에는 CGINCLUDE와 ENDCG 사이에 사용자 정의 코드 세그먼트가 있으며 현재 shaderlab에서 여전히 호출되므로 포함 정보가 없습니다. 서브 셰이더 SubShader의 채널 아래에있는 vert 및 frag 참조는 위의 사용자 정의 코드 세그먼트에 정의 된 두 가지 함수입니다. 이제 갑자기이 템플릿을 이해 했으니 위의 템플릿을 기반으로 이해할 수있는 버전으로 복원하게되는데 코드는 다음과 같습니다.

Shader "Shadertoy/Template" { 
    Properties{
        iMouse ("Mouse Pos", Vector) = (100, 100, 0, 0)
        iChannel0("iChannel0", 2D) = "white" {}  
        iChannelResolution0 ("iChannelResolution0", Vector) = (100, 100, 0, 0)
    }
    SubShader {    
        Pass {    
            CGPROGRAM    
            #pragma vertex vert    
            #pragma fragment frag 
			//使用低精度来提升片段着色器的运行速度 一般指fp16 半精度
            #pragma fragmentoption ARB_precision_hint_fastest     
			#include "UnityCG.cginc"   
			#pragma target 3.0      
			//定义各种常用宏
			#define vec2 float2
			#define vec3 float3
			#define vec4 float4
			#define mat2 float2x2
			#define mat3 float3x3
			#define mat4 float4x4
			#define iGlobalTime _Time.y
			#define mod fmod
			#define mix lerp
			#define fract frac
			#define texture2D tex2D
			//_ScreenParams为屏幕的分辨率
			#define iResolution _ScreenParams
  			

			#define PI2 6.28318530718
			#define pi 3.14159265358979
			#define halfpi (pi * 0.5)
			#define oneoverpi (1.0 / pi)

			fixed4 iMouse;
			sampler2D iChannel0;
			fixed4 iChannelResolution0;

			struct v2f {    
				float4 pos : SV_POSITION;    
				float4 scrPos : TEXCOORD0;   
			};              

			v2f vert(appdata_base v) {  
				v2f o;
				o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
				//将顶点转成屏幕坐标
				o.scrPos = ComputeScreenPos(o.pos);
				return o;
			}  
			/*代码是从上到下读取的,要想在方法前面调用还没定义好的main函数,需要先声main方法
			  或者将main方法写在调用之前,这里将main方法写在后面是为了代码的可观性 因这之后逻辑大都在main方法上编写
			*/
			vec4 main(vec2 fragCoord);

			fixed4 frag(v2f _iParam) : COLOR0 { 
			  /*
			  1.在四维中有xyzw四个分量 其中xyz三个点与w相除得到归一化的点
			  2.(_iParam.srcPos.xy/_iParam.srcPos.w)将得到在屏幕中归一化后的屏幕位置
			  3.最后与屏幕的分辨率相乘获得具体的位置
			  */
			   vec2 fragCoord = ((_iParam.scrPos.xy/_iParam.scrPos.w) * _ScreenParams.xy);
				return main(fragCoord);
			}  

			vec4 main(vec2 fragCoord) {
				return vec4(1, 1, 1, 1);
			}

            ENDCG    
        }    
    }     
    FallBack Off    
}

        개인적으로 이런 식으로 작성하면 논리가 매우 명확하다고 생각합니다. 결국 Unity에서 직접 효과를 보는 데 익숙합니다. 브라우저는 shadertoy를 봅니다. 물론 일부 효과가 정상적으로 실행되기를 희망하는 효과를 학습 한 후에는 효과가 웹에서 어떻게 나타나는지보기 위해 shadertoy로 변환됩니다.

        말도 안되는 부분이 많으니 이번에는 여기서 멈출 것입니다. 한 번에 너무 많이 쓸 수는 없다고 생각합니다. 쉐이더를 배우던 것처럼 항상 큰 파이를 한꺼번에 먹고 싶고 소화 흡수 전에 배출됩니다. 이 비유는 약간 역겨운 것이지만 사실입니다. 열심히 공부를 시작한 지 오래됐는데, 이것이 좋은 출발이되고 쉐이드 토이를 배우는 모든 과정을 기록하기를 바랍니다.

        인내 ~

추천

출처blog.csdn.net/ssssssilver/article/details/81111432