Three.js ShaderMaterial Post 处理和透明背景
Three.js ShaderMaterial Post Processing and Transparent Background
我正在尝试使用此 shader,但我需要一个透明背景,它呈现黑色背景。
我意识到这是在 fragmentShader 中完成的,但我还没有想出如何改变它,我什至不知道这是否可能。
哪位有shader经验的知道怎么告诉我吗?
var myEffect = {
uniforms: {
"tDiffuse": { value: null },
"distort": { value: 0 },
"resolution": { value: new THREE.Vector2(1., innerHeight / innerWidth) },
"uMouse": { value: new THREE.Vector2(-10, -10) },
"uVelo": { value: 0 },
"time": { value: 0 }
},
vertexShader: `uniform float time;
uniform float progress;
uniform vec2 resolution;
varying vec2 vUv;
uniform sampler2D texture1;
const float pi = 3.1415925;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );
}`,
fragmentShader: `uniform float time;
uniform float progress;
uniform sampler2D tDiffuse;
uniform vec2 resolution;
varying vec2 vUv;
uniform vec2 uMouse;
uniform float uVelo;
float circle(vec2 uv, vec2 disc_center, float disc_radius, float border_size) {
uv -= disc_center;
uv*=resolution;
float dist = sqrt(dot(uv, uv));
return smoothstep(disc_radius+border_size, disc_radius-border_size, dist);
}
float map(float value, float min1, float max1, float min2, float max2) {
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
float remap(float value, float inMin, float inMax, float outMin, float outMax) {
return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}
float hash12(vec2 p) {
float h = dot(p,vec2(127.1,311.7));
return fract(sin(h)*43758.5453123);
}
// #define HASHSCALE3 vec3(.1031, .1030, .0973)
vec2 hash2d(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
p3 += dot(p3, p3.yzx+19.19);
return fract((p3.xx+p3.yz)*p3.zy);
}
void main() {
vec2 newUV = vUv;
vec4 color = vec4(1.,0.,0.,1.);
float c = circle(newUV, uMouse, 0.0, 0.2);
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
color = vec4(r, g, b, 1.);
gl_FragColor = color;
}`
}
好吧,假设你 set up three.js for transparency 那么我的猜测是
最后一部分
void main() {
vec2 newUV = vUv;
vec4 color = vec4(1.,0.,0.,1.);
float c = circle(newUV, uMouse, 0.0, 0.2);
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
float a = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).w; // added
color = vec4(r, g, b, a); // changed
gl_FragColor = color;
}`
这也可能会更好
vec4 c1 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .5));
vec4 c2 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .525));
vec4 c3 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .55));
float a = min(min(c1.a, c2.a), c3.a);
vec4 color = vec4(c1.r, c2.g, c3.b, a);
gl_FragColor = color;
您可能还需要预乘 alpha
gl_FragColor = color;
gl_FragColor.rgb *= gl_FragColor.a;
谢谢@gman,你帮助我理解了算法。我是这样解决的
void main() {
vec2 newUV = vUv;
float c = circle(newUV, uMouse, 0.0, 0.2);
float a = texture2D(tDiffuse, newUV.xy+c*(uVelo)).w; //added
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
vec4 color = vec4(r, g, b, r+g+b+a); //changed
gl_FragColor = color;
}
我正在尝试使用此 shader,但我需要一个透明背景,它呈现黑色背景。 我意识到这是在 fragmentShader 中完成的,但我还没有想出如何改变它,我什至不知道这是否可能。 哪位有shader经验的知道怎么告诉我吗?
var myEffect = {
uniforms: {
"tDiffuse": { value: null },
"distort": { value: 0 },
"resolution": { value: new THREE.Vector2(1., innerHeight / innerWidth) },
"uMouse": { value: new THREE.Vector2(-10, -10) },
"uVelo": { value: 0 },
"time": { value: 0 }
},
vertexShader: `uniform float time;
uniform float progress;
uniform vec2 resolution;
varying vec2 vUv;
uniform sampler2D texture1;
const float pi = 3.1415925;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );
}`,
fragmentShader: `uniform float time;
uniform float progress;
uniform sampler2D tDiffuse;
uniform vec2 resolution;
varying vec2 vUv;
uniform vec2 uMouse;
uniform float uVelo;
float circle(vec2 uv, vec2 disc_center, float disc_radius, float border_size) {
uv -= disc_center;
uv*=resolution;
float dist = sqrt(dot(uv, uv));
return smoothstep(disc_radius+border_size, disc_radius-border_size, dist);
}
float map(float value, float min1, float max1, float min2, float max2) {
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
float remap(float value, float inMin, float inMax, float outMin, float outMax) {
return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}
float hash12(vec2 p) {
float h = dot(p,vec2(127.1,311.7));
return fract(sin(h)*43758.5453123);
}
// #define HASHSCALE3 vec3(.1031, .1030, .0973)
vec2 hash2d(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
p3 += dot(p3, p3.yzx+19.19);
return fract((p3.xx+p3.yz)*p3.zy);
}
void main() {
vec2 newUV = vUv;
vec4 color = vec4(1.,0.,0.,1.);
float c = circle(newUV, uMouse, 0.0, 0.2);
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
color = vec4(r, g, b, 1.);
gl_FragColor = color;
}`
}
好吧,假设你 set up three.js for transparency 那么我的猜测是
最后一部分
void main() {
vec2 newUV = vUv;
vec4 color = vec4(1.,0.,0.,1.);
float c = circle(newUV, uMouse, 0.0, 0.2);
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
float a = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).w; // added
color = vec4(r, g, b, a); // changed
gl_FragColor = color;
}`
这也可能会更好
vec4 c1 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .5));
vec4 c2 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .525));
vec4 c3 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .55));
float a = min(min(c1.a, c2.a), c3.a);
vec4 color = vec4(c1.r, c2.g, c3.b, a);
gl_FragColor = color;
您可能还需要预乘 alpha
gl_FragColor = color;
gl_FragColor.rgb *= gl_FragColor.a;
谢谢@gman,你帮助我理解了算法。我是这样解决的
void main() {
vec2 newUV = vUv;
float c = circle(newUV, uMouse, 0.0, 0.2);
float a = texture2D(tDiffuse, newUV.xy+c*(uVelo)).w; //added
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
vec4 color = vec4(r, g, b, r+g+b+a); //changed
gl_FragColor = color;
}