Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么我看到同一个着色器的不同显示?_Python_Glsl_Kivy_Shader - Fatal编程技术网

Python 为什么我看到同一个着色器的不同显示?

Python 为什么我看到同一个着色器的不同显示?,python,glsl,kivy,shader,Python,Glsl,Kivy,Shader,这里有一个例子说明了我问题的本质 main.py from kivy.app import App from kivy.clock import Clock from kivy.factory import Factory from kivy.graphics import RenderContext from kivy.properties import StringProperty from kivy.uix.widget import Widget import kivy.core.wi

这里有一个例子说明了我问题的本质

main.py

from kivy.app import App
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.graphics import RenderContext
from kivy.properties import StringProperty
from kivy.uix.widget import Widget

import kivy.core.window

shader = '''
$HEADER$

uniform vec2 resolution;

void main(void)
{
    vec2 position = (gl_FragCoord.xy / resolution.xy);

    float color = 0.0;
    color += position.y / position.x;
    if(color < 0.2) { color = 0.2; }
    vec3 output_color = vec3(color * 1.5, color, color * 2.0);

    gl_FragColor = vec4(output_color, 1.0);
}

'''

class ShaderWidget(Widget):
    fs = StringProperty(None)

    def __init__(self, **kwargs):
        self.canvas = RenderContext(use_parent_projection=True)
        super(ShaderWidget, self).__init__(**kwargs)
        self.canvas['time'] = Clock.get_boottime()
        Clock.schedule_interval(self.update_glsl, 1 / 60.)

    def update_glsl(self, *largs):
        self.canvas['time'] = Clock.get_boottime()
        self.canvas['resolution'] = [float(v) for v in self.size]

    def on_fs(self, instance, value):
        shader = self.canvas.shader
        shader.fs = value

class TestApp(App):
    def build(self):
        main_widget = Factory.MainWidget()
        main_widget.mini.fs = shader
        main_widget.mini2.fs = shader
        return main_widget

TestApp().run()
从kivy.app导入应用
从kivy.clock导入时钟
来自kivy工厂进口工厂
从kivy.graphics导入RenderContext
从kivy.properties导入StringProperty
从kivy.uix.widget导入widget
导入kivy.core.window
着色器=“”
$HEADER$
均匀vec2分辨率;
真空总管(真空)
{
vec2位置=(gl_FragCoord.xy/分辨率.xy);
浮动颜色=0.0;
颜色+=位置y/位置x;
如果(颜色<0.2){color=0.2;}
vec3输出颜色=vec3(颜色*1.5,颜色,颜色*2.0);
gl_FragColor=vec4(输出颜色,1.0);
}
'''
类ShaderWidget(小部件):
fs=StringProperty(无)
定义初始(自我,**kwargs):
self.canvas=RenderContext(使用\u parent\u projection=True)
超级(ShaderWidget,self)。\uuuuu init\uuuuuuu(**kwargs)
self.canvas['time']=Clock.get_boottime()
时钟。计划间隔(自更新glsl,1/60)
def更新\u glsl(自我,*largs):
self.canvas['time']=Clock.get_boottime()
self.canvas['resolution']=[self.size中v的浮点(v)]
_fs上的定义(自身、实例、值):
着色器=self.canvas.shader
shader.fs=值
类TestApp(应用程序):
def生成(自):
main\u widget=Factory.MainWidget()
main_widget.mini.fs=着色器
main_widget.mini2.fs=着色器
返回主窗口小部件
TestApp().run()
试验电压(千伏):

<MiniShaderWidget@ShaderWidget>:
    canvas:
        Color:
            rgb: 1.0, 1.0, 1.0
        Rectangle:
            pos: self.pos
            size: self.size


<MainWidget@ShaderWidget+FloatLayout>:
    mini: mini
    mini2: mini2

    BoxLayout
        MiniShaderWidget
            id: mini

        Label
            text: 'label'

        MiniShaderWidget
            id: mini2
:
画布:
颜色:
rgb:1.0、1.0、1.0
矩形:
pos:self.pos
大小:self.size
:
迷你:迷你
mini2:mini2
盒子布局
迷你短剑
id:mini
标签
文本:“标签”
迷你短剑
id:mini2
在这个应用程序中,我有一个由三个相等部分组成的窗口

来自同一源(变量着色器)的着色器将向左和向右绘制

着色器看起来像从白色到紫色的过渡

在中间,我添加了一个名为“label”的标签,以便于区分左着色器和右着色器

我从examples/shader/rotated.py(kivy github)中对这个示例进行了修改

问题是: 我希望在左侧和右侧看到相同的图片,但我看到相同着色器的不同图像。 为什么会这样

是否可以在左右两侧制作相同的图片?

有趣的问题

实际上,在左侧和右侧有两个不同的“图片”,它看起来像是同一个着色器分布在窗口的中间,标签小部件“浮动在顶部”。但这是一种错觉

您确实有三个不同的小部件,每个都不同。但是产生这种错觉是因为着色器函数使用屏幕空间的x,y位置来确定颜色

为了更清楚地说明这一点,我添加了第二个着色器并调整了配色方案:

from kivy.app import App
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.graphics import RenderContext
from kivy.properties import StringProperty
from kivy.uix.widget import Widget

import kivy.core.window

shader = '''
$HEADER$

uniform vec2 resolution;

void main(void)
{
    vec2 position = (gl_FragCoord.xy / resolution.xy);

    float color = 0.0;
    color += position.y / position.x;
    if(color < 0.2) { color = 0.2; }
    vec3 output_color = vec3(color * 1.5, color, color * 2.0);

    gl_FragColor = vec4(output_color, 1.0);
}

'''

shader2 = '''
$HEADER$

uniform vec2 resolution;

void main(void)
{
    vec2 position = (gl_FragCoord.xy / resolution.xy);

    float color = 0.0;
    color += position.y / position.x;
    if(color < 0.2) { color = 0.2; }
    vec3 output_color = vec3(color * 1.5, color * 2.0, color);

    gl_FragColor = vec4(output_color, 1.0);
}

'''

class ShaderWidget(Widget):
    fs = StringProperty(None)

    def __init__(self, **kwargs):
        self.canvas = RenderContext(use_parent_projection=True)
        super(ShaderWidget, self).__init__(**kwargs)
        self.canvas['time'] = Clock.get_boottime()
        Clock.schedule_interval(self.update_glsl, 1 / 60.)

    def update_glsl(self, *largs):
        self.canvas['time'] = Clock.get_boottime()
        self.canvas['resolution'] = [float(v) for v in self.size]

    def on_fs(self, instance, value):
        shader = self.canvas.shader
        shader.fs = value
        shader2 = self.canvas.shader
        shader2.fs = value

class TestApp(App):
    def build(self):
        main_widget = Factory.MainWidget()
        main_widget.mini.fs = shader
        main_widget.mini2.fs = shader2
        return main_widget

TestApp().run()
从kivy.app导入应用
从kivy.clock导入时钟
来自kivy工厂进口工厂
从kivy.graphics导入RenderContext
从kivy.properties导入StringProperty
从kivy.uix.widget导入widget
导入kivy.core.window
着色器=“”
$HEADER$
均匀vec2分辨率;
真空总管(真空)
{
vec2位置=(gl_FragCoord.xy/分辨率.xy);
浮动颜色=0.0;
颜色+=位置y/位置x;
如果(颜色<0.2){color=0.2;}
vec3输出颜色=vec3(颜色*1.5,颜色,颜色*2.0);
gl_FragColor=vec4(输出颜色,1.0);
}
'''
着色器2=''
$HEADER$
均匀vec2分辨率;
真空总管(真空)
{
vec2位置=(gl_FragCoord.xy/分辨率.xy);
浮动颜色=0.0;
颜色+=位置y/位置x;
如果(颜色<0.2){color=0.2;}
vec3输出颜色=vec3(颜色*1.5,颜色*2.0,颜色);
gl_FragColor=vec4(输出颜色,1.0);
}
'''
类ShaderWidget(小部件):
fs=StringProperty(无)
定义初始(自我,**kwargs):
self.canvas=RenderContext(使用\u parent\u projection=True)
超级(ShaderWidget,self)。\uuuuu init\uuuuuuu(**kwargs)
self.canvas['time']=Clock.get_boottime()
时钟。计划间隔(自更新glsl,1/60)
def更新\u glsl(自我,*largs):
self.canvas['time']=Clock.get_boottime()
self.canvas['resolution']=[self.size中v的浮点(v)]
_fs上的定义(自身、实例、值):
着色器=self.canvas.shader
shader.fs=值
shader2=self.canvas.shader
shader2.fs=值
类TestApp(应用程序):
def生成(自):
main\u widget=Factory.MainWidget()
main_widget.mini.fs=着色器
main_widget.mini2.fs=shader2
返回主窗口小部件
TestApp().run()
我想你的下一个问题是,如何将位置坐标传递给小部件的着色器,而不是屏幕空间?

有趣的问题

实际上,在左侧和右侧有两个不同的“图片”,它看起来像是同一个着色器分布在窗口的中间,标签小部件“浮动在顶部”。但这是一种错觉

您确实有三个不同的小部件,每个都不同。但是产生这种错觉是因为着色器函数使用屏幕空间的x,y位置来确定颜色

为了更清楚地说明这一点,我添加了第二个着色器并调整了配色方案:

from kivy.app import App
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.graphics import RenderContext
from kivy.properties import StringProperty
from kivy.uix.widget import Widget

import kivy.core.window

shader = '''
$HEADER$

uniform vec2 resolution;

void main(void)
{
    vec2 position = (gl_FragCoord.xy / resolution.xy);

    float color = 0.0;
    color += position.y / position.x;
    if(color < 0.2) { color = 0.2; }
    vec3 output_color = vec3(color * 1.5, color, color * 2.0);

    gl_FragColor = vec4(output_color, 1.0);
}

'''

shader2 = '''
$HEADER$

uniform vec2 resolution;

void main(void)
{
    vec2 position = (gl_FragCoord.xy / resolution.xy);

    float color = 0.0;
    color += position.y / position.x;
    if(color < 0.2) { color = 0.2; }
    vec3 output_color = vec3(color * 1.5, color * 2.0, color);

    gl_FragColor = vec4(output_color, 1.0);
}

'''

class ShaderWidget(Widget):
    fs = StringProperty(None)

    def __init__(self, **kwargs):
        self.canvas = RenderContext(use_parent_projection=True)
        super(ShaderWidget, self).__init__(**kwargs)
        self.canvas['time'] = Clock.get_boottime()
        Clock.schedule_interval(self.update_glsl, 1 / 60.)

    def update_glsl(self, *largs):
        self.canvas['time'] = Clock.get_boottime()
        self.canvas['resolution'] = [float(v) for v in self.size]

    def on_fs(self, instance, value):
        shader = self.canvas.shader
        shader.fs = value
        shader2 = self.canvas.shader
        shader2.fs = value

class TestApp(App):
    def build(self):
        main_widget = Factory.MainWidget()
        main_widget.mini.fs = shader
        main_widget.mini2.fs = shader2
        return main_widget

TestApp().run()
从kivy.app导入应用
从kivy.clock导入时钟
来自kivy工厂进口工厂
从kivy.graphics导入RenderContext
从kivy.properties导入StringProperty
从kivy.uix.widget导入widget
导入kivy.core.window
着色器=“”
$HEADER$
均匀vec2分辨率;
真空总管(真空)
{
vec2位置=(gl_FragCoord.xy/分辨率.xy);
浮动颜色=0.0;
颜色+=位置y/位置x;
如果(颜色<0.2){color=0.2;}
vec3输出颜色=vec3(颜色*1.5,颜色,颜色*2.0);
gl_FragColor=vec4(输出颜色,1.0);
}
'''
着色器
 pos: self.pos
 size: self.size
size: (self.width / 3, self.height)