■ Interleaved gradient noise
レイマーチのアーティファクトを減らすのに使えそう
https://blog.demofox.org/2017/10/31/animating-noise-for-integration-over-time/
Interleaved gradient noise, which gives middle results, is actually very similar in generation costs as white noise believe it or not, and so can also be done in real time on either the CPU or GPU.
If you have X and Y pixel coordinates (not uv coordinates), you can generate the noise value for the pixel by using this formula:
float noise = std::fmodf(52.9829189f * std::fmodf(0.06711056f*float(x) + 0.00583715f*float
■ マテリアルシェーダーの実験ソースメモ
動画:https://twitter.com/Nao_u_/status/1125247333183057920
元ネタ:https://twitter.com/MrZulubo/status/1122611573510377472
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/TestShader2" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex("Albedo (RGB)", 2D) = "white" {} _Volume("Volume", 3D) = "" {} _SparkMap("SparkMap", 2D) = "white" {} // _ParallaxMap("_ParallaxMap", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 _Distotion("Distotion", Float) = 0.5 _Iteration("Iteration", int) = 5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows #pragma vertex vert // #pragma fragment frag // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.5 sampler2D _MainTex; sampler2D _SparkMap; sampler3D _Volume; // sampler2D _ParallaxMap; half _Glossiness; half _Metallic; fixed4 _Color; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; float4 tangent : TANGENT; }; float _Distotion; int _Iteration; int _Type; // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // #pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here UNITY_INSTANCING_BUFFER_END(Props) struct Input { float2 uv_MainTex; float3 viewDirTangent; float4 screenPosition; float4 objPos; //UNITY_VPOS_TYPE vpos : VPOS; }; void vert(inout appdata_full v, out Input o) { UNITY_INITIALIZE_OUTPUT(Input, o); float4 objCam = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1.0)); float3 viewDir = v.vertex.xyz - objCam.xyz; float tangentSign = v.tangent.w * unity_WorldTransformParams.w; float3 bitangent = cross(v.normal.xyz, v.tangent.xyz) * tangentSign; o.viewDirTangent = float3( dot(viewDir, v.tangent.xyz), dot(viewDir, bitangent.xyz), dot(viewDir, v.normal.xyz) ); o.screenPosition = ComputeScreenPos(v.vertex); o.objPos = UnityObjectToClipPos(v.vertex); } void surf(Input IN, inout SurfaceOutputStandard o) { // Interleaved gradient noiseでアーティファクトを消す実験 float2 screenPos = IN.objPos.xy / IN.objPos.z; screenPos.xy *= 1; float x = screenPos.x; float y = screenPos.y*(16.0f / 9.0f); float ig_noise = frac(52.9829189f * frac(0.06711056f*float(x) + 0.00583715f*float(y))); float mm = 0.0001; // 100サンプルあるならいらないのでほとんど無効に float addNoize = -mm + (2 * mm *ig_noise); // テクスチャ歪み float2 warp = tex2D(_MainTex, -IN.uv_MainTex).rg; // パララックス float2 uv = IN.uv_MainTex; uv.x += _Time.x*-0.5; uv.y += _Time.x*-1.0; uv += warp*0.075; float parallax = 0; for (int j = 0; j < _Iteration; j++) { float ratio = (float)j / _Iteration; //float col = tex2D(_MainTex, uv + lerp(0, _Distotion, ratio+ addNoize) * normalize(IN.viewDirTangent)) * lerp(1, 0, ratio); float2 uv2 = uv + lerp(0, _Distotion, ratio + addNoize) * normalize(IN.viewDirTangent); float3 uv3 = float3(uv2.x, uv2.y, 0.5+_Time.x*2); float col = tex3D(_Volume, uv3) * lerp(1, 0, ratio)*1.0; if (col > ratio) { parallax += col; } } parallax /= _Iteration; // 適当に色を弄る fixed4 c = ((tex2D(_MainTex, IN.uv_MainTex+float2(_Time.x*-0.5,_Time.x*-1.1))-float4(0.2,0.5,0.5,0)) * 0.5) * float4(1, 0.5, 0.5, 1); o.Albedo = c.rgb + pow(parallax,1.7) * _Color.rgb*100; o.Albedo.gb = pow(o.Albedo.gb + float2(0.2, 0.1), 2.5); o.Albedo.r += c.r * 1.25; // 光の粒(3レイヤー) float4 spk_col0 = float4(1.0, 1.0, 1.0, 1); float4 spk_col1 = float4(2.0, 1.0, 2.0, 1); float4 spk_col2 = float4(2.0, 1.5, 2.0, 1); { float depth = 2.0; float2 uv = IN.uv_MainTex + float2(_Time.x * -3.1, _Time.x * -1.05); float4 spk = tex2D(_SparkMap, uv + depth * normalize(IN.viewDirTangent)) * spk_col0; o.Albedo += spk.rgb * 2; } { float depth = 0.5; float2 uv = IN.uv_MainTex + float2(_Time.x * 1.25, _Time.x * 0.25); float4 spk = tex2D(_SparkMap, uv + depth * normalize(IN.viewDirTangent)) * spk_col1; o.Albedo += spk.rgb * 3; } { float depth = 0.25; float2 uv = IN.uv_MainTex + float2(_Time.x * -0.20, _Time.x * -0.3); float4 spk = tex2D(_SparkMap, uv + depth * normalize(IN.viewDirTangent)) * spk_col2; o.Albedo += spk.rgb * 2; } // Metallic and smoothness come from slider variables o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }