关于翻录
一些论坛:
1、https://cs.rin.ru/forum/viewtopic.php?t=100672
这个帖子是用来查询和请求解压虚幻文件的AES KEY。
2、https://www.gildor.org/smf/index.php
这个是Umoder下兴者自己建立的论坛,主要是用来讨论 (寻找方法)解决一些有特殊加密的虚幻文件
3、https://forum.xentax.com/index.php
这是一个论坛,主要是解决各种非“通用”引擎的游戏文件
4、https://discord.gg/7yixAVhS
这是个Discord聊天群,主要用来解决一些有特殊加密的Unity3D的文件
displacement to normal
Shader "Saber/Unlit/DisplacementToNormals" { Properties { _DisplacementMap("Displacement Map", 2D) = "black" {} _NormalStrength("Normal Strength", float) = 1 } SubShader { Pass { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "Queue" = "Geometry" } HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" TEXTURE2D(_DisplacementMap); SAMPLER(sampler_DisplacementMap); float4 _DisplacementMap_TexelSize; float _NormalStrength; struct Attributes { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct Varyings { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; Varyings vert(Attributes input) { Varyings output; output.vertex = TransformObjectToHClip(input.vertex.xyz); output.uv = input.uv; return output; } float4 frag(Varyings input) : SV_Target { float2 uv = input.uv; float radius = _DisplacementMap_TexelSize; float xLeft = SAMPLE_TEXTURE2D(_DisplacementMap, sampler_DisplacementMap, float2(uv.xy - float2(radius, 0.0))).x; float xRight = SAMPLE_TEXTURE2D(_DisplacementMap, sampler_DisplacementMap, float2(uv.xy + float2(radius, 0.0))).x; float yUp = SAMPLE_TEXTURE2D(_DisplacementMap, sampler_DisplacementMap, float2(uv.xy - float2(0.0, radius))).x; float yDown = SAMPLE_TEXTURE2D(_DisplacementMap, sampler_DisplacementMap, float2(uv.xy + float2(0.0, radius))).x; float3 normalTS = float3(xRight - xLeft, yUp - yDown, 0) * _NormalStrength; normalTS.z = sqrt(1 - dot(normalTS.xy, normalTS.xy)); float3 normalColor = normalTS * 0.5 + 0.5; return half4(normalColor,1); } ENDHLSL } } }
dynamic effect:
using UnityEngine; using System; using UnityEngine.Rendering.Universal; using UnityEngine.Rendering; using UnityEngine.Experimental.Rendering; using UnityEditor; namespace GameLogic { [ExecuteAlways] public class ToonWaterDynamicEffects : MonoBehaviour { [Serializable] public enum Quality { VeryHigh, High, Medium, Low } [Header("Base")] [SerializeField] [Tooltip("Effect texture resolution\nVery High: 2048\nHigh: 1024\nMedium: 512\nLow: 256")] private Quality _Quality = Quality.High; [SerializeField] [Tooltip("Layers that will be used to capture the dynamic effects.")] private LayerMask _LayerMask = 2; [SerializeField] [Tooltip("Size of the capture region.")] private float _CaptureSize = 10f; [SerializeField] [Tooltip("Y distance of the capture camera from the target.")] private float _CaptureDistance = 10f; [SerializeField] [Range(0, 60)] [Tooltip("Limits the update of the render texture. Set this to 0 for no limits.")] private int _CapturePerSeconds = 0; [SerializeField] [Range(0.1f, 1f)] private float _EdgeMaskSize = 0.1f; [Header("Normals")] [SerializeField] private bool _EnableNormalBlur = false; [SerializeField] [Range(0, 4)] private float _NormalBlur = 1; [SerializeField] [Range(0, 2)] private float _NormalStrength = 1; [SerializeField] private Shader _EffectsShader; #if UNITY_EDITOR [Header("Debug")] [SerializeField] private bool _ShowRegion = false; #endif private RenderTexture _DynamicEffectsTexture; private RenderTexture _CompRT; private RenderTexture _TempRT1; private RenderTexture _TempRT2; private readonly int _NormalSharpId = Shader.PropertyToID("_NormalMap"); private readonly int _BaseTexId = Shader.PropertyToID("_BaseTex"); private readonly int _DynamicEffectsTextureId = Shader.PropertyToID("_DynamicEffectsTexture"); private readonly int _DynamicEffectsParams = Shader.PropertyToID("_DynamicEffectsParams"); private readonly int _NormalStrengthId = Shader.PropertyToID("_NormalStrength"); private readonly int _NormalBlurId = Shader.PropertyToID("_BlurStrength"); private readonly int _DebugTextureId = Shader.PropertyToID("_DebugTexture"); private Camera _DynamicEffectsCamera; private Material _EffectsMaterial; private bool _EnableRender = false; const RenderTextureFormat _HdrFormat = RenderTextureFormat.ARGB32; public static event Action<ScriptableRenderContext, Camera> BeginDynamicEffects; private void OnEnable() { RenderPipelineManager.beginCameraRendering += ComputeEffects; if (_CapturePerSeconds > 0) { InvokeRepeating("ResetTime", 0f, 1f / _CapturePerSeconds); } } // Cleanup all the objects we possibly have created private void OnDisable() { Cleanup(); } private void OnDestroy() { Cleanup(); } private void ResetTime() { _EnableRender = true; } private void ComputeEffects(ScriptableRenderContext context, Camera camera) { // Frame limiter if (_CapturePerSeconds == 0 || _EnableRender) { _EnableRender = false; } else { return; } // For overlay Camera var cameraData = camera.GetUniversalAdditionalCameraData(); if (cameraData.renderType != CameraRenderType.Base) return; // we dont want to render planar reflections in reflections or previews var cameraType = camera.cameraType; if (cameraType == CameraType.Reflection || cameraType == CameraType.Preview) return; if (_DynamicEffectsCamera == null) { _DynamicEffectsCamera = CreateEffectsCamera(); } CreateEffectsMaterial(); CreateEffectsTextures(); // create and assign RenderTexture UpdateEffectsCamera(_DynamicEffectsCamera); var data = new DynamicEffectsData(); // save quality settings and lower them for the planar reflections data.Set(); // set quality settings BeginDynamicEffects?.Invoke(context, _DynamicEffectsCamera); // callback Action for dynamic effect #pragma warning disable CS0618 UniversalRenderPipeline.RenderSingleCamera(context, _DynamicEffectsCamera); // render dynamic effect #pragma warning restore CS0618 DrawTextures(); data.Restore(); // restore the quality settings SetShaderProperties(); } /// <summary> /// Textures manipulations using shader /// </summary> private void DrawTextures() { _EffectsMaterial.SetFloat(_NormalStrengthId, _NormalStrength); _EffectsMaterial.SetFloat("_EdgeMaskSize", _EdgeMaskSize); // Create Normal if (_EnableNormalBlur) { _EffectsMaterial.SetFloat(_NormalBlurId, _NormalBlur); } else { _EffectsMaterial.SetFloat(_NormalBlurId, 0.0f); } Graphics.Blit(_DynamicEffectsTexture, _CompRT, _EffectsMaterial, 0); if (_EnableNormalBlur) { _EffectsMaterial.SetTexture(_BaseTexId, _CompRT); _EffectsMaterial.SetFloat(_NormalBlurId, _NormalBlur); // Blur Pass 1 Graphics.Blit(_CompRT, _TempRT1, _EffectsMaterial, 1); // Blur H Graphics.Blit(_TempRT1, _TempRT2, _EffectsMaterial, 2); // Blur V // Blur Pass 2 Graphics.Blit(_TempRT2, _TempRT1, _EffectsMaterial, 1); // Blur H Graphics.Blit(_TempRT1, _TempRT2, _EffectsMaterial, 2); // Blur V // Composite Channels _EffectsMaterial.SetTexture(_BaseTexId, _DynamicEffectsTexture); Graphics.Blit(_TempRT2, _CompRT, _EffectsMaterial, 3); } else { _EffectsMaterial.SetTexture(_BaseTexId, _DynamicEffectsTexture); Graphics.Blit(_CompRT, _TempRT1); Graphics.Blit(_TempRT1, _CompRT, _EffectsMaterial, 3); // Composite Channels } } private void SetShaderProperties() { var pos = transform.position; var parameters = new Vector4(); parameters.x = pos.x; parameters.y = pos.y; parameters.z = pos.z; parameters.w = _CaptureSize * 2.0f; Shader.SetGlobalVector(_DynamicEffectsParams, parameters); // Assign texture to water shader Shader.SetGlobalTexture(_DynamicEffectsTextureId, _CompRT); } #region Camera private void UpdateEffectsCamera(Camera cam) { cam.orthographicSize = _CaptureSize; cam.farClipPlane = _CaptureDistance; } private Camera CreateEffectsCamera() { var go = new GameObject("Effects Camera", typeof(Camera)); go.hideFlags = HideFlags.HideAndDontSave; go.transform.parent = this.transform; var cameraData = go.AddComponent(typeof(UniversalAdditionalCameraData)) as UniversalAdditionalCameraData; cameraData.renderShadows = false; cameraData.requiresColorOption = CameraOverrideOption.Off; cameraData.requiresDepthOption = CameraOverrideOption.Off; cameraData.SetRenderer(0); var t = transform; var position = Vector3.zero; var rotation = Quaternion.Euler(new Vector3(90f, 0f, 0)); var effectsCamera = go.GetComponent<Camera>(); effectsCamera.transform.localPosition = position; effectsCamera.transform.localRotation = rotation; effectsCamera.cullingMask = _LayerMask; effectsCamera.orthographic = true; effectsCamera.orthographicSize = _CaptureSize; effectsCamera.nearClipPlane = 0f; effectsCamera.farClipPlane = _CaptureDistance; effectsCamera.clearFlags = CameraClearFlags.Color; effectsCamera.backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.0f); effectsCamera.aspect = 1; effectsCamera.depth = -100; effectsCamera.enabled = false; return effectsCamera; } #endregion #region Material private void CreateEffectsMaterial() { if (_EffectsShader == null) { _EffectsShader = _EffectsShader = Shader.Find("Omnigames/Water/Hidden/WaterEffects"); } if (_EffectsMaterial == null) { _EffectsMaterial = new Material(_EffectsShader); } } #endregion #region Texture private void CreateEffectsTextures() { var res = EffectsResolution(UniversalRenderPipeline.asset.renderScale); var x = (int)res.x; var y = (int)res.y; if (_DynamicEffectsTexture == null) { _DynamicEffectsTexture = RenderTexture.GetTemporary(x, y, 16, GraphicsFormatUtility.GetGraphicsFormat(_HdrFormat, false)); _DynamicEffectsTexture.useMipMap = false; _DynamicEffectsTexture.autoGenerateMips = false; } if (_CompRT == null) { _CompRT = RenderTexture.GetTemporary(x, y, 16, GraphicsFormatUtility.GetGraphicsFormat(_HdrFormat, false)); _CompRT.useMipMap = false; _CompRT.autoGenerateMips = false; } if (_TempRT1 == null) { _TempRT1 = RenderTexture.GetTemporary(x / 2, y / 2, 16, GraphicsFormatUtility.GetGraphicsFormat(_HdrFormat, false)); _TempRT1.useMipMap = false; _TempRT1.autoGenerateMips = false; } if (_EnableNormalBlur && _TempRT2 == null) { _TempRT2 = RenderTexture.GetTemporary(x / 2, y / 2, 16, GraphicsFormatUtility.GetGraphicsFormat(_HdrFormat, false)); _TempRT2.useMipMap = false; _TempRT2.autoGenerateMips = false; } _DynamicEffectsCamera.targetTexture = _DynamicEffectsTexture; } private Vector2 EffectsResolution(float scale) { var x = (int)(2048 * scale * GetScaleValue()); var y = (int)(2048 * scale * GetScaleValue()); return new Vector2(x, y); } #endregion private Vector3 XZPos(Vector3 pos) { return new Vector3(pos.x, pos.y + _CaptureDistance, pos.z); } private float GetScaleValue() { switch (_Quality) { case Quality.VeryHigh: return 1f; case Quality.High: return 0.5f; case Quality.Medium: return 0.33f; case Quality.Low: return 0.25f; default: return 0.5f; } } private void Cleanup() { RenderPipelineManager.beginCameraRendering -= ComputeEffects; if (_DynamicEffectsCamera) { _DynamicEffectsCamera.targetTexture = null; SafeDestroy(_DynamicEffectsCamera.gameObject); } if (_DynamicEffectsTexture) { RenderTexture.ReleaseTemporary(_DynamicEffectsTexture); } if (_CompRT) { RenderTexture.ReleaseTemporary(_CompRT); } if (_EffectsMaterial) { SafeDestroy(_EffectsMaterial); } if (_TempRT1) { RenderTexture.ReleaseTemporary(_TempRT1); } if (_TempRT2) { RenderTexture.ReleaseTemporary(_TempRT2); } } private static void SafeDestroy(UnityEngine.Object obj) { if (Application.isEditor) { DestroyImmediate(obj); } else { Destroy(obj); } } void OnDrawGizmos() { #if UNITY_EDITOR if (_ShowRegion == false || _DynamicEffectsCamera == null) { return; } var pos = _DynamicEffectsCamera.transform.position; pos.y -= _DynamicEffectsCamera.farClipPlane * 0.5f; var size = new Vector3(_CaptureSize * 2.0f, _DynamicEffectsCamera.farClipPlane, _CaptureSize * 2.0f); Gizmos.color = new Color(0, 0.5f, 1, 0.5f); Gizmos.DrawCube(pos, size); Gizmos.color = new Color(0, 0.5f, 1, 0.9f); Gizmos.DrawWireCube(pos, size); #endif } /// <summary> /// Get or set the size of the capture. /// </summary> public float CaptureSize { get => _CaptureSize; set { _CaptureSize = value; } } /// <summary> /// Get or set the Y distance range of the capture. /// </summary> public float CaptureDistance { get => _CaptureDistance; set { _CaptureDistance = value; } } class DynamicEffectsData { private readonly bool _Fog; private readonly int _MaxLod; private readonly float _LodBias; private readonly bool _DrawGizmos; public DynamicEffectsData() { _Fog = RenderSettings.fog; _MaxLod = QualitySettings.maximumLODLevel; _LodBias = QualitySettings.lodBias; #if UNITY_EDITOR if (SceneView.currentDrawingSceneView != null) _DrawGizmos = SceneView.currentDrawingSceneView.drawGizmos; #endif } public void Set() { //GL.invertCulling = true; #if UNITY_EDITOR if (SceneView.currentDrawingSceneView != null) SceneView.currentDrawingSceneView.drawGizmos = false; #endif RenderSettings.fog = false; // disable fog for now as it's incorrect with projection QualitySettings.maximumLODLevel = 1; QualitySettings.lodBias = _LodBias * 0.5f; } public void Restore() { GL.invertCulling = false; #if UNITY_EDITOR if (SceneView.currentDrawingSceneView != null) SceneView.currentDrawingSceneView.drawGizmos = _DrawGizmos; #endif RenderSettings.fog = _Fog; QualitySettings.maximumLODLevel = _MaxLod; QualitySettings.lodBias = _LodBias; } } } }
toon water blur
#ifndef URPWATER_BLUR_INCLUDED #define URPWATER_BLUR_INCLUDED //#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" static const float _Offset[] = { 0.0, 1.0, 2.0, 3.0, 4.0 }; static const float _Weight[] = { 0.2270270270, 0.1945945946, 0.1216216216,0.0540540541, 0.0162162162 }; struct appdataBlur { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2fBlur { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; }; v2fBlur vertBlur(appdataBlur v) { v2fBlur o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } float4 fragBlur(v2fBlur IN) : SV_Target { float2 Offset = float2(1,0); #ifdef BLUR_H Offset = float2(1, 0); #endif #ifdef BLUR_V Offset = float2(0, 1); #endif Offset *= _MainTex_TexelSize.xy * _BlurStrength; float4 SharpColor = tex2D(_MainTex, IN.uv); float4 FragmentColor = SharpColor * _Weight[0]; UNITY_LOOP for (int i = 1; i < 5; i++) { float2 o = _Offset[i] * Offset; FragmentColor += tex2D(_MainTex, IN.uv + o) * _Weight[i]; FragmentColor += tex2D(_MainTex, IN.uv - o) * _Weight[i]; } FragmentColor = saturate(FragmentColor); FragmentColor.b = 0.5; return FragmentColor; } #endif
toon water effect
// Copyright(C) Yan Verde - All Rights Reserved // Copyright protected under Unity Asset Store EULA // Refer to https://unity3d.com/legal/as_terms for more informations // ----------------------------------------------------------------------------- // URP Water // Author : Yan Verde // Date : April 10, 2021 // ----------------------------------------------------------------------------- Shader "Omnigames/Water/Hidden/WaterEffects" { Properties { _MainTex ("Texture", 2D) = "white" {} _EdgeMaskSize ("EdgeMask Size", float) = 0.1 } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always CGINCLUDE CBUFFER_START(UnityPerMaterial) sampler2D _MainTex; float4 _MainTex_TexelSize; float _EdgeMaskSize; CBUFFER_END sampler2D _BaseTex; sampler2D _NormalMap; float _NormalStrength; float _BlurStrength; float3 RemapNormals(float3 from, float3 to, float3 value) { return (value - from) / (to - from); } float3 SafeNormalize(float3 inVec) { float dp3 = max(0.001, dot(inVec, inVec)); return inVec * rsqrt(dp3); } struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } ENDCG Pass { name "Base" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float4 frag(v2f i) : SV_Target { // Original float3 duv = float3(_MainTex_TexelSize.xy, 0); float4 v0 = tex2D(_MainTex, i.uv); // Create Normal float v1 = tex2D(_MainTex, i.uv - duv.xz).r; float v2 = tex2D(_MainTex, i.uv + duv.xz).r; float v3 = tex2D(_MainTex, i.uv - duv.zy).r; float v4 = tex2D(_MainTex, i.uv + duv.zy).r; float BlurMult = lerp(1, 16, _BlurStrength * 0.25); float3 n = SafeNormalize(float3(v2 - v1, v4 - v3, 0.0)) * _NormalStrength * BlurMult; // Blend with heightmap for smooth borders n *= v0.rrr; // Put back to 0-1 range in order to use non HDR texture. n = saturate(RemapNormals(-1, 1, n)); return float4(n.x, n.y, v0.b, v0.a); } ENDCG } Pass { name "BlurV" CGPROGRAM #pragma vertex vertBlur #pragma fragment fragBlur #define BLUR_H #include "UnityCG.cginc" #include "ToonWaterBlur.hlsl" ENDCG } Pass { name "BlurV" CGPROGRAM #pragma vertex vertBlur #pragma fragment fragBlur #define BLUR_V #include "UnityCG.cginc" #include "ToonWaterBlur.hlsl" ENDCG } Pass { name "CompositeBlur" CGPROGRAM #pragma vertex vert #pragma fragment fragComp #include "UnityCG.cginc" float4 fragComp(v2f i) : SV_Target { // Blurred / Normals float4 NormalsTex = tex2D(_MainTex, i.uv); // Original float4 BaseTex = tex2D(_BaseTex, i.uv); float2 edgeMaskUV = abs(i.uv * 2 - 1); float edgeMask = 1 - max(edgeMaskUV.x, edgeMaskUV.y); float mask = smoothstep(0, _EdgeMaskSize, edgeMask); BaseTex.ba *= mask; NormalsTex.a *= mask; return float4(NormalsTex.rg, BaseTex.b, NormalsTex.a); } ENDCG } } }
foam fx
Shader "Omnigames/Water/FoamFX" { Properties { _MainTex ("Foam Mask", 2D) = "white" {} } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent" "RenderPipeline"="UniversalPipeline"} ColorMask RGB Blend SrcAlpha OneMinusSrcAlpha Zwrite Off LOD 100 Pass { Name "URPWaterFoamFX" HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma multi_compile_instancing #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; CBUFFER_START(UnityPerMaterial) sampler2D _MainTex; float4 _MainTex_ST; CBUFFER_END v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.vertex = TransformObjectToHClip(v.vertex.xyz); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.color = v.color; return o; } half4 frag (v2f i) : SV_Target { half4 col = tex2D(_MainTex, i.uv) * i.color; col *= half4(0, 0, 1, 1 * col.b); return col; } ENDHLSL } } }
normal fx
Shader "Omnigames/Water/NormalFX" { Properties { _MainTex ("Foam Mask", 2D) = "white" {} } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent" "RenderPipeline"="UniversalPipeline"} Blend SrcAlpha OneMinusSrcAlpha Zwrite Off LOD 100 Pass { Name "URPWaterNormalFX" HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma multi_compile_instancing #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; CBUFFER_START(UnityPerMaterial) sampler2D _MainTex; float4 _MainTex_ST; CBUFFER_END v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.vertex = TransformObjectToHClip(v.vertex.xyz); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.color = v.color; return o; } half4 frag (v2f i) : SV_Target { half4 col = tex2D(_MainTex, i.uv); col.rgb *= half3(1,0,0); col.a = col.r * i.color.a; return col; } ENDHLSL } } }
normal tanget draw
using System.Text; using UnityEngine; using UnityEditor; [ExecuteAlways] public class NormalTangentVisualizer : MonoBehaviour { [Header("显示设置")] public bool showNormals = true; public bool showTangents = true; public bool showBitangents = true; public float normalLength = 0.1f; public float tangentLength = 0.05f; [Header("颜色设置")] public Color normalColor = Color.blue; public Color tangentColor = Color.red; public Color bitangentColor = Color.green; private Mesh mesh; private Vector3[] vertices; private Vector3[] normals; private Vector4[] tangents; void OnEnable() { RefreshMeshData(); } void RefreshMeshData() { MeshFilter mf = GetComponent<MeshFilter>(); if (mf != null && mf.sharedMesh != null) { mesh = mf.sharedMesh; vertices = mesh.vertices; normals = mesh.normals; tangents = mesh.tangents; } } void OnDrawGizmosSelected() { if (mesh == null) RefreshMeshData(); if (mesh == null) return; Transform transform = this.transform; if (showNormals && normals != null && normals.Length == vertices.Length) { Gizmos.color = normalColor; for (int i = 0; i < vertices.Length; i++) { Vector3 worldPos = transform.TransformPoint(vertices[i]); Vector3 worldNormal = transform.TransformDirection(normals[i]); Gizmos.DrawLine(worldPos, worldPos + worldNormal * normalLength); } } if ((showTangents || showBitangents) && tangents != null && tangents.Length == vertices.Length) { // 切线 Gizmos.color = tangentColor; for (int i = 0; i < vertices.Length; i++) { Vector3 worldPos = transform.TransformPoint(vertices[i]); Vector4 tangent4 = tangents[i]; Vector3 tangent = new Vector3(tangent4.x, tangent4.y, tangent4.z); Vector3 worldTangent = transform.TransformDirection(tangent); if (showTangents) { Gizmos.DrawLine(worldPos, worldPos + worldTangent * tangentLength); } if (showBitangents) { // 副切线 if (tangent4.w != 0 && normals != null && i < normals.Length) { Gizmos.color = bitangentColor; Vector3 worldNormal = transform.TransformDirection(normals[i]); Vector3 bitangent = Vector3.Cross(worldNormal, worldTangent) * tangent4.w; Gizmos.DrawLine(worldPos, worldPos + bitangent * tangentLength); Gizmos.color = tangentColor; } } } } } [ContextMenu("打印法线切线数据")] public void PrintNormalTangentData() { RefreshMeshData(); if (mesh == null) { Debug.LogError("没有找到Mesh数据"); return; } Debug.Log($"=== {gameObject.name} 法线切线数据 ==="); Debug.Log($"顶点数: {vertices.Length}"); Debug.Log($"法线数: {normals.Length}"); Debug.Log($"切线数: {tangents.Length}"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < Mathf.Min(vertices.Length, 10); i++) // 只显示前10个 { sb.AppendLine($"顶点 {i}:"); sb.AppendLine($" 位置: {vertices[i]}"); sb.AppendLine($" 法线: {normals[i]}"); if (i < tangents.Length) sb.AppendLine($" 切线: {tangents[i]} (w={tangents[i].w})"); sb.AppendLine(); } Debug.Log(sb.ToString()); } }
kajiya
Shader "Omnigames/Role/Hair Kajiya Lit Demo" { Properties { [MainTexture] _BaseMap("Texture", 2D) = "white" {} [MainColor] _BaseColor("Color", Color) = (1, 1, 1, 1) _NormalMap("Normal Map", 2D) = "bump" {} _AnosioMap("Anosio", 2D) = "white" {} _Cutoff("Alpha Cutoff", Range(0, 1)) = 0.5 [Header(Specular1)] _Specular1Roughness("Specular 1 Roughness", Range(0,1)) = 1 _Specular1Tint("Specular 1 Tint", Color) = (0.1,0.1,0.1,0) _Specular1Shift("Specular 1 Shift", Range(-2,2)) = 0 [Header(Specular2)] [Toggle] _UseSecondSpecular("Use Second Specular", float) = 0 _Specular2Roughness("Specular 2 Roughness", Range(0,1)) = 1 _Specular2Tint("Specular 2 Tint", Color) = (0.1,0.1,0.1,0) _Specular2Shift("Specular 2 Shift", Range(-2,2)) = 0 } SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "Queue" = "Geometry" } LOD 100 Pass { HLSLPROGRAM #pragma vertex UnlitPassVertex #pragma fragment UnlitPassFragment #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #pragma shader_feature_fragment _USESECONDSPECULAR_ON TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); TEXTURE2D(_AnosioMap); SAMPLER(sampler_AnosioMap); CBUFFER_START(UnityPerMaterial) half4 _BaseColor; half _Cutoff; float4 _AnosioMap_ST; half _Specular1Roughness; half4 _Specular1Tint; half _Specular1Shift; half _Specular2Roughness; half4 _Specular2Tint; half _Specular2Shift; CBUFFER_END struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; float4 tangentOS : TANGENT; float3 normalOS : NORMAL; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; float4 positionCS : SV_POSITION; float3 normalWS : TEXCOORD1; float3 tangentWS : TEXCOORD2; float3 bitangentWS : TEXCOORD3; float3 positionWS : TEXCOORD4; UNITY_VERTEX_INPUT_INSTANCE_ID }; Varyings UnlitPassVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_TRANSFER_INSTANCE_ID(input, output); VertexPositionInputs positionInputs = GetVertexPositionInputs(input.positionOS.xyz); VertexNormalInputs normalInputs = GetVertexNormalInputs(input.normalOS, input.tangentOS); output.positionCS = positionInputs.positionCS; output.uv = input.uv; output.positionWS = positionInputs.positionWS; output.normalWS = normalInputs.normalWS; output.tangentWS = normalInputs.tangentWS; output.bitangentWS = normalInputs.bitangentWS; return output; } real RoughnessToBlinnPhongSpecularExponent(real roughness) { return clamp(2 * rcp(roughness * roughness) - 2, FLT_EPS, rcp(FLT_EPS)); } half4 UnlitPassFragment(Varyings input) : SV_Target0 { UNITY_SETUP_INSTANCE_ID(input); float3 positionWS = input.positionWS; float3 V = GetWorldSpaceNormalizeViewDir(positionWS); float3 NModel = normalize(input.normalWS); float3 T = normalize(input.tangentWS); float3 B = normalize(input.bitangentWS); half4 normalMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.uv); float3 normalTS = UnpackNormal(normalMap); float3x3 TBN = float3x3(T, B, NModel); float3 N = TransformTangentToWorld(normalTS, TBN, true); Light mainLight = GetMainLight(); float3 L = mainLight.direction; float NoL = max(0, dot(N, L)); half3 radiance = mainLight.color * NoL; // * mainLight.shadowAttenuation * mainLight.distanceAttenuation; float3 H = normalize(L + V); half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv); half3 albedo = baseMap.rgb * _BaseColor.rgb; half alpha = baseMap.a * _BaseColor.a; // diffuse half3 diffuse = albedo; half4 anosioMap = SAMPLE_TEXTURE2D(_AnosioMap, sampler_AnosioMap, input.uv * _AnosioMap_ST.xy); // kaijiya-kay model float specularShift1 = _Specular1Shift + anosioMap.r; half3 t1 = ShiftTangent(B, N, specularShift1); float gloss1 = RoughnessToBlinnPhongSpecularExponent(_Specular1Roughness * anosioMap.g); half3 specular = _Specular1Tint.rgb * D_KajiyaKay(t1, H, gloss1); #if _USESECONDSPECULAR_ON float specularShift2 = _Specular2Shift + anosioMap.r; half3 t2 = ShiftTangent(B, N, specularShift2); float gloss2 = RoughnessToBlinnPhongSpecularExponent(_Specular2Roughness * anosioMap.g); half3 specular2 = _Specular2Tint.rgb * D_KajiyaKay(t2, H, gloss2); specular += specular2; #endif half4 color; color.a = alpha; color.rgb = (diffuse + specular) * radiance; return color; } ENDHLSL } } FallBack "Hidden/Universal Render Pipeline/FallbackError" }



浙公网安备 33010602011771号