radial blur 阅读笔记

本文介绍了一种使用WebGL着色器实现的彗星拖尾视觉效果,通过指向屏幕中心的放射线叠加,使白色部分呈现显著效果,同时提供了代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://oos.moxiecode.com/js_webgl/codevember2017/index9.html
效果图:
这里写图片描述

就是这种有点像彗星拖尾的效果,且这个方向是指向屏幕中央的,当然也可以修改。

代码着色器:
作者@oosmoxiecode,参考的也是 IQ大神 https://www.shadertoy.com/view/4sfGRn

这里直接注释IQ的代码了,都差不多。oos 就是写的可读性更高一些。

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 p = -1.0 + 2.0*fragCoord/iResolution.xy; // 从[0,1]变换到[-1,1]

    vec3  col = vec3(0.0);
    vec2  d = (vec2(0.0,0.0)-p)/64.0; // 求当前着色位置到屏幕中心的方向向量,这步是关键
    float w = 1.0;
    vec2  s = p;
    // i<10 说明这个过程要叠加10次,越多则效果越强
    for( int i=0; i<10; i++ )
    {
        vec3 res = deform( s ); // 取原texture像素,deform 是扭曲,非必要
        col += w*smoothstep( 0.0, 1.0, res );
        w *= .98; 
        s += d;
    }
    col = col * 3.5 / 64.0;

    fragColor = vec4( col, 1.0 );
}

oos 则加了一个限制条件,只有像素颜色值高于某个阈值才拿来做颜色叠加,因此白色的部分会有更强的效果,暗色的就没有:


    uniforms: {

        "tDiffuse": { type: "t", value: null },
        "tMap":   { type: "t", value: null },
        "steps":    { type: "f", value: 100.0 },
        "strength": { type: "f", value: 0.95 },
        "expo":     { type: "f", value: 5.0 },
        "threshold":    { type: "f", value: 0.7 },
        "center":   { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) },

    },

        "uniform float steps;",
        "uniform float strength;",
        "uniform float expo;",
        "uniform float threshold;",
        "uniform sampler2D tDiffuse;",
        "uniform sampler2D tMap;",
        "uniform vec2 center;",

        "varying vec2 vUv;",

        "void main() {",

            "vec2 s = vUv;",

            "vec3 total = vec3(0.0);",
            "vec2 d = (center-vUv)/steps;", // 中间往外放射线的效果
            "float w = 1.0;",

            //"float t = 0.7;",

            //"for( int i=0; i<int(steps); i++ ) {",
            "for( int i=0; i<40; i++ ) {", // hardcode since the above fails in angle...
                "vec3 res = texture2D( tMap, s).xyz;",
                "if (res.x > threshold || res.y > threshold || res.z > threshold) {",
                    //"res = vec3(1.0,1.0,1.0);",
                    // 越接近白色,放射效果越强
                    "res *= 5.0;",
                "} else {",
                    "res = vec3(0.0,0.0,0.0);",
                "}",
                "res = smoothstep(0.0,1.0,res);", 
                "total += w*res;",
                "w *= strength;", // strength < 1, w 逐渐减小
                "s += d;", // 沿放射方向,从vUv到屏幕中心
            "}",
            "total /= steps;",

            //"gl_FragColor = vec4( total*expo, 1.0);",
            "vec3 dif = texture2D( tDiffuse, vUv).xyz;",
            "gl_FragColor = vec4( mix(total*expo, dif*2.0, 0.5), 1.0);",
            //"gl_FragColor = vec4( total*expo, 1.0);",


        "}"

这个程序的思路可以想象为,每个像素朝着屏幕中心看一段距离(由 for 的次数决定),如果看到的范围内有符合

(res.x > threshold || res.y > threshold || res.z > threshold) 

的像素,就拿来作为当前着色像素的一个叠加的颜色。关键是要记住 GPU程序都是处理单个像素的,每次只能为当前着色的像素处理颜色。
很显然 center不一定是中间位置。利用这个可以更灵活地做效果。

### 径向布局与编程中的简单实现 在计算机科学领域,“radial”通常指代一种围绕中心点分布的设计模式或数据结构,常见于图形界面设计、网络可视化以及某些特定的算法中。以下是关于 **径向布局 (Radial Layout)** 的基本概念及其简单的实现方式。 #### 基本定义 径向布局是一种将节点分布在圆形或多边形上的方法[^4]。它常用于树状图、关系网或其他层次化数据结构的展示。通过这种方式,可以更直观地表示节点之间的距离和连接关系。 #### 数学基础 为了创建一个简单的径向布局,需要利用极坐标系的概念。假设圆心位于 `(cx, cy)`,半径为 `r`,则任意角度 θ 对应的点可以通过以下公式计算得出: \[ x = cx + r \cdot \cos(\theta) \] \[ y = cy + r \cdot \sin(\theta) \] 其中,θ 是弧度制的角度值,范围通常是 `[0, 2π]`。 --- ### Python 实现示例 下面是一个基于 Python 和 Matplotlib 库的简单径向布局实现: ```python import matplotlib.pyplot as plt import numpy as np def create_radial_layout(center_x=0, center_y=0, radius=1, num_points=8): angles = np.linspace(0, 2 * np.pi, num_points, endpoint=False) # Generate evenly spaced angles points = [] for angle in angles: x = center_x + radius * np.cos(angle) y = center_y + radius * np.sin(angle) points.append((x, y)) return points # Example usage points = create_radial_layout(radius=5, num_points=12) plt.figure(figsize=(6, 6)) for point in points: plt.scatter(point[0], point[1], color='blue') plt.text(point[0], point[1], f'({point[0]:.2f}, {point[1]:.2f})', fontsize=9) circle = plt.Circle((0, 0), 5, fill=False, linestyle='--') # Draw circle outline ax = plt.gca() ax.add_patch(circle) ax.set_aspect('equal') plt.title("Simple Radial Layout") plt.show() ``` 此代码片段展示了如何生成一组均匀分布在圆周上的点,并将其绘制出来。用户可以根据需求调整参数(如圆心位置、半径大小或点的数量)来满足具体应用场景的要求。 --- ### JavaScript 实现示例 如果目标是在 Web 环境下实现类似的径向布局,则可借助 HTML5 Canvas 或 SVG 技术完成。以下是一段使用 Canvas API 的例子: ```javascript function drawRadialLayout(canvasId, centerX, centerY, radius, numPoints) { const canvas = document.getElementById(canvasId); const ctx = canvas.getContext('2d'); const stepAngle = (Math.PI * 2) / numPoints; for (let i = 0; i < numPoints; i++) { const angle = i * stepAngle; const x = centerX + Math.cos(angle) * radius; const y = centerY + Math.sin(angle) * radius; ctx.beginPath(); ctx.arc(x, y, 3, 0, Math.PI * 2); // Draw small circles at calculated positions ctx.fillStyle = 'red'; ctx.fill(); ctx.font = "10px Arial"; ctx.fillText(`(${x.toFixed(2)}, ${y.toFixed(2)})`, x + 5, y + 5); } } // Usage example drawRadialLayout('myCanvas', 150, 150, 100, 12); ``` 在此脚本中,函数接受画布 ID 及其他配置项作为输入参数,在指定区域内渲染一系列红色的小圆圈代表各个节点的位置。 --- ### 相关扩展方向 除了静态显示外,还可以进一步探索动态交互效果或者结合实际业务场景优化视觉呈现形式。例如: - 使用 D3.js 创建更加复杂的图表; - 将该技术应用于社交网络分析工具中展现人际关系链路; - 开发游戏地图编辑器支持自定义地形生成逻辑等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值