我正在尝试将最基本的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完美配合。
答案 0 :(得分:2)
您正遇到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的自动同步机制失效,并且未设置统一值。
解决方法很简单,只需删除制服后的注释即可:
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>