-
-
Save NedMakesGames/09784830b01e2b7c5f0559e807d48815 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) 2021 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 TESSELLATION_FACTORS_INCLUDED | |
#define TESSELLATION_FACTORS_INCLUDED | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
struct Attributes { | |
float3 positionOS : POSITION; | |
float3 normalOS : NORMAL; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
}; | |
struct TessellationFactors { | |
float edge[3] : SV_TessFactor; | |
float inside : SV_InsideTessFactor; | |
}; | |
struct TessellationControlPoint { | |
float3 positionWS : INTERNALTESSPOS; | |
float3 normalWS : NORMAL; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
}; | |
struct Interpolators { | |
float3 normalWS : TEXCOORD0; | |
float3 positionWS : TEXCOORD1; | |
float4 positionCS : SV_POSITION; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
UNITY_VERTEX_OUTPUT_STEREO | |
}; | |
CBUFFER_START(UnityPerMaterial) | |
float3 _FactorEdge1; | |
float _FactorEdge2; | |
float _FactorEdge3; | |
float _FactorInside; | |
CBUFFER_END | |
float3 GetViewDirectionFromPosition(float3 positionWS) { | |
return normalize(GetCameraPositionWS() - positionWS); | |
} | |
float4 GetShadowCoord(float3 positionWS, float4 positionCS) { | |
// Calculate the shadow coordinate depending on the type of shadows currently in use | |
#if SHADOWS_SCREEN | |
return ComputeScreenPos(positionCS); | |
#else | |
return TransformWorldToShadowCoord(positionWS); | |
#endif | |
} | |
TessellationControlPoint Vertex(Attributes input) { | |
TessellationControlPoint output; | |
UNITY_SETUP_INSTANCE_ID(input); | |
UNITY_TRANSFER_INSTANCE_ID(input, output); | |
VertexPositionInputs posnInputs = GetVertexPositionInputs(input.positionOS); | |
VertexNormalInputs normalInputs = GetVertexNormalInputs(input.normalOS); | |
output.positionWS = posnInputs.positionWS; | |
output.normalWS = normalInputs.normalWS; | |
return output; | |
} | |
// The patch constant function runs once per triangle, or "patch" | |
// It runs in parallel to the hull function | |
TessellationFactors PatchConstantFunction( | |
InputPatch<TessellationControlPoint, 3> patch) { | |
UNITY_SETUP_INSTANCE_ID(patch[0]); // Set up instancing | |
// Calculate tessellation factors | |
TessellationFactors f; | |
f.edge[0] = _FactorEdge1.x; | |
f.edge[1] = _FactorEdge1.y; | |
f.edge[2] = _FactorEdge1.z; | |
f.inside = _FactorInside; | |
return f; | |
} | |
// The hull function runs once per vertex. You can use it to modify vertex | |
// data based on values in the entire triangle | |
[domain("tri")] // Signal we're inputting triangles | |
[outputcontrolpoints(3)] // Triangles have three points | |
[outputtopology("triangle_cw")] // Signal we're outputting triangles | |
[patchconstantfunc("PatchConstantFunction")] // Register the patch constant function | |
// Select a partitioning mode based on keywords | |
#if defined(_PARTITIONING_INTEGER) | |
[partitioning("integer")] | |
#elif defined(_PARTITIONING_FRAC_EVEN) | |
[partitioning("fractional_even")] | |
#elif defined(_PARTITIONING_FRAC_ODD) | |
[partitioning("fractional_odd")] | |
#elif defined(_PARTITIONING_POW2) | |
[partitioning("pow2")] | |
#else | |
[partitioning("fractional_odd")] | |
#endif | |
TessellationControlPoint Hull( | |
InputPatch<TessellationControlPoint, 3> patch, // Input triangle | |
uint id : SV_OutputControlPointID) { // Vertex index on the triangle | |
return patch[id]; | |
} | |
// Call this macro to interpolate between a triangle patch, passing the field name | |
#define BARYCENTRIC_INTERPOLATE(fieldName) \ | |
patch[0].fieldName * barycentricCoordinates.x + \ | |
patch[1].fieldName * barycentricCoordinates.y + \ | |
patch[2].fieldName * barycentricCoordinates.z | |
// The domain function runs once per vertex in the final, tessellated mesh | |
// Use it to reposition vertices and prepare for the fragment stage | |
[domain("tri")] // Signal we're inputting triangles | |
Interpolators Domain( | |
TessellationFactors factors, // The output of the patch constant function | |
OutputPatch<TessellationControlPoint, 3> patch, // The Input triangle | |
float3 barycentricCoordinates : SV_DomainLocation) { // The barycentric coordinates of the vertex on the triangle | |
Interpolators output; | |
// Setup instancing and stereo support (for VR) | |
UNITY_SETUP_INSTANCE_ID(patch[0]); | |
UNITY_TRANSFER_INSTANCE_ID(patch[0], output); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); | |
float3 positionWS = BARYCENTRIC_INTERPOLATE(positionWS); | |
float3 normalWS = BARYCENTRIC_INTERPOLATE(normalWS); | |
output.positionCS = TransformWorldToHClip(positionWS); | |
output.normalWS = normalWS; | |
output.positionWS = positionWS; | |
return output; | |
} | |
float4 Fragment(Interpolators input) : SV_Target{ | |
UNITY_SETUP_INSTANCE_ID(input); | |
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); | |
// Fill the various lighting and surface data structures for the PBR algorithm | |
InputData lightingInput = (InputData)0; // Found in URP/Input.hlsl | |
lightingInput.positionWS = input.positionWS; | |
lightingInput.normalWS = normalize(input.normalWS); | |
lightingInput.viewDirectionWS = GetViewDirectionFromPosition(lightingInput.positionWS); | |
lightingInput.shadowCoord = GetShadowCoord(lightingInput.positionWS, input.positionCS); | |
lightingInput.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); | |
SurfaceData surface = (SurfaceData)0; // Found in URP/SurfaceData.hlsl | |
surface.albedo = 0.5; | |
surface.alpha = 1; | |
surface.metallic = 0; | |
surface.smoothness = 0.5; | |
surface.normalTS = float3(0, 0, 1); | |
surface.occlusion = 1; | |
return UniversalFragmentPBR(lightingInput, surface); | |
} | |
#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) 2021 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. | |
// This is a shader that demonstrates tessellation factors and partitioning modes | |
Shader "NedMakesGames/TessellationFactors" { | |
Properties{ | |
_FactorEdge1("Edge factors", Vector) = (1, 1, 1, 0) | |
//_FactorEdge2("Edge 2 factor", Float) = 1 | |
//_FactorEdge3("Edge 3 factor", Float) = 1 | |
_FactorInside("Inside factor", Float) = 1 | |
// This keyword enum allows us to choose between partitioning modes. It's best to try them out for yourself | |
[KeywordEnum(INTEGER, FRAC_EVEN, FRAC_ODD, POW2)] _PARTITIONING("Partition algoritm", Float) = 0 | |
} | |
SubShader{ | |
Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True"} | |
Pass { | |
Name "ForwardLit" | |
Tags{"LightMode" = "UniversalForward"} | |
HLSLPROGRAM | |
#pragma target 5.0 // 5.0 required for tessellation | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
#pragma multi_compile _ _ADDITIONAL_LIGHTS | |
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS | |
#pragma multi_compile_fragment _ _SHADOWS_SOFT | |
#pragma multi_compile_fog | |
#pragma multi_compile_instancing | |
// Material keywords | |
#pragma shader_feature_local _PARTITIONING_INTEGER _PARTITIONING_FRAC_EVEN _PARTITIONING_FRAC_ODD _PARTITIONING_POW2 | |
#pragma vertex Vertex | |
#pragma hull Hull | |
#pragma domain Domain | |
#pragma fragment Fragment | |
#include "TessellationFactors.hlsl" | |
ENDHLSL | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment