用Standard核心自定義PBR Shader

上個MMO項目結束有段時間了 ,最近開始新的沙盒項目了,把自己這段時間遇到的問題都整理整理,分享出來。

本文主要講解如何用Unity Standard核心來快速的實現自定義PBR Shader,給大家一些簡單的參考意見。

話不多說,直接上代碼:

Shader "Custom/SimplePBRTest"
{
    Properties
    {
		_AlbedoMap("AlbedoMap", 2D) = "white" {}
		_BaseColor("BaseColor", Color) = (1,1,1,1)
		_Smooth("Smooth", Range( 0 , 1)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
       
        CGPROGRAM
		//StandardCustomLighting 自定義光照模型
		//noinstancing noforwardadd  爲了減少surface shader 生成通道
        #pragma surface surf StandardCustomLighting fullforwardshadows  noinstancing noforwardadd    

        #pragma target 3.0
		
		//引用PBR核心庫
		#include "UnityPBSLighting.cginc"
		#include "Lighting.cginc"
		
		//自定義輸入結構體
		struct Input
		{
			float2 uv_texcoord;
			float3 worldNormal;
		};
		//自定義輸出結構體
		struct SurfaceOutputCustomLightingCustom
		{
			half3 Albedo;
			half3 Normal;
			half3 Emission;
			half Metallic;
			half Smoothness;
			half Occlusion;
			half Alpha;
			Input SurfInput;
			UnityGIInput GIData;
		};

		float4 _BaseColor;
		sampler2D _AlbedoMap;
		float4 _AlbedoMap_ST;
		float _Smooth;

		inline half4 LightingStandardCustomLighting( inout SurfaceOutputCustomLightingCustom s, half3 viewDir, UnityGI gi )
		{
			UnityGIInput data = s.GIData;
			Input i = s.SurfInput;
			half4 c = 0;
			SurfaceOutputStandard sufaceStandard = (SurfaceOutputStandard ) 0;
			float2 uv_AlbedoMap = i.uv_texcoord * _AlbedoMap_ST.xy + _AlbedoMap_ST.zw;
			float4 mainTex = tex2D( _AlbedoMap, uv_AlbedoMap );
			sufaceStandard.Albedo = ( _BaseColor * mainTex ).rgb;
			float3 worldNormal = i.worldNormal;
			sufaceStandard.Normal = worldNormal;
			sufaceStandard.Emission = float3( 0,0,0 );
			sufaceStandard.Metallic = 0.0;   //可以自行從metallic 貼圖中採樣,這裏簡略了
			sufaceStandard.Smoothness = _Smooth;
			sufaceStandard.Occlusion = 1.0;

			data.light = gi.light;

			UnityGI customGI = gi;
			#ifdef UNITY_PASS_FORWARDBASE
			Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup( sufaceStandard.Smoothness, data.worldViewDir, sufaceStandard.Normal, float3(0,0,0));
			customGI = UnityGlobalIllumination( data, sufaceStandard.Occlusion, sufaceStandard.Normal, g);
			#endif

			c.rgb = LightingStandard ( sufaceStandard, viewDir, customGI ).rgb;  //Unity Standard 光照模型  PBR核心算法
			c.rbg+=sufaceStandard.Emission;  //自發光
			c.a = 1;

			return c;
		}

		inline void LightingStandardCustomLighting_GI( inout SurfaceOutputCustomLightingCustom s, UnityGIInput data, inout UnityGI gi )
		{
			s.GIData = data;
		}

        void surf (Input i, inout SurfaceOutputCustomLightingCustom o)
        {
            o.SurfInput = i;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

通過surface shader,利用Standard 核心算法來實現PBR。

當然具體生成代碼可以通過

在這裏插入圖片描述

查看。

過surface shader,利用Standard 核心算法來實現PBR。

這裏只是提供一種思路,用surface shader要考慮變體的問題,不然解析起來有點費勁。

需要PBR 頂點片元着色器的shader,可以留言,大家討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章