我对着色器非常陌生,我一直在尝试创建一个可以对纹理进行alpha倾斜的着色器,并且我已经接近了,但是我很确定有更好的方法。
这就是我要做的https://codepen.io/tkmoney/pen/REYrpV
varying vec2 vUv;
precision highp float;
precision highp int;
uniform sampler2D texture;
uniform float mask_position;
uniform float fade_size;
void main(void) {
float mask_starting_point = (0.0 - fade_size);
float mask_ending_point = (1.0 - fade_size);
vec4 orig_color = texture2D(texture, vUv);
vec4 color = texture2D(texture, vUv);
float mask_p = smoothstep(mask_starting_point, mask_ending_point, mask_position);
//color.a *= (distance(vUv.x, split_center_point));
vec2 p = vUv;
if (p.x > (mask_p)){
color.a = 0.0;
}else{
color.a *= (smoothstep(mask_position, (mask_position - fade_size), p.x ));
}
gl_FragColor = color;
}
淡入并不能完全显示出整个图像。任何更好的方法来解决这个问题的见解都是很棒的。谢谢!
答案 0 :(得分:1)
您想要做的是使package com.example.testapp.adapter;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.example.testapp.DocumentViewerActivity;
import com.example.testapp.R;
import com.example.testapp.model.Item;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
public class ItemAdapter extends FirestoreRecyclerAdapter<Item, ItemAdapter.ItemHolder> {
public ItemAdapter(@NonNull FirestoreRecyclerOptions<Item> options) {
super(options);
}
@Override
protected void onBindViewHolder(@NonNull ItemHolder holder, int position, @NonNull Item item) {
final String tubeNumber = item.getNumber();
holder.mNumberTextView.setText(item.getNumber());
holder.mNameTextView.setText(item.getName());
holder.mFormulaTextView.setText(item.getFormula());
holder.mRangeTextView.setText(item.getRange());
holder.mInfoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), DocumentViewerActivity.class);
intent.putExtra("number", tubeNumber);
intent.putExtra("doctype", "info");
v.getContext().startActivity(intent);
}
});
holder.mManualButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), DocumentViewerActivity.class);
intent.putExtra("number", tubeNumber);
intent.putExtra("doctype", "manual");
v.getContext().startActivity(intent);
}
});
}
@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View tubeView = inflater.inflate(R.layout.item_tube, viewGroup, false);
return new ItemHolder(tubeView);
}
public static class ItemHolder extends RecyclerView.ViewHolder {
public TextView mNumberTextView;
public TextView mNameTextView;
public TextView mFormulaTextView;
public TextView mRangeTextView;
public Button mInfoButton;
public Button mManualButton;
public ItemHolder(View itemView){
super(itemView);
mNumberTextView = itemView.findViewById(R.id.number);
mNameTextView = itemView.findViewById(R.id.name);
mFormulaTextView = itemView.findViewById(R.id.formula);
mRangeTextView = itemView.findViewById(R.id.range);
mInfoButton = itemView.findViewById(R.id.info_btn);
mManualButton = itemView.findViewById(R.id.manual_btn);
}
}
}
左侧的区域可见,但您想隐藏右侧的。这可以通过step
来实现:
mask_position
如果要从可见区域平滑过渡到不可见区域,则必须使用smoothstep
。衰落的开始是color.a *= 1.0 - step(fade_size, p);
之前的一定数量,结束的是mask_position
之后的一定数量:
mask_position
这将导致图像的开始和结束永远不会完全消失。为了对此进行补偿,必须将[vUV.x]从[0.0,1.0]范围映射到[[float start_p = mask_position-fade_size;
float end_p = mask_position+fade_size;
color.a *= 1.0 - smoothstep(start_p, end_p, vUv.x);
,fade_size
]范围。 mix
可以轻松计算得出:
1.0-fade_size
如果最终剔除者的alpha通道低于微小阈值,则可以丢弃该片段:
float p = vUv.x * (1.0-2.0*fade_size) + fade_size;
color.a *= 1.0 - smoothstep(start_p, end_p, p;
最终着色器:
if ( color.a < 0.01 )
discard;
请参见示例:
varying vec2 vUv;
precision highp float;
precision highp int;
uniform sampler2D texture;
uniform float mask_position;
uniform float fade_size;
void main(void) {
vec4 color = texture2D(texture, vUv);
float start_p = mask_position-fade_size;
float end_p = mask_position+fade_size;
float p = mix(fade_size, 1.0-fade_size, vUv.x);
color.a *= 1.0 - smoothstep(start_p, end_p, p);
if ( color.a < 0.01 )
discard;
gl_FragColor = color;
}
var container;
var camera, scene, renderer;
var uniforms;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
var texture = new THREE.TextureLoader().load( 'https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/background.jpg' );
uniforms = {
u_time: { type: "f", value: 1.0 },
u_resolution: { type: "v2", value: new THREE.Vector2() },
u_mouse: { type: "v2", value: new THREE.Vector2() },
texture: {type: 't', value: texture},
fade_size: { type: 'f', value: 0.2 },
mask_position: { type: 'f', value: 0 }
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( {alpha : true} );
renderer.setClearColor(0xffffff, 0.0);
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
document.onmousemove = function(e){
uniforms.u_mouse.value.x = e.pageX
uniforms.u_mouse.value.y = e.pageY
}
}
function onWindowResize( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}
function animate() {
requestAnimationFrame( animate );
render();
}
var mask_step = 0.01;
var mask_val = 0.0;
function render() {
if ( mask_val >= 1.0) { mask_val = 1.0; mask_step = -0.01; }
else if ( mask_val <= -0.0) { mask_val = 0.0; mask_step = 0.01; }
mask_val += mask_step;
uniforms.mask_position.value = mask_val;
uniforms.u_time.value += 0.05;
renderer.render( scene, camera );
}