首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从着色器到three.js的带有缓冲区的端口着色程序

从着色器到three.js的带有缓冲区的端口着色程序
EN

Stack Overflow用户
提问于 2018-12-13 02:54:46
回答 1查看 975关注 0票数 4

我最近正在试验和学习webgl和着色器,因为我试图为网站背景建立动画。我能够把简单的例子从着色玩具到three.js来玩。现在,我正在努力更好地理解更高级的示例,并且正在努力处理这个particlar示例:

https://www.shadertoy.com/view/4sfBWj

我知道要将着色器程序移植到three.js,您需要:

  1. 用three.js创建new THREE.PlaneGeometry()基本设置
  2. iTimeiResolution创建制服
  3. 创建顶点和片段着色脚本标记
  4. 填充带有着色器内容的碎片着色器(图像部分)
  5. 用通用脚本填充顶点着色器
  6. 将名称更改为gl_FragColorgl_FragCoord
  7. 将函数的名称更改为void main(void)

如果在一个或多个通道中使用了一些纹理,那么

  1. new THREE.TextureLoader()加载纹理并为iChannel0创建统一

基本的例子将是很好的与上述。然而,我所链接的是:

  • 缓冲器A
  • 缓冲器B

这两个程序都包括着色器程序和运行它们的主要功能,我如何处理它才能将其移植到three.js?

我目前的进展:

代码语言:javascript
运行
AI代码解释
复制
var container;
var camera, scene0, scene1, scene2, renderer;
var uniforms0, uniforms1, uniforms2;
var startTime;
var renderTarget0, renderTarget1;

var clock = new THREE.Clock();

init();
animate();

function init() {
	container = document.getElementById( 'container' );
	startTime = Date.now();
	camera = new THREE.Camera();
	camera.position.z = 1;
	
	scene0 = new THREE.Scene();
	scene1 = new THREE.Scene();
	scene2 = new THREE.Scene();
	
	renderTarget0 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
	renderTarget1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
	
	/* scene0 */
	var geometry0 = new THREE.PlaneGeometry(700, 394, 1, 1);
	uniforms0 = {
		iTime: { type: "f", value: 1.0 },
		iResolution: { type: "v1", value: new THREE.Vector2(), }
	};

	var material0 = new THREE.ShaderMaterial( {
		uniforms: uniforms0,
		vertexShader: document.getElementById( 'vs0' ).textContent,
		fragmentShader: document.getElementById( 'fs0' ).textContent
	});
	/* scene0 */

	var mesh0 = new THREE.Mesh( geometry0, material0 );
	
	/* scene1 */
	var geometry1 = new THREE.PlaneGeometry(700, 394, 1, 1);
	uniforms1 = {
		iTime: { type: "f", value: 1.0 },
		iResolution: { type: "v1", value: new THREE.Vector2(), }
	};

	var material1 = new THREE.ShaderMaterial( {
		uniforms: uniforms1,
		vertexShader: document.getElementById( 'vs1' ).textContent,
		fragmentShader: document.getElementById( 'fs1' ).textContent,
		iChannel0: {type: 't', value: renderTarget0 }
	});

	var mesh1 = new THREE.Mesh( geometry1, material1 );
	/* scene1 */
	
	/* scene2 */
	var geometry2 = new THREE.PlaneGeometry(700, 394, 1, 1);
	uniforms2 = {
		iTime: { type: "f", value: 1.0 },
		iResolution: { type: "v1", value: new THREE.Vector2(), }
	};

	var material2 = new THREE.ShaderMaterial( {
		uniforms: uniforms1,
		vertexShader: document.getElementById( 'vs2' ).textContent,
		fragmentShader: document.getElementById( 'fs2' ).textContent,
		iChannel0: {type: 't', value: renderTarget0 },
		iChannel1: {type: 't', value: renderTarget1 }
	});

	var mesh2 = new THREE.Mesh( geometry2, material2 );
	/* scene2 */
	
	scene0.add( mesh0 );
	scene1.add( mesh1 );
	scene2.add( mesh2 );
	
	renderer = new THREE.WebGLRenderer();
	container.appendChild( renderer.domElement );
	onWindowResize();
	window.addEventListener( 'resize', onWindowResize, false );
}

function onWindowResize( event ) {
	uniforms0.iResolution.value.x = window.innerWidth;
	uniforms0.iResolution.value.y = window.innerHeight;
	uniforms1.iResolution.value.x = window.innerWidth;
	uniforms1.iResolution.value.y = window.innerHeight;
	uniforms2.iResolution.value.x = window.innerWidth;
	uniforms2.iResolution.value.y = window.innerHeight;
	renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
	requestAnimationFrame( animate );
	render();
}

function render() {
	
	//renderer.render(scene0, camera, renderTarget0);
	//renderer.render(scene1, camera, renderTarget1);
	
	uniforms1.iChannel0.value = rendertarget0.texture;
	uniforms2.iChannel0.value = rendertarget0.texture;
	uniforms2.iChannel1.value = rendertarget1.texture;
	
	uniforms0.iTime.value += clock.getDelta();
	uniforms1.iTime.value += clock.getDelta();
	uniforms2.iTime.value += clock.getDelta();
	
	//renderer.render( scene2, camera );
	
}
代码语言:javascript
运行
AI代码解释
复制
body {
   margin:0;
   padding:0;
   overflow:hidden;
}
代码语言:javascript
运行
AI代码解释
复制
<script src="//threejs.org/build/three.min.js"></script>
<div id="container"></div>

<!--  BREAK --->

<script id="vs0" type="x-shader/x-vertex">
  void main() {
    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;
  }
</script>
<script id="fs0" type="x-shader/x-fragment">

    uniform vec2 iResolution;
    uniform float iTime;

	const mat2 m = mat2( 0.8,  0.6, -0.6,  0.8 );
	const mat3 m3 = mat3( 0.8,  0.6, 0.0, -0.6,  0.80, 0.0, 0.0, 0.0, 1.0) *
					mat3( 1.0,  0.0, 0.0, 0.0, -0.60,  0.80, 0.0, 0.8, 0.6) *
					mat3( 0.8, 0.6, 0.0, -0.6,  0.80, 0.0, 0.0, 0.0, 1.0) *
					mat3( 1.0,  0.0, 0.0, 0.0, -0.60,  0.80, 0.0, 0.8, 0.6);

	float time;

	float n1f0(float p) {
		return fract(sin(p * 1.7227636) * 8.03e2);
	}

	float n1f1(float p) {
		return fract(sin(p * 1.42736 + 1.12) * 5.1e2);
	}

	float n1f2(float p) {
		return fract(sin(p * 1.22712 + 12.161) * 5.2e2);
	}


	float n3f(vec3 p) {
		return fract(n1f0(p.x) + n1f1(p.y) + n1f2(p.z) + n1f0(p.x * 1.613) + n1f1(p.y * 3.112) + n1f2(p.z * 4.112));
	}

	float n3(vec3 p) {
		vec3 b = floor(p);
		vec3 e = b + vec3(1.0);
		vec3 f = smoothstep(vec3(0.0), vec3(1.0), fract(p));
		float c000 = n3f(b);
		float c001 = n3f(vec3(b.x, b.y, e.z));
		float c010 = n3f(vec3(b.x, e.y, b.z));
		float c011 = n3f(vec3(b.x, e.y, e.z));
		float c100 = n3f(vec3(e.x, b.y, b.z));
		float c101 = n3f(vec3(e.x, b.y, e.z));
		float c110 = n3f(vec3(e.x, e.y, b.z));
		float c111 = n3f(e);
		vec4 z = mix(vec4(c000, c100, c010, c110), vec4(c001, c101, c011, c111),  f.z);
		vec2 yz = mix(z.xy, z.zw, f.y);
		return mix(yz.x, yz.y, f.x);

	}


	float fbm4( vec3 p )
	{
		float f = 0.0;
		p = m3 * p;
		f +=     0.5000*n3( p ); p = m3*p*2.02;
		f +=     0.2500*n3( p ); p = m3*p*2.03;
		f +=     0.1250*n3( p ); p = m3*p*2.01;
		f +=     0.0625*n3( p );
		return f/0.9375;
	}

	float fbm4( vec2 p )
	{
		return fbm4(vec3(p, time));
	}

	float fbm6( vec3 p )
	{
		float f = 0.0;
		p = m3 * p;
		f +=     0.500000*n3( p ); p = m3*p*2.02;
		f +=     0.250000*n3( p ); p = m3*p*2.03;
		f +=     0.125000*n3( p ); p = m3*p*2.01;
		f +=     0.062500*n3( p ); p = m3*p*2.04;
		f +=     0.031250*n3( p ); p = m3*p*2.01;
		f +=     0.015625*n3( p );
		return f/0.984375;
	}


	float fbm6( vec2 p )
	{
		return fbm6(vec3(p, time));
	}

	float grid(vec2 p) {
		p = sin(p * 3.1415);
		return smoothstep(-0.01, 0.01, p.x * p.y);
	}

    void main(void) {

		time = iTime * 0.7;

		vec2 q = gl_FragCoord.xy / iResolution.xy;
		vec2 p = -1.0 + 2.0 * q;
		p.x *= iResolution.x/iResolution.y;
		p.y *= 0.3;
		p.y -= time * 1.5;
		float tc = time * 1.2;
		float tw1 = time * 2.5;
		float tw2 = time * 0.6;

		vec3 vw1 = vec3(p, tw1);
		vw1.y *= 2.8;
		vec2 ofs1 = vec2(fbm4(vw1), fbm4(vw1 + vec3(10.0, 20.0, 50.0)));
		ofs1.y *= 0.3;
		ofs1.x *= 1.3;

		vec3 vw2 = vec3(p, tw2);
		vw2.y *= 0.8;
		vec2 ofs2 = vec2(fbm4(vw2), fbm4(vw2 + vec3(10.0, 20.0, 50.0)));
		ofs2.y *= 0.3;
		ofs2.x *= 1.3;

		vec2 vs = (p + ofs1 * 0.5 + ofs2 * 0.9) * 4.0;
		vec3 vc = vec3(vs, tc);
		float l;
		l = fbm6(vc);
		l = smoothstep(0.0, 1.0, l);
		l = max(0.0, (l - pow(q.y * 0.8, 0.6)) * 1.8);
		float r = pow(l , 1.5);
		float g = pow(l , 3.0);
		float b = pow(l , 6.0);

		//r = grid(vs);
		gl_FragColor = vec4( r, g, b, 1.0 );

    }

</script>

<!--  BREAK --->

<script id="vs1" type="x-shader/x-vertex">
  void main() {
    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;
  }
</script>
<script id="fs1" type="x-shader/x-fragment">

    uniform vec2 iResolution;
    uniform float iTime;
	uniform sampler2D iChannel0;

	#ifdef GL_ES
	precision mediump float;
	#endif

	#define SIGMA 5.0

	float normpdf(in float x, in float sigma)
	{
		return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;
	}

    void main(void) {

		vec3 c = texture2D(iChannel0, gl_FragCoord.xy / iResolution.xy).rgb;

		//declare stuff
		const int mSize = int(SIGMA * 11.0/7.0);
		const int kSize = (mSize-1)/2;
		float kernel[mSize];
		vec3 finalColor = vec3(0.0);

		//create the 1-D kernel
		float sigma = SIGMA;
		float Z = 0.0;
		for (int j = 0; j <= kSize; ++j)
		{
			kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j), sigma);
		}

		//get the normalization factor (as the gaussian has been clamped)
		for (int j = 0; j < mSize; ++j)
		{
			Z += kernel[j];
		}

		//read out the texels
		for (int i=-kSize; i <= kSize; ++i)
		{
			for (int j=-kSize; j <= kSize; ++j)
			{
				finalColor += kernel[kSize+j]*kernel[kSize+i]*texture2D(iChannel0, (gl_FragCoord.xy+vec2(float(i),float(j))) / iResolution.xy).rgb;

			}
		}

		finalColor /= Z*Z;

		//finalColor = c + finalColor * 0.3;


		gl_FragColor = vec4(finalColor, 1.0);

    }

</script>

<!--  BREAK --->

<script id="vs2" type="x-shader/x-vertex">
  void main() {
    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;
  }
</script>
<script id="fs2" type="x-shader/x-fragment">

    uniform vec2 iResolution;
    uniform float iTime;
	uniform sampler2D iChannel0;
	uniform sampler2D iChannel1;
	
	#ifdef GL_ES
	precision mediump float;
	#endif

	#define SIGMA 5.0

	float normpdf(in float x, in float sigma)
	{
		return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;
	}

    void main(void) {

		vec3 c = texture2D(iChannel0, gl_FragCoord.xy / iResolution.xy).rgb;
		//gl_FragColor = vec4(c, 1.0);
		//return;
		//declare stuff
		const int mSize = int(SIGMA * 11.0/7.0);
		const int kSize = (mSize-1)/2;
		float kernel[mSize];
		vec3 finalColor = vec3(0.0);

		//create the 1-D kernel
		float sigma = SIGMA;
		float Z = 0.0;
		for (int j = 0; j <= kSize; ++j)
		{
			kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j), sigma);
		}

		//get the normalization factor (as the gaussian has been clamped)
		for (int j = 0; j < mSize; ++j)
		{
			Z += kernel[j];
		}

		//read out the texels
		for (int i=-kSize; i <= kSize; ++i)
		{
			for (int j=-kSize; j <= kSize; ++j)
			{
				finalColor += kernel[kSize+j]*kernel[kSize+i]*texture2D(iChannel1, (gl_FragCoord.xy+vec2(float(i),float(j))) / iResolution.xy).rgb;

			}
		}

		finalColor /= Z*Z;

		finalColor = c + pow(finalColor, vec3(0.5)) * 0.5;


		gl_FragColor = vec4(finalColor, 1.0);

    }

</script>

EN

回答 1

Stack Overflow用户

发布于 2018-12-13 13:45:28

此示例使用每个帧的多次呈现。它的工作方式如下:

  1. 将shaderA呈现为缓冲区
  2. 将输出传递给shaderB
  3. 将shaderB呈现为缓冲区
  4. 将输出传递给shaderC
  5. 将shaderC呈现到画布上

要在Three.js中复制这一点,您需要一个WebGLRenderTarget作为中介,将输出从一个渲染作为纹理传递到下一个着色器。下面是只有2个呈现的伪代码,如果需要更多的代码,则需要扩展它:

代码语言:javascript
运行
AI代码解释
复制
var renderer = new WebGLRenderer(w, h, ...);

var scene0 = new Scene();
var scene1 = new Scene();

var plane0 = new THREE.PlaneBufferGeometry(1, 1);
var plane1 = new THREE.PlaneBufferGeometry(1, 1);

// ... continue building materials, shaders, etc

// Add plane mesh to its corresponding scene
scene0.add(planeMesh0);
scene1.add(planeMesh1);

// You should only need one camera if they're both in the same position.
var cam = new Camera();

// renderTarget will store the first buffer
var renderTarget = new WebGLRenderTarget(w, h);

update() {
    // This pass will render the first shader
    // Its output will be drawn on the rendertarget's texture
    renderer.render(scene0, cam, renderTarget);

    // We assign the output of the first render pass to the second plane
    plane1.uniforms.texture.value = rendertarget.texture;

    // Now we render the second shader to the canvas
    renderer.render(scene1, cam);
}

请记住,您必须在每次传递中呈现不同的场景,以避免递归问题,因此您必须将每个平面添加到单独的场景中。了解有关WebGLRenderTarget 你可以在文档里读到的更多信息

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53760252

复制
相关文章
【说站】js原型链默认的原型
1、默认情况下,所有引用类型值都继承了Object,这种继承也是通过原型链实现的。
很酷的站长
2022/11/24
8750
【说站】js原型链默认的原型
纸上原型是什么?
原型(prototypes)是把系统主要功能和接口通过快速开发制作为“模型”,以可视化的形式展现给用户,用以征求意见,确定需求。同时也应用于开发团队内部,作为讨论的对象和分析、 设计的接口。
葆宁
2022/01/06
9490
纸上原型是什么?
Windows 系统的默认字体是什么?应用的默认字体是什么?
作为中文应用的开发者,我们多半会认为系统的默认字体是“微软雅黑”。然而如果真的产生了这种误解,则很容易在开发本地化应用的时候踩坑。
walterlv
2023/10/22
9.2K0
Windows 系统的默认字体是什么?应用的默认字体是什么?
sql2008删除默认实例_sql2000默认实例名
1.删除 SQL Server 的特定实例 若要删除 SQL Server 的某个特定实例,请按照以下步骤操作: 找到并删除%drive%:\\Program Files\\Microsoft SQL Server\\MSSQL\\Binn 文件夹,其中%drive% 是要删除的 SQL Server 实例的位置。 找到以下注册表项: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSSQLServer
全栈程序员站长
2022/11/10
3.7K0
快速原型模型是什么?
快速原型模型 快速建立起来的可以在计算机上运行的程序,它所能完成的功能往往是最终产品能完成的功能的一个子集。
葆宁
2022/01/11
1K0
快速原型模型是什么?
【说站】JavaScript原型链是什么
JavaScript原型链是什么 说明 1、所有引用类型都有一个__proto__(隐式原型)属性。 属性值是一个普通的对象 2、所有函数都有一个prototype(原型)属性。 属性值是一个普通的对象 3、所有引用类型的__proto__属性指向它构造函数的prototype 实例 function Person(name){this.name = name} let p1 = new Person("小白"); console.dir(p1)   console.log(p1.__proto__ =
很酷的站长
2022/11/24
2200
【说站】JavaScript原型链是什么
Python 中的默认值是什么?
默认值指示如果在函数调用期间未给出参数值,则函数参数将采用该值。默认值是使用表单关键字名称=值的赋值 (=) 运算符分配的。
很酷的站长
2023/02/25
2K0
Python 中的默认值是什么?
Vue 3 将成为新的默认版本
在最开始的时候,Vue 仅仅是一个运行时库。但这些年来,它已经逐步发展成了一个包含许多子项目的框架:
用户10106350
2022/10/28
7400
Vue 3 将成为新的默认版本
请务必阅读文末的 可能需要采取的措施 部分,来确认你是否需要在默认版本切换之前做相应改动以避免发生异常。
程序员海军
2022/01/26
7060
Vue 3 将成为新的默认版本
Javascript 原型链之原型对象、实例和构造函数三者之间的关系
首先来说一下名词解释,首先说一下prototype,每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法。
OECOM
2020/07/01
6570
PbootCMS的默认账号密码是什么?
系统后台默认访问路径 www.**.com/admin.php 也就是在域名后面加上/admin.php 如果想修改后台的路径,只需要将系统根目录下的admin.php修改成你想要的名字即可,这里提醒一下,尽量将名字改得越复杂越好,有利于加强自己网站的安全性。
小唐同学.
2022/02/23
4.1K0
java默认的hashcode方法到底得到的是什么?
hashcode方法会影响jvm性能?听上去天方夜谭,实际上蕴藏着一些微小的原理,接下来让我们走进hashcode方法,一探native方法源头。
zhangheng
2020/04/28
7.5K1
原型模式实例订单处理系统
订单处理系统 现在有一个订单处理系统,里面有一个保存订单的业务功能,需求:每当订单的预定产品数量超过1000的时候,就需要把订单拆成两份订单来保存。如果拆成两份后还是超过1000,则继续拆分,直到每份产品预订数量不超过1000. 根据业务,目前的订单系统分成两种,一种是个人订单、一种是公司订单。 客户名称、产品对象(ID,Name),订购产品数量。 公司名称、产品对象(ID,Name),订购产品数量。
Twcat_tree
2022/11/29
4420
原型模式实例订单处理系统
【说站】js原型模式是什么
1、JS中的每个函数都有prototype属性,指向一个对象。该对象的作用是该函数的所有实例都可以共享该对象的属性和方法。我们称这个对象为原型对象。
很酷的站长
2022/11/26
3190
【说站】js原型模式是什么
【说站】python默认索引是什么
以上就是python默认索引的介绍,希望对大家有所帮助。更多Python学习指路:python基础教程
很酷的站长
2022/11/23
4280
【说站】python默认索引是什么
设计模式之原型模式(Prototype 模式)引入原型模式原型模式的实例小结为什么需要使用原型模式
联想到浏览器中,如果我们生成了一个button实例,这个button实例经过一系列操作,携带了各种信息,比如button加颜色,加背景图,加文字,加事件等等。如果我们这时候需要和这个button实例完全一样的一个实例,仅仅通过类new 一个button出来是远远不够的,因为我们还要对它进行一系列的操作,所以这个生成一个完全一样的实例的过程是非常复杂的,所以这时候我们就想到可不可以直接根据这个实例,然后生成一个一模一样的实例呢?
desperate633
2018/08/22
2660
设计模式之原型模式(Prototype 模式)引入原型模式原型模式的实例小结为什么需要使用原型模式
让 JavaScript 区别于其它语言的是什么?原型继承!
最近开源了一个 Vue 组件,还不够完善,欢迎大家来一起完善它,也希望大家能给个 star 支持一下,谢谢各位了。
前端小智@大迁世界
2020/12/01
4470
让 JavaScript 区别于其它语言的是什么?原型继承!
IIS是什么?+ mpy实例
我今天收拾东西找到了几个IIS的传感器,看了下都是音频的器件。以前使用是ESP32 自带的IIS,因为时间的原因没有研究很多,这篇文章做下简单的总结。
云深无际
2022/04/15
1.1K0
IIS是什么?+ mpy实例
Java 8 新特性|接口默认方法
在 Java 7 和之前的版本中,接口 interface 是不能包含具体的方法实现的。对于一个接口有多个实现的时候,我们通常的做法就是让所有的实现继承另一个基础类,然后在这个基础类中实现这个方法。
Java小技巧
2022/05/23
6500
【说站】python默认字典是什么
1、Default Dict是高性能容器数据类型的一部分,是 dict 的子类,它返回一个字典对象。
很酷的站长
2022/11/24
2550
【说站】python默认字典是什么

相似问题

javascript函数默认原型与对象实例

10

原型实例,如cat c=新动物();?

11

Javascript:如何创建原型对象的新实例?

10

如果元素的原型是什么,那么默认的是什么?

36

默认导出类的新实例

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档