--label:アニメーション効果 --information:DVD Bounce --group:動作設定 --track@speed:速度,0.0,5000.0,400.0,1.0 --track@angle:移動角度,-360.0,360.0,45.0,0.1 --track@zoom_pct:サイズ(%),1.0,1000.0,100.0,1.0 --track@seed:乱数シード,0,10000,0,1 --group: --group:領域設定 --track@box_w:領域幅(0=自動),0,8000,0,1 --track@box_h:領域高さ(0=自動),0,8000,0,1 --trackgroup@box_w,box_h:領域サイズ --group: --group:色設定 --check@use_original:元の色を使用,0 --track@saturation:彩度,0.0,100.0,80.0,0.1 --track@brightness:明度,0.0,100.0,100.0,0.1 --track@color_mix:着色強度(%),0.0,100.0,100.0,0.1 --hide@saturation:use_original==1 --hide@brightness:use_original==1 --hide@color_mix:use_original==1 --group: --[[pixelshader@ps_dvd_bounce: cbuffer Params : register(b0) { float4 target_color; // rgb: target_rgb, w: mix_ratio }; Texture2D tex : register(t0); SamplerState samp : register(s0); float4 ps_dvd_bounce(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target { float4 c = tex.Sample(samp, uv); if (c.a <= 0.0) { return float4(0.0, 0.0, 0.0, 0.0); } // Straight RGB に変換してカラーブレンド float3 straight_rgb = c.rgb / c.a; float3 blended_rgb = lerp(straight_rgb, target_color.rgb, target_color.w); // Premultiplied Alpha 適用 return float4(blended_rgb * c.a, c.a); } ]] do local cos = math.cos local sin = math.sin local rad = math.rad local floor = math.floor local max = math.max local function bounce_position(distance, range) if range <= 0.0 then return 0.0, 0 end local period = range * 2.0 local normalized = distance % period local position = (normalized > range) and (period - normalized) or normalized return position, floor(distance / range) end local w = obj.w local h = obj.h if w <= 0 or h <= 0 then return end -- 1. 解像度および境界ボックスの取得 local screen_w = (obj.screen_w and obj.screen_w > 0) and obj.screen_w or 1920 local screen_h = (obj.screen_h and obj.screen_h > 0) and obj.screen_h or 1080 local bounds_w = (box_w <= 0) and screen_w or box_w local bounds_h = (box_h <= 0) and screen_h or box_h -- 2. 拡大率の適用と実寸の計算 local cur_zoom = obj.zoom or 1.0 local scale_factor = zoom_pct * 0.01 obj.zoom = cur_zoom * scale_factor local obj_w = w * obj.zoom local obj_h = h * obj.zoom -- 3. 移動ベクトルの算出と三角波バウンス計算 local rad_val = rad(angle) local vx = cos(rad_val) * speed local vy = sin(rad_val) * speed local range_x = max(0.0, bounds_w - obj_w) local range_y = max(0.0, bounds_h - obj_h) local initial_phase_x = (seed * 123.45) % 10000.0 local initial_phase_y = (seed * 678.91) % 10000.0 local dist_x = obj.time * vx + initial_phase_x local dist_y = obj.time * vy + initial_phase_y local pos_x, bounce_count_x = bounce_position(dist_x, range_x) local pos_y, bounce_count_y = bounce_position(dist_y, range_y) local total_bounces = bounce_count_x + bounce_count_y -- 中心原点の相対座標へ加算 obj.ox = (obj.ox or 0.0) + (pos_x - range_x * 0.5) obj.oy = (obj.oy or 0.0) + (pos_y - range_y * 0.5) -- 4. 着色シェーダー処理 (バウンス回数に応じた色相変化) if use_original == 0 and color_mix > 0.0 then local hue = obj.rand1(seed * 1000 + total_bounces * 17, 0) * 360.0 local col_hex = HSV(hue, saturation, brightness) local r, g, b = RGB(col_hex) obj.pixelshader( "ps_dvd_bounce", "object", { "object" }, { r / 255.0, g / 255.0, b / 255.0, color_mix * 0.01 }, "copy", "clamp" ) end end