-
-
Save NedMakesGames/4c9bc4ae54c8c481f299538ce420b29a to your computer and use it in GitHub Desktop.
NedMakesGames
This file contains 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
// MIT License | |
// Copyright (c) 2023 NedMakesGames | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files(the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions : | |
// The above copyright notice and this permission notice shall be included in all | |
// copies or substantial portions of the Software. | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
// SOFTWARE. | |
Shader "NedMakesGames/MyLit" { | |
Properties{ | |
[Header(Surface options)] | |
[MainTexture] _ColorMap("Color", 2D) = "white" {} | |
[MainColor] _ColorTint("Tint", Color) = (1, 1, 1, 1) | |
_Cutoff("Alpha cutout threshold", Range(0, 1)) = 0.5 | |
_Smoothness("Smoothness", Float) = 0 | |
[HideInInspector] _Cull("Cull mode", Float) = 2 // 2 is "Back" | |
[HideInInspector] _SourceBlend("Source blend", Float) = 0 | |
[HideInInspector] _DestBlend("Destination blend", Float) = 0 | |
[HideInInspector] _ZWrite("ZWrite", Float) = 0 | |
[HideInInspector] _SurfaceType("Surface type", Float) = 0 | |
[HideInInspector] _FaceRenderingMode("Face rendering type", Float) = 0 | |
} | |
SubShader { | |
Tags {"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"} | |
Pass { | |
Name "ForwardLit" | |
Tags{"LightMode" = "UniversalForward"} | |
Blend[_SourceBlend][_DestBlend] | |
ZWrite[_ZWrite] | |
Cull[_Cull] | |
HLSLPROGRAM | |
#define _SPECULAR_COLOR | |
#pragma shader_feature_local _ALPHA_CUTOUT | |
#pragma shader_feature_local _DOUBLE_SIDED_NORMALS | |
#if UNITY_VERSION >= 202120 | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE | |
#else | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
#endif | |
#pragma multi_compile_fragment _ _SHADOWS_SOFT | |
#pragma vertex Vertex | |
#pragma fragment Fragment | |
#include "MyLitForwardLitPass.hlsl" | |
ENDHLSL | |
} | |
Pass { | |
Name "ShadowCaster" | |
Tags{"LightMode" = "ShadowCaster"} | |
ColorMask 0 | |
Cull[_Cull] | |
HLSLPROGRAM | |
#pragma shader_feature_local _ALPHA_CUTOUT | |
#pragma shader_feature_local _DOUBLE_SIDED_NORMALS | |
#pragma vertex Vertex | |
#pragma fragment Fragment | |
#include "MyLitShadowCasterPass.hlsl" | |
ENDHLSL | |
} | |
} | |
CustomEditor "MyLitCustomInspector" | |
} |
This file contains 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
// MIT License | |
// Copyright (c) 2023 NedMakesGames | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files(the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions : | |
// The above copyright notice and this permission notice shall be included in all | |
// copies or substantial portions of the Software. | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
// SOFTWARE. | |
#ifndef MY_LIT_COMMON_INCLUDED | |
#define MY_LIT_COMMON_INCLUDED | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
TEXTURE2D(_ColorMap); SAMPLER(sampler_ColorMap); | |
float4 _ColorMap_ST; | |
float4 _ColorTint; | |
float _Cutoff; | |
float _Smoothness; | |
void TestAlphaClip(float4 colorSample) { | |
#ifdef _ALPHA_CUTOUT | |
clip(colorSample.a * _ColorTint.a - _Cutoff); | |
#endif | |
} | |
#endif |
This file contains 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
// MIT License | |
// Copyright (c) 2023 NedMakesGames | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files(the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions : | |
// The above copyright notice and this permission notice shall be included in all | |
// copies or substantial portions of the Software. | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
// SOFTWARE. | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.Rendering; | |
public class MyLitCustomInspector : ShaderGUI { | |
public enum SurfaceType { | |
Opaque, TransparentBlend, TransparentCutout | |
} | |
public enum FaceRenderingMode { | |
FrontOnly, NoCulling, DoubleSided | |
} | |
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) { | |
base.AssignNewShaderToMaterial(material, oldShader, newShader); | |
if(newShader.name == "NedMakesGames/MyLit") { | |
UpdateSurfaceType(material); | |
} | |
} | |
#if UNITY_2022_1_OR_NEWER | |
public override void ValidateMaterial(Material material) { | |
base.ValidateMaterial(material); | |
UpdateSurfaceType(material); | |
} | |
#endif | |
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { | |
Material material = materialEditor.target as Material; | |
var surfaceProp = BaseShaderGUI.FindProperty("_SurfaceType", properties, true); | |
var faceProp = BaseShaderGUI.FindProperty("_FaceRenderingMode", properties, true); | |
EditorGUI.BeginChangeCheck(); | |
#if UNITY_2022_1_OR_NEWER | |
MaterialEditor.BeginProperty(surfaceProp); | |
#endif | |
surfaceProp.floatValue = (int)(SurfaceType)EditorGUILayout.EnumPopup("Surface type", (SurfaceType)surfaceProp.floatValue); | |
#if UNITY_2022_1_OR_NEWER | |
MaterialEditor.EndProperty(); | |
#endif | |
#if UNITY_2022_1_OR_NEWER | |
MaterialEditor.BeginProperty(faceProp); | |
#endif | |
faceProp.floatValue = (int)(FaceRenderingMode)EditorGUILayout.EnumPopup("Face rendering mode", (FaceRenderingMode)faceProp.floatValue); | |
#if UNITY_2022_1_OR_NEWER | |
MaterialEditor.EndProperty(); | |
#endif | |
if(EditorGUI.EndChangeCheck()) { | |
UpdateSurfaceType(material); | |
} | |
base.OnGUI(materialEditor, properties); | |
} | |
private void UpdateSurfaceType(Material material) { | |
SurfaceType surface = (SurfaceType)material.GetFloat("_SurfaceType"); | |
switch(surface) { | |
case SurfaceType.Opaque: | |
material.renderQueue = (int)RenderQueue.Geometry; | |
material.SetOverrideTag("RenderType", "Opaque"); | |
break; | |
case SurfaceType.TransparentCutout: | |
material.renderQueue = (int)RenderQueue.AlphaTest; | |
material.SetOverrideTag("RenderType", "TransparentCutout"); | |
break; | |
case SurfaceType.TransparentBlend: | |
material.renderQueue = (int)RenderQueue.Transparent; | |
material.SetOverrideTag("RenderType", "Transparent"); | |
break; | |
} | |
switch(surface) { | |
case SurfaceType.Opaque: | |
case SurfaceType.TransparentCutout: | |
material.SetInt("_SourceBlend", (int)BlendMode.One); | |
material.SetInt("_DestBlend", (int)BlendMode.Zero); | |
material.SetInt("_ZWrite", 1); | |
break; | |
case SurfaceType.TransparentBlend: | |
material.SetInt("_SourceBlend", (int)BlendMode.SrcAlpha); | |
material.SetInt("_DestBlend", (int)BlendMode.OneMinusSrcAlpha); | |
material.SetInt("_ZWrite", 0); | |
break; | |
} | |
if(surface == SurfaceType.TransparentCutout) { | |
material.EnableKeyword("_ALPHA_CUTOUT"); | |
} else { | |
material.DisableKeyword("_ALPHA_CUTOUT"); | |
} | |
material.SetShaderPassEnabled("ShadowCaster", surface != SurfaceType.TransparentBlend); | |
FaceRenderingMode faceRenderingMode = (FaceRenderingMode)material.GetFloat("_FaceRenderingMode"); | |
if(faceRenderingMode == FaceRenderingMode.FrontOnly) { | |
material.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Back); | |
} else { | |
material.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off); | |
} | |
if(faceRenderingMode == FaceRenderingMode.DoubleSided) { | |
material.EnableKeyword("_DOUBLE_SIDED_NORMALS"); | |
} else { | |
material.DisableKeyword("_DOUBLE_SIDED_NORMALS"); | |
} | |
} | |
} |
This file contains 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
// MIT License | |
// Copyright (c) 2023 NedMakesGames | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files(the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions : | |
// The above copyright notice and this permission notice shall be included in all | |
// copies or substantial portions of the Software. | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
// SOFTWARE. | |
#ifndef MY_LIT_FORWARD_LIT_PASS_INCLUDED | |
#define MY_LIT_FORWARD_LIT_PASS_INCLUDED | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
#include "MyLitCommon.hlsl" | |
struct Attributes { | |
float3 positionOS : POSITION; | |
float3 normalOS : NORMAL; | |
float2 uv : TEXCOORD0; | |
}; | |
struct Interpolators { | |
float4 positionCS : SV_POSITION; | |
float2 uv : TEXCOORD0; | |
float3 positionWS : TEXCOORD1; | |
float3 normalWS : TEXCOORD2; | |
}; | |
Interpolators Vertex(Attributes input) { | |
Interpolators output; | |
// Found in URP/ShaderLib/ShaderVariablesFunctions.hlsl | |
VertexPositionInputs posnInputs = GetVertexPositionInputs(input.positionOS); | |
VertexNormalInputs normInputs = GetVertexNormalInputs(input.normalOS); | |
output.positionCS = posnInputs.positionCS; | |
output.uv = TRANSFORM_TEX(input.uv, _ColorMap); | |
output.normalWS = normInputs.normalWS; | |
output.positionWS = posnInputs.positionWS; | |
return output; | |
} | |
float4 Fragment(Interpolators input | |
#ifdef _DOUBLE_SIDED_NORMALS | |
, FRONT_FACE_TYPE frontFace : FRONT_FACE_SEMANTIC | |
#endif | |
) : SV_TARGET { | |
float2 uv = input.uv; | |
float4 colorSample = SAMPLE_TEXTURE2D(_ColorMap, sampler_ColorMap, uv) * _ColorTint; | |
TestAlphaClip(colorSample); | |
float3 normalWS = normalize(input.normalWS); | |
#ifdef _DOUBLE_SIDED_NORMALS | |
normalWS *= IS_FRONT_VFACE(frontFace, 1, -1); | |
#endif | |
InputData lightingInput = (InputData)0; // Found in URP/ShaderLib/Input.hlsl | |
lightingInput.positionWS = input.positionWS; | |
lightingInput.normalWS = normalWS; | |
lightingInput.viewDirectionWS = GetWorldSpaceNormalizeViewDir(input.positionWS); // In ShaderVariablesFunctions.hlsl | |
lightingInput.shadowCoord = TransformWorldToShadowCoord(input.positionWS); // In Shadows.hlsl | |
SurfaceData surfaceInput = (SurfaceData)0; | |
surfaceInput.albedo = colorSample.rgb; | |
surfaceInput.alpha = colorSample.a; | |
surfaceInput.specular = 1; | |
surfaceInput.smoothness = _Smoothness; | |
#if UNITY_VERSION >= 202120 | |
return UniversalFragmentBlinnPhong(lightingInput, surfaceInput); | |
#else | |
return UniversalFragmentBlinnPhong(lightingInput, surfaceInput.albedo, float4(surfaceInput.specular, 1), surfaceInput.smoothness, surfaceInput.emission, surfaceInput.alpha); | |
#endif | |
} | |
#endif |
This file contains 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
// MIT License | |
// Copyright (c) 2023 NedMakesGames | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files(the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions : | |
// The above copyright notice and this permission notice shall be included in all | |
// copies or substantial portions of the Software. | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
// SOFTWARE. | |
#ifndef MY_LIT_SHADOW_CASTER_PASS_INCLUDED | |
#define MY_LIT_SHADOW_CASTER_PASS_INCLUDED | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
#include "MyLitCommon.hlsl" | |
struct Attributes { | |
float3 positionOS : POSITION; | |
float3 normalOS : NORMAL; | |
#ifdef _ALPHA_CUTOUT | |
float2 uv : TEXCOORD0; | |
#endif | |
}; | |
struct Interpolators { | |
float4 positionCS : SV_POSITION; | |
#ifdef _ALPHA_CUTOUT | |
float2 uv : TEXCOORD0; | |
#endif | |
}; | |
float3 FlipNormalBasedOnViewDir(float3 normalWS, float3 positionWS) { | |
float3 viewDirWS = GetWorldSpaceNormalizeViewDir(positionWS); | |
return normalWS * (dot(normalWS, viewDirWS) < 0 ? -1 : 1); | |
} | |
float3 _LightDirection; | |
float4 GetShadowCasterPositionCS(float3 positionWS, float3 normalWS) { | |
float3 lightDirectionWS = _LightDirection; | |
#ifdef _DOUBLE_SIDED_NORMALS | |
normalWS = FlipNormalBasedOnViewDir(normalWS, positionWS); | |
#endif | |
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS)); | |
#if UNITY_REVERSED_Z | |
positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE); | |
#else | |
positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE); | |
#endif | |
return positionCS; | |
} | |
Interpolators Vertex(Attributes input) { | |
Interpolators output; | |
VertexPositionInputs posnInputs = GetVertexPositionInputs(input.positionOS); // Found in URP/ShaderLib/ShaderVariablesFunctions.hlsl | |
VertexNormalInputs normInputs = GetVertexNormalInputs(input.normalOS); // Found in URP/ShaderLib/ShaderVariablesFunctions.hlsl | |
output.positionCS = GetShadowCasterPositionCS(posnInputs.positionWS, normInputs.normalWS); | |
#ifdef _ALPHA_CUTOUT | |
output.uv = TRANSFORM_TEX(input.uv, _ColorMap); | |
#endif | |
return output; | |
} | |
float4 Fragment(Interpolators input) : SV_TARGET { | |
#ifdef _ALPHA_CUTOUT | |
float2 uv = input.uv; | |
float4 colorSample = SAMPLE_TEXTURE2D(_ColorMap, sampler_ColorMap, uv); | |
TestAlphaClip(colorSample); | |
#endif | |
return 0; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment