Last active
March 16, 2024 08:43
-
-
Save shivaduke28/b224ebaebf4d70b7bd7ad396ecf2af31 to your computer and use it in GitHub Desktop.
simple URP Lit shaders for learning
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 "MyShader/URP_Normal" | |
{ | |
Properties | |
{ | |
[Header(Base Color)] | |
[MainTexture]_BaseMap("_BaseMap (Albedo)", 2D) = "white" {} | |
[HDR][MainColor]_BaseColor("_BaseColor", Color) = (1,1,1,1) | |
[Header(Normal)] | |
[MainTexture]_NormalMap("_NormalMap", 2D) = "white" {} | |
} | |
SubShader | |
{ | |
Tags | |
{ | |
"RenderPipeline" = "UniversalPipeline" | |
"RenderType"="Opaque" | |
"UniversalMaterialType" = "Lit" | |
"Queue"="Geometry" | |
} | |
Pass | |
{ | |
Name "ForwardLit" | |
Tags | |
{ | |
"LightMode"="UniversalForward" | |
} | |
HLSLPROGRAM | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS | |
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS | |
#pragma multi_compile_fragment _ _SHADOWS_SOFT | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
struct Attributes | |
{ | |
float3 positionOS : POSITION; | |
half3 normalOS : NORMAL; | |
half4 tangentOS : TANGENT; | |
float2 uv : TEXCOORD0; | |
}; | |
struct Varyings | |
{ | |
float2 uv : TEXCOORD0; | |
float4 positionWSAndFogFactor : TEXCOORD1; // xyz: positionWS, w: vertex fog factor | |
half3 normalWS : TEXCOORD2; | |
float4 positionCS : SV_POSITION; | |
float3 lightTS : TEXCOORD3; // light Direction in tangent space | |
}; | |
sampler2D _BaseMap; | |
sampler2D _NormalMap; | |
CBUFFER_START(UnityPerMaterial) | |
float4 _BaseMap_ST; | |
float4 _NormalMap_ST; | |
CBUFFER_END | |
/* MEMO | |
from Core.hlsl | |
struct VertexPositionInputs | |
{ | |
float3 positionWS; // World space position | |
float3 positionVS; // View space position | |
float4 positionCS; // Homogeneous clip space position | |
float4 positionNDC;// Homogeneous normalized device coordinates | |
}; | |
from Core.hlsl | |
struct VertexNormalInputs | |
{ | |
real3 tangentWS; | |
real3 bitangentWS; | |
float3 normalWS; | |
}; | |
from Lighting.hlsl | |
struct Light | |
{ | |
half3 direction; | |
half3 color; | |
half distanceAttenuation; | |
half shadowAttenuation; | |
}; | |
*/ | |
Varyings vert (Attributes input) | |
{ | |
Varyings output; | |
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS); | |
VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); | |
output.uv = TRANSFORM_TEX(input.uv, _BaseMap); | |
output.positionCS = TransformWorldToHClip(vertexInput.positionWS); | |
//output.normalWS = vertexNormalInput.normalWS; | |
// Get Main Light | |
Light mainLight = GetMainLight(); | |
// world to tangent | |
float3x3 tangentMat = float3x3(vertexNormalInput.tangentWS, vertexNormalInput.bitangentWS, vertexNormalInput.normalWS); | |
output.lightTS = mul(tangentMat, mainLight.direction);; | |
return output; | |
} | |
half4 frag (Varyings input) : SV_Target | |
{ | |
half4 col = tex2D(_BaseMap, input.uv); | |
float3 normal = UnpackNormal(tex2D(_NormalMap, input.uv)); | |
float diff = saturate(dot(input.lightTS, normal)); | |
col *= diff; | |
return col; | |
} | |
ENDHLSL | |
} | |
} | |
} |
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 "MyShader/URP_Parallax" | |
{ | |
Properties | |
{ | |
[Header(Base Color)] | |
[MainTexture]_BaseMap("_BaseMap (Albedo)", 2D) = "white" {} | |
[HDR][MainColor]_BaseColor("_BaseColor", Color) = (1,1,1,1) | |
[Header(Bump Map)] | |
[MainTexture]_NormalMap("_NormalMap", 2D) = "white" {} | |
[MainTexture]_HeightMap("_HeightMap", 2D) = "white" {} | |
_Height("_Height",float) = 1 | |
} | |
SubShader | |
{ | |
Tags | |
{ | |
"RenderPipeline" = "UniversalPipeline" | |
"RenderType"="Opaque" | |
"UniversalMaterialType" = "Lit" | |
"Queue"="Geometry" | |
} | |
Pass | |
{ | |
Name "ForwardLit" | |
Tags | |
{ | |
"LightMode"="UniversalForward" | |
} | |
HLSLPROGRAM | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS | |
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS | |
#pragma multi_compile_fragment _ _SHADOWS_SOFT | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
struct Attributes | |
{ | |
float3 positionOS : POSITION; | |
half3 normalOS : NORMAL; | |
half4 tangentOS : TANGENT; | |
float2 uv : TEXCOORD0; | |
}; | |
struct Varyings | |
{ | |
float2 uv : TEXCOORD0; | |
float4 positionWSAndFogFactor : TEXCOORD1; // xyz: positionWS, w: vertex fog factor | |
half3 normalWS : TEXCOORD2; | |
float4 positionCS : SV_POSITION; | |
float3 lightTS : TEXCOORD3; // light Direction in tangent space | |
float3 viewTS : TEXCOORD4; // camera direction in tangent space | |
}; | |
sampler2D _BaseMap; | |
sampler2D _NormalMap; | |
sampler2D _HeightMap; | |
CBUFFER_START(UnityPerMaterial) | |
float4 _BaseMap_ST; | |
float4 _NormalMap_ST; | |
float4 _HeightMap_ST; | |
float _Height; | |
CBUFFER_END | |
/* MEMO | |
from Core.hlsl | |
struct VertexPositionInputs | |
{ | |
float3 positionWS; // World space position | |
float3 positionVS; // View space position | |
float4 positionCS; // Homogeneous clip space position | |
float4 positionNDC;// Homogeneous normalized device coordinates | |
}; | |
from Core.hlsl | |
struct VertexNormalInputs | |
{ | |
real3 tangentWS; | |
real3 bitangentWS; | |
float3 normalWS; | |
}; | |
from Lighting.hlsl | |
struct Light | |
{ | |
half3 direction; | |
half3 color; | |
half distanceAttenuation; | |
half shadowAttenuation; | |
}; | |
*/ | |
Varyings vert (Attributes input) | |
{ | |
Varyings output; | |
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS); | |
VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); | |
output.uv = TRANSFORM_TEX(input.uv, _BaseMap); | |
output.positionCS = TransformWorldToHClip(vertexInput.positionWS); | |
//output.normalWS = vertexNormalInput.normalWS; | |
// Get Main Light | |
Light mainLight = GetMainLight(); | |
// world to tangent | |
float3x3 tangentMat = float3x3(vertexNormalInput.tangentWS, vertexNormalInput.bitangentWS, vertexNormalInput.normalWS); | |
output.lightTS = mul(tangentMat, mainLight.direction);; | |
// view direction | |
float3 camera = _WorldSpaceCameraPos; | |
output.viewTS = mul(tangentMat, normalize(camera - vertexInput.positionWS)); | |
return output; | |
} | |
half4 frag (Varyings input) : SV_Target | |
{ | |
float height = tex2D(_HeightMap, input.uv) * _Height * 0.01; | |
// creepy animation | |
//height *= sin(_Time.y * 2) + 1; | |
float2 uvh = input.uv + input.viewTS.xy * height; | |
half4 col = tex2D(_BaseMap, uvh); | |
float3 normal = UnpackNormal(tex2D(_NormalMap, uvh)); | |
float diff = saturate(dot(input.lightTS, normal)); | |
col *= diff; | |
return col; | |
} | |
ENDHLSL | |
} | |
} | |
} |
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 "MyShader/URP_Tessellation" | |
{ | |
Properties | |
{ | |
[Header(Base Color)] | |
[MainTexture]_BaseMap("_BaseMap (Albedo)", 2D) = "white" {} | |
[HDR][MainColor]_BaseColor("_BaseColor", Color) = (1,1,1,1) | |
[Header(Bump Map)] | |
[MainTexture]_NormalMap("_NormalMap", 2D) = "white" {} | |
[MainTexture]_HeightMap("_HeightMap", 2D) = "white" {} | |
_Height("_Height",float) = 1 | |
[Header(Tessellation)] | |
_TessFactor("Tessellation", Range(1, 50)) = 10 | |
_MinEdge("Min Edge", Range(0, 0.5)) = 0.4 | |
} | |
SubShader | |
{ | |
Tags | |
{ | |
"RenderPipeline" = "UniversalPipeline" | |
"RenderType"="Opaque" | |
"UniversalMaterialType" = "Lit" | |
"Queue"="Geometry" | |
} | |
Pass | |
{ | |
Name "ForwardLit" | |
Tags | |
{ | |
"LightMode"="UniversalForward" | |
} | |
HLSLPROGRAM | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS | |
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS | |
#pragma multi_compile_fragment _ _SHADOWS_SOFT | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma hull hull | |
#pragma domain domain | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
struct VSInput | |
{ | |
float3 positionOS : POSITION; | |
half3 normalOS : NORMAL; | |
half4 tangentOS : TANGENT; | |
float2 uv : TEXCOORD0; | |
}; | |
struct HsInput | |
{ | |
float4 positionOS : POS; | |
half3 normalOS : NORMAL; | |
float2 uv : TEXCOORD0; | |
half4 tangentOS : TEXCOORD1; | |
}; | |
struct HsControlPointOutput | |
{ | |
float3 positionOS : POS; | |
float3 normalOS : NORMAL; | |
float2 uv : TEXCOORD; | |
float4 tangentOS : TEXCOORD3; | |
}; | |
struct HsConstantOutput | |
{ | |
float tessFactor[3] : SV_TessFactor; | |
float insideTessFactor : SV_InsideTessFactor; | |
}; | |
struct DsOutput | |
{ | |
float4 positionCS : SV_Position; | |
float2 uv : TEXCOORD0; | |
float3 lightTS : TEXCOORD1; | |
}; | |
sampler2D _BaseMap; | |
sampler2D _NormalMap; | |
sampler2D _HeightMap; | |
CBUFFER_START(UnityPerMaterial) | |
float4 _BaseMap_ST; | |
float4 _NormalMap_ST; | |
float4 _HeightMap_ST; | |
float _Height; | |
float _MinEdge; | |
float _TessFactor; | |
CBUFFER_END | |
/* MEMO | |
from Core.hlsl | |
struct VertexPositionInputs | |
{ | |
float3 positionWS; // World space position | |
float3 positionVS; // View space position | |
float4 positionCS; // Homogeneous clip space position | |
float4 positionNDC;// Homogeneous normalized device coordinates | |
}; | |
from Core.hlsl | |
struct VertexNormalInputs | |
{ | |
real3 tangentWS; | |
real3 bitangentWS; | |
float3 normalWS; | |
}; | |
from Lighting.hlsl | |
struct Light | |
{ | |
half3 direction; | |
half3 color; | |
half distanceAttenuation; | |
half shadowAttenuation; | |
}; | |
*/ | |
HsInput vert (VSInput input) | |
{ | |
HsInput output; | |
output.positionOS = float4(input.positionOS, 1); | |
output.uv = input.uv; | |
output.tangentOS = input.tangentOS; | |
output.normalOS = input.normalOS; | |
// NOT transform from OS to WS here. | |
return output; | |
} | |
[domain("tri")] | |
[partitioning("integer")] | |
[outputtopology("triangle_cw")] | |
[patchconstantfunc("hullConst")] | |
[outputcontrolpoints(3)] | |
HsControlPointOutput hull(InputPatch<HsInput, 3> input, uint id : SV_OutputControlPointID) | |
{ | |
HsControlPointOutput output; | |
output.positionOS = input[id].positionOS.xyz; | |
output.normalOS = input[id].normalOS; | |
output.uv = input[id].uv; | |
output.tangentOS = input[id].tangentOS; | |
return output; | |
} | |
HsConstantOutput hullConst(InputPatch<HsInput, 3> i) | |
{ | |
HsConstantOutput o; | |
float4 p0 = i[0].positionOS; | |
float4 p1 = i[1].positionOS; | |
float4 p2 = i[2].positionOS; | |
o.tessFactor[0] = _TessFactor; | |
o.tessFactor[1] = _TessFactor; | |
o.tessFactor[2] = _TessFactor; | |
o.insideTessFactor = _TessFactor; | |
return o; | |
} | |
[domain("tri")] | |
DsOutput domain( | |
HsConstantOutput hsConst, | |
const OutputPatch<HsControlPointOutput, 3> input, | |
float3 bary : SV_DomainLocation) | |
{ | |
DsOutput output; | |
float3 positionOS = | |
bary.x * input[0].positionOS + | |
bary.y * input[1].positionOS + | |
bary.z * input[2].positionOS; | |
float3 normalOS = normalize( | |
bary.x * input[0].normalOS + | |
bary.y * input[1].normalOS + | |
bary.z * input[2].normalOS); | |
output.uv = | |
bary.x * input[0].uv + | |
bary.y * input[1].uv + | |
bary.z * input[2].uv; | |
float4 tangentOS = normalize( | |
bary.x * input[0].tangentOS + | |
bary.y * input[1].tangentOS + | |
bary.z * input[2].tangentOS); | |
// displacement | |
float2 st = abs(output.uv - 0.5); | |
// factor to avoid "gap" | |
float edge = 1 - smoothstep(_MinEdge, 0.5, max(st.x, st.y)); | |
float disp = tex2Dlod(_HeightMap, float4(output.uv, 0, 0)).r * _Height * edge; | |
positionOS.xyz += normalOS * disp; | |
// ----------------- copied from vertex shader ------------------- | |
// get vectors in the world coordinate | |
VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS); | |
VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(normalOS, tangentOS); | |
output.positionCS = TransformWorldToHClip(vertexInput.positionWS); | |
// Get Main Light | |
Light mainLight = GetMainLight(); | |
// world to tangent | |
float3x3 tangentMat = float3x3(vertexNormalInput.tangentWS, vertexNormalInput.bitangentWS, vertexNormalInput.normalWS); | |
output.lightTS = mul(tangentMat, mainLight.direction);; | |
// ----------------- copied from vertex shader END------------------- | |
return output; | |
} | |
half4 frag (DsOutput input) : SV_Target | |
{ | |
half4 col = tex2D(_BaseMap, input.uv); | |
float3 normal = UnpackNormal(tex2D(_NormalMap, input.uv)); | |
float diff = saturate(dot(input.lightTS, normal)); | |
col *= diff; | |
return col; | |
} | |
ENDHLSL | |
} | |
} | |
} |
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 "MyShader/URP_Tessellation_Shadow" | |
{ | |
Properties | |
{ | |
[Header(Base Color)] | |
[MainTexture]_BaseMap("_BaseMap (Albedo)", 2D) = "white" {} | |
[HDR][MainColor]_BaseColor("_BaseColor", Color) = (1,1,1,1) | |
[Header(Bump Map)] | |
[MainTexture]_NormalMap("_NormalMap", 2D) = "white" {} | |
[MainTexture]_HeightMap("_HeightMap", 2D) = "white" {} | |
_Height("_Height",float) = 1 | |
_HeightForNormal("_HeightForNormal",float) = 1 | |
[Header(Tessellation)] | |
_TessFactor("Tessellation", Range(1, 1000)) = 10 | |
_MinEdge("Min Edge", Range(0, 0.5)) = 0.4 | |
[Header(Lighting)] | |
_ReceiveShadowMappingPosOffset("ShadowMapping Offset", Range(0, 1)) = 0 | |
} | |
SubShader | |
{ | |
Tags | |
{ | |
"RenderPipeline" = "UniversalPipeline" | |
"RenderType"="Opaque" | |
"UniversalMaterialType" = "Lit" | |
"Queue"="Geometry" | |
} | |
Pass | |
{ | |
Name "ForwardLit" | |
Tags | |
{ | |
"LightMode"="UniversalForward" | |
} | |
HLSLPROGRAM | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS | |
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE | |
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS | |
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS | |
#pragma multi_compile_fragment _ _SHADOWS_SOFT | |
#pragma vertex vert | |
#pragma hull hull | |
#pragma domain domain | |
#pragma fragment frag | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
struct VSInput | |
{ | |
float3 positionOS : POSITION; | |
half3 normalOS : NORMAL; | |
half4 tangentOS : TANGENT; | |
float2 uv : TEXCOORD0; | |
}; | |
struct HsInput | |
{ | |
float4 positionOS : POS; | |
half3 normalOS : NORMAL; | |
float2 uv : TEXCOORD0; | |
half4 tangentOS : TEXCOORD1; | |
}; | |
struct HsControlPointOutput | |
{ | |
float3 positionOS : POS; | |
float3 normalOS : NORMAL; | |
float2 uv : TEXCOORD; | |
float4 tangentOS : TEXCOORD3; | |
}; | |
struct HsConstantOutput | |
{ | |
float tessFactor[3] : SV_TessFactor; | |
float insideTessFactor : SV_InsideTessFactor; | |
}; | |
struct DsOutput | |
{ | |
float4 positionCS : SV_Position; | |
float2 uv : TEXCOORD0; | |
float3 lightTS : TEXCOORD1; | |
float3 positionWS : TEXCOORD2; | |
float3 normalWS : TEXCOORD3; | |
real3 tangentWS : TEXCOORD4; | |
real3 bitangentWS : TEXCOORD5; | |
}; | |
struct LightingData | |
{ | |
half3 normalWS; | |
float3 positionWS; | |
half3 viewDirectionWS; | |
float4 shadowCoord; | |
}; | |
sampler2D _BaseMap; | |
sampler2D _NormalMap; | |
sampler2D _HeightMap; | |
CBUFFER_START(UnityPerMaterial) | |
float4 _BaseMap_ST; | |
float4 _NormalMap_ST; | |
float4 _HeightMap_ST; | |
float _Height; | |
float _HeightForNormal; | |
float _MinEdge; | |
float _TessFactor; | |
float _ReceiveShadowMappingPosOffset; | |
CBUFFER_END | |
/* MEMO | |
from Core.hlsl | |
struct VertexPositionInputs | |
{ | |
float3 positionWS; // World space position | |
float3 positionVS; // View space position | |
float4 positionCS; // Homogeneous clip space position | |
float4 positionNDC;// Homogeneous normalized device coordinates | |
}; | |
from Core.hlsl | |
struct VertexNormalInputs | |
{ | |
real3 tangentWS; | |
real3 bitangentWS; | |
float3 normalWS; | |
}; | |
from Lighting.hlsl | |
struct Light | |
{ | |
half3 direction; | |
half3 color; | |
half distanceAttenuation; | |
half shadowAttenuation; | |
}; | |
*/ | |
HsInput vert (VSInput input) | |
{ | |
HsInput output; | |
output.positionOS = float4(input.positionOS, 1); | |
output.uv = input.uv; | |
output.tangentOS = input.tangentOS; | |
output.normalOS = input.normalOS; | |
// Keep OS coordinate in the vertex stage. | |
return output; | |
} | |
[domain("tri")] | |
[partitioning("integer")] | |
[outputtopology("triangle_cw")] | |
[patchconstantfunc("hullConst")] | |
[outputcontrolpoints(3)] | |
HsControlPointOutput hull(InputPatch<HsInput, 3> input, uint id : SV_OutputControlPointID) | |
{ | |
HsControlPointOutput output; | |
output.positionOS = input[id].positionOS.xyz; | |
output.normalOS = input[id].normalOS; | |
output.uv = input[id].uv; | |
output.tangentOS = input[id].tangentOS; | |
return output; | |
} | |
HsConstantOutput hullConst(InputPatch<HsInput, 3> i) | |
{ | |
HsConstantOutput o; | |
float4 p0 = i[0].positionOS; | |
float4 p1 = i[1].positionOS; | |
float4 p2 = i[2].positionOS; | |
// you can arrange tessellation factor here (eg. with respect to distance from camera) | |
o.tessFactor[0] = _TessFactor; | |
o.tessFactor[1] = _TessFactor; | |
o.tessFactor[2] = _TessFactor; | |
o.insideTessFactor = _TessFactor; | |
return o; | |
} | |
float3 normalTSfromHeight(float2 uv, float height) | |
{ | |
float2 e = float2(1,0) / 256; | |
float L = tex2Dlod(_HeightMap, float4(uv - e, 0, 0)).r; | |
float R = tex2Dlod(_HeightMap, float4(uv + e, 0, 0)).r; | |
float D = tex2Dlod(_HeightMap, float4(uv - e.yx, 0, 0)).r; | |
float U = tex2Dlod(_HeightMap, float4(uv + e.yx, 0, 0)).r; | |
return normalize(float3(2*(L-R) * height * _HeightForNormal, 2*(U-D) * height * _HeightForNormal, 4)); | |
} | |
[domain("tri")] | |
DsOutput domain( | |
HsConstantOutput hsConst, | |
const OutputPatch<HsControlPointOutput, 3> input, | |
float3 bary : SV_DomainLocation) | |
{ | |
DsOutput output; | |
float3 positionOS = | |
bary.x * input[0].positionOS + | |
bary.y * input[1].positionOS + | |
bary.z * input[2].positionOS; | |
float3 normalOS = normalize( | |
bary.x * input[0].normalOS + | |
bary.y * input[1].normalOS + | |
bary.z * input[2].normalOS); | |
output.uv = | |
bary.x * input[0].uv + | |
bary.y * input[1].uv + | |
bary.z * input[2].uv; | |
float4 tangentOS = normalize( | |
bary.x * input[0].tangentOS + | |
bary.y * input[1].tangentOS + | |
bary.z * input[2].tangentOS); | |
// displacement | |
float2 st = abs(output.uv - 0.5); | |
// make displacement zero at edge | |
float edge = 1 - smoothstep(_MinEdge, 0.5, max(st.x, st.y)); | |
float disp = tex2Dlod(_HeightMap, float4(output.uv, 0, 0)).r * _Height * edge; | |
positionOS.xyz += normalOS * disp; | |
float3 normal2TS = normalTSfromHeight(output.uv, _Height * edge); | |
// real sign = tangentOS.w * GetOddNegativeScale(); | |
// float3 bitangentOS = cross(normalOS, tangentOS.xyz) * sign; | |
// // // OS to TS | |
// float3x3 objectMat = float3x3(tangentOS.xyz, bitangentOS, normalOS); | |
// float3 normal2OS = mul(objectMat, normalTS); | |
// float3 tangent2OS = normalize(tangentOS.xyz - dot(normal2OS, tangentOS) * normal2OS); | |
// ----------------- copied from vertex shader ------------------- | |
// get vectors in the world coordinate | |
VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS); | |
VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(normalOS, tangentOS); | |
output.positionCS = TransformWorldToHClip(vertexInput.positionWS); | |
output.positionWS = vertexInput.positionWS; | |
// output.normalWS = vertexNormalInput.normalWS; | |
// Get Main Light | |
Light mainLight = GetMainLight(); | |
// world to tangent | |
float3 tangentWS = vertexNormalInput.tangentWS; | |
float3x3 tangentMat = float3x3(vertexNormalInput.tangentWS, vertexNormalInput.bitangentWS, vertexNormalInput.normalWS); | |
float3 normal2WS = mul(transpose(tangentMat), normal2TS); | |
float3 tangent2WS = normalize(tangentWS - dot(tangentWS, normal2WS) * normal2WS); | |
float3 bitangent2WS = cross(normal2WS, tangent2WS); | |
float3x3 tangent2Mat = float3x3(tangent2WS, bitangent2WS, normal2WS); | |
output.lightTS = mul(tangent2Mat, mainLight.direction); | |
// ----------------- copied from vertex shader END------------------- | |
return output; | |
} | |
LightingData InitializeLightingData(DsOutput input) | |
{ | |
LightingData lightingData; | |
lightingData.positionWS = input.positionWS; | |
lightingData.viewDirectionWS = SafeNormalize(GetCameraPositionWS() - lightingData.positionWS); | |
float3 normal = UnpackNormal(tex2D(_NormalMap, input.uv)); | |
lightingData.normalWS = normalize(input.normalWS); //interpolated normal is NOT unit vector, we need to normalize it | |
return lightingData; | |
} | |
half3 BaseColor(DsOutput input) | |
{ | |
half4 col = tex2D(_BaseMap, input.uv); | |
float3 normal = UnpackNormal(tex2D(_NormalMap, input.uv)); | |
float diff = saturate(dot(input.lightTS, normal)); | |
col *= diff; | |
//col.rgb = input.lightTS; | |
return col.xyz; | |
} | |
half3 ShadeMainLight(half3 col, LightingData lightingData) | |
{ | |
Light mainLight = GetMainLight(); | |
float3 shadowTestPosWS = lightingData.positionWS + mainLight.direction * _ReceiveShadowMappingPosOffset; | |
//#ifdef _MAIN_LIGHT_SHADOWS | |
float4 shadowCoord = TransformWorldToShadowCoord(shadowTestPosWS); | |
mainLight.shadowAttenuation = MainLightRealtimeShadow(shadowCoord); | |
//#endif | |
col *= (mainLight.color * mainLight.shadowAttenuation); | |
return col; | |
} | |
half4 frag (DsOutput input) : SV_Target | |
{ | |
LightingData lightingData = InitializeLightingData(input); | |
half3 col = BaseColor(input); | |
half3 shaded = ShadeMainLight(col, lightingData); | |
return half4(shaded, 1); | |
} | |
ENDHLSL | |
} | |
Pass | |
{ | |
Name "ShadowCaster" | |
Tags{"LightMode" = "ShadowCaster"} | |
// more explict render state to avoid confusion | |
ZWrite On // the only goal of this pass is to write depth! | |
ZTest LEqual // early exit at Early-Z stage if possible | |
ColorMask 0 // we don't care about color, we just want to write depth, ColorMask 0 will save some write bandwidth | |
Cull Back // support Cull[_Cull] requires "flip vertex normal" using VFACE in fragment shader, which is maybe beyond the scope of a simple tutorial shader | |
HLSLPROGRAM | |
// the only keywords we need in this pass = _UseAlphaClipping, which is already defined inside the HLSLINCLUDE block | |
// (so no need to write any multi_compile or shader_feature in this pass) | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
#pragma vertex vert | |
#pragma hull hull | |
#pragma domain domain | |
#pragma fragment frag | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" | |
struct VSInput | |
{ | |
float3 positionOS : POSITION; | |
half3 normalOS : NORMAL; | |
half4 tangentOS : TANGENT; | |
float2 uv : TEXCOORD0; | |
}; | |
struct HsInput | |
{ | |
float4 positionOS : POS; | |
half3 normalOS : NORMAL; | |
float2 uv : TEXCOORD0; | |
half4 tangentOS : TEXCOORD1; | |
}; | |
struct HsControlPointOutput | |
{ | |
float3 positionOS : POS; | |
float3 normalOS : NORMAL; | |
float2 uv : TEXCOORD; | |
float4 tangentOS : TEXCOORD3; | |
}; | |
struct HsConstantOutput | |
{ | |
float tessFactor[3] : SV_TessFactor; | |
float insideTessFactor : SV_InsideTessFactor; | |
}; | |
struct DsOutput | |
{ | |
float4 positionCS : SV_Position; | |
float2 uv : TEXCOORD0; | |
float3 lightTS : TEXCOORD1; | |
}; | |
sampler2D _BaseMap; | |
sampler2D _NormalMap; | |
sampler2D _HeightMap; | |
float3 _LightDirection; | |
CBUFFER_START(UnityPerMaterial) | |
float4 _BaseMap_ST; | |
float4 _NormalMap_ST; | |
float4 _HeightMap_ST; | |
float _Height; | |
float _MinEdge; | |
float _TessFactor; | |
CBUFFER_END | |
HsInput vert (VSInput input) | |
{ | |
HsInput output; | |
output.positionOS = float4(input.positionOS, 1); | |
output.uv = input.uv; | |
output.tangentOS = input.tangentOS; | |
output.normalOS = input.normalOS; | |
// NOT transform from OS to WS here. | |
return output; | |
} | |
[domain("tri")] | |
[partitioning("integer")] | |
[outputtopology("triangle_cw")] | |
[patchconstantfunc("hullConst")] | |
[outputcontrolpoints(3)] | |
HsControlPointOutput hull(InputPatch<HsInput, 3> input, uint id : SV_OutputControlPointID) | |
{ | |
HsControlPointOutput output; | |
output.positionOS = input[id].positionOS.xyz; | |
output.normalOS = input[id].normalOS; | |
output.uv = input[id].uv; | |
output.tangentOS = input[id].tangentOS; | |
return output; | |
} | |
HsConstantOutput hullConst(InputPatch<HsInput, 3> i) | |
{ | |
HsConstantOutput o; | |
float4 p0 = i[0].positionOS; | |
float4 p1 = i[1].positionOS; | |
float4 p2 = i[2].positionOS; | |
o.tessFactor[0] = _TessFactor; | |
o.tessFactor[1] = _TessFactor; | |
o.tessFactor[2] = _TessFactor; | |
o.insideTessFactor = _TessFactor; | |
return o; | |
} | |
[domain("tri")] | |
DsOutput domain( | |
HsConstantOutput hsConst, | |
const OutputPatch<HsControlPointOutput, 3> input, | |
float3 bary : SV_DomainLocation) | |
{ | |
DsOutput output; | |
float3 positionOS = | |
bary.x * input[0].positionOS + | |
bary.y * input[1].positionOS + | |
bary.z * input[2].positionOS; | |
float3 normalOS = normalize( | |
bary.x * input[0].normalOS + | |
bary.y * input[1].normalOS + | |
bary.z * input[2].normalOS); | |
output.uv = | |
bary.x * input[0].uv + | |
bary.y * input[1].uv + | |
bary.z * input[2].uv; | |
float4 tangentOS = normalize( | |
bary.x * input[0].tangentOS + | |
bary.y * input[1].tangentOS + | |
bary.z * input[2].tangentOS); | |
// displacement | |
float2 st = abs(output.uv - 0.5); | |
// factor to avoid "gap" | |
float edge = 1 - smoothstep(_MinEdge, 0.5, max(st.x, st.y)); | |
float disp = tex2Dlod(_HeightMap, float4(output.uv, 0, 0)).r * _Height * edge; | |
positionOS.xyz += normalOS * disp; | |
// get vectors in the world coordinate | |
VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS); | |
VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(normalOS, tangentOS); | |
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, vertexNormalInput.normalWS, _LightDirection)); | |
#if UNITY_REVERSED_Z | |
positionCS.z = min(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE); | |
#else | |
positionCS.z = max(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE); | |
#endif | |
output.positionCS = positionCS; | |
return output; | |
} | |
void frag (DsOutput input) | |
{ | |
} | |
ENDHLSL | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment