ShaderToy 着色器转换为 PixiJS v4 的问题
Problem with ShaderToy shader converted to PixiJS v4
我正在尝试将最基本的 ShaderToy 着色器 (https://www.shadertoy.com/new) 转换为与 PixiJS v4.5.5 一起使用。我得到的是一个完全静止的背景:
背景应该像 ShaderToy 示例中那样在颜色之间移动和混合。我在控制台中没有收到任何错误。
我的代码:
let width = window.innerWidth;
let height = window.innerHeight;
let app = new PIXI.Application(width, height);
document.body.appendChild(app.view);
let shaderFrag = `
precision mediump float;
uniform vec3 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
void main() {
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = gl_FragCoord.xy/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
gl_FragColor = vec4(col,1.0);
}
`;
let container = new PIXI.Container();
container.filterArea = app.screen;
app.stage.addChild(container);
let filter = new PIXI.Filter(null, shaderFrag);
filter.uniforms.iResolution = [width, height, 1.0];
filter.uniforms.iTime = 1.0;
container.filters = [filter];
// Animate the filter
app.ticker.add(function(delta) {
filter.uniforms.iTime += 0.1;
});
这可能是什么问题?
PS:完全相同的着色器代码与 Three.js.
完美配合
您在 PixiJS 中遇到了错误。
见Comments in shader can comment out lines of code #5048
我调试了代码并进行了调查,PixiJs(版本 4.8.2)正在解析片段着色器文件,以找到制服。
查看原代码,我从库里复制过来的:
function extractUniformsFromString(string)
{
const maskRegex = new RegExp('^(projectionMatrix|uSampler|filterArea|filterClamp)$');
const uniforms = {};
let nameSplit;
// clean the lines a little - remove extra spaces / tabs etc
// then split along ';'
const lines = string.replace(/\s+/g, ' ').split(/\s*;\s*/);
// loop through..
for (let i = 0; i < lines.length; i++)
{
const line = lines[i].trim();
if (line.indexOf('uniform') > -1)
{
const splitLine = line.split(' ');
const type = splitLine[1];
let name = splitLine[2];
let size = 1;
if (name.indexOf('[') > -1)
{
// array!
nameSplit = name.split(/\[|]/);
name = nameSplit[0];
size *= Number(nameSplit[1]);
}
if (!name.match(maskRegex))
{
uniforms[name] = {
value: defaultValue(type, size),
name,
type,
};
}
}
}
return uniforms;
}
如果在统一声明之前有一行注释,就像在iTime
之前的片段着色器中一样,则无法找到统一。
这导致PixiJS的自动同步机制出现故障,并没有设置uniform的值。
解决方法很简单,去掉制服后面的注释即可:
precision mediump float;
uniform vec3 iResolution;
uniform float iTime;
....
参见示例:
let width = window.innerWidth;
let height = window.innerHeight;
let app = new PIXI.Application(width, height);
document.body.appendChild(app.view);
let shaderFrag = `
precision mediump float;
uniform vec3 iResolution;
uniform float iTime;
void main() {
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = gl_FragCoord.xy/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
gl_FragColor = vec4(col,1.0);
}
`;
let container = new PIXI.Container();
container.filterArea = app.screen;
app.stage.addChild(container);
let filter = new PIXI.Filter(null, shaderFrag);
filter.uniforms.iResolution = [width, height, 1.0];
filter.uniforms.iTime = [1.0];
container.filters = [filter];
app.ticker.add(function(delta) {
filter.uniforms.iTime[0] += 0.1;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
我正在尝试将最基本的 ShaderToy 着色器 (https://www.shadertoy.com/new) 转换为与 PixiJS v4.5.5 一起使用。我得到的是一个完全静止的背景:
背景应该像 ShaderToy 示例中那样在颜色之间移动和混合。我在控制台中没有收到任何错误。
我的代码:
let width = window.innerWidth;
let height = window.innerHeight;
let app = new PIXI.Application(width, height);
document.body.appendChild(app.view);
let shaderFrag = `
precision mediump float;
uniform vec3 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
void main() {
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = gl_FragCoord.xy/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
gl_FragColor = vec4(col,1.0);
}
`;
let container = new PIXI.Container();
container.filterArea = app.screen;
app.stage.addChild(container);
let filter = new PIXI.Filter(null, shaderFrag);
filter.uniforms.iResolution = [width, height, 1.0];
filter.uniforms.iTime = 1.0;
container.filters = [filter];
// Animate the filter
app.ticker.add(function(delta) {
filter.uniforms.iTime += 0.1;
});
这可能是什么问题?
PS:完全相同的着色器代码与 Three.js.
完美配合您在 PixiJS 中遇到了错误。
见Comments in shader can comment out lines of code #5048
我调试了代码并进行了调查,PixiJs(版本 4.8.2)正在解析片段着色器文件,以找到制服。
查看原代码,我从库里复制过来的:
function extractUniformsFromString(string)
{
const maskRegex = new RegExp('^(projectionMatrix|uSampler|filterArea|filterClamp)$');
const uniforms = {};
let nameSplit;
// clean the lines a little - remove extra spaces / tabs etc
// then split along ';'
const lines = string.replace(/\s+/g, ' ').split(/\s*;\s*/);
// loop through..
for (let i = 0; i < lines.length; i++)
{
const line = lines[i].trim();
if (line.indexOf('uniform') > -1)
{
const splitLine = line.split(' ');
const type = splitLine[1];
let name = splitLine[2];
let size = 1;
if (name.indexOf('[') > -1)
{
// array!
nameSplit = name.split(/\[|]/);
name = nameSplit[0];
size *= Number(nameSplit[1]);
}
if (!name.match(maskRegex))
{
uniforms[name] = {
value: defaultValue(type, size),
name,
type,
};
}
}
}
return uniforms;
}
如果在统一声明之前有一行注释,就像在iTime
之前的片段着色器中一样,则无法找到统一。
这导致PixiJS的自动同步机制出现故障,并没有设置uniform的值。
解决方法很简单,去掉制服后面的注释即可:
precision mediump float;
uniform vec3 iResolution;
uniform float iTime;
....
参见示例:
let width = window.innerWidth;
let height = window.innerHeight;
let app = new PIXI.Application(width, height);
document.body.appendChild(app.view);
let shaderFrag = `
precision mediump float;
uniform vec3 iResolution;
uniform float iTime;
void main() {
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = gl_FragCoord.xy/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
gl_FragColor = vec4(col,1.0);
}
`;
let container = new PIXI.Container();
container.filterArea = app.screen;
app.stage.addChild(container);
let filter = new PIXI.Filter(null, shaderFrag);
filter.uniforms.iResolution = [width, height, 1.0];
filter.uniforms.iTime = [1.0];
container.filters = [filter];
app.ticker.add(function(delta) {
filter.uniforms.iTime[0] += 0.1;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>