Plasma Shader移植到Spark AR后渲染异常(画面压缩至角落)求助
解决Spark AR中Plasma Shader画面压缩至角落的问题
问题背景
将ShaderToy中的Plasma Shader适配到Spark AR的sca格式后,画面被压缩至角落,且对输入参数direction vec2的作用不明确。
转换后的sca代码:
precision highp float; vec4 main( in vec2 direction, in float time, in vec2 touch, in vec2 screen ) { vec2 uv = fragment(std::getVertexTexCoord()); float t = time/.1 + touch.x; vec2 R = uv.xy, S = screen * 0.01, p = ( direction+direction - R ) / R * S, q = vec2(cos(-t / 165.), cos( t / 45.)) * S - p; t = 1. + cos( length( vec2(cos( t / 98.), sin( t / 178.)) * S - p ) / 30.) + cos( length( vec2(sin(-t / 124.), cos( t / 104.)) * S - p ) / 20.) + sin( length(q) / 25. ) * sin(q.x / 20.) * sin(q.y / 15.); return .5 + .5* cos( (time+touch.y) / vec4(63,78,45,1) + ( t + vec4(0,1,-.5,0) ) *3.14 ); }
原ShaderToy代码:
void mainImage( out vec4 O, vec2 U ) { float t = iTime/.1 + iMouse.x; vec2 R = iResolution.xy, S = vec2(160,100), p = ( U+U - R ) / R * S, q = vec2(cos(-t / 165.), cos( t / 45.)) * S - p; t = 1. + cos( length( vec2(cos( t / 98.), sin( t / 178.)) * S - p ) / 30.) + cos( length( vec2(sin(-t / 124.), cos( t / 104.)) * S - p ) / 20.) + sin( length(q) / 25. ) * sin(q.x / 20.) * sin(q.y / 15.); O = .5 + .5* cos( (iTime+iMouse.y) / vec4(63,78,45,1) + ( t + vec4(0,1,-.5,0) ) *3.14 ); }
解决思路
修正坐标系统映射错误
ShaderToy中U是当前像素的像素坐标,iResolution.xy是屏幕分辨率;而Spark AR中fragment(std::getVertexTexCoord())和direction都是归一化UV坐标(范围0-1),不是像素坐标。你错误地将归一化UV赋值给了代表分辨率的R,这直接导致了画面压缩。正确的映射逻辑:
- 用
screen对应原代码的iResolution.xy(即R) - 将归一化UV转换为像素坐标:
vec2 U = direction * screen;
- 用
明确
direction参数的作用
在Spark AR的sca shader入口函数中,direction就是当前片段的归一化UV坐标,和fragment(std::getVertexTexCoord())返回值完全一致,无需重复获取。还原原代码的缩放参数
S
原代码中S是固定的vec2(160,100),你改成了screen * 0.01,这会导致缩放比例随屏幕尺寸变化,破坏原效果的比例,需要改回固定值。
调整后的完整代码
precision highp float; vec4 main( in vec2 direction, in float time, in vec2 touch, in vec2 screen ) { float t = time / 0.1 + touch.x; vec2 R = screen; vec2 S = vec2(160, 100); vec2 U = direction * R; // 归一化UV转像素坐标 vec2 p = (U + U - R) / R * S; vec2 q = vec2(cos(-t / 165.), cos(t / 45.)) * S - p; t = 1.0 + cos(length(vec2(cos(t / 98.), sin(t / 178.)) * S - p) / 30.0) + cos(length(vec2(sin(-t / 124.), cos(t / 104.)) * S - p) / 20.0) + sin(length(q) / 25.0) * sin(q.x / 20.0) * sin(q.y / 15.0); return 0.5 + 0.5 * cos((time + touch.y) / vec4(63.0, 78.0, 45.0, 1.0) + (t + vec4(0.0, 1.0, -0.5, 0.0)) * 3.14159); }
内容的提问来源于stack exchange,提问作者Lee Probert
相关产品推荐
相关产品推荐

