Created
May 27, 2025 19:57
-
-
Save koturn/2626d9e33d3fc2b0ea2237c5afe6d8a3 to your computer and use it in GitHub Desktop.
VRCLightVolumesのサンプルコード(Amplify Shader Editorの出力)を人間向けに読みやすくしたやつ
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 "Light Volume Samples/Light Volume PBR" | |
{ | |
Properties | |
{ | |
_MainTex("Albedo", 2D) = "white" {} | |
_Color("Color", Color) = (1,1,1,1) | |
[NoScaleOffset]_MetallicGlossMap("Metal AO Smoothness", 2D) = "white" {} | |
_Metallic("Metallic", Range( 0 , 1)) = 0 | |
_Glossiness("Smoothness", Range( 0 , 1)) = 1 | |
_OcclusionStrength("AO", Range( 0 , 1)) = 1 | |
[NoScaleOffset]_BumpMap("Normal", 2D) = "bump" {} | |
_BumpScale("Normal Power", Float) = 1 | |
[HDR][NoScaleOffset]_EmissionMap("Emission Map", 2D) = "white" {} | |
[HDR]_EmissionColor("Emission Color", Color) = (0,0,0,1) | |
[Toggle(_LIGHTVOLUMES_ON)] _LightVolumes("Enable Light Volumes", Float) = 1 | |
[Toggle(_ADDITIVEONLY_ON)] _AdditiveOnly("Additive Only", Float) = 0 | |
[Toggle(_SPECULARS_ON)] _Speculars("Speculars", Float) = 1 | |
[Toggle(_DOMINANTDIRSPECULARS_ON)] _DominantDirSpeculars("Dominant Dir Speculars", Float) = 0 | |
[Enum(UnityEngine.Rendering.CullMode)]_Culling("Culling", Float) = 2 | |
[HideInInspector] _texcoord( "", 2D ) = "white" {} | |
[HideInInspector] __dirty( "", Int ) = 1 | |
} | |
SubShader | |
{ | |
Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+0" "IsEmissive" = "true" } | |
Cull [_Culling] | |
Blend SrcAlpha OneMinusSrcAlpha | |
CGINCLUDE | |
#include "UnityStandardUtils.cginc" | |
#include "Packages/red.sim.lightvolumes/Shaders/LightVolumes.cginc" | |
#include "UnityStandardBRDF.cginc" | |
#include "UnityPBSLighting.cginc" | |
#include "Lighting.cginc" | |
#pragma target 5.0 | |
#pragma shader_feature_local _SPECULARS_ON | |
#pragma shader_feature_local _LIGHTVOLUMES_ON | |
#pragma shader_feature_local _ADDITIVEONLY_ON | |
#pragma shader_feature_local _DOMINANTDIRSPECULARS_ON | |
#define ASE_VERSION 19801 | |
#ifdef UNITY_PASS_SHADOWCASTER | |
#undef INTERNAL_DATA | |
#undef WorldReflectionVector | |
#undef WorldNormalVector | |
#define INTERNAL_DATA half3 internalSurfaceTtoW0; half3 internalSurfaceTtoW1; half3 internalSurfaceTtoW2; | |
#define WorldReflectionVector(data,normal) reflect (data.worldRefl, half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal))) | |
#define WorldNormalVector(data,normal) half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal)) | |
#endif | |
struct Input | |
{ | |
float2 uv_texcoord; | |
float3 worldNormal; | |
INTERNAL_DATA | |
float3 worldPos; | |
}; | |
uniform float _Culling; | |
uniform sampler2D _BumpMap; | |
uniform float _BumpScale; | |
uniform float4 _Color; | |
uniform sampler2D _MainTex; | |
uniform float4 _MainTex_ST; | |
uniform float4 _EmissionColor; | |
uniform sampler2D _EmissionMap; | |
uniform sampler2D _MetallicGlossMap; | |
uniform float _Metallic; | |
uniform float _Glossiness; | |
uniform float _OcclusionStrength; | |
void surf( Input i , inout SurfaceOutputStandard o ) | |
{ | |
float3 normal = UnpackScaleNormal(tex2D(_BumpMap, i.uv_texcoord), _BumpScale); | |
o.Normal = normal; | |
float2 uv_MainTex = i.uv_texcoord * _MainTex_ST.xy + _MainTex_ST.zw; | |
float3 albedo = (_Color.rgb * tex2D(_MainTex, uv_MainTex).rgb); | |
o.Albedo = albedo; | |
float3 worldNormal = normalize((WorldNormalVector(i, normal))); | |
#if !defined(_LIGHTVOLUMES_ON) | |
float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); | |
float3 L1r = (unity_SHAr).xyz; | |
float3 L1g = (unity_SHAg).xyz; | |
float3 L1b = (unity_SHAb).xyz; | |
#elif defined(_ADDITIVEONLY_ON) | |
float3 L0 = float3(0, 0, 0); | |
float3 L1r = float3(0, 0, 0); | |
float3 L1g = float3(0, 0, 0); | |
float3 L1b = float3(0, 0, 0); | |
LightVolumeAdditiveSH(i.worldPos, /* out */ L0, /* out */ L1r, /* out */ L1g, /* out */ L1b); | |
#else | |
float3 L0 = float3(0, 0, 0); | |
float3 L1r = float3(0, 0, 0); | |
float3 L1g = float3(0, 0, 0); | |
float3 L1b = float3(0, 0, 0); | |
LightVolumeSH(i.worldPos, /* out */ L0, /* out */ L1r, /* out */ L1g, /* out */ L1b); | |
#endif | |
float3 lvEval = LightVolumeEvaluate(worldNormal, L0, L1r, L1g, L1b); | |
float4 texMetallic = tex2D(_MetallicGlossMap, i.uv_texcoord); | |
float metallic = pow(texMetallic.r * _Metallic, 2.0); | |
float3 indirect = (lvEval * albedo * (1.0 - metallic)); | |
float smoothness = (texMetallic.a * _Glossiness); | |
float3 worldViewDir = Unity_SafeNormalize(_WorldSpaceCameraPos.xyz - i.worldPos); | |
float ao = lerp(1.0, texMetallic.g, _OcclusionStrength); | |
#if defined(_SPECULARS_ON) | |
#ifdef _DOMINANTDIRSPECULARS_ON | |
float3 specular = LightVolumeSpecularDominant(albedo, smoothness, metallic, worldNormal, worldViewDir, L0, L1r, L1g, L1b); | |
#else | |
float3 specular = LightVolumeSpecular(albedo, smoothness, metallic, worldNormal, worldViewDir, L0, L1r, L1g, L1b); | |
#endif | |
float3 indirectAndSpecular = (indirect + specular * ao) * ao; | |
#else | |
float3 indirectAndSpecular = indirect * ao; | |
#endif | |
o.Emission = (_EmissionColor.rgb * tex2D(_EmissionMap, i.uv_texcoord).rgb) + indirectAndSpecular; | |
o.Metallic = metallic; | |
o.Smoothness = smoothness; | |
o.Occlusion = ao; | |
o.Alpha = 1; | |
} | |
ENDCG | |
CGPROGRAM | |
#pragma surface surf Standard keepalpha fullforwardshadows exclude_path:deferred noambient | |
ENDCG | |
Pass | |
{ | |
Name "ShadowCaster" | |
Tags{ "LightMode" = "ShadowCaster" } | |
ZWrite On | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma target 5.0 | |
#pragma multi_compile_shadowcaster | |
#pragma multi_compile UNITY_PASS_SHADOWCASTER | |
#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2 | |
#include "HLSLSupport.cginc" | |
#if ( SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN ) | |
#define CAN_SKIP_VPOS | |
#endif | |
#include "UnityCG.cginc" | |
#include "Lighting.cginc" | |
#include "UnityPBSLighting.cginc" | |
struct v2f | |
{ | |
V2F_SHADOW_CASTER; | |
float2 customPack1 : TEXCOORD1; | |
float4 tSpace0 : TEXCOORD2; | |
float4 tSpace1 : TEXCOORD3; | |
float4 tSpace2 : TEXCOORD4; | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
UNITY_VERTEX_OUTPUT_STEREO | |
}; | |
v2f vert( appdata_full v ) | |
{ | |
v2f o; | |
UNITY_SETUP_INSTANCE_ID( v ); | |
UNITY_INITIALIZE_OUTPUT( v2f, o ); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o ); | |
UNITY_TRANSFER_INSTANCE_ID( v, o ); | |
Input customInputData; | |
float3 worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz; | |
half3 worldNormal = UnityObjectToWorldNormal( v.normal ); | |
half3 worldTangent = UnityObjectToWorldDir( v.tangent.xyz ); | |
half tangentSign = v.tangent.w * unity_WorldTransformParams.w; | |
half3 worldBinormal = cross( worldNormal, worldTangent ) * tangentSign; | |
o.tSpace0 = float4( worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x ); | |
o.tSpace1 = float4( worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y ); | |
o.tSpace2 = float4( worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z ); | |
o.customPack1.xy = customInputData.uv_texcoord; | |
o.customPack1.xy = v.texcoord; | |
TRANSFER_SHADOW_CASTER_NORMALOFFSET( o ) | |
return o; | |
} | |
half4 frag( v2f IN | |
#if !defined( CAN_SKIP_VPOS ) | |
, UNITY_VPOS_TYPE vpos : VPOS | |
#endif | |
) : SV_Target | |
{ | |
UNITY_SETUP_INSTANCE_ID( IN ); | |
Input surfIN; | |
UNITY_INITIALIZE_OUTPUT( Input, surfIN ); | |
surfIN.uv_texcoord = IN.customPack1.xy; | |
float3 worldPos = float3( IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w ); | |
half3 worldViewDir = normalize( UnityWorldSpaceViewDir( worldPos ) ); | |
surfIN.worldPos = worldPos; | |
surfIN.worldNormal = float3( IN.tSpace0.z, IN.tSpace1.z, IN.tSpace2.z ); | |
surfIN.internalSurfaceTtoW0 = IN.tSpace0.xyz; | |
surfIN.internalSurfaceTtoW1 = IN.tSpace1.xyz; | |
surfIN.internalSurfaceTtoW2 = IN.tSpace2.xyz; | |
SurfaceOutputStandard o; | |
UNITY_INITIALIZE_OUTPUT( SurfaceOutputStandard, o ) | |
surf( surfIN, o ); | |
#if defined( CAN_SKIP_VPOS ) | |
float2 vpos = IN.pos; | |
#endif | |
SHADOW_CASTER_FRAGMENT( IN ) | |
} | |
ENDCG | |
} | |
} | |
Fallback "Diffuse" | |
CustomEditor "AmplifyShaderEditor.MaterialInspector" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment