Last active
May 7, 2025 20:55
-
-
Save takumifukasawa/f5a2878a1c35847365fe07146ff4156d to your computer and use it in GitHub Desktop.
Examples of Custom URP Lit Shader and Custom Shader GUI Script: Unity2019.4.21f, URP7.8.3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
using UnityEditor; | |
using UnityEditor.Rendering.Universal.ShaderGUI; | |
class CustomLitShader : BaseShaderGUI | |
{ | |
// Properties | |
private LitGUI.LitProperties litProperties; | |
// ADDTIONAL | |
private bool m_AddtionalFoldout = true; | |
private MaterialProperty customRangeValueProp = null; | |
private MaterialProperty customTextureValueProp = null; | |
// collect properties from the material properties | |
public override void FindProperties(MaterialProperty[] properties) | |
{ | |
base.FindProperties(properties); | |
litProperties = new LitGUI.LitProperties(properties); | |
// ADDTIONAL | |
customRangeValueProp = FindProperty("_CustomRangeValue", properties); | |
customTextureValueProp = FindProperty("_CustomTextureValue", properties); | |
} | |
// material changed check | |
public override void MaterialChanged(Material material) | |
{ | |
if (material == null) | |
throw new ArgumentNullException("material"); | |
SetMaterialKeywords(material, LitGUI.SetMaterialKeywords); | |
} | |
// material main surface options | |
public override void DrawSurfaceOptions(Material material) | |
{ | |
if (material == null) | |
throw new ArgumentNullException("material"); | |
// Use default labelWidth | |
EditorGUIUtility.labelWidth = 0f; | |
// Detect any changes to the material | |
EditorGUI.BeginChangeCheck(); | |
if (litProperties.workflowMode != null) | |
{ | |
DoPopup(LitGUI.Styles.workflowModeText, litProperties.workflowMode, Enum.GetNames(typeof(LitGUI.WorkflowMode))); | |
} | |
if (EditorGUI.EndChangeCheck()) | |
{ | |
foreach (var obj in blendModeProp.targets) | |
MaterialChanged((Material)obj); | |
} | |
base.DrawSurfaceOptions(material); | |
} | |
// material main surface inputs | |
public override void DrawSurfaceInputs(Material material) | |
{ | |
base.DrawSurfaceInputs(material); | |
LitGUI.Inputs(litProperties, materialEditor, material); | |
DrawEmissionProperties(material, true); | |
DrawTileOffset(materialEditor, baseMapProp); | |
} | |
// material main advanced options | |
public override void DrawAdvancedOptions(Material material) | |
{ | |
if (litProperties.reflections != null && litProperties.highlights != null) | |
{ | |
EditorGUI.BeginChangeCheck(); | |
materialEditor.ShaderProperty(litProperties.highlights, LitGUI.Styles.highlightsText); | |
materialEditor.ShaderProperty(litProperties.reflections, LitGUI.Styles.reflectionsText); | |
if (EditorGUI.EndChangeCheck()) | |
{ | |
MaterialChanged(material); | |
} | |
} | |
base.DrawAdvancedOptions(material); | |
} | |
// ADDTIONAL | |
public override void DrawAdditionalFoldouts(Material material) | |
{ | |
// if needed | |
// EditorGUI.BeginChangeCheck(); | |
m_AddtionalFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(m_AddtionalFoldout, "Addtional"); | |
if (m_AddtionalFoldout) | |
{ | |
materialEditor.RangeProperty(customRangeValueProp, "Custom Range Value"); | |
materialEditor.TextureProperty(customTextureValueProp, "Custom Texture Value"); | |
} | |
// if needed | |
// if (EditorGUI.EndChangeCheck()) | |
// { | |
// } | |
base.DrawAdditionalFoldouts(material); | |
} | |
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) | |
{ | |
if (material == null) | |
throw new ArgumentNullException("material"); | |
// _Emission property is lost after assigning Standard shader to the material | |
// thus transfer it before assigning the new shader | |
if (material.HasProperty("_Emission")) | |
{ | |
material.SetColor("_EmissionColor", material.GetColor("_Emission")); | |
} | |
base.AssignNewShaderToMaterial(material, oldShader, newShader); | |
if (oldShader == null || !oldShader.name.Contains("Legacy Shaders/")) | |
{ | |
SetupMaterialBlendMode(material); | |
return; | |
} | |
SurfaceType surfaceType = SurfaceType.Opaque; | |
BlendMode blendMode = BlendMode.Alpha; | |
if (oldShader.name.Contains("/Transparent/Cutout/")) | |
{ | |
surfaceType = SurfaceType.Opaque; | |
material.SetFloat("_AlphaClip", 1); | |
} | |
else if (oldShader.name.Contains("/Transparent/")) | |
{ | |
// NOTE: legacy shaders did not provide physically based transparency | |
// therefore Fade mode | |
surfaceType = SurfaceType.Transparent; | |
blendMode = BlendMode.Alpha; | |
} | |
material.SetFloat("_Surface", (float)surfaceType); | |
material.SetFloat("_Blend", (float)blendMode); | |
if (oldShader.name.Equals("Standard (Specular setup)")) | |
{ | |
material.SetFloat("_WorkflowMode", (float)LitGUI.WorkflowMode.Specular); | |
Texture texture = material.GetTexture("_SpecGlossMap"); | |
if (texture != null) | |
material.SetTexture("_MetallicSpecGlossMap", texture); | |
} | |
else | |
{ | |
material.SetFloat("_WorkflowMode", (float)LitGUI.WorkflowMode.Metallic); | |
Texture texture = material.GetTexture("_MetallicGlossMap"); | |
if (texture != null) | |
material.SetTexture("_MetallicSpecGlossMap", texture); | |
} | |
MaterialChanged(material); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Custom/Custom URP Lit" | |
{ | |
Properties | |
{ | |
// Specular vs Metallic workflow | |
[HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0 | |
[MainTexture] _BaseMap("Albedo", 2D) = "white" {} | |
[MainColor] _BaseColor("Color", Color) = (1,1,1,1) | |
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 | |
_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 | |
_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 | |
_SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 | |
_Metallic("Metallic", Range(0.0, 1.0)) = 0.0 | |
_MetallicGlossMap("Metallic", 2D) = "white" {} | |
_SpecColor("Specular", Color) = (0.2, 0.2, 0.2) | |
_SpecGlossMap("Specular", 2D) = "white" {} | |
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 | |
[ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0 | |
_BumpScale("Scale", Float) = 1.0 | |
_BumpMap("Normal Map", 2D) = "bump" {} | |
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 | |
_OcclusionMap("Occlusion", 2D) = "white" {} | |
_EmissionColor("Color", Color) = (0,0,0) | |
_EmissionMap("Emission", 2D) = "white" {} | |
// Blending state | |
[HideInInspector] _Surface("__surface", Float) = 0.0 | |
[HideInInspector] _Blend("__blend", Float) = 0.0 | |
[HideInInspector] _AlphaClip("__clip", Float) = 0.0 | |
[HideInInspector] _SrcBlend("__src", Float) = 1.0 | |
[HideInInspector] _DstBlend("__dst", Float) = 0.0 | |
[HideInInspector] _ZWrite("__zw", Float) = 1.0 | |
[HideInInspector] _Cull("__cull", Float) = 2.0 | |
_ReceiveShadows("Receive Shadows", Float) = 1.0 | |
// Editmode props | |
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0 | |
// ObsoleteProperties | |
[HideInInspector] _MainTex("BaseMap", 2D) = "white" {} | |
[HideInInspector] _Color("Base Color", Color) = (1, 1, 1, 1) | |
[HideInInspector] _GlossMapScale("Smoothness", Float) = 0.0 | |
[HideInInspector] _Glossiness("Smoothness", Float) = 0.0 | |
[HideInInspector] _GlossyReflections("EnvironmentReflections", Float) = 0.0 | |
// ADDTIONAL | |
_CustomRangeValue("Custom Range Value", Range(0, 1)) = 0.0 | |
_CustomTextureValue("Custom Texture Value", 2D) = "white" {} | |
} | |
SubShader | |
{ | |
// Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings | |
// this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this | |
// material work with both Universal Render Pipeline and Builtin Unity Pipeline | |
Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True"} | |
LOD 300 | |
// ------------------------------------------------------------------ | |
// Forward pass. Shades all light in a single pass. GI + emission + Fog | |
Pass | |
{ | |
// Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with | |
// no LightMode tag are also rendered by Universal Render Pipeline | |
Name "ForwardLit" | |
Tags{"LightMode" = "UniversalForward"} | |
Blend[_SrcBlend][_DstBlend] | |
ZWrite[_ZWrite] | |
Cull[_Cull] | |
HLSLPROGRAM | |
// Required to compile gles 2.0 with standard SRP library | |
// All shaders must be compiled with HLSLcc and currently only gles is not using HLSLcc by default | |
#pragma prefer_hlslcc gles | |
#pragma exclude_renderers d3d11_9x | |
#pragma target 2.0 | |
// ------------------------------------- | |
// Material Keywords | |
#pragma shader_feature _NORMALMAP | |
#pragma shader_feature _ALPHATEST_ON | |
#pragma shader_feature _ALPHAPREMULTIPLY_ON | |
#pragma shader_feature _EMISSION | |
#pragma shader_feature _METALLICSPECGLOSSMAP | |
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
#pragma shader_feature _OCCLUSIONMAP | |
#pragma shader_feature _SPECULARHIGHLIGHTS_OFF | |
#pragma shader_feature _ENVIRONMENTREFLECTIONS_OFF | |
#pragma shader_feature _SPECULAR_SETUP | |
#pragma shader_feature _RECEIVE_SHADOWS_OFF | |
// ------------------------------------- | |
// Universal Pipeline keywords | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS | |
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS | |
#pragma multi_compile _ _SHADOWS_SOFT | |
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE | |
// ------------------------------------- | |
// Unity defined keywords | |
#pragma multi_compile _ DIRLIGHTMAP_COMBINED | |
#pragma multi_compile _ LIGHTMAP_ON | |
#pragma multi_compile_fog | |
//-------------------------------------- | |
// GPU Instancing | |
#pragma multi_compile_instancing | |
#pragma vertex CustomLitPassVertex | |
#pragma fragment CustomLitPassFragment | |
// MODIFIED | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl" | |
// ADDITIONAL | |
struct CustomAttributes | |
{ | |
float4 positionOS : POSITION; | |
float3 normalOS : NORMAL; | |
float4 tangentOS : TANGENT; | |
float2 texcoord : TEXCOORD0; | |
float2 lightmapUV : TEXCOORD1; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
}; | |
// ADDITIONAL | |
struct CustomVaryings | |
{ | |
float2 uv : TEXCOORD0; | |
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1); | |
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR) | |
float3 positionWS : TEXCOORD2; | |
#endif | |
float3 normalWS : TEXCOORD3; | |
#ifdef _NORMALMAP | |
float4 tangentWS : TEXCOORD4; // xyz: tangent, w: sign | |
#endif | |
float3 viewDirWS : TEXCOORD5; | |
half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light | |
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) | |
float4 shadowCoord : TEXCOORD7; | |
#endif | |
float4 positionCS : SV_POSITION; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
UNITY_VERTEX_OUTPUT_STEREO | |
}; | |
// ADDITIONAL | |
float _CustomRangeValue; | |
sampler2D _CustomTextureValue; | |
// ADDITIONAL | |
// Used in Standard (Physically Based) shader | |
CustomVaryings CustomLitPassVertex(CustomAttributes input) | |
{ | |
Varyings output = (Varyings)0; | |
UNITY_SETUP_INSTANCE_ID(input); | |
UNITY_TRANSFER_INSTANCE_ID(input, output); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); | |
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); | |
// normalWS and tangentWS already normalize. | |
// this is required to avoid skewing the direction during interpolation | |
// also required for per-vertex lighting and SH evaluation | |
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); | |
float3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS; | |
half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS); | |
half fogFactor = ComputeFogFactor(vertexInput.positionCS.z); | |
output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); | |
// already normalized from normal transform to WS. | |
output.normalWS = normalInput.normalWS; | |
output.viewDirWS = viewDirWS; | |
#ifdef _NORMALMAP | |
real sign = input.tangentOS.w * GetOddNegativeScale(); | |
output.tangentWS = half4(normalInput.tangentWS.xyz, sign); | |
#endif | |
OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV); | |
OUTPUT_SH(output.normalWS.xyz, output.vertexSH); | |
output.fogFactorAndVertexLight = half4(fogFactor, vertexLight); | |
#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR) | |
output.positionWS = vertexInput.positionWS; | |
#endif | |
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) | |
output.shadowCoord = GetShadowCoord(vertexInput); | |
#endif | |
output.positionCS = vertexInput.positionCS; | |
return output; | |
} | |
// ADDITIONAL | |
// Used in Standard (Physically Based) shader | |
half4 CustomLitPassFragment(CustomVaryings input) : SV_Target | |
{ | |
UNITY_SETUP_INSTANCE_ID(input); | |
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); | |
SurfaceData surfaceData; | |
InitializeStandardLitSurfaceData(input.uv, surfaceData); | |
InputData inputData; | |
InitializeInputData(input, surfaceData.normalTS, inputData); | |
half4 color = UniversalFragmentPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha); | |
color.rgb = MixFog(color.rgb, inputData.fogCoord); | |
color.a = OutputAlpha(color.a, _Surface); | |
return color; | |
} | |
ENDHLSL | |
} | |
Pass | |
{ | |
Name "ShadowCaster" | |
Tags{"LightMode" = "ShadowCaster"} | |
ZWrite On | |
ZTest LEqual | |
ColorMask 0 | |
Cull[_Cull] | |
HLSLPROGRAM | |
// Required to compile gles 2.0 with standard srp library | |
#pragma prefer_hlslcc gles | |
#pragma exclude_renderers d3d11_9x | |
#pragma target 2.0 | |
// ------------------------------------- | |
// Material Keywords | |
#pragma shader_feature _ALPHATEST_ON | |
//-------------------------------------- | |
// GPU Instancing | |
#pragma multi_compile_instancing | |
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
#pragma vertex ShadowPassVertex | |
#pragma fragment ShadowPassFragment | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl" | |
ENDHLSL | |
} | |
Pass | |
{ | |
Name "DepthOnly" | |
Tags{"LightMode" = "DepthOnly"} | |
ZWrite On | |
ColorMask 0 | |
Cull[_Cull] | |
HLSLPROGRAM | |
// Required to compile gles 2.0 with standard srp library | |
#pragma prefer_hlslcc gles | |
#pragma exclude_renderers d3d11_9x | |
#pragma target 2.0 | |
#pragma vertex DepthOnlyVertex | |
#pragma fragment DepthOnlyFragment | |
// ------------------------------------- | |
// Material Keywords | |
#pragma shader_feature _ALPHATEST_ON | |
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
//-------------------------------------- | |
// GPU Instancing | |
#pragma multi_compile_instancing | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl" | |
ENDHLSL | |
} | |
// This pass it not used during regular rendering, only for lightmap baking. | |
Pass | |
{ | |
Name "Meta" | |
Tags{"LightMode" = "Meta"} | |
Cull Off | |
HLSLPROGRAM | |
// Required to compile gles 2.0 with standard srp library | |
#pragma prefer_hlslcc gles | |
#pragma exclude_renderers d3d11_9x | |
#pragma vertex UniversalVertexMeta | |
#pragma fragment UniversalFragmentMeta | |
#pragma shader_feature _SPECULAR_SETUP | |
#pragma shader_feature _EMISSION | |
#pragma shader_feature _METALLICSPECGLOSSMAP | |
#pragma shader_feature _ALPHATEST_ON | |
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
#pragma shader_feature _SPECGLOSSMAP | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl" | |
ENDHLSL | |
} | |
Pass | |
{ | |
Name "Universal2D" | |
Tags{ "LightMode" = "Universal2D" } | |
Blend[_SrcBlend][_DstBlend] | |
ZWrite[_ZWrite] | |
Cull[_Cull] | |
HLSLPROGRAM | |
// Required to compile gles 2.0 with standard srp library | |
#pragma prefer_hlslcc gles | |
#pragma exclude_renderers d3d11_9x | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma shader_feature _ALPHATEST_ON | |
#pragma shader_feature _ALPHAPREMULTIPLY_ON | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl" | |
ENDHLSL | |
} | |
} | |
FallBack "Hidden/Universal Render Pipeline/FallbackError" | |
// MODIFIED | |
CustomEditor "CustomLitShader" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment